gfx-rs / naga

Universal shader translation in Rust

Home Page:https://github.com/gfx-rs/wgpu/tree/trunk/naga

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Artifacts when using binding_array with textures. #2282 Related

trixnz opened this issue · comments

commented

I originally created an issue on bevyengine/bevy#9221 as that was where I first noticed the behaviour, but curiosity got the better of me, so while bisecting through naga and running the texture-arrays example each step, I found that this gfx-rs/wgpu@dcad7dfb commit resulted in the artifacts appearing.

Okay, so it's in naga; more bisecting through naga and this commit 37b3c36 introduces the behaviour.

Relevant system information:

OS: NixOS 23.11.20230719.7f256d7 (Tapir)
Display Server: Wayland 1.22

AdapterInfo { name: "AMD Radeon RX 6800 XT (RADV NAVI21)", vendor: 4098, device: 29631, device_type: DiscreteGpu, driver: "radv", driver_info: "Mesa 23.1.3", backend: Vulkan } 

From what I can visibly observe, it seems like textures from other indices in the array are bleeding over into other textures. The artifact colors are always from another texture in the array.

I've attached a screenshot:
image
Artifacts in the image, more prominent when resizing the window

If there's any additional information I can provide to help track down the cause, i'm more than happy to pass it on!

Very nice! I actually noticed this myself, I just forgot to file. This only affects AMD as only AMD cares, but how we are setting the NON_UNIFORM flag in spirv isn't correct.

What exactly is wrong with our non-uniform declarations? Does the test output has the issue?

If you run that spirv through spirv-cross (or do as I have and run wgsl through rga) you'll see that neither pick up the image accesses as non-uniform and generate the appropriate code. I suspect it's because we're marking the result of the access chain non-uniform as opposed to the result of the OpLoad - but we should compare with what glslc generates.

Yeah just validated this with the example if you do the following as is:

spirv-as ./tests/out/spv/binding-array.spvasm -o binding-array.spv
spirv-cross binding-array.spv -V

you get:

    if (all(lessThan(uvec2(_120), uvec2(imageSize(_12[_116])))))
    {
        imageStore(_12[_116], _120, _107);
    }

at the end of the shader.

If you change

OpDecorate %412 NonUniform
to point at 413 (the load result) instead of 412 (the access chain result) and run the same commands, you get

     if (all(lessThan(uvec2(_120), uvec2(imageSize(_12[nonuniformEXT(_116)])))))
    {
        imageStore(_12[nonuniformEXT(_116)], _120, _107);
    }

I don't think this will be that hard to fix, will try it tomorrow.