-
Notifications
You must be signed in to change notification settings - Fork 195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect SPIR-V shader passthrough #1400
Comments
This is a great report! |
I looked at this and found the problem in
In the produced SPIR-V:
I'm surprised that the matrix stride on SPIR-V is 16. Here are the steps to proceed:
|
In the meantime, you can work around it by using |
That makes quite a lot of sense. How did you go about dumping the produced SPIR-V? This could be caused by being of the key differences in layout between |
This seems like a problem with spv-out we aren't passing the matrix stride and it's assuming the stride is the vector length, which is correct in std430 (also probably what wgsl uses but need to check) but since glsl defines that matrix stride must be a multiple of a vec4 alignment (16 machine units) in std140 it isn't working. The long term solution is allowing to pass the matrix stride, the short term solution is algining with what wgsl and you potentially will need to use std430. |
When I try to use
(And I don't want to request any extensions above WebGPU). The workaround of |
Yes glsl requires you to enable #extension GL_EXT_scalar_block_layout : require to the top of your shader should fix the error |
Perfect, thank you. |
@kvark I've checked and the wgsl spec defines that the matrices strides follow the Another issue is the glsl backend because glsl requires the |
We have not need
WGSL should work with std140 in uniform blocks. I think |
It's not that easy because matrices, structures and arrays are affected by this rule of rounding the alignment to a struct Inner {
float a; // 0 offset, 4 alignment
}
struct Outer {
vec2 b; // 0 offset, 8 alignment
Inner c; // 16 offset, 16 alignment because of round up
} how do you access |
I don't think we need to do anything fancy about arrays. WGSL already requires that for uniform storage class:
So naga expects incoming SPIR-V or whatever to already specify the stride=16 for such arrays, and the validation is happy, and the backend can just omit the stride if it sees this is a uniform buffer. For structs, a similar rule is there:
So this should mean WGSL uniform class is the same layout as std140. Again, I think mat2 is the only exception. |
I don't think this issue is limited to SPIR-V in or out. GLSL input also causes incorrect WGSL output! Here's a simple pair of shaders to act as a litmus test. If both of these shaders result in the same WGSL, then this bug is still present: #version 450
layout(std140, set = 0, binding = 0) readonly buffer INPUT {
mat2 in_data;
};
layout(std140, set = 0, binding = 1) buffer OUTPUT {
mat2 out_data;
};
void main() {
out_data = in_data;
} #version 450
layout(std430, set = 0, binding = 0) readonly buffer INPUT {
mat2 in_data;
};
layout(std430, set = 0, binding = 1) buffer OUTPUT {
mat2 out_data;
};
void main() {
out_data = in_data;
} These shaders differ only by their layout, which influences the layout of [[block]]
struct INPUT {
in_data: mat2x2<f32>;
};
[[block]]
struct OUTPUT {
out_data: mat2x2<f32>;
};
[[group(0), binding(0)]]
var<storage> global: INPUT;
[[group(0), binding(1)]]
var<storage, read_write> global1: OUTPUT;
fn main1() {
let e4: mat2x2<f32> = global.in_data;
global1.out_data = e4;
return;
}
[[stage(compute), workgroup_size(1, 1, 1)]]
fn main() {
main1();
return;
} |
@kvark this is related to the lack of support for different matrix strides in the IR |
Oh the mat2x2 thing? I think we can keep IR strict, but the GLSL and SPIR-V frontends would treat |
How should we deal with the other matrices of the form |
I'm not sure that treating Imagine specifying std140, including a |
The frontend should make it legally and transparently. I.e. it wouldn't just change the type in IR, it would also change all of the operations on that type to correctly work with vec4. This is doable, but also very low priority, since it's for GLSL and SPIR-V frontends only, a lot of work, and somewhat easy to work around for users. |
What I was trying to point out is that for a buffer with the following data
the user will write a Unless we replace the Having the user change the type manually works because they are expected to write the type into the buffer with the right layout but us changing it will only work if we read the data in the same way it was written. Correct me if I'm wrong but I didn't see how the previous comments address this. |
@kvark in light of your previous comment, I opened the following PRs/issues. #1805 - [spv-in] error on an unsupported I think we can close this issue and track the newly opened PRs/issues. |
I see what you mean, thanks for clarification! |
Passing SPIR-V shaders to naga and back alters their effects.
For example see this fragment shader used to paint a 2d normal distribution.
https://github.com/HeroicKatora/stealth-paint/blob/wgpu-0.10/src/shaders/distribution_normal2d.frag
We paint over a screen-filling quad (uv = [0; 1]×[0; 1]). With parameters
Expected:
Actual:
With parameters
Expected:
Actual:
Additional information
Reproduce: Run the test suite here.
There is a cryptic, reappearing validation error that seems to be unrelated.
The text was updated successfully, but these errors were encountered: