Skip to content

Move ShaderCache shader defs into a resource #8202

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/bevy_gizmos/src/pipeline_3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl SpecializedMeshPipeline for GizmoPipeline {
(depth_test, key): Self::Key,
layout: &MeshVertexBufferLayout,
) -> Result<RenderPipelineDescriptor, SpecializedMeshPipelineError> {
let mut shader_defs = Vec::new();
let mut shader_defs = self.mesh_pipeline.shader_defs.clone();
shader_defs.push("GIZMO_LINES_3D".into());
shader_defs.push(ShaderDefVal::Int(
"MAX_DIRECTIONAL_LIGHTS".to_string(),
Expand Down
4 changes: 3 additions & 1 deletion crates/bevy_pbr/src/prepass/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ pub struct PrepassPipeline<M: Material> {
pub material_vertex_shader: Option<Handle<Shader>>,
pub material_fragment_shader: Option<Handle<Shader>>,
pub material_pipeline: MaterialPipeline<M>,
pub shader_defs: Vec<ShaderDefVal>,
_marker: PhantomData<M>,
}

Expand Down Expand Up @@ -215,6 +216,7 @@ impl<M: Material> FromWorld for PrepassPipeline<M> {
},
material_layout: M::bind_group_layout(render_device),
material_pipeline: world.resource::<MaterialPipeline<M>>().clone(),
shader_defs: mesh_pipeline.shader_defs.clone(),
_marker: PhantomData,
}
}
Expand All @@ -232,7 +234,7 @@ where
layout: &MeshVertexBufferLayout,
) -> Result<RenderPipelineDescriptor, SpecializedMeshPipelineError> {
let mut bind_group_layout = vec![self.view_layout.clone()];
let mut shader_defs = Vec::new();
let mut shader_defs = self.shader_defs.clone();
let mut vertex_attributes = Vec::new();

// NOTE: Eventually, it would be nice to only add this when the shaders are overloaded by the Material.
Expand Down
6 changes: 5 additions & 1 deletion crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ pub struct MeshPipeline {
// This dummy white texture is to be used in place of optional StandardMaterial textures
pub dummy_white_gpu_image: GpuImage,
pub clustered_forward_buffer_binding_type: BufferBindingType,
pub shader_defs: Vec<ShaderDefVal>,
}

impl FromWorld for MeshPipeline {
Expand Down Expand Up @@ -532,13 +533,16 @@ impl FromWorld for MeshPipeline {
}
};

let shader_defs = world.resource::<BaseShaderDefs>().to_vec();

MeshPipeline {
view_layout,
view_layout_multisampled,
mesh_layout,
skinned_mesh_layout,
clustered_forward_buffer_binding_type,
dummy_white_gpu_image,
shader_defs,
}
}
}
Expand Down Expand Up @@ -654,7 +658,7 @@ impl SpecializedMeshPipeline for MeshPipeline {
key: Self::Key,
layout: &MeshVertexBufferLayout,
) -> Result<RenderPipelineDescriptor, SpecializedMeshPipelineError> {
let mut shader_defs = Vec::new();
let mut shader_defs = self.shader_defs.clone();
let mut vertex_attributes = Vec::new();

if layout.contains(Mesh::ATTRIBUTE_POSITION) {
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub use once_cell;
use crate::{
camera::CameraPlugin,
mesh::MeshPlugin,
render_resource::{PipelineCache, Shader, ShaderLoader},
render_resource::{BaseShaderDefs, PipelineCache, Shader, ShaderLoader},
renderer::{render_system, RenderInstance},
settings::WgpuSettings,
view::{ViewPlugin, WindowRenderPlugin},
Expand Down Expand Up @@ -242,6 +242,7 @@ impl Plugin for RenderPlugin {
.init_resource::<render_graph::RenderGraph>()
.insert_resource(RenderInstance(instance))
.insert_resource(PipelineCache::new(device.clone()))
.insert_resource(BaseShaderDefs::new(&device))
.insert_resource(device)
.insert_resource(queue)
.insert_resource(render_adapter)
Expand Down
43 changes: 32 additions & 11 deletions crates/bevy_render/src/render_resource/pipeline_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{
Extract,
};
use bevy_asset::{AssetEvent, Assets, Handle};
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::system::{Res, ResMut};
use bevy_ecs::{event::EventReader, system::Resource};
use bevy_utils::{
Expand Down Expand Up @@ -161,6 +162,35 @@ impl ShaderDefVal {
}
}

/// Provides globally-constant shader definitions to pipeline implementors.
///
/// Contains the following definitions:
///
/// - `NO_ARRAY_TEXTURES_SUPPORT`
/// - `SIXTEEN_BYTE_ALIGNMENT`
/// - `AVAILABLE_STORAGE_BUFFER_BINDINGS`
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deref, DerefMut, Resource)]
pub struct BaseShaderDefs(pub Vec<ShaderDefVal>);

impl BaseShaderDefs {
pub fn new(device: &RenderDevice) -> Self {
let mut shader_defs = vec![];

#[cfg(feature = "webgl")]
{
shader_defs.push("NO_ARRAY_TEXTURES_SUPPORT".into());
shader_defs.push("SIXTEEN_BYTE_ALIGNMENT".into());
}

shader_defs.push(ShaderDefVal::UInt(
String::from("AVAILABLE_STORAGE_BUFFER_BINDINGS"),
device.limits().max_storage_buffers_per_shader_stage,
));

BaseShaderDefs(shader_defs)
}
}

impl ShaderCache {
fn get(
&mut self,
Expand Down Expand Up @@ -193,17 +223,7 @@ impl ShaderCache {
let module = match data.processed_shaders.entry(shader_defs.to_vec()) {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => {
let mut shader_defs = shader_defs.to_vec();
#[cfg(feature = "webgl")]
{
shader_defs.push("NO_ARRAY_TEXTURES_SUPPORT".into());
shader_defs.push("SIXTEEN_BYTE_ALIGNMENT".into());
}

shader_defs.push(ShaderDefVal::UInt(
String::from("AVAILABLE_STORAGE_BUFFER_BINDINGS"),
render_device.limits().max_storage_buffers_per_shader_stage,
));
let shader_defs = shader_defs.to_vec();

debug!(
"processing shader {:?}, with shader defs {:?}",
Expand Down Expand Up @@ -697,6 +717,7 @@ impl PipelineCache {
// shader could not be processed ... retrying won't help
PipelineCacheError::ProcessShaderError(err) => {
error!("failed to process shader: {}", err);
error!("{:#?}", pipeline.descriptor);
continue;
}
PipelineCacheError::AsModuleDescriptorError(err, source) => {
Expand Down
7 changes: 6 additions & 1 deletion crates/bevy_sprite/src/mesh2d/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ pub struct Mesh2dPipeline {
pub mesh_layout: BindGroupLayout,
// This dummy white texture is to be used in place of optional textures
pub dummy_white_gpu_image: GpuImage,
pub shader_defs: Vec<ShaderDefVal>,
}

impl FromWorld for Mesh2dPipeline {
Expand Down Expand Up @@ -256,10 +257,14 @@ impl FromWorld for Mesh2dPipeline {
mip_level_count: image.texture_descriptor.mip_level_count,
}
};

let shader_defs = world.resource::<BaseShaderDefs>().to_vec();

Mesh2dPipeline {
view_layout,
mesh_layout,
dummy_white_gpu_image,
shader_defs,
}
}
}
Expand Down Expand Up @@ -362,7 +367,7 @@ impl SpecializedMeshPipeline for Mesh2dPipeline {
key: Self::Key,
layout: &MeshVertexBufferLayout,
) -> Result<RenderPipelineDescriptor, SpecializedMeshPipelineError> {
let mut shader_defs = Vec::new();
let mut shader_defs = self.shader_defs.clone();
let mut vertex_attributes = Vec::new();

if layout.contains(Mesh::ATTRIBUTE_POSITION) {
Expand Down