From 028050cf044dafe667de71167eadeecbc0e328a6 Mon Sep 17 00:00:00 2001 From: MaranBr Date: Mon, 6 Apr 2026 19:13:35 +0200 Subject: [PATCH] [shader_recompiler] Fix IsScaled dynamic indexing reading wrong bit source (#3789) The non-immediate path in IsScaled was incorrectly using index_value as the source for OpBitFieldUExtract, instead of loading the corresponding word from the push constant bitmask. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3789 Reviewed-by: CamilleLaVey Reviewed-by: crueter Co-authored-by: MaranBr Co-committed-by: MaranBr --- src/shader_recompiler/backend/spirv/emit_spirv_image.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index c4c898bec9..c2511942d9 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp @@ -285,8 +285,13 @@ Id IsScaled(EmitContext& ctx, const IR::Value& index, Id member_index, u32 base_ if (base_index != 0) { index_value = ctx.OpIAdd(ctx.U32[1], index_value, ctx.Const(base_index)); } + const Id word_index{ctx.OpShiftRightLogical(ctx.U32[1], index_value, ctx.Const(5u))}; const Id bit_index{ctx.OpBitwiseAnd(ctx.U32[1], index_value, ctx.Const(31u))}; - bit = ctx.OpBitFieldUExtract(ctx.U32[1], index_value, bit_index, ctx.Const(1u)); + const Id pointer{ctx.OpAccessChain(push_constant_u32, ctx.rescaling_push_constants, + member_index, word_index)}; + const Id word{ctx.OpLoad(ctx.U32[1], pointer)}; + const Id bit_index_mask{ctx.OpShiftLeftLogical(ctx.U32[1], ctx.Const(1u), bit_index)}; + bit = ctx.OpBitwiseAnd(ctx.U32[1], word, bit_index_mask); } return ctx.OpINotEqual(ctx.U1, bit, ctx.u32_zero_value); }