diff options
Diffstat (limited to 'src')
10 files changed, 22 insertions, 0 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index e5d83e9b4..bf2210899 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -790,6 +790,9 @@ void EmitContext::DefineInputs(const Info& info) { | |||
| 790 | if (info.uses_local_invocation_id) { | 790 | if (info.uses_local_invocation_id) { |
| 791 | local_invocation_id = DefineInput(*this, U32[3], spv::BuiltIn::LocalInvocationId); | 791 | local_invocation_id = DefineInput(*this, U32[3], spv::BuiltIn::LocalInvocationId); |
| 792 | } | 792 | } |
| 793 | if (info.uses_is_helper_invocation) { | ||
| 794 | is_helper_invocation = DefineInput(*this, U1, spv::BuiltIn::HelperInvocation); | ||
| 795 | } | ||
| 793 | if (info.uses_subgroup_mask) { | 796 | if (info.uses_subgroup_mask) { |
| 794 | subgroup_mask_eq = DefineInput(*this, U32[4], spv::BuiltIn::SubgroupEqMaskKHR); | 797 | subgroup_mask_eq = DefineInput(*this, U32[4], spv::BuiltIn::SubgroupEqMaskKHR); |
| 795 | subgroup_mask_lt = DefineInput(*this, U32[4], spv::BuiltIn::SubgroupLtMaskKHR); | 798 | subgroup_mask_lt = DefineInput(*this, U32[4], spv::BuiltIn::SubgroupLtMaskKHR); |
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h index 34f38454f..98a9140bf 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.h +++ b/src/shader_recompiler/backend/spirv/emit_context.h | |||
| @@ -107,6 +107,7 @@ public: | |||
| 107 | 107 | ||
| 108 | Id workgroup_id{}; | 108 | Id workgroup_id{}; |
| 109 | Id local_invocation_id{}; | 109 | Id local_invocation_id{}; |
| 110 | Id is_helper_invocation{}; | ||
| 110 | Id subgroup_local_invocation_id{}; | 111 | Id subgroup_local_invocation_id{}; |
| 111 | Id subgroup_mask_eq{}; | 112 | Id subgroup_mask_eq{}; |
| 112 | Id subgroup_mask_lt{}; | 113 | Id subgroup_mask_lt{}; |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index a3398a605..04340fa70 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -65,6 +65,7 @@ void EmitSetCFlag(EmitContext& ctx); | |||
| 65 | void EmitSetOFlag(EmitContext& ctx); | 65 | void EmitSetOFlag(EmitContext& ctx); |
| 66 | Id EmitWorkgroupId(EmitContext& ctx); | 66 | Id EmitWorkgroupId(EmitContext& ctx); |
| 67 | Id EmitLocalInvocationId(EmitContext& ctx); | 67 | Id EmitLocalInvocationId(EmitContext& ctx); |
| 68 | Id EmitIsHelperInvocation(EmitContext& ctx); | ||
| 68 | Id EmitLoadLocal(EmitContext& ctx, Id word_offset); | 69 | Id EmitLoadLocal(EmitContext& ctx, Id word_offset); |
| 69 | void EmitWriteLocal(EmitContext& ctx, Id word_offset, Id value); | 70 | void EmitWriteLocal(EmitContext& ctx, Id word_offset, Id value); |
| 70 | Id EmitUndefU1(EmitContext& ctx); | 71 | Id EmitUndefU1(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 5dc150ce2..d552a1b52 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 | |||
| @@ -274,6 +274,10 @@ Id EmitLocalInvocationId(EmitContext& ctx) { | |||
| 274 | return ctx.OpLoad(ctx.U32[3], ctx.local_invocation_id); | 274 | return ctx.OpLoad(ctx.U32[3], ctx.local_invocation_id); |
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | Id EmitIsHelperInvocation(EmitContext& ctx) { | ||
| 278 | return ctx.OpLoad(ctx.U1, ctx.is_helper_invocation); | ||
| 279 | } | ||
| 280 | |||
| 277 | Id EmitLoadLocal(EmitContext& ctx, Id word_offset) { | 281 | Id EmitLoadLocal(EmitContext& ctx, Id word_offset) { |
| 278 | const Id pointer{ctx.OpAccessChain(ctx.private_u32, ctx.local_memory, word_offset)}; | 282 | const Id pointer{ctx.OpAccessChain(ctx.private_u32, ctx.local_memory, word_offset)}; |
| 279 | return ctx.OpLoad(ctx.U32[1], pointer); | 283 | return ctx.OpLoad(ctx.U32[1], pointer); |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index a3339f624..54a273a92 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -347,6 +347,10 @@ U32 IREmitter::LocalInvocationIdZ() { | |||
| 347 | return U32{CompositeExtract(Inst(Opcode::LocalInvocationId), 2)}; | 347 | return U32{CompositeExtract(Inst(Opcode::LocalInvocationId), 2)}; |
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | U1 IREmitter::IsHelperInvocation() { | ||
| 351 | return Inst<U1>(Opcode::IsHelperInvocation); | ||
| 352 | } | ||
| 353 | |||
| 350 | U32 IREmitter::LaneId() { | 354 | U32 IREmitter::LaneId() { |
| 351 | return Inst<U32>(Opcode::LaneId); | 355 | return Inst<U32>(Opcode::LaneId); |
| 352 | } | 356 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index f9cbf1304..d04224707 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -90,6 +90,8 @@ public: | |||
| 90 | [[nodiscard]] U32 LocalInvocationIdY(); | 90 | [[nodiscard]] U32 LocalInvocationIdY(); |
| 91 | [[nodiscard]] U32 LocalInvocationIdZ(); | 91 | [[nodiscard]] U32 LocalInvocationIdZ(); |
| 92 | 92 | ||
| 93 | [[nodiscard]] U1 IsHelperInvocation(); | ||
| 94 | |||
| 93 | [[nodiscard]] U32 LaneId(); | 95 | [[nodiscard]] U32 LaneId(); |
| 94 | 96 | ||
| 95 | [[nodiscard]] U32 LoadGlobalU8(const U64& address); | 97 | [[nodiscard]] U32 LoadGlobalU8(const U64& address); |
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index dc776a73e..f70008682 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -58,6 +58,7 @@ OPCODE(SetCFlag, Void, U1, | |||
| 58 | OPCODE(SetOFlag, Void, U1, ) | 58 | OPCODE(SetOFlag, Void, U1, ) |
| 59 | OPCODE(WorkgroupId, U32x3, ) | 59 | OPCODE(WorkgroupId, U32x3, ) |
| 60 | OPCODE(LocalInvocationId, U32x3, ) | 60 | OPCODE(LocalInvocationId, U32x3, ) |
| 61 | OPCODE(IsHelperInvocation, U1, ) | ||
| 61 | 62 | ||
| 62 | // Undefined | 63 | // Undefined |
| 63 | OPCODE(UndefU1, U1, ) | 64 | OPCODE(UndefU1, U1, ) |
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 be1f21e7b..50650cc56 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_THREAD_KILL: | ||
| 117 | return IR::U32{ir.Select(ir.IsHelperInvocation(), ir.Imm32(-1), ir.Imm32(0))}; | ||
| 116 | case SpecialRegister::SR_TID_X: | 118 | case SpecialRegister::SR_TID_X: |
| 117 | return ir.LocalInvocationIdX(); | 119 | return ir.LocalInvocationIdX(); |
| 118 | case SpecialRegister::SR_TID_Y: | 120 | case SpecialRegister::SR_TID_Y: |
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 73373576b..c80d2d29c 100644 --- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp +++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp | |||
| @@ -348,6 +348,9 @@ void VisitUsages(Info& info, IR::Inst& inst) { | |||
| 348 | case IR::Opcode::LocalInvocationId: | 348 | case IR::Opcode::LocalInvocationId: |
| 349 | info.uses_local_invocation_id = true; | 349 | info.uses_local_invocation_id = true; |
| 350 | break; | 350 | break; |
| 351 | case IR::Opcode::IsHelperInvocation: | ||
| 352 | info.uses_is_helper_invocation = true; | ||
| 353 | break; | ||
| 351 | case IR::Opcode::LaneId: | 354 | case IR::Opcode::LaneId: |
| 352 | case IR::Opcode::ShuffleIndex: | 355 | case IR::Opcode::ShuffleIndex: |
| 353 | case IR::Opcode::ShuffleUp: | 356 | case IR::Opcode::ShuffleUp: |
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h index 7bcecf554..aa204ae37 100644 --- a/src/shader_recompiler/shader_info.h +++ b/src/shader_recompiler/shader_info.h | |||
| @@ -92,6 +92,7 @@ struct Info { | |||
| 92 | 92 | ||
| 93 | bool uses_workgroup_id{}; | 93 | bool uses_workgroup_id{}; |
| 94 | bool uses_local_invocation_id{}; | 94 | bool uses_local_invocation_id{}; |
| 95 | bool uses_is_helper_invocation{}; | ||
| 95 | bool uses_subgroup_invocation_id{}; | 96 | bool uses_subgroup_invocation_id{}; |
| 96 | 97 | ||
| 97 | std::array<InputVarying, 32> input_generics{}; | 98 | std::array<InputVarying, 32> input_generics{}; |