summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/spirv
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend/spirv')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.cpp13
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp2
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp35
3 files changed, 31 insertions, 19 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
index 265ac9c85..0f86a8004 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp
@@ -402,8 +402,10 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
402 ctx.AddCapability(spv::Capability::SparseResidency); 402 ctx.AddCapability(spv::Capability::SparseResidency);
403 } 403 }
404 if (info.uses_demote_to_helper_invocation && profile.support_demote_to_helper_invocation) { 404 if (info.uses_demote_to_helper_invocation && profile.support_demote_to_helper_invocation) {
405 ctx.AddExtension("SPV_EXT_demote_to_helper_invocation"); 405 if (profile.supported_spirv < 0x00010600) {
406 ctx.AddCapability(spv::Capability::DemoteToHelperInvocationEXT); 406 ctx.AddExtension("SPV_EXT_demote_to_helper_invocation");
407 }
408 ctx.AddCapability(spv::Capability::DemoteToHelperInvocation);
407 } 409 }
408 if (info.stores[IR::Attribute::ViewportIndex]) { 410 if (info.stores[IR::Attribute::ViewportIndex]) {
409 ctx.AddCapability(spv::Capability::MultiViewport); 411 ctx.AddCapability(spv::Capability::MultiViewport);
@@ -426,12 +428,11 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
426 if ((info.uses_subgroup_vote || info.uses_subgroup_invocation_id || 428 if ((info.uses_subgroup_vote || info.uses_subgroup_invocation_id ||
427 info.uses_subgroup_shuffles) && 429 info.uses_subgroup_shuffles) &&
428 profile.support_vote) { 430 profile.support_vote) {
429 ctx.AddExtension("SPV_KHR_shader_ballot"); 431 ctx.AddCapability(spv::Capability::GroupNonUniformBallot);
430 ctx.AddCapability(spv::Capability::SubgroupBallotKHR); 432 ctx.AddCapability(spv::Capability::GroupNonUniformShuffle);
431 if (!profile.warp_size_potentially_larger_than_guest) { 433 if (!profile.warp_size_potentially_larger_than_guest) {
432 // vote ops are only used when not taking the long path 434 // vote ops are only used when not taking the long path
433 ctx.AddExtension("SPV_KHR_subgroup_vote"); 435 ctx.AddCapability(spv::Capability::GroupNonUniformVote);
434 ctx.AddCapability(spv::Capability::SubgroupVoteKHR);
435 } 436 }
436 } 437 }
437 if (info.uses_int64_bit_atomics && profile.support_int64_atomics) { 438 if (info.uses_int64_bit_atomics && profile.support_int64_atomics) {
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp
index 7ad0b08ac..fb2c792c1 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp
@@ -12,7 +12,7 @@ void EmitJoin(EmitContext&) {
12 12
13void EmitDemoteToHelperInvocation(EmitContext& ctx) { 13void EmitDemoteToHelperInvocation(EmitContext& ctx) {
14 if (ctx.profile.support_demote_to_helper_invocation) { 14 if (ctx.profile.support_demote_to_helper_invocation) {
15 ctx.OpDemoteToHelperInvocationEXT(); 15 ctx.OpDemoteToHelperInvocation();
16 } else { 16 } else {
17 const Id kill_label{ctx.OpLabel()}; 17 const Id kill_label{ctx.OpLabel()};
18 const Id impossible_label{ctx.OpLabel()}; 18 const Id impossible_label{ctx.OpLabel()};
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp
index 7cbbbfaa6..2c90f2368 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp
@@ -6,6 +6,10 @@
6 6
7namespace Shader::Backend::SPIRV { 7namespace Shader::Backend::SPIRV {
8namespace { 8namespace {
9Id SubgroupScope(EmitContext& ctx) {
10 return ctx.Const(static_cast<u32>(spv::Scope::Subgroup));
11}
12
9Id GetThreadId(EmitContext& ctx) { 13Id GetThreadId(EmitContext& ctx) {
10 return ctx.OpLoad(ctx.U32[1], ctx.subgroup_local_invocation_id); 14 return ctx.OpLoad(ctx.U32[1], ctx.subgroup_local_invocation_id);
11} 15}
@@ -49,8 +53,9 @@ Id GetMaxThreadId(EmitContext& ctx, Id thread_id, Id clamp, Id segmentation_mask
49} 53}
50 54
51Id SelectValue(EmitContext& ctx, Id in_range, Id value, Id src_thread_id) { 55Id SelectValue(EmitContext& ctx, Id in_range, Id value, Id src_thread_id) {
52 return ctx.OpSelect(ctx.U32[1], in_range, 56 return ctx.OpSelect(
53 ctx.OpSubgroupReadInvocationKHR(ctx.U32[1], value, src_thread_id), value); 57 ctx.U32[1], in_range,
58 ctx.OpGroupNonUniformShuffle(ctx.U32[1], SubgroupScope(ctx), value, src_thread_id), value);
54} 59}
55 60
56Id GetUpperClamp(EmitContext& ctx, Id invocation_id, Id clamp) { 61Id GetUpperClamp(EmitContext& ctx, Id invocation_id, Id clamp) {
@@ -71,40 +76,46 @@ Id EmitLaneId(EmitContext& ctx) {
71 76
72Id EmitVoteAll(EmitContext& ctx, Id pred) { 77Id EmitVoteAll(EmitContext& ctx, Id pred) {
73 if (!ctx.profile.warp_size_potentially_larger_than_guest) { 78 if (!ctx.profile.warp_size_potentially_larger_than_guest) {
74 return ctx.OpSubgroupAllKHR(ctx.U1, pred); 79 return ctx.OpGroupNonUniformAll(ctx.U1, SubgroupScope(ctx), pred);
75 } 80 }
76 const Id mask_ballot{ctx.OpSubgroupBallotKHR(ctx.U32[4], ctx.true_value)}; 81 const Id mask_ballot{
82 ctx.OpGroupNonUniformBallot(ctx.U32[4], SubgroupScope(ctx), ctx.true_value)};
77 const Id active_mask{WarpExtract(ctx, mask_ballot)}; 83 const Id active_mask{WarpExtract(ctx, mask_ballot)};
78 const Id ballot{WarpExtract(ctx, ctx.OpSubgroupBallotKHR(ctx.U32[4], pred))}; 84 const Id ballot{
85 WarpExtract(ctx, ctx.OpGroupNonUniformBallot(ctx.U32[4], SubgroupScope(ctx), pred))};
79 const Id lhs{ctx.OpBitwiseAnd(ctx.U32[1], ballot, active_mask)}; 86 const Id lhs{ctx.OpBitwiseAnd(ctx.U32[1], ballot, active_mask)};
80 return ctx.OpIEqual(ctx.U1, lhs, active_mask); 87 return ctx.OpIEqual(ctx.U1, lhs, active_mask);
81} 88}
82 89
83Id EmitVoteAny(EmitContext& ctx, Id pred) { 90Id EmitVoteAny(EmitContext& ctx, Id pred) {
84 if (!ctx.profile.warp_size_potentially_larger_than_guest) { 91 if (!ctx.profile.warp_size_potentially_larger_than_guest) {
85 return ctx.OpSubgroupAnyKHR(ctx.U1, pred); 92 return ctx.OpGroupNonUniformAny(ctx.U1, SubgroupScope(ctx), pred);
86 } 93 }
87 const Id mask_ballot{ctx.OpSubgroupBallotKHR(ctx.U32[4], ctx.true_value)}; 94 const Id mask_ballot{
95 ctx.OpGroupNonUniformBallot(ctx.U32[4], SubgroupScope(ctx), ctx.true_value)};
88 const Id active_mask{WarpExtract(ctx, mask_ballot)}; 96 const Id active_mask{WarpExtract(ctx, mask_ballot)};
89 const Id ballot{WarpExtract(ctx, ctx.OpSubgroupBallotKHR(ctx.U32[4], pred))}; 97 const Id ballot{
98 WarpExtract(ctx, ctx.OpGroupNonUniformBallot(ctx.U32[4], SubgroupScope(ctx), pred))};
90 const Id lhs{ctx.OpBitwiseAnd(ctx.U32[1], ballot, active_mask)}; 99 const Id lhs{ctx.OpBitwiseAnd(ctx.U32[1], ballot, active_mask)};
91 return ctx.OpINotEqual(ctx.U1, lhs, ctx.u32_zero_value); 100 return ctx.OpINotEqual(ctx.U1, lhs, ctx.u32_zero_value);
92} 101}
93 102
94Id EmitVoteEqual(EmitContext& ctx, Id pred) { 103Id EmitVoteEqual(EmitContext& ctx, Id pred) {
95 if (!ctx.profile.warp_size_potentially_larger_than_guest) { 104 if (!ctx.profile.warp_size_potentially_larger_than_guest) {
96 return ctx.OpSubgroupAllEqualKHR(ctx.U1, pred); 105 return ctx.OpGroupNonUniformAllEqual(ctx.U1, SubgroupScope(ctx), pred);
97 } 106 }
98 const Id mask_ballot{ctx.OpSubgroupBallotKHR(ctx.U32[4], ctx.true_value)}; 107 const Id mask_ballot{
108 ctx.OpGroupNonUniformBallot(ctx.U32[4], SubgroupScope(ctx), ctx.true_value)};
99 const Id active_mask{WarpExtract(ctx, mask_ballot)}; 109 const Id active_mask{WarpExtract(ctx, mask_ballot)};
100 const Id ballot{WarpExtract(ctx, ctx.OpSubgroupBallotKHR(ctx.U32[4], pred))}; 110 const Id ballot{
111 WarpExtract(ctx, ctx.OpGroupNonUniformBallot(ctx.U32[4], SubgroupScope(ctx), pred))};
101 const Id lhs{ctx.OpBitwiseXor(ctx.U32[1], ballot, active_mask)}; 112 const Id lhs{ctx.OpBitwiseXor(ctx.U32[1], ballot, active_mask)};
102 return ctx.OpLogicalOr(ctx.U1, ctx.OpIEqual(ctx.U1, lhs, ctx.u32_zero_value), 113 return ctx.OpLogicalOr(ctx.U1, ctx.OpIEqual(ctx.U1, lhs, ctx.u32_zero_value),
103 ctx.OpIEqual(ctx.U1, lhs, active_mask)); 114 ctx.OpIEqual(ctx.U1, lhs, active_mask));
104} 115}
105 116
106Id EmitSubgroupBallot(EmitContext& ctx, Id pred) { 117Id EmitSubgroupBallot(EmitContext& ctx, Id pred) {
107 const Id ballot{ctx.OpSubgroupBallotKHR(ctx.U32[4], pred)}; 118 const Id ballot{ctx.OpGroupNonUniformBallot(ctx.U32[4], SubgroupScope(ctx), pred)};
108 if (!ctx.profile.warp_size_potentially_larger_than_guest) { 119 if (!ctx.profile.warp_size_potentially_larger_than_guest) {
109 return ctx.OpCompositeExtract(ctx.U32[1], ballot, 0U); 120 return ctx.OpCompositeExtract(ctx.U32[1], ballot, 0U);
110 } 121 }