From e0c055fd740f27915ff04ed85984f620fd0f2261 Mon Sep 17 00:00:00 2001 From: CheesyPoofs3460 Date: Mon, 31 Aug 2026 16:37:55 -0700 Subject: [PATCH] renderer: decode R32_SFLOAT packed colour clears (#436) * renderer: decode R32_SFLOAT packed colour clears DecodePackedColorClear handled R32Uint, R32Sint and the 8/10-bit formats but fell through to the default false case for R32Sfloat. metadata_clear_supported then went false, the clear value was discarded, and the target kept its previous contents. Decode the packed word as float bits, matching DecodePackedDepthClear directly below, and reject non-finite patterns rather than materializing them. * renderer: preserve all R32_SFLOAT clear bits --------- Co-authored-by: nmzik --- src/graphics/host_gpu/renderer/image/imageInfo.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/graphics/host_gpu/renderer/image/imageInfo.h b/src/graphics/host_gpu/renderer/image/imageInfo.h index 77e71f4f1..a9ab0fc80 100644 --- a/src/graphics/host_gpu/renderer/image/imageInfo.h +++ b/src/graphics/host_gpu/renderer/image/imageInfo.h @@ -431,6 +431,10 @@ IsSupportedDisplayRenderTargetTileMode(Prospero::TileMode tile_mode) noexcept { return encoded <= 0.04045f ? encoded / 12.92f : std::pow((encoded + 0.055f) / 1.055f, 2.4f); }; switch (format) { + // A single-plane float target carries its clear as raw float bits, the same encoding the + // depth decoder below uses. Without this the clear is discarded and the target keeps stale + // contents. + case vk::Format::eR32Sfloat: next.float32[0] = std::bit_cast(packed); break; case vk::Format::eR32Uint: next.uint32[0] = packed; break; case vk::Format::eR32Sint: next.int32[0] = static_cast(packed); break; case vk::Format::eR8G8B8A8Srgb: