-
Notifications
You must be signed in to change notification settings - Fork 329
Description
The WebGPU spec currently requires that the texture view formats for a color attachment and its resolve attachment are the same.
This is required by at least the Vulkan specification.
Multisample resolve has an interesting interaction with view format reinterpretation in that you may resolve from a color attachment into a resolve attachment which has the same texture view format, but a different base texture format.
Doing so is allowed (could not find spec text against it) in all of the backend APIs (Vulkan/Metal/D3D12), and it doesn't run into any issues with their respective backend validation layers enabled.
However, the result of the resolve operation is different in the APIs.
If you create an rgba8unorm
texture and render to it as rgba8unorm
, and resolve it to an rgba8unorm-srgb
texture viewed as rgba8unorm
...
- Concretely, in the shader, write out constant value
{ R: 0.4, G: 0.3, B: 0.6, A: 0.8 }
. - All of the APIs will store into the rendered texture +/-2 ULPs
[102, 77, 153, 204]
. This is the sRGB encoding of those values. - Metal/D3D12 will store into the resolve texture +/-2 ULPs
[102, 77, 153, 204]
(the same thing). Makes sense because we are resolving sRGB to sRGB.
Vulkan does something different.
Vulkan will interpret the contents rendered viewrgba8unorm
using the original texture formatrgba8unorm
.
[102, 77, 153, 204]
is interpreted as{R: 0.4, G: 0.30196078431372547, B: 0.6, A: 0.8}
.
(this result is the same, modulo precision, for this set of formats rgba8unorm->rgba8unorm, but different for other formats).
It will then resolve and encode this value based on the resolve texture formatrgba8unorm-srgb
(not the resolve view format!). Thergba8unorm-srgb
encoding of the color is[170, 149, 203, 204]
.
I spent a while trying to find a way to make the various APIs have the same behavior, but was unsuccessful.
For now, my suggestion is that WebGPU V1 requires the base texture formats for a color attachment and its resolve attachment to match exactly.
Another example: render to rgba8unorm
viewed as rgba8unorm-srgb
; resolve to rgba8unorm-srgb
viewed as rgba8unorm-srgb
.
- Write in the shader
{R: 0.4, G: 0.3, B: 0.6, A: 0.8}
- Stored render results are
[170, 149, 203, 204]
, the sRGB encoding of the color - Vulkan interprets these bytes using the render format (not view)
rgba8unorm
as {R: 0.6666666666666666, G: 0.5843137254901961, B: 0.796078431372549, A: 0.8} - And resolves it by encoding the color to
rgba8unorm-srgb
:[213, 201, 231, 204]