diff options
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/translate/impl')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/load_store_attribute.cpp | 38 |
1 files changed, 25 insertions, 13 deletions
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)}; |