Skip to content

Commit 96dcbc5

Browse files
tychedeliamockersfElabajaba
authored
Ugrade to wgpu version 25.0 (#19563)
# Objective Upgrade to `wgpu` version `25.0`. Depends on bevyengine/naga_oil#121 ## Solution ### Problem The biggest issue we face upgrading is the following requirement: > To facilitate this change, there was an additional validation rule put in place: if there is a binding array in a bind group, you may not use dynamic offset buffers or uniform buffers in that bind group. This requirement comes from vulkan rules on UpdateAfterBind descriptors. This is a major difficulty for us, as there are a number of binding arrays that are used in the view bind group. Note, this requirement does not affect merely uniform buffors that use dynamic offset but the use of *any* uniform in a bind group that also has a binding array. ### Attempted fixes The easiest fix would be to change uniforms to be storage buffers whenever binding arrays are in use: ```wgsl #ifdef BINDING_ARRAYS_ARE_USED @group(0) @binding(0) var<uniform> view: View; @group(0) @binding(1) var<uniform> lights: types::Lights; #else @group(0) @binding(0) var<storage> view: array<View>; @group(0) @binding(1) var<storage> lights: array<types::Lights>; #endif ``` This requires passing the view index to the shader so that we know where to index into the buffer: ```wgsl struct PushConstants { view_index: u32, } var<push_constant> push_constants: PushConstants; ``` Using push constants is no problem because binding arrays are only usable on native anyway. However, this greatly complicates the ability to access `view` in shaders. For example: ```wgsl #ifdef BINDING_ARRAYS_ARE_USED mesh_view_bindings::view.view_from_world[0].z #else mesh_view_bindings::view[mesh_view_bindings::view_index].view_from_world[0].z #endif ``` Using this approach would work but would have the effect of polluting our shaders with ifdef spam basically *everywhere*. Why not use a function? Unfortunately, the following is not valid wgsl as it returns a binding directly from a function in the uniform path. ```wgsl fn get_view() -> View { #if BINDING_ARRAYS_ARE_USED let view_index = push_constants.view_index; let view = views[view_index]; #endif return view; } ``` This also poses problems for things like lights where we want to return a ptr to the light data. Returning ptrs from wgsl functions isn't allowed even if both bindings were buffers. The next attempt was to simply use indexed buffers everywhere, in both the binding array and non binding array path. This would be viable if push constants were available everywhere to pass the view index, but unfortunately they are not available on webgpu. This means either passing the view index in a storage buffer (not ideal for such a small amount of state) or using push constants sometimes and uniform buffers only on webgpu. However, this kind of conditional layout infects absolutely everything. Even if we were to accept just using storage buffer for the view index, there's also the additional problem that some dynamic offsets aren't actually per-view but per-use of a setting on a camera, which would require passing that uniform data on *every* camera regardless of whether that rendering feature is being used, which is also gross. As such, although it's gross, the simplest solution just to bump binding arrays into `@group(1)` and all other bindings up one bind group. This should still bring us under the device limit of 4 for most users. ### Next steps / looking towards the future I'd like to avoid needing split our view bind group into multiple parts. In the future, if `wgpu` were to add `@builtin(draw_index)`, we could build a list of draw state in gpu processing and avoid the need for any kind of state change at all (see gfx-rs/wgpu#6823). This would also provide significantly more flexibility to handle things like offsets into other arrays that may not be per-view. ### Testing Tested a number of examples, there are probably more that are still broken. --------- Co-authored-by: François Mockers <mockersf@gmail.com> Co-authored-by: Elabajaba <Elabajaba@users.noreply.github.com>
1 parent 92e65d5 commit 96dcbc5

File tree

74 files changed

+719
-446
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+719
-446
lines changed

assets/shaders/array_texture.wgsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
}
88
#import bevy_core_pipeline::tonemapping::tone_mapping
99

10-
@group(2) @binding(0) var my_array_texture: texture_2d_array<f32>;
11-
@group(2) @binding(1) var my_array_texture_sampler: sampler;
10+
@group(3) @binding(0) var my_array_texture: texture_2d_array<f32>;
11+
@group(3) @binding(1) var my_array_texture_sampler: sampler;
1212

1313
@fragment
1414
fn fragment(

assets/shaders/automatic_instancing.wgsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
view_transformations::position_world_to_clip
44
}
55

6-
@group(2) @binding(0) var texture: texture_2d<f32>;
7-
@group(2) @binding(1) var texture_sampler: sampler;
6+
@group(3) @binding(0) var texture: texture_2d<f32>;
7+
@group(3) @binding(1) var texture_sampler: sampler;
88

99
struct Vertex {
1010
@builtin(instance_index) instance_index: u32,

assets/shaders/bindless_material.wgsl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ struct MaterialBindings {
1515
}
1616

1717
#ifdef BINDLESS
18-
@group(2) @binding(0) var<storage> materials: array<MaterialBindings>;
19-
@group(2) @binding(10) var<storage> material_color: binding_array<Color>;
18+
@group(3) @binding(0) var<storage> materials: array<MaterialBindings>;
19+
@group(3) @binding(10) var<storage> material_color: binding_array<Color>;
2020
#else // BINDLESS
21-
@group(2) @binding(0) var<uniform> material_color: Color;
22-
@group(2) @binding(1) var material_color_texture: texture_2d<f32>;
23-
@group(2) @binding(2) var material_color_sampler: sampler;
21+
@group(3) @binding(0) var<uniform> material_color: Color;
22+
@group(3) @binding(1) var material_color_texture: texture_2d<f32>;
23+
@group(3) @binding(2) var material_color_sampler: sampler;
2424
#endif // BINDLESS
2525

2626
@fragment

assets/shaders/cubemap_unlit.wgsl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
#import bevy_pbr::forward_io::VertexOutput
22

33
#ifdef CUBEMAP_ARRAY
4-
@group(2) @binding(0) var base_color_texture: texture_cube_array<f32>;
4+
@group(3) @binding(0) var base_color_texture: texture_cube_array<f32>;
55
#else
6-
@group(2) @binding(0) var base_color_texture: texture_cube<f32>;
6+
@group(3) @binding(0) var base_color_texture: texture_cube<f32>;
77
#endif
88

9-
@group(2) @binding(1) var base_color_sampler: sampler;
9+
@group(3) @binding(1) var base_color_sampler: sampler;
1010

1111
@fragment
1212
fn fragment(

assets/shaders/custom_material.frag

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ layout(location = 0) in vec2 v_Uv;
33

44
layout(location = 0) out vec4 o_Target;
55

6-
layout(set = 2, binding = 0) uniform vec4 CustomMaterial_color;
6+
layout(set = 3, binding = 0) uniform vec4 CustomMaterial_color;
77

8-
layout(set = 2, binding = 1) uniform texture2D CustomMaterial_texture;
9-
layout(set = 2, binding = 2) uniform sampler CustomMaterial_sampler;
8+
layout(set = 3, binding = 1) uniform texture2D CustomMaterial_texture;
9+
layout(set = 3, binding = 2) uniform sampler CustomMaterial_sampler;
1010

1111
// wgsl modules can be imported and used in glsl
1212
// FIXME - this doesn't work any more ...

assets/shaders/custom_material.vert

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ struct Mesh {
2525
};
2626

2727
#ifdef PER_OBJECT_BUFFER_BATCH_SIZE
28-
layout(set = 1, binding = 0) uniform Mesh Meshes[#{PER_OBJECT_BUFFER_BATCH_SIZE}];
28+
layout(set = 2, binding = 0) uniform Mesh Meshes[#{PER_OBJECT_BUFFER_BATCH_SIZE}];
2929
#else
30-
layout(set = 1, binding = 0) readonly buffer _Meshes {
30+
layout(set = 2, binding = 0) readonly buffer _Meshes {
3131
Mesh Meshes[];
3232
};
3333
#endif // PER_OBJECT_BUFFER_BATCH_SIZE

assets/shaders/custom_material.wesl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ struct CustomMaterial {
1010
time: vec4<f32>,
1111
}
1212

13-
@group(2) @binding(0) var<uniform> material: CustomMaterial;
13+
@group(3) @binding(0) var<uniform> material: CustomMaterial;
1414

1515
@fragment
1616
fn fragment(

assets/shaders/custom_material.wgsl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
// we can import items from shader modules in the assets folder with a quoted path
33
#import "shaders/custom_material_import.wgsl"::COLOR_MULTIPLIER
44

5-
@group(2) @binding(0) var<uniform> material_color: vec4<f32>;
6-
@group(2) @binding(1) var material_color_texture: texture_2d<f32>;
7-
@group(2) @binding(2) var material_color_sampler: sampler;
5+
@group(3) @binding(0) var<uniform> material_color: vec4<f32>;
6+
@group(3) @binding(1) var material_color_texture: texture_2d<f32>;
7+
@group(3) @binding(2) var material_color_sampler: sampler;
88

99
@fragment
1010
fn fragment(

assets/shaders/custom_material_screenspace_texture.wgsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
utils::coords_to_viewport_uv,
55
}
66

7-
@group(2) @binding(0) var texture: texture_2d<f32>;
8-
@group(2) @binding(1) var texture_sampler: sampler;
7+
@group(3) @binding(0) var texture: texture_2d<f32>;
8+
@group(3) @binding(1) var texture_sampler: sampler;
99

1010
@fragment
1111
fn fragment(

assets/shaders/custom_vertex_attribute.wgsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
struct CustomMaterial {
44
color: vec4<f32>,
55
};
6-
@group(2) @binding(0) var<uniform> material: CustomMaterial;
6+
@group(3) @binding(0) var<uniform> material: CustomMaterial;
77

88
struct Vertex {
99
@builtin(instance_index) instance_index: u32,

0 commit comments

Comments
 (0)