Skip to content

Commit d3241c4

Browse files
authored
Fix the texture_binding_array, specialized_mesh_pipeline, and custom_shader_instancing examples after the bindless change. (bevyengine#16641)
The bindless PR (bevyengine#16368) broke some examples: * `specialized_mesh_pipeline` and `custom_shader_instancing` failed because they expect to be able to render a mesh with no material, by overriding enough of the render pipeline to be able to do so. This PR fixes the issue by restoring the old behavior in which we extract meshes even if they have no material. * `texture_binding_array` broke because it doesn't implement `AsBindGroup::unprepared_bind_group`. This was tricky to fix because there's a very good reason why `texture_binding_array` doesn't implement that method: there's no sensible way to do so with `wgpu`'s current bindless API, due to its multiple levels of borrowed references. To fix the example, I split `MaterialBindGroup` into `MaterialBindlessBindGroup` and `MaterialNonBindlessBindGroup`, and allow direct custom implementations of `AsBindGroup::as_bind_group` for the latter type of bind groups. To opt in to the new behavior, return the `AsBindGroupError::CreateBindGroupDirectly` error from your `AsBindGroup::unprepared_bind_group` implementation, and Bevy will call your custom `AsBindGroup::as_bind_group` method as before. ## Migration Guide * Bevy will now unconditionally call `AsBindGroup::unprepared_bind_group` for your materials, so you must no longer panic in that function. Instead, return the new `AsBindGroupError::CreateBindGroupDirectly` error, and Bevy will fall back to calling `AsBindGroup::as_bind_group` as before.
1 parent 73c6479 commit d3241c4

File tree

5 files changed

+399
-74
lines changed

5 files changed

+399
-74
lines changed

crates/bevy_pbr/src/material.rs

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,24 +1038,24 @@ impl<M: Material> RenderAsset for PreparedMaterial<M> {
10381038
return Err(PrepareAssetError::RetryNextUpdate(material));
10391039
};
10401040

1041+
let method = match material.opaque_render_method() {
1042+
OpaqueRendererMethod::Forward => OpaqueRendererMethod::Forward,
1043+
OpaqueRendererMethod::Deferred => OpaqueRendererMethod::Deferred,
1044+
OpaqueRendererMethod::Auto => default_opaque_render_method.0,
1045+
};
1046+
let mut mesh_pipeline_key_bits = MeshPipelineKey::empty();
1047+
mesh_pipeline_key_bits.set(
1048+
MeshPipelineKey::READS_VIEW_TRANSMISSION_TEXTURE,
1049+
material.reads_view_transmission_texture(),
1050+
);
1051+
10411052
match material.unprepared_bind_group(
10421053
&pipeline.material_layout,
10431054
render_device,
10441055
material_param,
10451056
) {
10461057
Ok(unprepared) => {
1047-
let method = match material.opaque_render_method() {
1048-
OpaqueRendererMethod::Forward => OpaqueRendererMethod::Forward,
1049-
OpaqueRendererMethod::Deferred => OpaqueRendererMethod::Deferred,
1050-
OpaqueRendererMethod::Auto => default_opaque_render_method.0,
1051-
};
1052-
let mut mesh_pipeline_key_bits = MeshPipelineKey::empty();
1053-
mesh_pipeline_key_bits.set(
1054-
MeshPipelineKey::READS_VIEW_TRANSMISSION_TEXTURE,
1055-
material.reads_view_transmission_texture(),
1056-
);
1057-
1058-
bind_group_allocator.init(*material_binding_id, unprepared);
1058+
bind_group_allocator.init(render_device, *material_binding_id, unprepared);
10591059

10601060
Ok(PreparedMaterial {
10611061
binding: *material_binding_id,
@@ -1070,9 +1070,51 @@ impl<M: Material> RenderAsset for PreparedMaterial<M> {
10701070
phantom: PhantomData,
10711071
})
10721072
}
1073+
10731074
Err(AsBindGroupError::RetryNextUpdate) => {
10741075
Err(PrepareAssetError::RetryNextUpdate(material))
10751076
}
1077+
1078+
Err(AsBindGroupError::CreateBindGroupDirectly) => {
1079+
// This material has opted out of automatic bind group creation
1080+
// and is requesting a fully-custom bind group. Invoke
1081+
// `as_bind_group` as requested, and store the resulting bind
1082+
// group in the slot.
1083+
match material.as_bind_group(
1084+
&pipeline.material_layout,
1085+
render_device,
1086+
material_param,
1087+
) {
1088+
Ok(prepared_bind_group) => {
1089+
// Store the resulting bind group directly in the slot.
1090+
bind_group_allocator.init_custom(
1091+
*material_binding_id,
1092+
prepared_bind_group.bind_group,
1093+
prepared_bind_group.data,
1094+
);
1095+
1096+
Ok(PreparedMaterial {
1097+
binding: *material_binding_id,
1098+
properties: MaterialProperties {
1099+
alpha_mode: material.alpha_mode(),
1100+
depth_bias: material.depth_bias(),
1101+
reads_view_transmission_texture: mesh_pipeline_key_bits
1102+
.contains(MeshPipelineKey::READS_VIEW_TRANSMISSION_TEXTURE),
1103+
render_method: method,
1104+
mesh_pipeline_key_bits,
1105+
},
1106+
phantom: PhantomData,
1107+
})
1108+
}
1109+
1110+
Err(AsBindGroupError::RetryNextUpdate) => {
1111+
Err(PrepareAssetError::RetryNextUpdate(material))
1112+
}
1113+
1114+
Err(other) => Err(PrepareAssetError::AsBindGroupError(other)),
1115+
}
1116+
}
1117+
10761118
Err(other) => Err(PrepareAssetError::AsBindGroupError(other)),
10771119
}
10781120
}

0 commit comments

Comments
 (0)