diff options
Diffstat (limited to 'src')
10 files changed, 73 insertions, 17 deletions
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt index 8c24c1377..bbbfa98a3 100644 --- a/src/shader_recompiler/CMakeLists.txt +++ b/src/shader_recompiler/CMakeLists.txt | |||
| @@ -134,6 +134,7 @@ add_library(shader_recompiler STATIC | |||
| 134 | frontend/maxwell/translate/impl/move_register_to_predicate.cpp | 134 | frontend/maxwell/translate/impl/move_register_to_predicate.cpp |
| 135 | frontend/maxwell/translate/impl/move_special_register.cpp | 135 | frontend/maxwell/translate/impl/move_special_register.cpp |
| 136 | frontend/maxwell/translate/impl/not_implemented.cpp | 136 | frontend/maxwell/translate/impl/not_implemented.cpp |
| 137 | frontend/maxwell/translate/impl/output_geometry.cpp | ||
| 137 | frontend/maxwell/translate/impl/predicate_set_predicate.cpp | 138 | frontend/maxwell/translate/impl/predicate_set_predicate.cpp |
| 138 | frontend/maxwell/translate/impl/predicate_set_register.cpp | 139 | frontend/maxwell/translate/impl/predicate_set_register.cpp |
| 139 | frontend/maxwell/translate/impl/select_source_with_predicate.cpp | 140 | frontend/maxwell/translate/impl/select_source_with_predicate.cpp |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index 150477ff6..440075212 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -34,6 +34,8 @@ void EmitMemoryBarrierDeviceLevel(EmitContext& ctx); | |||
| 34 | void EmitMemoryBarrierSystemLevel(EmitContext& ctx); | 34 | void EmitMemoryBarrierSystemLevel(EmitContext& ctx); |
| 35 | void EmitPrologue(EmitContext& ctx); | 35 | void EmitPrologue(EmitContext& ctx); |
| 36 | void EmitEpilogue(EmitContext& ctx); | 36 | void EmitEpilogue(EmitContext& ctx); |
| 37 | void EmitEmitVertex(EmitContext& ctx, Id stream); | ||
| 38 | void EmitEndPrimitive(EmitContext& ctx, Id stream); | ||
| 37 | void EmitGetRegister(EmitContext& ctx); | 39 | void EmitGetRegister(EmitContext& ctx); |
| 38 | void EmitSetRegister(EmitContext& ctx); | 40 | void EmitSetRegister(EmitContext& ctx); |
| 39 | void EmitGetPred(EmitContext& ctx); | 41 | void EmitGetPred(EmitContext& ctx); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp index 5f80c189f..d20f4def3 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp | |||
| @@ -36,4 +36,12 @@ void EmitEpilogue(EmitContext& ctx) { | |||
| 36 | } | 36 | } |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | void EmitEmitVertex(EmitContext& ctx, Id stream) { | ||
| 40 | ctx.OpEmitStreamVertex(stream); | ||
| 41 | } | ||
| 42 | |||
| 43 | void EmitEndPrimitive(EmitContext& ctx, Id stream) { | ||
| 44 | ctx.OpEndStreamPrimitive(stream); | ||
| 45 | } | ||
| 46 | |||
| 39 | } // namespace Shader::Backend::SPIRV | 47 | } // namespace Shader::Backend::SPIRV |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 54a273a92..7d48fa1ba 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -125,6 +125,14 @@ void IREmitter::Epilogue() { | |||
| 125 | Inst(Opcode::Epilogue); | 125 | Inst(Opcode::Epilogue); |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | void IREmitter::EmitVertex(const U32& stream) { | ||
| 129 | Inst(Opcode::EmitVertex, stream); | ||
| 130 | } | ||
| 131 | |||
| 132 | void IREmitter::EndPrimitive(const U32& stream) { | ||
| 133 | Inst(Opcode::EndPrimitive, stream); | ||
| 134 | } | ||
| 135 | |||
| 128 | U32 IREmitter::GetReg(IR::Reg reg) { | 136 | U32 IREmitter::GetReg(IR::Reg reg) { |
| 129 | return Inst<U32>(Opcode::GetRegister, reg); | 137 | return Inst<U32>(Opcode::GetRegister, reg); |
| 130 | } | 138 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index d04224707..033c4332e 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -43,6 +43,9 @@ public: | |||
| 43 | void Prologue(); | 43 | void Prologue(); |
| 44 | void Epilogue(); | 44 | void Epilogue(); |
| 45 | 45 | ||
| 46 | void EmitVertex(const U32& stream); | ||
| 47 | void EndPrimitive(const U32& stream); | ||
| 48 | |||
| 46 | [[nodiscard]] U32 GetReg(IR::Reg reg); | 49 | [[nodiscard]] U32 GetReg(IR::Reg reg); |
| 47 | void SetReg(IR::Reg reg, const U32& value); | 50 | void SetReg(IR::Reg reg, const U32& value); |
| 48 | 51 | ||
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp index 0f66c5627..204c55fa8 100644 --- a/src/shader_recompiler/frontend/ir/microinstruction.cpp +++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp | |||
| @@ -69,6 +69,8 @@ bool Inst::MayHaveSideEffects() const noexcept { | |||
| 69 | case Opcode::MemoryBarrierSystemLevel: | 69 | case Opcode::MemoryBarrierSystemLevel: |
| 70 | case Opcode::Prologue: | 70 | case Opcode::Prologue: |
| 71 | case Opcode::Epilogue: | 71 | case Opcode::Epilogue: |
| 72 | case Opcode::EmitVertex: | ||
| 73 | case Opcode::EndPrimitive: | ||
| 72 | case Opcode::SetAttribute: | 74 | case Opcode::SetAttribute: |
| 73 | case Opcode::SetAttributeIndexed: | 75 | case Opcode::SetAttributeIndexed: |
| 74 | case Opcode::SetFragColor: | 76 | case Opcode::SetFragColor: |
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index f70008682..0e487f1a7 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -25,6 +25,8 @@ OPCODE(MemoryBarrierSystemLevel, Void, | |||
| 25 | // Special operations | 25 | // Special operations |
| 26 | OPCODE(Prologue, Void, ) | 26 | OPCODE(Prologue, Void, ) |
| 27 | OPCODE(Epilogue, Void, ) | 27 | OPCODE(Epilogue, Void, ) |
| 28 | OPCODE(EmitVertex, Void, U32, ) | ||
| 29 | OPCODE(EndPrimitive, Void, U32, ) | ||
| 28 | 30 | ||
| 29 | // Context getters/setters | 31 | // Context getters/setters |
| 30 | OPCODE(GetRegister, U32, Reg, ) | 32 | OPCODE(GetRegister, U32, Reg, ) |
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 f629e7167..79293bd6b 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 | |||
| @@ -64,7 +64,7 @@ void TranslatorVisitor::ALD(u64 insn) { | |||
| 64 | BitField<8, 8, IR::Reg> index_reg; | 64 | BitField<8, 8, IR::Reg> index_reg; |
| 65 | BitField<20, 10, u64> absolute_offset; | 65 | BitField<20, 10, u64> absolute_offset; |
| 66 | BitField<20, 11, s64> relative_offset; | 66 | BitField<20, 11, s64> relative_offset; |
| 67 | BitField<39, 8, IR::Reg> stream_reg; | 67 | BitField<39, 8, IR::Reg> array_reg; |
| 68 | BitField<32, 1, u64> o; | 68 | BitField<32, 1, u64> o; |
| 69 | BitField<31, 1, u64> patch; | 69 | BitField<31, 1, u64> patch; |
| 70 | BitField<47, 2, Size> size; | 70 | BitField<47, 2, Size> size; |
| @@ -100,16 +100,13 @@ void TranslatorVisitor::AST(u64 insn) { | |||
| 100 | BitField<20, 10, u64> absolute_offset; | 100 | BitField<20, 10, u64> absolute_offset; |
| 101 | BitField<20, 11, s64> relative_offset; | 101 | BitField<20, 11, s64> relative_offset; |
| 102 | BitField<31, 1, u64> patch; | 102 | BitField<31, 1, u64> patch; |
| 103 | BitField<39, 8, IR::Reg> stream_reg; | 103 | BitField<39, 8, IR::Reg> array_reg; |
| 104 | BitField<47, 2, Size> size; | 104 | BitField<47, 2, Size> size; |
| 105 | } const ast{insn}; | 105 | } const ast{insn}; |
| 106 | 106 | ||
| 107 | if (ast.patch != 0) { | 107 | if (ast.patch != 0) { |
| 108 | throw NotImplementedException("P"); | 108 | throw NotImplementedException("P"); |
| 109 | } | 109 | } |
| 110 | if (ast.stream_reg != IR::Reg::RZ) { | ||
| 111 | throw NotImplementedException("Stream store"); | ||
| 112 | } | ||
| 113 | if (ast.index_reg != IR::Reg::RZ) { | 110 | if (ast.index_reg != IR::Reg::RZ) { |
| 114 | throw NotImplementedException("Indexed store"); | 111 | throw NotImplementedException("Indexed store"); |
| 115 | } | 112 | } |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp index 694bdfccb..a45d1e4be 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | |||
| @@ -169,18 +169,6 @@ void TranslatorVisitor::NOP(u64) { | |||
| 169 | // NOP is No-Op. | 169 | // NOP is No-Op. |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | void TranslatorVisitor::OUT_reg(u64) { | ||
| 173 | ThrowNotImplemented(Opcode::OUT_reg); | ||
| 174 | } | ||
| 175 | |||
| 176 | void TranslatorVisitor::OUT_cbuf(u64) { | ||
| 177 | ThrowNotImplemented(Opcode::OUT_cbuf); | ||
| 178 | } | ||
| 179 | |||
| 180 | void TranslatorVisitor::OUT_imm(u64) { | ||
| 181 | ThrowNotImplemented(Opcode::OUT_imm); | ||
| 182 | } | ||
| 183 | |||
| 184 | void TranslatorVisitor::PBK() { | 172 | void TranslatorVisitor::PBK() { |
| 185 | // PBK is a no-op | 173 | // PBK is a no-op |
| 186 | } | 174 | } |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/output_geometry.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/output_geometry.cpp new file mode 100644 index 000000000..01cfad88d --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/output_geometry.cpp | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/bit_field.h" | ||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||
| 8 | |||
| 9 | namespace Shader::Maxwell { | ||
| 10 | namespace { | ||
| 11 | void OUT(TranslatorVisitor& v, u64 insn, IR::U32 stream_index) { | ||
| 12 | union { | ||
| 13 | u64 raw; | ||
| 14 | BitField<0, 8, IR::Reg> dest_reg; | ||
| 15 | BitField<8, 8, IR::Reg> output_reg; // Not needed on host | ||
| 16 | BitField<39, 1, u64> emit; | ||
| 17 | BitField<40, 1, u64> cut; | ||
| 18 | } const out{insn}; | ||
| 19 | |||
| 20 | stream_index = v.ir.BitwiseAnd(stream_index, v.ir.Imm32(0b11)); | ||
| 21 | |||
| 22 | if (out.emit != 0) { | ||
| 23 | v.ir.EmitVertex(stream_index); | ||
| 24 | } | ||
| 25 | if (out.cut != 0) { | ||
| 26 | v.ir.EndPrimitive(stream_index); | ||
| 27 | } | ||
| 28 | // Host doesn't need the output register, but we can write to it to avoid undefined reads | ||
| 29 | v.X(out.dest_reg, v.ir.Imm32(0)); | ||
| 30 | } | ||
| 31 | } // Anonymous namespace | ||
| 32 | |||
| 33 | void TranslatorVisitor::OUT_reg(u64 insn) { | ||
| 34 | OUT(*this, insn, GetReg20(insn)); | ||
| 35 | } | ||
| 36 | |||
| 37 | void TranslatorVisitor::OUT_cbuf(u64 insn) { | ||
| 38 | OUT(*this, insn, GetCbuf(insn)); | ||
| 39 | } | ||
| 40 | |||
| 41 | void TranslatorVisitor::OUT_imm(u64 insn) { | ||
| 42 | OUT(*this, insn, GetImm20(insn)); | ||
| 43 | } | ||
| 44 | |||
| 45 | } // namespace Shader::Maxwell | ||