Open Noxime opened 2 years ago
As far as im aware, webgpu doesn't allow dynamic indexing into vectors like that. If you were to define it as an array (var q = array<f32, 4>) you could index into it however you need.
I'm totally wrong, see the 5th row here: https://gpuweb.github.io/gpuweb/wgsl/#vector-single-component
This may be a problem with either FXC or dxbc (vs dxil). The workaround using array<f32, 4> will still get around the problem.
Using an array<f32, 4>
for the decompressor works correctly, however naga denies the compressor function if q is changed to an array. "May only be indexed by a constant". WGSL spec says array read access is done with OpCompositeExtract
while vector indexing is done with OpVectorExtractDynamic
. Fascinating. Is dynamic array read indexing planned or is it purposefully forced to be static? Either way, the workaround you suggested works, thanks!
WGSL group decided that dynamic indexing for array
values needs to be allowed, and SPIR-V based implementation would have to find a way to make it possible. Our implementation isn't updated to reflect that. We had this working at some point, but were happy to remove it once the group previously agreed to disallow that. And then the decision was reversed.
compressor function if q is changed to an array. "May only be indexed by a constant".
Make sure it is stored in a var, not let.
Tint had to deal with this as well, see https://bugs.chromium.org/p/tint/issues/detail?id=998.
See also #4337
When trying to assign to a vector component through indexing, the Direct3D shader compiler rejects the generated HLSL. On Vulkan and Metal the shader is built without any issues and runs correctly.
Error message:
Related WGSL (32-bit quaternion decompression)
Generated HLSL
From reading the error messages, it seems that the first dynamic indexes in the loop can be avoided by unrolling the loop, but the last access towards the end of the function cannot be unrolled since it is not in a loop and causes the issue. Where does WGSL / WebGPU stand on the issue? Is assignment into vectors by dynamic indexing supported or am I invoking unvalidated behaviour?
Update: If I wrap the last indexing into a dummy loop of
for i in 0..4 { if i == largest_i { q[i] = ... } }
then the shader compiler is able to work around by unrolling. Not ideal but if someone else runs into this, it might be useful as a temporary fix