From fb213e8ae5ab3e6f77411dc5454ae4d0d860399f Mon Sep 17 00:00:00 2001 From: nmzik Date: Thu, 15 Oct 2026 04:25:10 +0200 Subject: [PATCH] shader: share packed color component encoding --- .../recompiler/backend/spirv/spirvEmitterImage.cpp | 14 ++++---------- .../backend/spirv/spirvEmitterInternal.h | 3 +++ .../backend/spirv/spirvEmitterMemoryHelpers.cpp | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterImage.cpp b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterImage.cpp index dc1428ed0..3440e6cd2 100644 --- a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterImage.cpp +++ b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterImage.cpp @@ -642,19 +642,13 @@ uint32_t StoreTexel(ValueEmitContext& ctx, const IR::MemoryInfo& mem, uint32_t d } if (converted) { if (!selected) continue; - auto value = EncodeFormattedStoreComponent(ctx.state, info, component, raw, mem.data_bits); if (!packed) { - values[component] = value; + values[component] = + EncodeFormattedStoreComponent(ctx.state, info, component, raw, mem.data_bits); continue; } - if (info.type == Format::ComponentType::Uint) { - value = EmitUMin32(ctx.state, value, - ConstantU32(ctx.state, (1u << info.component_bits[component]) - 1u)); - } - if (info.component_bit_offset[component] != 0u) { - value = Binary(ctx.state, spv::OpShiftLeftLogical, TypeU32(ctx.state), value, - ConstantU32(ctx.state, info.component_bit_offset[component])); - } + const auto value = + EncodePackedColorComponent(ctx.state, info, component, raw, mem.data_bits); packed_value = packed_value == zero ? value : Binary(ctx.state, spv::OpBitwiseOr, TypeU32(ctx.state), packed_value, value); continue; diff --git a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h index e31ec84d1..05ebceb1a 100644 --- a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h +++ b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterInternal.h @@ -459,6 +459,9 @@ uint32_t NormalizeFormatComponent(EmitterState& state, const Format::BufferForma uint32_t EncodeFormattedStoreComponent(EmitterState& state, const Format::BufferFormatInfo& info, uint32_t component, uint32_t data, uint32_t data_bits); +uint32_t EncodePackedColorComponent(EmitterState& state, const Format::BufferFormatInfo& info, + uint32_t component, uint32_t data, uint32_t data_bits); + spv::Op SpirvAtomicOpcode(IR::ValueOpcode opcode); uint32_t EmitAtomicOperation(ValueEmitContext& ctx, const IR::Inst& inst, uint32_t pointer, diff --git a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterMemoryHelpers.cpp b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterMemoryHelpers.cpp index a6cbdbcfb..79d267c82 100644 --- a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterMemoryHelpers.cpp +++ b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterMemoryHelpers.cpp @@ -480,6 +480,20 @@ uint32_t EncodeFormattedStoreComponent(EmitterState& state, const Format::Buffer return data; } +uint32_t EncodePackedColorComponent(EmitterState& state, const Format::BufferFormatInfo& info, + uint32_t component, uint32_t data, uint32_t data_bits) { + auto value = EncodeFormattedStoreComponent(state, info, component, data, data_bits); + if (info.type == Format::ComponentType::Uint) { + value = EmitUMin32(state, value, + ConstantU32(state, (1u << info.component_bits[component]) - 1u)); + } + if (info.component_bit_offset[component] != 0u) { + value = Binary(state, spv::OpShiftLeftLogical, TypeU32(state), value, + ConstantU32(state, info.component_bit_offset[component])); + } + return value; +} + spv::Op SpirvAtomicOpcode(IR::ValueOpcode opcode) { switch (opcode) { case IR::ValueOpcode::SharedAtomicCmpSwap64: