gfx-rs / wgpu

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

Phony assignments causing errors #4437

Open unvestigate opened 1 year ago

unvestigate commented 1 year ago

I have a shader which I run through Naga to convert it from SPIR-V to WGSL. As part of it the following struct is generated:

struct cbVolumetricLight {
    gLightWorldTransform: mat4x4<f32>,
    gLightIndex: u32,
    padding1_: u32,
    padding2_: u32,
    padding3_: u32,
}

Then later Naga generates code like this:

let _e63 = unnamed.gLightWorldTransform;
_ = (&unnamed.gLightWorldTransform[0][3u]);
let _e70 = unnamed.gLightWorldTransform;
_ = (&unnamed.gLightWorldTransform[1][3u]);
let _e77 = unnamed.gLightWorldTransform;
_ = (&unnamed.gLightWorldTransform[2][3u]);
let _e83 = vec3<f32>(transpose(_e63)[0][3u], transpose(_e70)[1][3u], transpose(_e77)[2][3u]);
let _e85 = unnamed_1.gCameraPosition;
let _e91 = normalize((_e60 - vec3<f32>(_e85.x, _e85.y, _e85.z)));
let _e93 = unnamed.gLightIndex;
let _e96 = unnamed_2.gLights[_e93];
let _e104 = unnamed_1.gCameraPosition;
let _e108 = vec3<f32>(_e104.x, _e104.y, _e104.z);
let _e110 = unnamed.gLightWorldTransform;
_ = (&unnamed.gLightWorldTransform[0][2u]);
let _e117 = unnamed.gLightWorldTransform;
_ = (&unnamed.gLightWorldTransform[1][2u]);
let _e124 = unnamed.gLightWorldTransform;
_ = (&unnamed.gLightWorldTransform[2][2u]);
let _e130 = vec3<f32>(transpose(_e110)[0][2u], transpose(_e117)[1][2u], transpose(_e124)[2][2u]);

When trying to load the generated code using the Dawn WebGPU backend I get the following errors:

Tint WGSL reader failure: :108:42 error: cannot take the address of a vector component
    _ = (&unnamed.gLightWorldTransform[0][3u]);

I was wondering. Why is it inserting those phony assignments into the code? Is it to make sure something isn't optimized away or what is the deal?

teoxoy commented 1 year ago

I was wondering. Why is it inserting those phony assignments into the code? Is it to make sure something isn't optimized away or what is the deal?

The SPIR-V front-end might be doing some transformations (looking at those transpose calls) and not cleaning up after itself. The WGSL back-end might also be misbehaving and trying to "take the address of a vector component".

Could you share your SPIR-V input file?

unvestigate commented 1 year ago

Sure. I uploaded the file here: https://drive.proton.me/urls/JQ577Y7N8R#Wn1D9KWe5t1v

teoxoy commented 1 year ago

Thanks!

The phony assignments should be harmless and are indeed some leftovers of a transformation in the frontend (row major matrix -> column major).

We need to disallow taking the address of a vector component https://github.com/gpuweb/gpuweb/pull/2225.

unvestigate commented 1 year ago

I added a small hack to my shader compilation pipeline for this. It basically looks for lines that look like these and removes them. The rest of the code is left as-is and does work how I expect it to.

And yes, I do use row-major matrices due to the source language being HLSL, and I appreciate Naga doing the conversion here so that the shaders work with WebGPU.

teoxoy commented 1 year ago

naga already knows that those expressions are not actually used but still writes them to improve the debugging experience in some cases, also some of our snapshot tests make use of this behavior. We should add a flag to make this behavior configurable.