Since all push constants are required to be passed as u32s I've encountered some issues passing f32s.
As examples here are 2 shaders, the 1st works (gets the correct floating point result), the 2nd does not.
#version 450
layout(local_size_x = 1024, local_size_y = 1, local_size_z = 1) in;
layout(binding = 0) buffer Buffer0 {
float x[];
};
layout(binding = 1) buffer Buffer1 {
float y[];
};
layout(push_constant) uniform PushConsts {
uint a;
};
void main() {
uint indx = gl_GlobalInvocationID.x;
y[indx] += x[indx] * a;
}
#version 450
layout(local_size_x = 1024, local_size_y = 1, local_size_z = 1) in;
layout(binding = 0) buffer Buffer {
float x[];
};
layout(push_constant) uniform PushConsts {
uint a;
};
void main() {
uint indx = gl_GlobalInvocationID.x;
x[indx] *= a;
}
I have tried variations of x[indx] *= a;, replacing it with x[indx] *= float(a);, x[indx] = x[indx]*a; and a couple more and non seem to work.
Defining uint a; instead as float a; does not work either.
Test project (run cargo test): gpu_blas.zip
Push constants are basically raw memory you can provide. So instead of doing &[a as u32] you'd do mem::transmute(&[a][..]), and the shader side would see it as float a
@kvark So that worked great! My follow up question is, how would I pass both f32 and u32 type push constants?
For passing 2 f32s I do mem::transmute(&[a,b][..]). Now lets say I want to pass 2 f32s and 2 u32s, mem::transmute(&[a,b,c,d][..]) doesn't work (a,b being f32 and c,d being u32) with it throwing the following error on c and d:
mismatched types
expected `f32`, found `u32`
You could do something like this:
struct PushConstants {
a: [f32; 2],
b: [u32; 2],
}
And then slice::from_raw_parts(&my_struct as *const _ as *const u32, size_of::<PushConstants>() / 4)
Closing as it seems like this issue is solved, if any more questions come up, feel free to re-open.
Most helpful comment
Push constants are basically raw memory you can provide. So instead of doing
&[a as u32]you'd domem::transmute(&[a][..]), and the shader side would see it asfloat a