这是indexloc提供的服务,不要输入任何密码
Skip to content

Multisample resolve when base texture formats do not match #2729

@austinEng

Description

@austinEng

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...

  1. Concretely, in the shader, write out constant value { R: 0.4, G: 0.3, B: 0.6, A: 0.8 }.
  2. All of the APIs will store into the rendered texture +/-2 ULPs [102, 77, 153, 204]. This is the sRGB encoding of those values.
  3. 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 view rgba8unorm using the original texture format rgba8unorm.
    [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 format rgba8unorm-srgb (not the resolve view format!). The rgba8unorm-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.

  1. Write in the shader {R: 0.4, G: 0.3, B: 0.6, A: 0.8}
  2. Stored render results are [170, 149, 203, 204], the sRGB encoding of the color
  3. Vulkan interprets these bytes using the render format (not view) rgba8unorm as {R: 0.6666666666666666, G: 0.5843137254901961, B: 0.796078431372549, A: 0.8}
  4. And resolves it by encoding the color to rgba8unorm-srgb: [213, 201, 231, 204]

Metadata

Metadata

Assignees

Labels

copyeditingPure editorial stuff (copyediting, *.bs file syntax, etc.)

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions