summaryrefslogtreecommitdiff
path: root/src/video_core/shader/decode
diff options
context:
space:
mode:
authorGravatar bunnei2019-05-19 14:02:58 -0400
committerGravatar GitHub2019-05-19 14:02:58 -0400
commitd49efbfb4aa4e935f6c753871d6af6534701f542 (patch)
tree79608391a32719a0be20c898fc79aba93f9f1d48 /src/video_core/shader/decode
parentMerge pull request #2410 from lioncash/affinity (diff)
parentshader_ir/other: Implement IPA.IDX (diff)
downloadyuzu-d49efbfb4aa4e935f6c753871d6af6534701f542.tar.gz
yuzu-d49efbfb4aa4e935f6c753871d6af6534701f542.tar.xz
yuzu-d49efbfb4aa4e935f6c753871d6af6534701f542.zip
Merge pull request #2441 from ReinUsesLisp/al2p
shader: Implement AL2P and ALD.PHYS
Diffstat (limited to 'src/video_core/shader/decode')
-rw-r--r--src/video_core/shader/decode/memory.cpp30
-rw-r--r--src/video_core/shader/decode/other.cpp13
2 files changed, 33 insertions, 10 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index ea1092db1..6a992c543 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -12,6 +12,8 @@
12#include "video_core/engines/shader_bytecode.h" 12#include "video_core/engines/shader_bytecode.h"
13#include "video_core/shader/shader_ir.h" 13#include "video_core/shader/shader_ir.h"
14 14
15#pragma optimize("", off)
16
15namespace VideoCommon::Shader { 17namespace VideoCommon::Shader {
16 18
17using Tegra::Shader::Attribute; 19using Tegra::Shader::Attribute;
@@ -47,17 +49,20 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
47 "Indirect attribute loads are not supported"); 49 "Indirect attribute loads are not supported");
48 UNIMPLEMENTED_IF_MSG((instr.attribute.fmt20.immediate.Value() % sizeof(u32)) != 0, 50 UNIMPLEMENTED_IF_MSG((instr.attribute.fmt20.immediate.Value() % sizeof(u32)) != 0,
49 "Unaligned attribute loads are not supported"); 51 "Unaligned attribute loads are not supported");
52 UNIMPLEMENTED_IF_MSG(instr.attribute.fmt20.IsPhysical() &&
53 instr.attribute.fmt20.size != Tegra::Shader::AttributeSize::Word,
54 "Non-32 bits PHYS reads are not implemented");
50 55
51 Tegra::Shader::IpaMode input_mode{Tegra::Shader::IpaInterpMode::Pass, 56 const Node buffer{GetRegister(instr.gpr39)};
52 Tegra::Shader::IpaSampleMode::Default};
53 57
54 u64 next_element = instr.attribute.fmt20.element; 58 u64 next_element = instr.attribute.fmt20.element;
55 auto next_index = static_cast<u64>(instr.attribute.fmt20.index.Value()); 59 auto next_index = static_cast<u64>(instr.attribute.fmt20.index.Value());
56 60
57 const auto LoadNextElement = [&](u32 reg_offset) { 61 const auto LoadNextElement = [&](u32 reg_offset) {
58 const Node buffer = GetRegister(instr.gpr39); 62 const Node attribute{instr.attribute.fmt20.IsPhysical()
59 const Node attribute = GetInputAttribute(static_cast<Attribute::Index>(next_index), 63 ? GetPhysicalInputAttribute(instr.gpr8, buffer)
60 next_element, input_mode, buffer); 64 : GetInputAttribute(static_cast<Attribute::Index>(next_index),
65 next_element, buffer)};
61 66
62 SetRegister(bb, instr.gpr0.Value() + reg_offset, attribute); 67 SetRegister(bb, instr.gpr0.Value() + reg_offset, attribute);
63 68
@@ -239,6 +244,21 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
239 } 244 }
240 break; 245 break;
241 } 246 }
247 case OpCode::Id::AL2P: {
248 // Ignore al2p.direction since we don't care about it.
249
250 // Calculate emulation fake physical address.
251 const Node fixed_address{Immediate(static_cast<u32>(instr.al2p.address))};
252 const Node reg{GetRegister(instr.gpr8)};
253 const Node fake_address{Operation(OperationCode::IAdd, NO_PRECISE, reg, fixed_address)};
254
255 // Set the fake address to target register.
256 SetRegister(bb, instr.gpr0, fake_address);
257
258 // Signal the shader IR to declare all possible attributes and varyings
259 uses_physical_attributes = true;
260 break;
261 }
242 default: 262 default:
243 UNIMPLEMENTED_MSG("Unhandled memory instruction: {}", opcode->get().GetName()); 263 UNIMPLEMENTED_MSG("Unhandled memory instruction: {}", opcode->get().GetName());
244 } 264 }
diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp
index d750a2936..fa17c45b5 100644
--- a/src/video_core/shader/decode/other.cpp
+++ b/src/video_core/shader/decode/other.cpp
@@ -130,15 +130,18 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
130 break; 130 break;
131 } 131 }
132 case OpCode::Id::IPA: { 132 case OpCode::Id::IPA: {
133 const auto& attribute = instr.attribute.fmt28; 133 const bool is_physical = instr.ipa.idx && instr.gpr8.Value() != 0xff;
134
135 const auto attribute = instr.attribute.fmt28;
134 const Tegra::Shader::IpaMode input_mode{instr.ipa.interp_mode.Value(), 136 const Tegra::Shader::IpaMode input_mode{instr.ipa.interp_mode.Value(),
135 instr.ipa.sample_mode.Value()}; 137 instr.ipa.sample_mode.Value()};
136 138
137 const Node attr = GetInputAttribute(attribute.index, attribute.element, input_mode); 139 Node value = is_physical ? GetPhysicalInputAttribute(instr.gpr8)
138 Node value = attr; 140 : GetInputAttribute(attribute.index, attribute.element);
139 const Tegra::Shader::Attribute::Index index = attribute.index.Value(); 141 const Tegra::Shader::Attribute::Index index = attribute.index.Value();
140 if (index >= Tegra::Shader::Attribute::Index::Attribute_0 && 142 const bool is_generic = index >= Tegra::Shader::Attribute::Index::Attribute_0 &&
141 index <= Tegra::Shader::Attribute::Index::Attribute_31) { 143 index <= Tegra::Shader::Attribute::Index::Attribute_31;
144 if (is_generic || is_physical) {
142 // TODO(Blinkhawk): There are cases where a perspective attribute use PASS. 145 // TODO(Blinkhawk): There are cases where a perspective attribute use PASS.
143 // In theory by setting them as perspective, OpenGL does the perspective correction. 146 // In theory by setting them as perspective, OpenGL does the perspective correction.
144 // A way must figured to reverse the last step of it. 147 // A way must figured to reverse the last step of it.