diff options
Diffstat (limited to 'src')
10 files changed, 169 insertions, 45 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index e70b78a28..5ef637fe7 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -390,8 +390,16 @@ void EmitContext::DefineInputs(const Info& info) { | |||
| 390 | if (info.uses_local_invocation_id) { | 390 | if (info.uses_local_invocation_id) { |
| 391 | local_invocation_id = DefineInput(*this, U32[3], spv::BuiltIn::LocalInvocationId); | 391 | local_invocation_id = DefineInput(*this, U32[3], spv::BuiltIn::LocalInvocationId); |
| 392 | } | 392 | } |
| 393 | if (info.uses_subgroup_mask) { | ||
| 394 | subgroup_mask_eq = DefineInput(*this, U32[4], spv::BuiltIn::SubgroupEqMaskKHR); | ||
| 395 | subgroup_mask_lt = DefineInput(*this, U32[4], spv::BuiltIn::SubgroupLtMaskKHR); | ||
| 396 | subgroup_mask_le = DefineInput(*this, U32[4], spv::BuiltIn::SubgroupLeMaskKHR); | ||
| 397 | subgroup_mask_gt = DefineInput(*this, U32[4], spv::BuiltIn::SubgroupGtMaskKHR); | ||
| 398 | subgroup_mask_ge = DefineInput(*this, U32[4], spv::BuiltIn::SubgroupGeMaskKHR); | ||
| 399 | } | ||
| 393 | if (info.uses_subgroup_invocation_id || | 400 | if (info.uses_subgroup_invocation_id || |
| 394 | (profile.warp_size_potentially_larger_than_guest && info.uses_subgroup_vote)) { | 401 | (profile.warp_size_potentially_larger_than_guest && |
| 402 | (info.uses_subgroup_vote || info.uses_subgroup_mask))) { | ||
| 395 | subgroup_local_invocation_id = | 403 | subgroup_local_invocation_id = |
| 396 | DefineInput(*this, U32[1], spv::BuiltIn::SubgroupLocalInvocationId); | 404 | DefineInput(*this, U32[1], spv::BuiltIn::SubgroupLocalInvocationId); |
| 397 | } | 405 | } |
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h index 3a686a78c..03c5a6aba 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.h +++ b/src/shader_recompiler/backend/spirv/emit_context.h | |||
| @@ -97,6 +97,11 @@ public: | |||
| 97 | Id workgroup_id{}; | 97 | Id workgroup_id{}; |
| 98 | Id local_invocation_id{}; | 98 | Id local_invocation_id{}; |
| 99 | Id subgroup_local_invocation_id{}; | 99 | Id subgroup_local_invocation_id{}; |
| 100 | Id subgroup_mask_eq{}; | ||
| 101 | Id subgroup_mask_lt{}; | ||
| 102 | Id subgroup_mask_le{}; | ||
| 103 | Id subgroup_mask_gt{}; | ||
| 104 | Id subgroup_mask_ge{}; | ||
| 100 | Id instance_id{}; | 105 | Id instance_id{}; |
| 101 | Id instance_index{}; | 106 | Id instance_index{}; |
| 102 | Id base_instance{}; | 107 | Id base_instance{}; |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index 032b0b2f9..712c5e61f 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -401,6 +401,11 @@ Id EmitVoteAll(EmitContext& ctx, Id pred); | |||
| 401 | Id EmitVoteAny(EmitContext& ctx, Id pred); | 401 | Id EmitVoteAny(EmitContext& ctx, Id pred); |
| 402 | Id EmitVoteEqual(EmitContext& ctx, Id pred); | 402 | Id EmitVoteEqual(EmitContext& ctx, Id pred); |
| 403 | Id EmitSubgroupBallot(EmitContext& ctx, Id pred); | 403 | Id EmitSubgroupBallot(EmitContext& ctx, Id pred); |
| 404 | Id EmitSubgroupEqMask(EmitContext& ctx); | ||
| 405 | Id EmitSubgroupLtMask(EmitContext& ctx); | ||
| 406 | Id EmitSubgroupLeMask(EmitContext& ctx); | ||
| 407 | Id EmitSubgroupGtMask(EmitContext& ctx); | ||
| 408 | Id EmitSubgroupGeMask(EmitContext& ctx); | ||
| 404 | Id EmitShuffleIndex(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clamp, | 409 | Id EmitShuffleIndex(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clamp, |
| 405 | Id segmentation_mask); | 410 | Id segmentation_mask); |
| 406 | Id EmitShuffleUp(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clamp, | 411 | Id EmitShuffleUp(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clamp, |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp index cbc5b1c96..c57bd291d 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp | |||
| @@ -6,10 +6,18 @@ | |||
| 6 | 6 | ||
| 7 | namespace Shader::Backend::SPIRV { | 7 | namespace Shader::Backend::SPIRV { |
| 8 | namespace { | 8 | namespace { |
| 9 | Id LargeWarpBallot(EmitContext& ctx, Id ballot) { | 9 | Id WarpExtract(EmitContext& ctx, Id value) { |
| 10 | const Id shift{ctx.Constant(ctx.U32[1], 5)}; | 10 | const Id shift{ctx.Constant(ctx.U32[1], 5)}; |
| 11 | const Id local_index{ctx.OpLoad(ctx.U32[1], ctx.subgroup_local_invocation_id)}; | 11 | const Id local_index{ctx.OpLoad(ctx.U32[1], ctx.subgroup_local_invocation_id)}; |
| 12 | return ctx.OpVectorExtractDynamic(ctx.U32[1], ballot, local_index); | 12 | return ctx.OpVectorExtractDynamic(ctx.U32[1], value, local_index); |
| 13 | } | ||
| 14 | |||
| 15 | Id LoadMask(EmitContext& ctx, Id mask) { | ||
| 16 | const Id value{ctx.OpLoad(ctx.U32[4], mask)}; | ||
| 17 | if (!ctx.profile.warp_size_potentially_larger_than_guest) { | ||
| 18 | return ctx.OpCompositeExtract(ctx.U32[1], value, 0U); | ||
| 19 | } | ||
| 20 | return WarpExtract(ctx, value); | ||
| 13 | } | 21 | } |
| 14 | 22 | ||
| 15 | void SetInBoundsFlag(IR::Inst* inst, Id result) { | 23 | void SetInBoundsFlag(IR::Inst* inst, Id result) { |
| @@ -47,8 +55,8 @@ Id EmitVoteAll(EmitContext& ctx, Id pred) { | |||
| 47 | return ctx.OpSubgroupAllKHR(ctx.U1, pred); | 55 | return ctx.OpSubgroupAllKHR(ctx.U1, pred); |
| 48 | } | 56 | } |
| 49 | const Id mask_ballot{ctx.OpSubgroupBallotKHR(ctx.U32[4], ctx.true_value)}; | 57 | const Id mask_ballot{ctx.OpSubgroupBallotKHR(ctx.U32[4], ctx.true_value)}; |
| 50 | const Id active_mask{LargeWarpBallot(ctx, mask_ballot)}; | 58 | const Id active_mask{WarpExtract(ctx, mask_ballot)}; |
| 51 | const Id ballot{LargeWarpBallot(ctx, ctx.OpSubgroupBallotKHR(ctx.U32[4], pred))}; | 59 | const Id ballot{WarpExtract(ctx, ctx.OpSubgroupBallotKHR(ctx.U32[4], pred))}; |
| 52 | const Id lhs{ctx.OpBitwiseAnd(ctx.U32[1], ballot, active_mask)}; | 60 | const Id lhs{ctx.OpBitwiseAnd(ctx.U32[1], ballot, active_mask)}; |
| 53 | return ctx.OpIEqual(ctx.U1, lhs, active_mask); | 61 | return ctx.OpIEqual(ctx.U1, lhs, active_mask); |
| 54 | } | 62 | } |
| @@ -58,8 +66,8 @@ Id EmitVoteAny(EmitContext& ctx, Id pred) { | |||
| 58 | return ctx.OpSubgroupAnyKHR(ctx.U1, pred); | 66 | return ctx.OpSubgroupAnyKHR(ctx.U1, pred); |
| 59 | } | 67 | } |
| 60 | const Id mask_ballot{ctx.OpSubgroupBallotKHR(ctx.U32[4], ctx.true_value)}; | 68 | const Id mask_ballot{ctx.OpSubgroupBallotKHR(ctx.U32[4], ctx.true_value)}; |
| 61 | const Id active_mask{LargeWarpBallot(ctx, mask_ballot)}; | 69 | const Id active_mask{WarpExtract(ctx, mask_ballot)}; |
| 62 | const Id ballot{LargeWarpBallot(ctx, ctx.OpSubgroupBallotKHR(ctx.U32[4], pred))}; | 70 | const Id ballot{WarpExtract(ctx, ctx.OpSubgroupBallotKHR(ctx.U32[4], pred))}; |
| 63 | const Id lhs{ctx.OpBitwiseAnd(ctx.U32[1], ballot, active_mask)}; | 71 | const Id lhs{ctx.OpBitwiseAnd(ctx.U32[1], ballot, active_mask)}; |
| 64 | return ctx.OpINotEqual(ctx.U1, lhs, ctx.u32_zero_value); | 72 | return ctx.OpINotEqual(ctx.U1, lhs, ctx.u32_zero_value); |
| 65 | } | 73 | } |
| @@ -69,8 +77,8 @@ Id EmitVoteEqual(EmitContext& ctx, Id pred) { | |||
| 69 | return ctx.OpSubgroupAllEqualKHR(ctx.U1, pred); | 77 | return ctx.OpSubgroupAllEqualKHR(ctx.U1, pred); |
| 70 | } | 78 | } |
| 71 | const Id mask_ballot{ctx.OpSubgroupBallotKHR(ctx.U32[4], ctx.true_value)}; | 79 | const Id mask_ballot{ctx.OpSubgroupBallotKHR(ctx.U32[4], ctx.true_value)}; |
| 72 | const Id active_mask{LargeWarpBallot(ctx, mask_ballot)}; | 80 | const Id active_mask{WarpExtract(ctx, mask_ballot)}; |
| 73 | const Id ballot{LargeWarpBallot(ctx, ctx.OpSubgroupBallotKHR(ctx.U32[4], pred))}; | 81 | const Id ballot{WarpExtract(ctx, ctx.OpSubgroupBallotKHR(ctx.U32[4], pred))}; |
| 74 | const Id lhs{ctx.OpBitwiseXor(ctx.U32[1], ballot, active_mask)}; | 82 | const Id lhs{ctx.OpBitwiseXor(ctx.U32[1], ballot, active_mask)}; |
| 75 | return ctx.OpLogicalOr(ctx.U1, ctx.OpIEqual(ctx.U1, lhs, ctx.u32_zero_value), | 83 | return ctx.OpLogicalOr(ctx.U1, ctx.OpIEqual(ctx.U1, lhs, ctx.u32_zero_value), |
| 76 | ctx.OpIEqual(ctx.U1, lhs, active_mask)); | 84 | ctx.OpIEqual(ctx.U1, lhs, active_mask)); |
| @@ -81,7 +89,27 @@ Id EmitSubgroupBallot(EmitContext& ctx, Id pred) { | |||
| 81 | if (!ctx.profile.warp_size_potentially_larger_than_guest) { | 89 | if (!ctx.profile.warp_size_potentially_larger_than_guest) { |
| 82 | return ctx.OpCompositeExtract(ctx.U32[1], ballot, 0U); | 90 | return ctx.OpCompositeExtract(ctx.U32[1], ballot, 0U); |
| 83 | } | 91 | } |
| 84 | return LargeWarpBallot(ctx, ballot); | 92 | return WarpExtract(ctx, ballot); |
| 93 | } | ||
| 94 | |||
| 95 | Id EmitSubgroupEqMask(EmitContext& ctx) { | ||
| 96 | return LoadMask(ctx, ctx.subgroup_mask_eq); | ||
| 97 | } | ||
| 98 | |||
| 99 | Id EmitSubgroupLtMask(EmitContext& ctx) { | ||
| 100 | return LoadMask(ctx, ctx.subgroup_mask_lt); | ||
| 101 | } | ||
| 102 | |||
| 103 | Id EmitSubgroupLeMask(EmitContext& ctx) { | ||
| 104 | return LoadMask(ctx, ctx.subgroup_mask_le); | ||
| 105 | } | ||
| 106 | |||
| 107 | Id EmitSubgroupGtMask(EmitContext& ctx) { | ||
| 108 | return LoadMask(ctx, ctx.subgroup_mask_gt); | ||
| 109 | } | ||
| 110 | |||
| 111 | Id EmitSubgroupGeMask(EmitContext& ctx) { | ||
| 112 | return LoadMask(ctx, ctx.subgroup_mask_ge); | ||
| 85 | } | 113 | } |
| 86 | 114 | ||
| 87 | Id EmitShuffleIndex(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clamp, | 115 | Id EmitShuffleIndex(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clamp, |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index 246c3b9ef..ed1e0dd3b 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -1628,6 +1628,26 @@ U32 IREmitter::SubgroupBallot(const U1& value) { | |||
| 1628 | return Inst<U32>(Opcode::SubgroupBallot, value); | 1628 | return Inst<U32>(Opcode::SubgroupBallot, value); |
| 1629 | } | 1629 | } |
| 1630 | 1630 | ||
| 1631 | U32 IREmitter::SubgroupEqMask() { | ||
| 1632 | return Inst<U32>(Opcode::SubgroupEqMask); | ||
| 1633 | } | ||
| 1634 | |||
| 1635 | U32 IREmitter::SubgroupLtMask() { | ||
| 1636 | return Inst<U32>(Opcode::SubgroupLtMask); | ||
| 1637 | } | ||
| 1638 | |||
| 1639 | U32 IREmitter::SubgroupLeMask() { | ||
| 1640 | return Inst<U32>(Opcode::SubgroupLeMask); | ||
| 1641 | } | ||
| 1642 | |||
| 1643 | U32 IREmitter::SubgroupGtMask() { | ||
| 1644 | return Inst<U32>(Opcode::SubgroupGtMask); | ||
| 1645 | } | ||
| 1646 | |||
| 1647 | U32 IREmitter::SubgroupGeMask() { | ||
| 1648 | return Inst<U32>(Opcode::SubgroupGeMask); | ||
| 1649 | } | ||
| 1650 | |||
| 1631 | U32 IREmitter::ShuffleIndex(const IR::U32& value, const IR::U32& index, const IR::U32& clamp, | 1651 | U32 IREmitter::ShuffleIndex(const IR::U32& value, const IR::U32& index, const IR::U32& clamp, |
| 1632 | const IR::U32& seg_mask) { | 1652 | const IR::U32& seg_mask) { |
| 1633 | return Inst<U32>(Opcode::ShuffleIndex, value, index, clamp, seg_mask); | 1653 | return Inst<U32>(Opcode::ShuffleIndex, value, index, clamp, seg_mask); |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index 1b00c548d..42756af43 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -281,6 +281,11 @@ public: | |||
| 281 | [[nodiscard]] U1 VoteAny(const U1& value); | 281 | [[nodiscard]] U1 VoteAny(const U1& value); |
| 282 | [[nodiscard]] U1 VoteEqual(const U1& value); | 282 | [[nodiscard]] U1 VoteEqual(const U1& value); |
| 283 | [[nodiscard]] U32 SubgroupBallot(const U1& value); | 283 | [[nodiscard]] U32 SubgroupBallot(const U1& value); |
| 284 | [[nodiscard]] U32 SubgroupEqMask(); | ||
| 285 | [[nodiscard]] U32 SubgroupLtMask(); | ||
| 286 | [[nodiscard]] U32 SubgroupLeMask(); | ||
| 287 | [[nodiscard]] U32 SubgroupGtMask(); | ||
| 288 | [[nodiscard]] U32 SubgroupGeMask(); | ||
| 284 | [[nodiscard]] U32 ShuffleIndex(const IR::U32& value, const IR::U32& index, const IR::U32& clamp, | 289 | [[nodiscard]] U32 ShuffleIndex(const IR::U32& value, const IR::U32& index, const IR::U32& clamp, |
| 285 | const IR::U32& seg_mask); | 290 | const IR::U32& seg_mask); |
| 286 | [[nodiscard]] U32 ShuffleUp(const IR::U32& value, const IR::U32& index, const IR::U32& clamp, | 291 | [[nodiscard]] U32 ShuffleUp(const IR::U32& value, const IR::U32& index, const IR::U32& clamp, |
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index dcd54bcf7..1697de965 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -417,6 +417,11 @@ OPCODE(VoteAll, U1, U1, | |||
| 417 | OPCODE(VoteAny, U1, U1, ) | 417 | OPCODE(VoteAny, U1, U1, ) |
| 418 | OPCODE(VoteEqual, U1, U1, ) | 418 | OPCODE(VoteEqual, U1, U1, ) |
| 419 | OPCODE(SubgroupBallot, U32, U1, ) | 419 | OPCODE(SubgroupBallot, U32, U1, ) |
| 420 | OPCODE(SubgroupEqMask, U32, ) | ||
| 421 | OPCODE(SubgroupLtMask, U32, ) | ||
| 422 | OPCODE(SubgroupLeMask, U32, ) | ||
| 423 | OPCODE(SubgroupGtMask, U32, ) | ||
| 424 | OPCODE(SubgroupGeMask, U32, ) | ||
| 420 | OPCODE(ShuffleIndex, U32, U32, U32, U32, U32, ) | 425 | OPCODE(ShuffleIndex, U32, U32, U32, U32, U32, ) |
| 421 | OPCODE(ShuffleUp, U32, U32, U32, U32, U32, ) | 426 | OPCODE(ShuffleUp, U32, U32, U32, U32, U32, ) |
| 422 | OPCODE(ShuffleDown, U32, U32, U32, U32, U32, ) | 427 | OPCODE(ShuffleDown, U32, U32, U32, U32, U32, ) |
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 7d9c42a83..be1f21e7b 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 | |||
| @@ -10,6 +10,7 @@ namespace Shader::Maxwell { | |||
| 10 | namespace { | 10 | namespace { |
| 11 | enum class SpecialRegister : u64 { | 11 | enum class SpecialRegister : u64 { |
| 12 | SR_LANEID = 0, | 12 | SR_LANEID = 0, |
| 13 | SR_CLOCK = 1, | ||
| 13 | SR_VIRTCFG = 2, | 14 | SR_VIRTCFG = 2, |
| 14 | SR_VIRTID = 3, | 15 | SR_VIRTID = 3, |
| 15 | SR_PM0 = 4, | 16 | SR_PM0 = 4, |
| @@ -20,6 +21,9 @@ enum class SpecialRegister : u64 { | |||
| 20 | SR_PM5 = 9, | 21 | SR_PM5 = 9, |
| 21 | SR_PM6 = 10, | 22 | SR_PM6 = 10, |
| 22 | SR_PM7 = 11, | 23 | SR_PM7 = 11, |
| 24 | SR12 = 12, | ||
| 25 | SR13 = 13, | ||
| 26 | SR14 = 14, | ||
| 23 | SR_ORDERING_TICKET = 15, | 27 | SR_ORDERING_TICKET = 15, |
| 24 | SR_PRIM_TYPE = 16, | 28 | SR_PRIM_TYPE = 16, |
| 25 | SR_INVOCATION_ID = 17, | 29 | SR_INVOCATION_ID = 17, |
| @@ -41,44 +45,70 @@ enum class SpecialRegister : u64 { | |||
| 41 | SR_TID_X = 33, | 45 | SR_TID_X = 33, |
| 42 | SR_TID_Y = 34, | 46 | SR_TID_Y = 34, |
| 43 | SR_TID_Z = 35, | 47 | SR_TID_Z = 35, |
| 48 | SR_CTA_PARAM = 36, | ||
| 44 | SR_CTAID_X = 37, | 49 | SR_CTAID_X = 37, |
| 45 | SR_CTAID_Y = 38, | 50 | SR_CTAID_Y = 38, |
| 46 | SR_CTAID_Z = 39, | 51 | SR_CTAID_Z = 39, |
| 47 | SR_NTID = 49, | 52 | SR_NTID = 40, |
| 48 | SR_CirQueueIncrMinusOne = 50, | 53 | SR_CirQueueIncrMinusOne = 41, |
| 49 | SR_NLATC = 51, | 54 | SR_NLATC = 42, |
| 50 | SR_SWINLO = 57, | 55 | SR43 = 43, |
| 51 | SR_SWINSZ = 58, | 56 | SR_SM_SPA_VERSION = 44, |
| 52 | SR_SMEMSZ = 59, | 57 | SR_MULTIPASSSHADERINFO = 45, |
| 53 | SR_SMEMBANKS = 60, | 58 | SR_LWINHI = 46, |
| 54 | SR_LWINLO = 61, | 59 | SR_SWINHI = 47, |
| 55 | SR_LWINSZ = 62, | 60 | SR_SWINLO = 48, |
| 56 | SR_LMEMLOSZ = 63, | 61 | SR_SWINSZ = 49, |
| 57 | SR_LMEMHIOFF = 64, | 62 | SR_SMEMSZ = 50, |
| 58 | SR_EQMASK = 65, | 63 | SR_SMEMBANKS = 51, |
| 59 | SR_LTMASK = 66, | 64 | SR_LWINLO = 52, |
| 60 | SR_LEMASK = 67, | 65 | SR_LWINSZ = 53, |
| 61 | SR_GTMASK = 68, | 66 | SR_LMEMLOSZ = 54, |
| 62 | SR_GEMASK = 69, | 67 | SR_LMEMHIOFF = 55, |
| 63 | SR_REGALLOC = 70, | 68 | SR_EQMASK = 56, |
| 64 | SR_GLOBALERRORSTATUS = 73, | 69 | SR_LTMASK = 57, |
| 65 | SR_WARPERRORSTATUS = 75, | 70 | SR_LEMASK = 58, |
| 66 | SR_PM_HI0 = 81, | 71 | SR_GTMASK = 59, |
| 67 | SR_PM_HI1 = 82, | 72 | SR_GEMASK = 60, |
| 68 | SR_PM_HI2 = 83, | 73 | SR_REGALLOC = 61, |
| 69 | SR_PM_HI3 = 84, | 74 | SR_BARRIERALLOC = 62, |
| 70 | SR_PM_HI4 = 85, | 75 | SR63 = 63, |
| 71 | SR_PM_HI5 = 86, | 76 | SR_GLOBALERRORSTATUS = 64, |
| 72 | SR_PM_HI6 = 87, | 77 | SR65 = 65, |
| 73 | SR_PM_HI7 = 88, | 78 | SR_WARPERRORSTATUS = 66, |
| 74 | SR_CLOCKLO = 89, | 79 | SR_WARPERRORSTATUSCLEAR = 67, |
| 75 | SR_CLOCKHI = 90, | 80 | SR68 = 68, |
| 76 | SR_GLOBALTIMERLO = 91, | 81 | SR69 = 69, |
| 77 | SR_GLOBALTIMERHI = 92, | 82 | SR70 = 70, |
| 78 | SR_HWTASKID = 105, | 83 | SR71 = 71, |
| 79 | SR_CIRCULARQUEUEENTRYINDEX = 106, | 84 | SR_PM_HI0 = 72, |
| 80 | SR_CIRCULARQUEUEENTRYADDRESSLOW = 107, | 85 | SR_PM_HI1 = 73, |
| 81 | SR_CIRCULARQUEUEENTRYADDRESSHIGH = 108, | 86 | SR_PM_HI2 = 74, |
| 87 | SR_PM_HI3 = 75, | ||
| 88 | SR_PM_HI4 = 76, | ||
| 89 | SR_PM_HI5 = 77, | ||
| 90 | SR_PM_HI6 = 78, | ||
| 91 | SR_PM_HI7 = 79, | ||
| 92 | SR_CLOCKLO = 80, | ||
| 93 | SR_CLOCKHI = 81, | ||
| 94 | SR_GLOBALTIMERLO = 82, | ||
| 95 | SR_GLOBALTIMERHI = 83, | ||
| 96 | SR84 = 84, | ||
| 97 | SR85 = 85, | ||
| 98 | SR86 = 86, | ||
| 99 | SR87 = 87, | ||
| 100 | SR88 = 88, | ||
| 101 | SR89 = 89, | ||
| 102 | SR90 = 90, | ||
| 103 | SR91 = 91, | ||
| 104 | SR92 = 92, | ||
| 105 | SR93 = 93, | ||
| 106 | SR94 = 94, | ||
| 107 | SR95 = 95, | ||
| 108 | SR_HWTASKID = 96, | ||
| 109 | SR_CIRCULARQUEUEENTRYINDEX = 97, | ||
| 110 | SR_CIRCULARQUEUEENTRYADDRESSLOW = 98, | ||
| 111 | SR_CIRCULARQUEUEENTRYADDRESSHIGH = 99, | ||
| 82 | }; | 112 | }; |
| 83 | 113 | ||
| 84 | [[nodiscard]] IR::U32 Read(IR::IREmitter& ir, SpecialRegister special_register) { | 114 | [[nodiscard]] IR::U32 Read(IR::IREmitter& ir, SpecialRegister special_register) { |
| @@ -103,6 +133,16 @@ enum class SpecialRegister : u64 { | |||
| 103 | return ir.Imm32(Common::BitCast<u32>(1.0f)); | 133 | return ir.Imm32(Common::BitCast<u32>(1.0f)); |
| 104 | case SpecialRegister::SR_LANEID: | 134 | case SpecialRegister::SR_LANEID: |
| 105 | return ir.LaneId(); | 135 | return ir.LaneId(); |
| 136 | case SpecialRegister::SR_EQMASK: | ||
| 137 | return ir.SubgroupEqMask(); | ||
| 138 | case SpecialRegister::SR_LTMASK: | ||
| 139 | return ir.SubgroupLtMask(); | ||
| 140 | case SpecialRegister::SR_LEMASK: | ||
| 141 | return ir.SubgroupLeMask(); | ||
| 142 | case SpecialRegister::SR_GTMASK: | ||
| 143 | return ir.SubgroupGtMask(); | ||
| 144 | case SpecialRegister::SR_GEMASK: | ||
| 145 | return ir.SubgroupGeMask(); | ||
| 106 | default: | 146 | default: |
| 107 | throw NotImplementedException("S2R special register {}", special_register); | 147 | throw NotImplementedException("S2R special register {}", special_register); |
| 108 | } | 148 | } |
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 07f031ea6..0f870535b 100644 --- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp +++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp | |||
| @@ -414,6 +414,13 @@ void VisitUsages(Info& info, IR::Inst& inst) { | |||
| 414 | inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp) != nullptr; | 414 | inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp) != nullptr; |
| 415 | break; | 415 | break; |
| 416 | } | 416 | } |
| 417 | case IR::Opcode::SubgroupEqMask: | ||
| 418 | case IR::Opcode::SubgroupLtMask: | ||
| 419 | case IR::Opcode::SubgroupLeMask: | ||
| 420 | case IR::Opcode::SubgroupGtMask: | ||
| 421 | case IR::Opcode::SubgroupGeMask: | ||
| 422 | info.uses_subgroup_mask = true; | ||
| 423 | break; | ||
| 417 | case IR::Opcode::VoteAll: | 424 | case IR::Opcode::VoteAll: |
| 418 | case IR::Opcode::VoteAny: | 425 | case IR::Opcode::VoteAny: |
| 419 | case IR::Opcode::VoteEqual: | 426 | case IR::Opcode::VoteEqual: |
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h index d4d039eaf..9551a124f 100644 --- a/src/shader_recompiler/shader_info.h +++ b/src/shader_recompiler/shader_info.h | |||
| @@ -99,6 +99,7 @@ struct Info { | |||
| 99 | bool uses_sparse_residency{}; | 99 | bool uses_sparse_residency{}; |
| 100 | bool uses_demote_to_helper_invocation{}; | 100 | bool uses_demote_to_helper_invocation{}; |
| 101 | bool uses_subgroup_vote{}; | 101 | bool uses_subgroup_vote{}; |
| 102 | bool uses_subgroup_mask{}; | ||
| 102 | bool uses_fswzadd{}; | 103 | bool uses_fswzadd{}; |
| 103 | 104 | ||
| 104 | IR::Type used_constant_buffer_types{}; | 105 | IR::Type used_constant_buffer_types{}; |