From 8a5e5c54769266495e17c673a7dde02014072636 Mon Sep 17 00:00:00 2001 From: nmzik Date: Wed, 23 Sep 2026 10:49:42 +0400 Subject: [PATCH] Fold buffer address identities and remove empty predicates --- .../backend/spirv/spirvEmitterInternal.h | 12 +++---- .../backend/spirv/spirvEmitterMemory.cpp | 33 +++++++++++-------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h index 546f483df..3d467722d 100644 --- a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h +++ b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h @@ -494,22 +494,18 @@ template uint32_t EmitValueOrDefaultIfCondition(EmitterState& state, uint32_t condition, uint32_t type, uint32_t default_value, Fn&& fn) { const auto then_label = state.builder.AllocateId(); - const auto then_exit = state.builder.AllocateId(); - const auto else_label = state.builder.AllocateId(); + const auto header = state.current_label; const auto merge_label = state.builder.AllocateId(); state.builder.AddFunction(spv::OpSelectionMerge, merge_label, spv::SelectionControlMaskNone); - state.builder.AddFunction(spv::OpBranchConditional, condition, then_label, else_label); + state.builder.AddFunction(spv::OpBranchConditional, condition, then_label, merge_label); EmitLabel(state, then_label); const auto then_value = fn(); - state.builder.AddFunction(spv::OpBranch, then_exit); - EmitLabel(state, then_exit); - state.builder.AddFunction(spv::OpBranch, merge_label); - EmitLabel(state, else_label); + const auto then_exit = state.current_label; state.builder.AddFunction(spv::OpBranch, merge_label); EmitLabel(state, merge_label); const auto value = state.builder.AllocateId(); state.builder.AddFunction(spv::OpPhi, type, value, then_value, then_exit, default_value, - else_label); + header); return value; } diff --git a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterMemory.cpp b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterMemory.cpp index 9523410fc..a9013344a 100644 --- a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterMemory.cpp +++ b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterMemory.cpp @@ -35,11 +35,22 @@ struct BufferAddress { BufferAddress CalculateBufferAddress(EmitterState& state, uint32_t index, uint32_t offset, uint32_t soffset, uint32_t immediate, uint32_t stride, uint32_t swizzle, uint32_t index_stride) { + const auto zero = ConstantU32(state, 0); + const auto one = ConstantU32(state, 1); + const auto add = [&](uint32_t lhs, uint32_t rhs) { + return lhs == zero ? rhs : rhs == zero ? lhs + : Binary(state, spv::OpIAdd, TypeU32(state), lhs, rhs); + }; + const auto mul = [&](uint32_t lhs, uint32_t rhs) { + return lhs == zero || rhs == zero ? zero + : lhs == one ? rhs + : rhs == one ? lhs + : Binary(state, spv::OpIMul, TypeU32(state), lhs, rhs); + }; if (immediate != 0u) { - offset = Binary(state, spv::OpIAdd, TypeU32(state), offset, ConstantU32(state, immediate)); + offset = add(offset, ConstantU32(state, immediate)); } - const auto indexed = Binary(state, spv::OpIMul, TypeU32(state), index, stride); - auto address = Binary(state, spv::OpIAdd, TypeU32(state), indexed, offset); + auto address = add(mul(index, stride), offset); if (swizzle != 0u) { const auto index_shift = Binary(state, spv::OpIAdd, TypeU32(state), index_stride, ConstantU32(state, 3)); @@ -54,18 +65,12 @@ BufferAddress CalculateBufferAddress(EmitterState& state, uint32_t index, uint32 Binary(state, spv::OpBitwiseAnd, TypeU32(state), offset, ConstantU32(state, ~3u)); const auto offset_lsb = Binary(state, spv::OpBitwiseAnd, TypeU32(state), offset, ConstantU32(state, 3u)); - const auto indexed_msb = Binary(state, spv::OpIMul, TypeU32(state), index_msb, stride); - const auto msb = - Binary(state, spv::OpIMul, TypeU32(state), - Binary(state, spv::OpIAdd, TypeU32(state), indexed_msb, offset_msb), indices); - const auto lsb = Binary(state, spv::OpIAdd, TypeU32(state), - Binary(state, spv::OpShiftLeftLogical, TypeU32(state), index_lsb, - ConstantU32(state, 2u)), - offset_lsb); - address = Select(state, TypeU32(state), swizzle, - Binary(state, spv::OpIAdd, TypeU32(state), msb, lsb), address); + const auto msb = mul(add(mul(index_msb, stride), offset_msb), indices); + const auto lsb = add(Binary(state, spv::OpShiftLeftLogical, TypeU32(state), index_lsb, + ConstantU32(state, 2u)), offset_lsb); + address = Select(state, TypeU32(state), swizzle, add(msb, lsb), address); } - return {offset, Binary(state, spv::OpIAdd, TypeU32(state), address, soffset)}; + return {offset, add(address, soffset)}; } uint32_t BufferLane(EmitterState& state) {