From 0f7d11254564dabea0ec7067ffd4c1b6b48c3618 Mon Sep 17 00:00:00 2001 From: nmzik Date: Wed, 21 Oct 2026 23:26:07 +0200 Subject: [PATCH] shader: emit constant-true guarded blocks inline and fold immediate constant-buffer indices --- .../recompiler/backend/spirv/spirvEmitterInternal.h | 5 +++++ .../recompiler/backend/spirv/spirvEmitterMemory.cpp | 9 ++++++--- tests/shaderCfgTests.cpp | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h index 67444ef9c..bc6b7b45e 100644 --- a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h +++ b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h @@ -580,6 +580,10 @@ auto EmitIndexSwitch(EmitterState& state, uint32_t index, uint32_t count, template void EmitIfCondition(EmitterState& state, uint32_t condition, Fn&& fn) { + if (condition == ConstantBool(state, true)) { + fn(); + return; + } const auto then_label = state.builder.AllocateId(); const auto merge_label = state.builder.AllocateId(); state.builder.AddFunction(spv::OpSelectionMerge, merge_label, spv::SelectionControlMaskNone); @@ -593,6 +597,7 @@ void EmitIfCondition(EmitterState& state, uint32_t condition, Fn&& fn) { template uint32_t EmitValueOrDefaultIfCondition(EmitterState& state, uint32_t condition, uint32_t type, uint32_t default_value, Fn&& fn) { + if (condition == ConstantBool(state, true)) return fn(); const auto then_label = state.builder.AllocateId(); const auto header = state.current_label; const auto merge_label = state.builder.AllocateId(); diff --git a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterMemory.cpp b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterMemory.cpp index 6159e56ed..71bd27c81 100644 --- a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterMemory.cpp +++ b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterMemory.cpp @@ -1605,9 +1605,12 @@ void EmitReadConstBuffer(ValueEmitContext& ctx, const IR::Inst& inst) { } auto& state = ctx.state; mem.kind = IR::ResourceKind::ScalarBuffer; - auto index = Binary(state, spv::OpShiftRightLogical, TypeU32(state), ctx.Arg(inst, 1), - ConstantU32(state, 2)); - if (mem.offset >= 4u) { + const auto offset = inst.Arg(1).Resolve(); + auto index = offset.IsImmediate() + ? ConstantU32(state, (offset.U32() >> 2u) + (mem.offset >> 2u)) + : Binary(state, spv::OpShiftRightLogical, TypeU32(state), + ctx.Arg(inst, 1), ConstantU32(state, 2)); + if (!offset.IsImmediate() && mem.offset >= 4u) { index = Binary(state, spv::OpIAdd, TypeU32(state), index, ConstantU32(state, mem.offset >> 2u)); } const auto access = PrepareMemoryResourceAccess(state, mem); diff --git a/tests/shaderCfgTests.cpp b/tests/shaderCfgTests.cpp index 965f182ea..09b0be1d9 100644 --- a/tests/shaderCfgTests.cpp +++ b/tests/shaderCfgTests.cpp @@ -10532,6 +10532,7 @@ void TestComputeDispatchWaveSize() { void TestNewShaderRecompilerBufferLoadsGuardedByExec() { const uint32_t shader[] = { + EncodeVopc(0xd4, 0 + 256, 1), // v_cmpx_gt_u32 v0, v1 EncodeMubuf0(0x0c), EncodeMubuf1(0, 0, 1), // buffer_load_dword // v0