diff options
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell')
3 files changed, 27 insertions, 13 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/program.cpp b/src/shader_recompiler/frontend/maxwell/program.cpp index ab67446c8..20a1d61cc 100644 --- a/src/shader_recompiler/frontend/maxwell/program.cpp +++ b/src/shader_recompiler/frontend/maxwell/program.cpp | |||
| @@ -70,6 +70,11 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo | |||
| 70 | program.stage = env.ShaderStage(); | 70 | program.stage = env.ShaderStage(); |
| 71 | program.local_memory_size = env.LocalMemorySize(); | 71 | program.local_memory_size = env.LocalMemorySize(); |
| 72 | switch (program.stage) { | 72 | switch (program.stage) { |
| 73 | case Stage::TessellationControl: { | ||
| 74 | const ProgramHeader& sph{env.SPH()}; | ||
| 75 | program.invocations = sph.common2.threads_per_input_primitive; | ||
| 76 | break; | ||
| 77 | } | ||
| 73 | case Stage::Geometry: { | 78 | case Stage::Geometry: { |
| 74 | const ProgramHeader& sph{env.SPH()}; | 79 | const ProgramHeader& sph{env.SPH()}; |
| 75 | program.output_topology = sph.common3.output_topology; | 80 | program.output_topology = sph.common3.output_topology; |
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 eb6a80de2..7d7dcc3cb 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 | |||
| @@ -70,12 +70,6 @@ void TranslatorVisitor::ALD(u64 insn) { | |||
| 70 | BitField<47, 2, Size> size; | 70 | BitField<47, 2, Size> size; |
| 71 | } const ald{insn}; | 71 | } const ald{insn}; |
| 72 | 72 | ||
| 73 | if (ald.o != 0) { | ||
| 74 | throw NotImplementedException("O"); | ||
| 75 | } | ||
| 76 | if (ald.patch != 0) { | ||
| 77 | throw NotImplementedException("P"); | ||
| 78 | } | ||
| 79 | const u64 offset{ald.absolute_offset.Value()}; | 73 | const u64 offset{ald.absolute_offset.Value()}; |
| 80 | if (offset % 4 != 0) { | 74 | if (offset % 4 != 0) { |
| 81 | throw NotImplementedException("Unaligned absolute offset {}", offset); | 75 | throw NotImplementedException("Unaligned absolute offset {}", offset); |
| @@ -84,11 +78,19 @@ void TranslatorVisitor::ALD(u64 insn) { | |||
| 84 | const u32 num_elements{NumElements(ald.size)}; | 78 | const u32 num_elements{NumElements(ald.size)}; |
| 85 | if (ald.index_reg == IR::Reg::RZ) { | 79 | if (ald.index_reg == IR::Reg::RZ) { |
| 86 | for (u32 element = 0; element < num_elements; ++element) { | 80 | for (u32 element = 0; element < num_elements; ++element) { |
| 87 | const IR::Attribute attr{offset / 4 + element}; | 81 | if (ald.patch != 0) { |
| 88 | F(ald.dest_reg + element, ir.GetAttribute(attr, vertex)); | 82 | const IR::Patch patch{offset / 4 + element}; |
| 83 | F(ald.dest_reg + element, ir.GetPatch(patch)); | ||
| 84 | } else { | ||
| 85 | const IR::Attribute attr{offset / 4 + element}; | ||
| 86 | F(ald.dest_reg + element, ir.GetAttribute(attr, vertex)); | ||
| 87 | } | ||
| 89 | } | 88 | } |
| 90 | return; | 89 | return; |
| 91 | } | 90 | } |
| 91 | if (ald.patch != 0) { | ||
| 92 | throw NotImplementedException("Indirect patch read"); | ||
| 93 | } | ||
| 92 | HandleIndexed(*this, ald.index_reg, num_elements, [&](u32 element, IR::U32 final_offset) { | 94 | HandleIndexed(*this, ald.index_reg, num_elements, [&](u32 element, IR::U32 final_offset) { |
| 93 | F(ald.dest_reg + element, ir.GetAttributeIndexed(final_offset, vertex)); | 95 | F(ald.dest_reg + element, ir.GetAttributeIndexed(final_offset, vertex)); |
| 94 | }); | 96 | }); |
| @@ -106,9 +108,6 @@ void TranslatorVisitor::AST(u64 insn) { | |||
| 106 | BitField<47, 2, Size> size; | 108 | BitField<47, 2, Size> size; |
| 107 | } const ast{insn}; | 109 | } const ast{insn}; |
| 108 | 110 | ||
| 109 | if (ast.patch != 0) { | ||
| 110 | throw NotImplementedException("P"); | ||
| 111 | } | ||
| 112 | if (ast.index_reg != IR::Reg::RZ) { | 111 | if (ast.index_reg != IR::Reg::RZ) { |
| 113 | throw NotImplementedException("Indexed store"); | 112 | throw NotImplementedException("Indexed store"); |
| 114 | } | 113 | } |
| @@ -120,11 +119,19 @@ void TranslatorVisitor::AST(u64 insn) { | |||
| 120 | const u32 num_elements{NumElements(ast.size)}; | 119 | const u32 num_elements{NumElements(ast.size)}; |
| 121 | if (ast.index_reg == IR::Reg::RZ) { | 120 | if (ast.index_reg == IR::Reg::RZ) { |
| 122 | for (u32 element = 0; element < num_elements; ++element) { | 121 | for (u32 element = 0; element < num_elements; ++element) { |
| 123 | const IR::Attribute attr{offset / 4 + element}; | 122 | if (ast.patch != 0) { |
| 124 | ir.SetAttribute(attr, F(ast.src_reg + element), vertex); | 123 | const IR::Patch patch{offset / 4 + element}; |
| 124 | ir.SetPatch(patch, F(ast.src_reg + element)); | ||
| 125 | } else { | ||
| 126 | const IR::Attribute attr{offset / 4 + element}; | ||
| 127 | ir.SetAttribute(attr, F(ast.src_reg + element), vertex); | ||
| 128 | } | ||
| 125 | } | 129 | } |
| 126 | return; | 130 | return; |
| 127 | } | 131 | } |
| 132 | if (ast.patch != 0) { | ||
| 133 | throw NotImplementedException("Indexed tessellation patch store"); | ||
| 134 | } | ||
| 128 | HandleIndexed(*this, ast.index_reg, num_elements, [&](u32 element, IR::U32 final_offset) { | 135 | HandleIndexed(*this, ast.index_reg, num_elements, [&](u32 element, IR::U32 final_offset) { |
| 129 | ir.SetAttributeIndexed(final_offset, F(ast.src_reg + element), vertex); | 136 | ir.SetAttributeIndexed(final_offset, F(ast.src_reg + element), vertex); |
| 130 | }); | 137 | }); |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp index bc822d585..660b84c20 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp | |||
| @@ -113,6 +113,8 @@ enum class SpecialRegister : u64 { | |||
| 113 | 113 | ||
| 114 | [[nodiscard]] IR::U32 Read(IR::IREmitter& ir, SpecialRegister special_register) { | 114 | [[nodiscard]] IR::U32 Read(IR::IREmitter& ir, SpecialRegister special_register) { |
| 115 | switch (special_register) { | 115 | switch (special_register) { |
| 116 | case SpecialRegister::SR_INVOCATION_ID: | ||
| 117 | return ir.InvocationId(); | ||
| 116 | case SpecialRegister::SR_THREAD_KILL: | 118 | case SpecialRegister::SR_THREAD_KILL: |
| 117 | return IR::U32{ir.Select(ir.IsHelperInvocation(), ir.Imm32(-1), ir.Imm32(0))}; | 119 | return IR::U32{ir.Select(ir.IsHelperInvocation(), ir.Imm32(-1), ir.Imm32(0))}; |
| 118 | case SpecialRegister::SR_INVOCATION_INFO: | 120 | case SpecialRegister::SR_INVOCATION_INFO: |