gfx-rs / wgpu

A cross-platform, safe, pure-Rust graphics API.
https://wgpu.rs
Apache License 2.0
12.41k stars 908 forks source link

[spv-in] Writing to texture #6420

Open schell opened 4 hours ago

schell commented 4 hours ago

Description As I wrote about here and as far as I can tell, it's not possible to write to textures in wgpu if your shader is SPIR-V.

This seems to be because the OpTypeImage passed to OpImageWrite must have its "Sampled" parameter set to 2:

Image must be an object whose type is OpTypeImage with a Sampled operand of 0 or 2.

...

2 indicates an image compatible with read/write operations (a storage or subpass data image)

I think naga's spv frontend erroneously assumes that 2 in this case means read AND write instead of "one of readonly, writeonly or readwrite", as is implied by only having one value for all of them in the SPIR-V spec.

Repro steps Working on it...

Expected vs observed behavior I expect to be able to build my shader pipeline and write to storage textures.

Instead, I got this error:

wgpu error: Validation Error

Caused by:
  In Device::create_compute_pipeline, label = 'compute-occlusion-copy-depth-to-pyramid'
    Error matching shader requirements against the pipeline
      Shader global ResourceBinding { group: 0, binding: 2 } is not available in the pipeline layout
        Texture class Storage { format: R32Float, access: StorageAccess(STORE) } doesn't match the shader Storage { format: R32Float, access: StorageAccess(LOAD | STORE) }

I should note that simply marking my texture as read+write is not an option as that is a native-only feature and I target web.

schell commented 4 hours ago

@jimblandy had mentioned later in the matrix channel that in order to properly support this, we may need to do something similar to the atomics upgrade.

What that means is storing the pointer to the image during parsing and then doing a late-pass over the generated module to inspect how that image is used (read or write or readwrite), and then updating the type accordingly.