summaryrefslogtreecommitdiffstats
path: root/src/video_core/shader/decode
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2019-12-16 08:09:24 +0100
committerReinUsesLisp <reinuseslisp@airmail.cc>2019-12-16 08:09:24 +0100
commite09c1fbc1f5868b1bff54a69a58fd6d788c54251 (patch)
tree4c77f899cb97fa590fbb028ef9ba3c5187900b99 /src/video_core/shader/decode
parentshader/texture: Enable arrayed TLD4 (diff)
downloadyuzu-e09c1fbc1f5868b1bff54a69a58fd6d788c54251.tar
yuzu-e09c1fbc1f5868b1bff54a69a58fd6d788c54251.tar.gz
yuzu-e09c1fbc1f5868b1bff54a69a58fd6d788c54251.tar.bz2
yuzu-e09c1fbc1f5868b1bff54a69a58fd6d788c54251.tar.lz
yuzu-e09c1fbc1f5868b1bff54a69a58fd6d788c54251.tar.xz
yuzu-e09c1fbc1f5868b1bff54a69a58fd6d788c54251.tar.zst
yuzu-e09c1fbc1f5868b1bff54a69a58fd6d788c54251.zip
Diffstat (limited to 'src/video_core/shader/decode')
-rw-r--r--src/video_core/shader/decode/texture.cpp74
1 files changed, 56 insertions, 18 deletions
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index 6b6458993..dd8ff851e 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -91,18 +91,17 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
case OpCode::Id::TLD4: {
UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(TextureMiscMode::NDV),
"NDV is not implemented");
- UNIMPLEMENTED_IF_MSG(instr.tld4.UsesMiscMode(TextureMiscMode::PTP),
- "PTP is not implemented");
-
const auto texture_type = instr.tld4.texture_type.Value();
const bool depth_compare = is_bindless ? instr.tld4_b.UsesMiscMode(TextureMiscMode::DC)
: instr.tld4.UsesMiscMode(TextureMiscMode::DC);
const bool is_array = instr.tld4.array != 0;
const bool is_aoffi = is_bindless ? instr.tld4_b.UsesMiscMode(TextureMiscMode::AOFFI)
: instr.tld4.UsesMiscMode(TextureMiscMode::AOFFI);
- WriteTexInstructionFloat(
- bb, instr,
- GetTld4Code(instr, texture_type, depth_compare, is_array, is_aoffi, is_bindless));
+ const bool is_ptp = is_bindless ? instr.tld4_b.UsesMiscMode(TextureMiscMode::PTP)
+ : instr.tld4.UsesMiscMode(TextureMiscMode::PTP);
+ WriteTexInstructionFloat(bb, instr,
+ GetTld4Code(instr, texture_type, depth_compare, is_array, is_aoffi,
+ is_ptp, is_bindless));
break;
}
case OpCode::Id::TLD4S: {
@@ -145,7 +144,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
Node4 values;
for (u32 element = 0; element < values.size(); ++element) {
auto coords_copy = coords;
- MetaTexture meta{sampler, {}, depth_compare, aoffi, {}, {}, {}, component, element};
+ MetaTexture meta{sampler, {}, depth_compare, aoffi, {}, {}, {}, {}, component, element};
values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
}
@@ -194,7 +193,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
}
for (u32 element = 0; element < values.size(); ++element) {
- MetaTexture meta{*sampler, {}, {}, {}, derivates, {}, {}, {}, element};
+ MetaTexture meta{*sampler, {}, {}, {}, {}, derivates, {}, {}, {}, element};
values[element] = Operation(OperationCode::TextureGradient, std::move(meta), coords);
}
@@ -234,7 +233,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
if (!instr.txq.IsComponentEnabled(element)) {
continue;
}
- MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, element};
+ MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, {}, element};
const Node value =
Operation(OperationCode::TextureQueryDimensions, meta,
GetRegister(instr.gpr8.Value() + (is_bindless ? 1 : 0)));
@@ -303,7 +302,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
continue;
}
auto params = coords;
- MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, element};
+ MetaTexture meta{*sampler, {}, {}, {}, {}, {}, {}, {}, {}, element};
const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params));
SetTemporary(bb, indexer++, value);
}
@@ -542,7 +541,7 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type,
for (u32 element = 0; element < values.size(); ++element) {
auto copy_coords = coords;
- MetaTexture meta{*sampler, array, depth_compare, aoffi, {}, bias, lod, {}, element};
+ MetaTexture meta{*sampler, array, depth_compare, aoffi, {}, {}, bias, lod, {}, element};
values[element] = Operation(read_method, meta, std::move(copy_coords));
}
@@ -639,7 +638,9 @@ Node4 ShaderIR::GetTexsCode(Instruction instr, TextureType texture_type,
}
Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool depth_compare,
- bool is_array, bool is_aoffi, bool is_bindless) {
+ bool is_array, bool is_aoffi, bool is_ptp, bool is_bindless) {
+ ASSERT_MSG(!(is_aoffi && is_ptp), "AOFFI and PTP can't be enabled at the same time");
+
const std::size_t coord_count = GetCoordCount(texture_type);
// If enabled arrays index is always stored in the gpr8 field
@@ -665,12 +666,15 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
return values;
}
- std::vector<Node> aoffi;
+ std::vector<Node> aoffi, ptp;
if (is_aoffi) {
aoffi = GetAoffiCoordinates(GetRegister(parameter_register++), coord_count, true);
+ } else if (is_ptp) {
+ ptp = GetPtpCoordinates(
+ {GetRegister(parameter_register++), GetRegister(parameter_register++)});
}
- Node dc{};
+ Node dc;
if (depth_compare) {
dc = GetRegister(parameter_register++);
}
@@ -680,8 +684,8 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de
for (u32 element = 0; element < values.size(); ++element) {
auto coords_copy = coords;
- MetaTexture meta{*sampler, GetRegister(array_register), dc, aoffi, {}, {}, {}, component,
- element};
+ MetaTexture meta{
+ *sampler, GetRegister(array_register), dc, aoffi, ptp, {}, {}, {}, component, element};
values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy));
}
@@ -714,7 +718,7 @@ Node4 ShaderIR::GetTldCode(Tegra::Shader::Instruction instr) {
Node4 values;
for (u32 element = 0; element < values.size(); ++element) {
auto coords_copy = coords;
- MetaTexture meta{sampler, array_register, {}, {}, {}, {}, lod, {}, element};
+ MetaTexture meta{sampler, array_register, {}, {}, {}, {}, {}, lod, {}, element};
values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy));
}
@@ -759,7 +763,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is
Node4 values;
for (u32 element = 0; element < values.size(); ++element) {
auto coords_copy = coords;
- MetaTexture meta{sampler, array, {}, {}, {}, {}, lod, {}, element};
+ MetaTexture meta{sampler, array, {}, {}, {}, {}, {}, lod, {}, element};
values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy));
}
return values;
@@ -824,4 +828,38 @@ std::vector<Node> ShaderIR::GetAoffiCoordinates(Node aoffi_reg, std::size_t coor
return aoffi;
}
+std::vector<Node> ShaderIR::GetPtpCoordinates(std::array<Node, 2> ptp_regs) {
+ static constexpr u32 num_entries = 8;
+
+ std::vector<Node> ptp;
+ ptp.reserve(num_entries);
+
+ const auto global_size = static_cast<s64>(global_code.size());
+ const std::optional low = TrackImmediate(ptp_regs[0], global_code, global_size);
+ const std::optional high = TrackImmediate(ptp_regs[1], global_code, global_size);
+ if (!low || !high) {
+ for (u32 entry = 0; entry < num_entries; ++entry) {
+ const u32 reg = entry / 4;
+ const u32 offset = entry % 4;
+ const Node value = BitfieldExtract(ptp_regs[reg], offset * 8, 6);
+ const Node condition =
+ Operation(OperationCode::LogicalIGreaterEqual, value, Immediate(32));
+ const Node negative = Operation(OperationCode::IAdd, value, Immediate(-64));
+ ptp.push_back(Operation(OperationCode::Select, condition, negative, value));
+ }
+ return ptp;
+ }
+
+ const u64 immediate = (static_cast<u64>(*high) << 32) | static_cast<u64>(*low);
+ for (u32 entry = 0; entry < num_entries; ++entry) {
+ s32 value = (immediate >> (entry * 8)) & 0b111111;
+ if (value >= 32) {
+ value -= 64;
+ }
+ ptp.push_back(Immediate(value));
+ }
+
+ return ptp;
+}
+
} // namespace VideoCommon::Shader