Wgpu-rs: How should I pass f32 push constants?

Created on 21 Aug 2020  路  4Comments  路  Source: gfx-rs/wgpu-rs

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

question

Most helpful comment

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

All 4 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kvark picture kvark  路  3Comments

chinedufn picture chinedufn  路  3Comments

RazrFalcon picture RazrFalcon  路  3Comments

inguar picture inguar  路  5Comments

donpdonp picture donpdonp  路  3Comments