EmbarkStudios / rust-gpu

🐉 Making Rust a first-class language and ecosystem for GPU shaders 🚧
https://shader.rs
Apache License 2.0
7.35k stars 245 forks source link

spirv-std/`Image!` should expose `AccessQualifier`. #1097

Open FishArmy100 opened 1 year ago

FishArmy100 commented 1 year ago

I think it would be beneficial to expose the AccessQualifier in the Image! macro, as at least for wgpu, ReadWrite and ReadOnly storage textures are only supported on native platforms. So, it would be benificial for Images allow for WriteOnly.

eddyb commented 9 months ago

Oh I'm really sorry I haven't checked what SPIR-V's "Access Qualifier" is. The reason it's optional and not included in spirv_std::Image seems to be that it's Kernel-only.

That is, this is an OpenCL feature, not a Vulkan one, and wgpu couldn't possibly make use of it (unless they misunderstood the specification, too?).

The Vulkan feature is NonWritable/NonReadable on the OpVariable, seems like, just like StorageBuffers.

It does seem weird to put it in the attribute in the #[spirv(...)] img: Image!(...) declaration, as the Image<...> type could really use the knowledge, and a writable &Image behaves more like a &[Cell<u32>]/&[AtomicU32] (relying on interior mutability), if that makes sense.

It may be possible to pretend that it is a parameter on image types, or even reuse the AccessQualifier (and rewrite it away to the Vulkan equivalent), but that seems a bit sketchy, not sure what to do about it for now.

(cc @Algorhythm-sxv - sorry you ended up implementing a different feature that the needed one)

Algorhythm-sxv commented 9 months ago

@eddyb is there a workaround to allow use of a wgpu StorageTexture using the attribute syntax then? I see the AccessQualifier in spirv-headers but no documentation on how to use it, or if it's possible to use it.

eddyb commented 9 months ago

This is the relevant part of my message:

The Vulkan feature is NonWritable/NonReadable on the OpVariable, seems like, just like StorageBuffers.

We currently support toggling NonWritable for buffers based on whether you use &T vs &mut T with #[spirv(storage_buffer, ...)] entry-point parameter declarations, since:

In theory, we could do it for images based on &Image vs &mut Image, but like I was saying earlier that doesn't fit very well IMO, since images already behaves as if they wrap interior mutability anyway, and also that doesn't cover NonReadable (because Rust has nothing like a "write-only reference"), which I believe you need?

There's two possible paths, as I see it: