shader: unpack compressed SNORM16 color exports as normalized signed values

This commit is contained in:
Claxten
2026-10-07 18:22:46 +04:00
committed by nmzik
parent 21a1346e27
commit b96871e2bf
2 changed files with 35 additions and 2 deletions
@@ -262,8 +262,12 @@ uint32_t ExportVector(ValueEmitContext& ctx, uint32_t data, const IR::ExportInfo
bool uint_output) {
auto& state = ctx.state;
if (exp.compr && !uint_output) {
const auto unpack =
MrtOutputMode(state, exp) == 5u ? GLSLstd450UnpackUnorm2x16 : GLSLstd450UnpackHalf2x16;
auto unpack = GLSLstd450UnpackHalf2x16;
switch (MrtOutputMode(state, exp)) {
case 5: unpack = GLSLstd450UnpackUnorm2x16; break;
case 6: unpack = GLSLstd450UnpackSnorm2x16; break;
default: break;
}
uint32_t f32[4] = {ConstantF32(state, 0), ConstantF32(state, 0), ConstantF32(state, 0),
ConstantF32(state, 0x3f800000u)};
for (uint32_t pair = 0; pair < 2u; pair++) {
+29
View File
@@ -16470,6 +16470,35 @@ public:
}
}
static const auto snorm_pixel = [] {
std::vector<u32> code;
AppendVMovLiteral(&code, 0, 0xc0008000u);
AppendVMovLiteral(&code, 1, 0x7fff4000u);
code.insert(code.end(), {EncodeExp0(0, 0xf, true, true), EncodeExp1(0, 1, 0, 0)});
AppendEnd(&code);
return code;
}();
const auto snorm_address = reinterpret_cast<uint64_t>(snorm_pixel.data());
ShaderMapUserData(snorm_address,
{.type = Prospero::ShaderBinaryType::kPs,
.code_size_bytes = static_cast<uint32_t>(snorm_pixel.size() * sizeof(u32))});
shaders.SetPsShaderBase(snorm_address);
registers.SetShaderMask(0xf000);
registers.SetTargetOutputMode(0, 6);
registers.SetTargetOutputMode(1, 0);
RenderExecutorTestAccess::DrawAuto(
executor, scheduler.Current(), {.vertex_count = 3, .instance_count = 1});
const auto snorm_pixels = ReadCachedTexel(name, context, sparse_color.image_id,
{}, {extent, extent, 1});
constexpr std::array<float, 4> snorm_expected{-1, -16384.0f / 32767,
16384.0f / 32767, 1};
for (size_t component = 0; component < snorm_pixels.size(); component++) {
Require(name, "compressed SNORM16 color export",
std::abs(std::bit_cast<float>(snorm_pixels[component]) -
snorm_expected[component % 4]) < 0.00001f,
"SNORM16 export lost its sign, normalization or negative endpoint clamp");
}
registers.SetTargetOutputMode(0, 4);
// A fourth VS invocation reads beyond the descriptor instead of reconstructing the corner.
const ShaderBufferResource rect_buffer{{