diff options
11 files changed, 22 insertions, 2 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index 0b4abeb44..b9e6d5655 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -1179,7 +1179,10 @@ void EmitContext::DefineOutputs(const IR::Program& program) { | |||
| 1179 | if (info.stores_frag_depth) { | 1179 | if (info.stores_frag_depth) { |
| 1180 | frag_depth = DefineOutput(*this, F32[1], std::nullopt); | 1180 | frag_depth = DefineOutput(*this, F32[1], std::nullopt); |
| 1181 | Decorate(frag_depth, spv::Decoration::BuiltIn, spv::BuiltIn::FragDepth); | 1181 | Decorate(frag_depth, spv::Decoration::BuiltIn, spv::BuiltIn::FragDepth); |
| 1182 | Name(frag_depth, "frag_depth"); | 1182 | } |
| 1183 | if (info.stores_sample_mask) { | ||
| 1184 | sample_mask = DefineOutput(*this, U32[1], std::nullopt); | ||
| 1185 | Decorate(sample_mask, spv::Decoration::BuiltIn, spv::BuiltIn::SampleMask); | ||
| 1183 | } | 1186 | } |
| 1184 | break; | 1187 | break; |
| 1185 | default: | 1188 | default: |
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h index 9d8340333..528dc33fe 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.h +++ b/src/shader_recompiler/backend/spirv/emit_context.h | |||
| @@ -215,6 +215,7 @@ public: | |||
| 215 | std::array<Id, 30> patches{}; | 215 | std::array<Id, 30> patches{}; |
| 216 | 216 | ||
| 217 | std::array<Id, 8> frag_color{}; | 217 | std::array<Id, 8> frag_color{}; |
| 218 | Id sample_mask{}; | ||
| 218 | Id frag_depth{}; | 219 | Id frag_depth{}; |
| 219 | 220 | ||
| 220 | std::vector<Id> interfaces; | 221 | std::vector<Id> interfaces; |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index dfddf5e58..9f658a4bd 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -58,6 +58,7 @@ void EmitSetAttributeIndexed(EmitContext& ctx, Id offset, Id value, Id vertex); | |||
| 58 | Id EmitGetPatch(EmitContext& ctx, IR::Patch patch); | 58 | Id EmitGetPatch(EmitContext& ctx, IR::Patch patch); |
| 59 | void EmitSetPatch(EmitContext& ctx, IR::Patch patch, Id value); | 59 | void EmitSetPatch(EmitContext& ctx, IR::Patch patch, Id value); |
| 60 | void EmitSetFragColor(EmitContext& ctx, u32 index, u32 component, Id value); | 60 | void EmitSetFragColor(EmitContext& ctx, u32 index, u32 component, Id value); |
| 61 | void EmitSetSampleMask(EmitContext& ctx, Id value); | ||
| 61 | void EmitSetFragDepth(EmitContext& ctx, Id value); | 62 | void EmitSetFragDepth(EmitContext& ctx, Id value); |
| 62 | void EmitGetZFlag(EmitContext& ctx); | 63 | void EmitGetZFlag(EmitContext& ctx); |
| 63 | void EmitGetSFlag(EmitContext& ctx); | 64 | void EmitGetSFlag(EmitContext& ctx); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index 7555dd94c..e5e4c352b 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp | |||
| @@ -343,6 +343,10 @@ void EmitSetFragColor(EmitContext& ctx, u32 index, u32 component, Id value) { | |||
| 343 | ctx.OpStore(pointer, value); | 343 | ctx.OpStore(pointer, value); |
| 344 | } | 344 | } |
| 345 | 345 | ||
| 346 | void EmitSetSampleMask(EmitContext& ctx, Id value) { | ||
| 347 | ctx.OpStore(ctx.sample_mask, value); | ||
| 348 | } | ||
| 349 | |||
| 346 | void EmitSetFragDepth(EmitContext& ctx, Id value) { | 350 | void EmitSetFragDepth(EmitContext& ctx, Id value) { |
| 347 | ctx.OpStore(ctx.frag_depth, value); | 351 | ctx.OpStore(ctx.frag_depth, value); |
| 348 | } | 352 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 141efd86c..ef3b00bc2 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -343,6 +343,10 @@ void IREmitter::SetFragColor(u32 index, u32 component, const F32& value) { | |||
| 343 | Inst(Opcode::SetFragColor, Imm32(index), Imm32(component), value); | 343 | Inst(Opcode::SetFragColor, Imm32(index), Imm32(component), value); |
| 344 | } | 344 | } |
| 345 | 345 | ||
| 346 | void IREmitter::SetSampleMask(const U32& value) { | ||
| 347 | Inst(Opcode::SetSampleMask, value); | ||
| 348 | } | ||
| 349 | |||
| 346 | void IREmitter::SetFragDepth(const F32& value) { | 350 | void IREmitter::SetFragDepth(const F32& value) { |
| 347 | Inst(Opcode::SetFragDepth, value); | 351 | Inst(Opcode::SetFragDepth, value); |
| 348 | } | 352 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index 81833d928..1a585df15 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -88,6 +88,7 @@ public: | |||
| 88 | void SetPatch(Patch patch, const F32& value); | 88 | void SetPatch(Patch patch, const F32& value); |
| 89 | 89 | ||
| 90 | void SetFragColor(u32 index, u32 component, const F32& value); | 90 | void SetFragColor(u32 index, u32 component, const F32& value); |
| 91 | void SetSampleMask(const U32& value); | ||
| 91 | void SetFragDepth(const F32& value); | 92 | void SetFragDepth(const F32& value); |
| 92 | 93 | ||
| 93 | [[nodiscard]] U32 WorkgroupIdX(); | 94 | [[nodiscard]] U32 WorkgroupIdX(); |
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp index b2d7573d9..b53fe2e2a 100644 --- a/src/shader_recompiler/frontend/ir/microinstruction.cpp +++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp | |||
| @@ -75,6 +75,7 @@ bool Inst::MayHaveSideEffects() const noexcept { | |||
| 75 | case Opcode::SetAttributeIndexed: | 75 | case Opcode::SetAttributeIndexed: |
| 76 | case Opcode::SetPatch: | 76 | case Opcode::SetPatch: |
| 77 | case Opcode::SetFragColor: | 77 | case Opcode::SetFragColor: |
| 78 | case Opcode::SetSampleMask: | ||
| 78 | case Opcode::SetFragDepth: | 79 | case Opcode::SetFragDepth: |
| 79 | case Opcode::WriteGlobalU8: | 80 | case Opcode::WriteGlobalU8: |
| 80 | case Opcode::WriteGlobalS8: | 81 | case Opcode::WriteGlobalS8: |
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index d5e443673..0748efa8d 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -51,6 +51,7 @@ OPCODE(SetAttributeIndexed, Void, U32, | |||
| 51 | OPCODE(GetPatch, F32, Patch, ) | 51 | OPCODE(GetPatch, F32, Patch, ) |
| 52 | OPCODE(SetPatch, Void, Patch, F32, ) | 52 | OPCODE(SetPatch, Void, Patch, F32, ) |
| 53 | OPCODE(SetFragColor, Void, U32, U32, F32, ) | 53 | OPCODE(SetFragColor, Void, U32, U32, F32, ) |
| 54 | OPCODE(SetSampleMask, Void, U32, ) | ||
| 54 | OPCODE(SetFragDepth, Void, F32, ) | 55 | OPCODE(SetFragDepth, Void, F32, ) |
| 55 | OPCODE(GetZFlag, U1, Void, ) | 56 | OPCODE(GetZFlag, U1, Void, ) |
| 56 | OPCODE(GetSFlag, U1, Void, ) | 57 | OPCODE(GetSFlag, U1, Void, ) |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/exit_program.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/exit_program.cpp index 58a53c0ec..c2443c886 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/exit_program.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/exit_program.cpp | |||
| @@ -22,7 +22,7 @@ void ExitFragment(TranslatorVisitor& v) { | |||
| 22 | } | 22 | } |
| 23 | } | 23 | } |
| 24 | if (sph.ps.omap.sample_mask != 0) { | 24 | if (sph.ps.omap.sample_mask != 0) { |
| 25 | throw NotImplementedException("Sample mask"); | 25 | v.ir.SetSampleMask(v.X(src_reg)); |
| 26 | } | 26 | } |
| 27 | if (sph.ps.omap.depth != 0) { | 27 | if (sph.ps.omap.depth != 0) { |
| 28 | v.ir.SetFragDepth(v.F(src_reg + 1)); | 28 | v.ir.SetFragDepth(v.F(src_reg + 1)); |
diff --git a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp index 5d1310466..60b7d3a36 100644 --- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp +++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp | |||
| @@ -403,6 +403,9 @@ void VisitUsages(Info& info, IR::Inst& inst) { | |||
| 403 | case IR::Opcode::SetFragColor: | 403 | case IR::Opcode::SetFragColor: |
| 404 | info.stores_frag_color[inst.Arg(0).U32()] = true; | 404 | info.stores_frag_color[inst.Arg(0).U32()] = true; |
| 405 | break; | 405 | break; |
| 406 | case IR::Opcode::SetSampleMask: | ||
| 407 | info.stores_sample_mask = true; | ||
| 408 | break; | ||
| 406 | case IR::Opcode::SetFragDepth: | 409 | case IR::Opcode::SetFragDepth: |
| 407 | info.stores_frag_depth = true; | 410 | info.stores_frag_depth = true; |
| 408 | break; | 411 | break; |
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h index 686f5c719..0a8931930 100644 --- a/src/shader_recompiler/shader_info.h +++ b/src/shader_recompiler/shader_info.h | |||
| @@ -118,6 +118,7 @@ struct Info { | |||
| 118 | bool loads_indexed_attributes{}; | 118 | bool loads_indexed_attributes{}; |
| 119 | 119 | ||
| 120 | std::array<bool, 8> stores_frag_color{}; | 120 | std::array<bool, 8> stores_frag_color{}; |
| 121 | bool stores_sample_mask{}; | ||
| 121 | bool stores_frag_depth{}; | 122 | bool stores_frag_depth{}; |
| 122 | std::array<bool, 32> stores_generics{}; | 123 | std::array<bool, 32> stores_generics{}; |
| 123 | bool stores_position{}; | 124 | bool stores_position{}; |