aboutsummaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2023-06-05 21:43:43 -0700
committerGitHub <noreply@github.com>2023-06-05 21:43:43 -0700
commitcb95d7fe1b6d81899fe6b279400da2c991e3132c (patch)
treea856ac45b1053009c4c11ee141c49d7faa4c8a19 /src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp
parentdb7b106f1d9d559dadfd9ed070a8b0986609ec57 (diff)
parent036996429e1766231c5002bb333ee4e67d216c2c (diff)
Merge pull request #10508 from yuzu-emu/lime
Project Lime - yuzu Android Port
Diffstat (limited to 'src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp
index c5db19d09..77ff8c573 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_warp.cpp
@@ -17,7 +17,22 @@ Id GetThreadId(EmitContext& ctx) {
Id WarpExtract(EmitContext& ctx, Id value) {
const Id thread_id{GetThreadId(ctx)};
const Id local_index{ctx.OpShiftRightArithmetic(ctx.U32[1], thread_id, ctx.Const(5U))};
- return ctx.OpVectorExtractDynamic(ctx.U32[1], value, local_index);
+ if (ctx.profile.has_broken_spirv_subgroup_mask_vector_extract_dynamic) {
+ const Id c0_sel{ctx.OpSelect(ctx.U32[1], ctx.OpIEqual(ctx.U1, local_index, ctx.Const(0U)),
+ ctx.OpCompositeExtract(ctx.U32[1], value, 0U), ctx.Const(0U))};
+ const Id c1_sel{ctx.OpSelect(ctx.U32[1], ctx.OpIEqual(ctx.U1, local_index, ctx.Const(1U)),
+ ctx.OpCompositeExtract(ctx.U32[1], value, 1U), ctx.Const(0U))};
+ const Id c2_sel{ctx.OpSelect(ctx.U32[1], ctx.OpIEqual(ctx.U1, local_index, ctx.Const(2U)),
+ ctx.OpCompositeExtract(ctx.U32[1], value, 2U), ctx.Const(0U))};
+ const Id c3_sel{ctx.OpSelect(ctx.U32[1], ctx.OpIEqual(ctx.U1, local_index, ctx.Const(3U)),
+ ctx.OpCompositeExtract(ctx.U32[1], value, 3U), ctx.Const(0U))};
+ const Id c0_or_c1{ctx.OpBitwiseOr(ctx.U32[1], c0_sel, c1_sel)};
+ const Id c2_or_c3{ctx.OpBitwiseOr(ctx.U32[1], c2_sel, c3_sel)};
+ const Id c0_or_c1_or_c2_or_c3{ctx.OpBitwiseOr(ctx.U32[1], c0_or_c1, c2_or_c3)};
+ return c0_or_c1_or_c2_or_c3;
+ } else {
+ return ctx.OpVectorExtractDynamic(ctx.U32[1], value, local_index);
+ }
}
Id LoadMask(EmitContext& ctx, Id mask) {