diff options
Diffstat (limited to '')
4 files changed, 37 insertions, 14 deletions
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index ed1e0dd3b..e4e9b260c 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -307,6 +307,14 @@ void IREmitter::SetAttribute(IR::Attribute attribute, const F32& value) { | |||
| 307 | Inst(Opcode::SetAttribute, attribute, value); | 307 | Inst(Opcode::SetAttribute, attribute, value); |
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | F32 IREmitter::GetAttributeIndexed(IR::U32 phys_address) { | ||
| 311 | return Inst<F32>(Opcode::GetAttributeIndexed, phys_address); | ||
| 312 | } | ||
| 313 | |||
| 314 | void IREmitter::SetAttributeIndexed(IR::U32 phys_address, const F32& value) { | ||
| 315 | Inst(Opcode::SetAttributeIndexed, phys_address, value); | ||
| 316 | } | ||
| 317 | |||
| 310 | void IREmitter::SetFragColor(u32 index, u32 component, const F32& value) { | 318 | void IREmitter::SetFragColor(u32 index, u32 component, const F32& value) { |
| 311 | Inst(Opcode::SetFragColor, Imm32(index), Imm32(component), value); | 319 | Inst(Opcode::SetFragColor, Imm32(index), Imm32(component), value); |
| 312 | } | 320 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index 42756af43..afa8bd924 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -76,6 +76,9 @@ public: | |||
| 76 | [[nodiscard]] F32 GetAttribute(IR::Attribute attribute); | 76 | [[nodiscard]] F32 GetAttribute(IR::Attribute attribute); |
| 77 | void SetAttribute(IR::Attribute attribute, const F32& value); | 77 | void SetAttribute(IR::Attribute attribute, const F32& value); |
| 78 | 78 | ||
| 79 | [[nodiscard]] F32 GetAttributeIndexed(IR::U32 phys_address); | ||
| 80 | void SetAttributeIndexed(IR::U32 phys_address, const F32& value); | ||
| 81 | |||
| 79 | void SetFragColor(u32 index, u32 component, const F32& value); | 82 | void SetFragColor(u32 index, u32 component, const F32& value); |
| 80 | void SetFragDepth(const F32& value); | 83 | void SetFragDepth(const F32& value); |
| 81 | 84 | ||
diff --git a/src/shader_recompiler/frontend/maxwell/program.cpp b/src/shader_recompiler/frontend/maxwell/program.cpp index 58caa35a1..aaf2a74a7 100644 --- a/src/shader_recompiler/frontend/maxwell/program.cpp +++ b/src/shader_recompiler/frontend/maxwell/program.cpp | |||
| @@ -87,7 +87,7 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo | |||
| 87 | Optimization::DeadCodeEliminationPass(program); | 87 | Optimization::DeadCodeEliminationPass(program); |
| 88 | Optimization::IdentityRemovalPass(program); | 88 | Optimization::IdentityRemovalPass(program); |
| 89 | Optimization::VerificationPass(program); | 89 | Optimization::VerificationPass(program); |
| 90 | Optimization::CollectShaderInfoPass(program); | 90 | Optimization::CollectShaderInfoPass(env, program); |
| 91 | CollectInterpolationInfo(env, program); | 91 | CollectInterpolationInfo(env, program); |
| 92 | return program; | 92 | return program; |
| 93 | } | 93 | } |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/load_store_attribute.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/load_store_attribute.cpp index 54bc1e34c..0d248c020 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/load_store_attribute.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/load_store_attribute.cpp | |||
| @@ -31,7 +31,7 @@ enum class SampleMode : u64 { | |||
| 31 | Offset, | 31 | Offset, |
| 32 | }; | 32 | }; |
| 33 | 33 | ||
| 34 | int NumElements(Size size) { | 34 | u32 NumElements(Size size) { |
| 35 | switch (size) { | 35 | switch (size) { |
| 36 | case Size::B32: | 36 | case Size::B32: |
| 37 | return 1; | 37 | return 1; |
| @@ -65,15 +65,21 @@ void TranslatorVisitor::ALD(u64 insn) { | |||
| 65 | if (ald.patch != 0) { | 65 | if (ald.patch != 0) { |
| 66 | throw NotImplementedException("P"); | 66 | throw NotImplementedException("P"); |
| 67 | } | 67 | } |
| 68 | if (ald.index_reg != IR::Reg::RZ) { | ||
| 69 | throw NotImplementedException("Indexed"); | ||
| 70 | } | ||
| 71 | const u64 offset{ald.absolute_offset.Value()}; | 68 | const u64 offset{ald.absolute_offset.Value()}; |
| 72 | if (offset % 4 != 0) { | 69 | if (offset % 4 != 0) { |
| 73 | throw NotImplementedException("Unaligned absolute offset {}", offset); | 70 | throw NotImplementedException("Unaligned absolute offset {}", offset); |
| 74 | } | 71 | } |
| 75 | const int num_elements{NumElements(ald.size)}; | 72 | const u32 num_elements{NumElements(ald.size)}; |
| 76 | for (int element = 0; element < num_elements; ++element) { | 73 | if (ald.index_reg != IR::Reg::RZ) { |
| 74 | const IR::U32 index_value = X(ald.index_reg); | ||
| 75 | for (u32 element = 0; element < num_elements; ++element) { | ||
| 76 | const IR::U32 final_offset = | ||
| 77 | element == 0 ? index_value : IR::U32{ir.IAdd(index_value, ir.Imm32(element * 4U))}; | ||
| 78 | F(ald.dest_reg + element, ir.GetAttributeIndexed(final_offset)); | ||
| 79 | } | ||
| 80 | return; | ||
| 81 | } | ||
| 82 | for (u32 element = 0; element < num_elements; ++element) { | ||
| 77 | F(ald.dest_reg + element, ir.GetAttribute(IR::Attribute{offset / 4 + element})); | 83 | F(ald.dest_reg + element, ir.GetAttribute(IR::Attribute{offset / 4 + element})); |
| 78 | } | 84 | } |
| 79 | } | 85 | } |
| @@ -103,8 +109,17 @@ void TranslatorVisitor::AST(u64 insn) { | |||
| 103 | if (offset % 4 != 0) { | 109 | if (offset % 4 != 0) { |
| 104 | throw NotImplementedException("Unaligned absolute offset {}", offset); | 110 | throw NotImplementedException("Unaligned absolute offset {}", offset); |
| 105 | } | 111 | } |
| 106 | const int num_elements{NumElements(ast.size)}; | 112 | const u32 num_elements{NumElements(ast.size)}; |
| 107 | for (int element = 0; element < num_elements; ++element) { | 113 | if (ast.index_reg != IR::Reg::RZ) { |
| 114 | const IR::U32 index_value = X(ast.index_reg); | ||
| 115 | for (u32 element = 0; element < num_elements; ++element) { | ||
| 116 | const IR::U32 final_offset = | ||
| 117 | element == 0 ? index_value : IR::U32{ir.IAdd(index_value, ir.Imm32(element * 4U))}; | ||
| 118 | ir.SetAttributeIndexed(final_offset, F(ast.src_reg + element)); | ||
| 119 | } | ||
| 120 | return; | ||
| 121 | } | ||
| 122 | for (u32 element = 0; element < num_elements; ++element) { | ||
| 108 | ir.SetAttribute(IR::Attribute{offset / 4 + element}, F(ast.src_reg + element)); | 123 | ir.SetAttribute(IR::Attribute{offset / 4 + element}, F(ast.src_reg + element)); |
| 109 | } | 124 | } |
| 110 | } | 125 | } |
| @@ -134,12 +149,9 @@ void TranslatorVisitor::IPA(u64 insn) { | |||
| 134 | // gl_FragColor = colors[idx]; | 149 | // gl_FragColor = colors[idx]; |
| 135 | // } | 150 | // } |
| 136 | const bool is_indexed{ipa.idx != 0 && ipa.index_reg != IR::Reg::RZ}; | 151 | const bool is_indexed{ipa.idx != 0 && ipa.index_reg != IR::Reg::RZ}; |
| 137 | if (is_indexed) { | ||
| 138 | throw NotImplementedException("IDX"); | ||
| 139 | } | ||
| 140 | |||
| 141 | const IR::Attribute attribute{ipa.attribute}; | 152 | const IR::Attribute attribute{ipa.attribute}; |
| 142 | IR::F32 value{ir.GetAttribute(attribute)}; | 153 | IR::F32 value{is_indexed ? ir.GetAttributeIndexed(X(ipa.index_reg)) |
| 154 | : ir.GetAttribute(attribute)}; | ||
| 143 | if (IR::IsGeneric(attribute)) { | 155 | if (IR::IsGeneric(attribute)) { |
| 144 | const ProgramHeader& sph{env.SPH()}; | 156 | const ProgramHeader& sph{env.SPH()}; |
| 145 | const u32 attr_index{IR::GenericAttributeIndex(attribute)}; | 157 | const u32 attr_index{IR::GenericAttributeIndex(attribute)}; |