From 6123419437a804876d38a80d624e60f0509387fd Mon Sep 17 00:00:00 2001 From: nmzik Date: Thu, 22 Oct 2026 00:35:09 +0200 Subject: [PATCH] shader: skip full DPP row and bank masks and test partial ones with one bit extract --- .../backend/spirv/spirvEmitterFlow.cpp | 61 ++++++------------- 1 file changed, 18 insertions(+), 43 deletions(-) diff --git a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterFlow.cpp b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterFlow.cpp index 17a19ebe3..6d1926a40 100644 --- a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterFlow.cpp +++ b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterFlow.cpp @@ -114,51 +114,26 @@ uint32_t EmitBuiltinU32(EmitterState& state, IR::StageInputKind kind, uint32_t c uint32_t EmitDppWriteCondition(ValueEmitContext& ctx, const IR::DppMoveFlags& flags, uint32_t exec) { - auto& state = ctx.state; - const auto lane = EmitSubgroupLocalInvocationId(state); - const auto bank_shift = state.builder.AllocateId(); - const auto row_shift = state.builder.AllocateId(); - const auto bank = state.builder.AllocateId(); - const auto row = state.builder.AllocateId(); - const auto bank_bit = state.builder.AllocateId(); - const auto row_bit = state.builder.AllocateId(); - const auto bank_hit = state.builder.AllocateId(); - const auto row_hit = state.builder.AllocateId(); - const auto bank_ok = state.builder.AllocateId(); - const auto row_ok = state.builder.AllocateId(); - const auto masks_ok = state.builder.AllocateId(); - state.builder.AddFunction(spv::OpShiftRightLogical, TypeU32(state), bank_shift, lane, - ConstantU32(state, 2)); - state.builder.AddFunction(spv::OpShiftRightLogical, TypeU32(state), row_shift, lane, - ConstantU32(state, 4)); - state.builder.AddFunction(spv::OpBitwiseAnd, TypeU32(state), bank, bank_shift, - ConstantU32(state, 3)); - state.builder.AddFunction(spv::OpBitwiseAnd, TypeU32(state), row, row_shift, - ConstantU32(state, 3)); - state.builder.AddFunction(spv::OpShiftLeftLogical, TypeU32(state), bank_bit, - ConstantU32(state, 1), bank); - state.builder.AddFunction(spv::OpShiftLeftLogical, TypeU32(state), row_bit, - ConstantU32(state, 1), row); - state.builder.AddFunction(spv::OpBitwiseAnd, TypeU32(state), bank_hit, - ConstantU32(state, flags.bank_mask), bank_bit); - state.builder.AddFunction(spv::OpBitwiseAnd, TypeU32(state), row_hit, - ConstantU32(state, flags.row_mask), row_bit); - state.builder.AddFunction(spv::OpINotEqual, TypeBool(state), bank_ok, bank_hit, - ConstantU32(state, 0)); - state.builder.AddFunction(spv::OpINotEqual, TypeBool(state), row_ok, row_hit, - ConstantU32(state, 0)); - state.builder.AddFunction(spv::OpLogicalAnd, TypeBool(state), masks_ok, bank_ok, row_ok); - uint32_t writable = masks_ok; + auto& state = ctx.state; + uint32_t writable = exec; + // Each mask bit enables writes to one bank (4 lanes) or row (16 lanes); a full mask enables all. + const auto enable = [&](uint32_t mask, uint32_t group_shift) { + if (mask == 0xfu) return; + const auto group = EmitNative( + state, EmitSubgroupLocalInvocationId(state), ConstantU32(state, group_shift), + ConstantU32(state, 2)); + const auto bit = EmitNative( + state, ConstantU32(state, mask), group, ConstantU32(state, 1)); + writable = Binary(state, spv::OpLogicalAnd, TypeBool(state), writable, + Binary(state, spv::OpINotEqual, TypeBool(state), bit, ConstantU32(state, 0))); + }; + enable(flags.bank_mask, 2u); + enable(flags.row_mask, 4u); if (!flags.bound_control) { - const auto target = EmitDppTargetLane(state, flags); - const auto bounded = state.builder.AllocateId(); - state.builder.AddFunction(spv::OpLogicalAnd, TypeBool(state), bounded, writable, - target.valid); - writable = bounded; + writable = Binary(state, spv::OpLogicalAnd, TypeBool(state), writable, + EmitDppTargetLane(state, flags).valid); } - const auto result = state.builder.AllocateId(); - state.builder.AddFunction(spv::OpLogicalAnd, TypeBool(state), result, exec, writable); - return result; + return writable; } uint32_t EmitAttribute(EmitterState& state, uint32_t attr, uint32_t chan) {