From 10a852c2ac480878ca077e605d7593bee582ad90 Mon Sep 17 00:00:00 2001 From: nmzik Date: Wed, 21 Oct 2026 22:46:04 +0200 Subject: [PATCH] shader: pack 16-bit lane pairs with one bit-field insert --- .../recompiler/backend/spirv/spirvEmitterAlu.cpp | 7 +++---- .../shader/recompiler/frontend/translate/Convert.cpp | 11 ++++------- tests/ShaderRecompilerComputeTests.cpp | 6 ++---- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterAlu.cpp b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterAlu.cpp index 5076e255c..ae29d3468 100644 --- a/src/graphics/shader/recompiler/backend/spirv/spirvEmitterAlu.cpp +++ b/src/graphics/shader/recompiler/backend/spirv/spirvEmitterAlu.cpp @@ -211,10 +211,9 @@ uint32_t EmitCompositeExtractU32x2(EmitterState& state, uint32_t arg0, IR::Value } uint32_t EmitPackFloat2x16Rtz(EmitterState& state, uint32_t arg0, uint32_t arg1) { - const auto low = EmitF32ToF16RtzBits(state, arg0); - const auto high = Binary(state, spv::OpShiftLeftLogical, TypeU32(state), - EmitF32ToF16RtzBits(state, arg1), ConstantU32(state, 16)); - return EmitOrU32(state, low, high); + return EmitNative( + state, EmitF32ToF16RtzBits(state, arg0), EmitF32ToF16RtzBits(state, arg1), + ConstantU32(state, 16), ConstantU32(state, 16)); } uint32_t EmitFPSaturate32(EmitterState& state, uint32_t arg0) { diff --git a/src/graphics/shader/recompiler/frontend/translate/Convert.cpp b/src/graphics/shader/recompiler/frontend/translate/Convert.cpp index 90c2c64d3..7417f2e72 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Convert.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Convert.cpp @@ -166,16 +166,13 @@ void Translator::V_CVT_PK_U8_F32(const Decoder::Instruction& inst) { } void Translator::V_PACK_B32_F16(const Decoder::Instruction& inst) { - const auto low = Read16LaneBits(inst.src0, false); - const auto high = - ir.ShiftLeftLogical(Read16LaneBits(inst.src1, false), IR::U32(IR::Value(16u))); - WriteOperand(DestinationOperand(inst), ir.BitwiseOr(low, high)); + WriteOperand(DestinationOperand(inst), + PackU16Lanes(Read16LaneBits(inst.src0, false), Read16LaneBits(inst.src1, false))); } IR::U32 Translator::PackU16Lanes(IR::U32 low, IR::U32 high) { - const auto mask = IR::U32(IR::Value(0xffffu)); - return ir.BitwiseOr(ir.BitwiseAnd(low, mask), - ir.ShiftLeftLogical(ir.BitwiseAnd(high, mask), IR::U32(IR::Value(16u)))); + return IR::U32( + ir.Emit(IR::ValueOpcode::BitFieldInsert, {low, high, IR::Value(16u), IR::Value(16u)})); } } // namespace Libs::Graphics::ShaderRecompiler::Frontend diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 87445e15a..bf69e15d8 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -25109,10 +25109,8 @@ TestCase Vop3CvtPkI16I32Captured() { test.opcodes = {O::BUFFER_LOAD_DWORD, O::V_MOV_B32, O::V_CVT_PK_I16_I32, O::BUFFER_STORE_DWORD, O::S_ENDPGM}; test.decoded_counts = {{"0x00000014: V_CVT_PK_I16_I32 v5, v7, v16\n", 1}}; - test.ir_counts = {{" = BitwiseAnd32 ", 2}, - {" = ShiftLeftLogical32 ", 1}, - {" = BitwiseOr32 ", 1}}; - test.required_spirv = {"OpBitwiseAnd", "OpShiftLeftLogical", "OpBitwiseOr"}; + test.ir_counts = {{" = BitFieldInsert ", 1}}; + test.required_spirv = {"OpBitFieldInsert"}; return test; }