shader: preserve export vectors instead of rebuilding scalar components

This commit is contained in:
nmzik
2026-10-09 02:42:43 +02:00
parent ee4dd90649
commit b4853a0e08
2 changed files with 35 additions and 38 deletions
@@ -304,6 +304,7 @@ uint32_t ExportVector(ValueEmitContext& ctx, uint32_t data, const IR::ExportInfo
f32[0], f32[1], f32[2], f32[3]); f32[0], f32[1], f32[2], f32[3]);
return vector; return vector;
} }
if (exp.compr || exp.en != 0xfu) {
uint32_t raw[4] = { uint32_t raw[4] = {
ConstantU32(state, 0), ConstantU32(state, 0),
ConstantU32(state, 0), ConstantU32(state, 0),
@@ -334,20 +335,15 @@ uint32_t ExportVector(ValueEmitContext& ctx, uint32_t data, const IR::ExportInfo
} }
} }
} }
if (uint_output) { data = state.builder.AllocateId();
const auto vector = state.builder.AllocateId(); state.builder.AddFunction(spv::OpCompositeConstruct, TypeU32Vector(state, 4), data,
state.builder.AddFunction(spv::OpCompositeConstruct, TypeU32Vector(state, 4), vector,
raw[0], raw[1], raw[2], raw[3]); raw[0], raw[1], raw[2], raw[3]);
return vector;
} }
uint32_t f32[4] {}; if (uint_output) {
for (uint32_t component = 0; component < 4u; component++) { return data;
f32[component] = state.builder.AllocateId();
state.builder.AddFunction(spv::OpBitcast, TypeF32(state), f32[component], raw[component]);
} }
const auto vector = state.builder.AllocateId(); const auto vector = state.builder.AllocateId();
state.builder.AddFunction(spv::OpCompositeConstruct, TypeF32Vector(state, 4), vector, f32[0], state.builder.AddFunction(spv::OpBitcast, TypeF32Vector(state, 4), vector, data);
f32[1], f32[2], f32[3]);
return vector; return vector;
} }
+3 -2
View File
@@ -12826,7 +12826,7 @@ void TestNewShaderRecompilerExpPixelOutputs() {
options.input_info.pixel = &default_info; options.input_info.pixel = &default_info;
auto partial_result = RecompileForTest(partial_shader, options); auto partial_result = RecompileForTest(partial_shader, options);
const auto partial_source = DisassembleSpirvBinary(partial_result.spirv); const auto partial_source = DisassembleSpirvBinary(partial_result.spirv);
Check(SpirvSourceHasInstructionOperand(partial_source, "OpBitcast", Check(SpirvSourceHasInstructionOperand(partial_source, "OpCompositeConstruct",
"%uint_1065353216"), "%uint_1065353216"),
"disabled float alpha export did not default to 1.0f bits"); "disabled float alpha export did not default to 1.0f bits");
CheckSpirvBinaryValidates(partial_result.spirv); CheckSpirvBinaryValidates(partial_result.spirv);
@@ -13228,8 +13228,9 @@ void TestLogicalAlphaBlendExport() {
const auto source = DisassembleSpirvBinary(guest.spirv); const auto source = DisassembleSpirvBinary(guest.spirv);
Check(source.find("OpDecorate %out_mrt_1 Location 0") != std::string::npos && Check(source.find("OpDecorate %out_mrt_1 Location 0") != std::string::npos &&
source.find("OpDecorate %out_mrt_1 Index 1") != std::string::npos && source.find("OpDecorate %out_mrt_1 Index 1") != std::string::npos &&
CountSourceOccurrences(source, "OpStore %out_mrt_0 ") == 1 &&
CountSourceOccurrences(source, "OpStore %out_mrt_1 ") == 1 && CountSourceOccurrences(source, "OpStore %out_mrt_1 ") == 1 &&
SpirvInstructionOpcodeCount(guest.spirv, 81u) == 8u, !SpirvContainsVectorShuffle(guest.spirv, {3u, 3u, 3u, 3u}),
"guest dual-source export was replaced by synthetic alpha"); "guest dual-source export was replaced by synthetic alpha");
} }