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

writing to storage buffers/textures in fragment shaders with multisample targets is not portable. #4696

@greggman

Description

@greggman

IIUC the spec says or implies if you're using a non-multisampled target you get 1 invocation of the fragment shader for each pixel being rendered

If rendering to a multisampled target then then you still only get 1 invocation per pixel, unless you're using sample_index or @interpolate(..., sample) in which case you'll get 1 invocation per sample

But, testing, that's not the case. We can test how many times a fragment shader is called with something like

     @group(0) @binding(0) var<storage, read_write> count: atomic<u32>; 

     @fragment fn fs() -> @location(0) vec4f {
       atomicAdd(&count, 1);
       ...
     }

So, testing that

M1 Mac

PASS: sampleCount: 1, @interpolate(perspective)        ,             , count = 1, should be 1
PASS: sampleCount: 1, @interpolate(perspective)        , sample_index, count = 1, should be 1
PASS: sampleCount: 1, @interpolate(perspective, sample),             , count = 1, should be 1
PASS: sampleCount: 1, @interpolate(perspective, sample), sample_index, count = 1, should be 1
FAIL: sampleCount: 4, @interpolate(perspective)        ,             , count = 4, should be 1  <---
PASS: sampleCount: 4, @interpolate(perspective)        , sample_index, count = 4, should be 4
PASS: sampleCount: 4, @interpolate(perspective, sample),             , count = 4, should be 4
PASS: sampleCount: 4, @interpolate(perspective, sample), sample_index, count = 4, should be 4

AMD/Intel Mac

PASS: sampleCount: 1, @interpolate(perspective)        ,             , count = 1, should be 1
PASS: sampleCount: 1, @interpolate(perspective)        , sample_index, count = 1, should be 1
PASS: sampleCount: 1, @interpolate(perspective, sample),             , count = 1, should be 1
PASS: sampleCount: 1, @interpolate(perspective, sample), sample_index, count = 1, should be 1
PASS: sampleCount: 4, @interpolate(perspective)        ,             , count = 1, should be 1
FAIL: sampleCount: 4, @interpolate(perspective)        , sample_index, count = 1, should be 4  <--
FAIL: sampleCount: 4, @interpolate(perspective, sample),             , count = 1, should be 4  <--
FAIL: sampleCount: 4, @interpolate(perspective, sample), sample_index, count = 1, should be 4  <--

Windows NVidia 2070 Super

PASS: sampleCount: 1, @interpolate(perspective)        ,             , count = 1, should be 1
PASS: sampleCount: 1, @interpolate(perspective)        , sample_index, count = 1, should be 1
PASS: sampleCount: 1, @interpolate(perspective, sample),             , count = 1, should be 1
PASS: sampleCount: 1, @interpolate(perspective, sample), sample_index, count = 1, should be 1
PASS: sampleCount: 4, @interpolate(perspective)        ,             , count = 1, should be 1
FAIL: sampleCount: 4, @interpolate(perspective)        , sample_index, count = 1, should be 4 <--
FAIL: sampleCount: 4, @interpolate(perspective, sample),             , count = 1, should be 4 <--
FAIL: sampleCount: 4, @interpolate(perspective, sample), sample_index, count = 1, should be 4 <--

Does this need to be called out in the spec in some way? Like one idea is to mention it's not portable to use storage buffers/texture in a fragment shader because number of invocations in undefined. Another idea would be to generate a validation error if storage buffers/textures are written to a fragment shader with a mulitsample target.

It's also possible these are bugs in my code or in dawn or my understanding 😅

Metadata

Metadata

Assignees

No one assigned

    Labels

    apiWebGPU APIneeds-cts-issueThis change requires tests (or would need tests if accepted), but may not have a CTS issue filed yet

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions