diff --git a/crates/bevy_render/src/render_resource/pipeline_cache.rs b/crates/bevy_render/src/render_resource/pipeline_cache.rs index 76ff5eaafc322..93e985a44b31f 100644 --- a/crates/bevy_render/src/render_resource/pipeline_cache.rs +++ b/crates/bevy_render/src/render_resource/pipeline_cache.rs @@ -12,7 +12,7 @@ use bevy_ecs::{ }; use bevy_platform::collections::{HashMap, HashSet}; use bevy_shader::{ - CachedPipelineId, PipelineCacheError, Shader, ShaderCache, ShaderCacheSource, ShaderDefVal, + CachedPipelineId, Shader, ShaderCache, ShaderCacheError, ShaderCacheSource, ShaderDefVal, ValidateShader, }; use bevy_tasks::Task; @@ -74,23 +74,16 @@ pub struct CachedPipeline { } /// State of a cached pipeline inserted into a [`PipelineCache`]. -#[cfg_attr( - not(target_arch = "wasm32"), - expect( - clippy::large_enum_variant, - reason = "See https://github.com/bevyengine/bevy/issues/19220" - ) -)] #[derive(Debug)] pub enum CachedPipelineState { /// The pipeline GPU object is queued for creation. Queued, /// The pipeline GPU object is being created. - Creating(Task>), + Creating(Task>), /// The pipeline GPU object was created successfully and is available (allocated on the GPU). Ok(Pipeline), /// An error occurred while trying to create the pipeline GPU object. - Err(PipelineCacheError), + Err(ShaderCacheError), } impl CachedPipelineState { @@ -151,15 +144,11 @@ impl LayoutCache { } } -#[expect( - clippy::result_large_err, - reason = "See https://github.com/bevyengine/bevy/issues/19220" -)] fn load_module( render_device: &RenderDevice, shader_source: ShaderCacheSource, validate_shader: &ValidateShader, -) -> Result, PipelineCacheError> { +) -> Result, ShaderCacheError> { let shader_source = match shader_source { #[cfg(feature = "shader_format_spirv")] ShaderCacheSource::SpirV(data) => wgpu::util::make_spirv(data), @@ -201,7 +190,7 @@ fn load_module( if let Some(Some(wgpu::Error::Validation { description, .. })) = bevy_tasks::futures::now_or_never(error) { - return Err(PipelineCacheError::CreateShaderModule(description)); + return Err(ShaderCacheError::CreateShaderModule(description)); } Ok(shader_module) @@ -739,13 +728,13 @@ impl PipelineCache { CachedPipelineState::Err(err) => match err { // Retry - PipelineCacheError::ShaderNotLoaded(_) - | PipelineCacheError::ShaderImportNotYetAvailable => { + ShaderCacheError::ShaderNotLoaded(_) + | ShaderCacheError::ShaderImportNotYetAvailable => { cached_pipeline.state = CachedPipelineState::Queued; } // Shader could not be processed ... retrying won't help - PipelineCacheError::ProcessShaderError(err) => { + ShaderCacheError::ProcessShaderError(err) => { let error_detail = err.emit_to_string(&self.shader_cache.lock().unwrap().composer); if std::env::var("VERBOSE_SHADER_ERROR") @@ -756,7 +745,7 @@ impl PipelineCache { error!("failed to process shader error:\n{}", error_detail); return; } - PipelineCacheError::CreateShaderModule(description) => { + ShaderCacheError::CreateShaderModule(description) => { error!("failed to create shader module: {}", description); return; } @@ -851,7 +840,7 @@ fn pipeline_error_context(cached_pipeline: &CachedPipeline) -> String { feature = "multi_threaded" ))] fn create_pipeline_task( - task: impl Future> + Send + 'static, + task: impl Future> + Send + 'static, sync: bool, ) -> CachedPipelineState { if !sync { @@ -870,7 +859,7 @@ fn create_pipeline_task( not(feature = "multi_threaded") ))] fn create_pipeline_task( - task: impl Future> + Send + 'static, + task: impl Future> + Send + 'static, _sync: bool, ) -> CachedPipelineState { match bevy_tasks::block_on(task) { diff --git a/crates/bevy_shader/src/shader_cache.rs b/crates/bevy_shader/src/shader_cache.rs index 141c64fdfbc4d..5f196649969e0 100644 --- a/crates/bevy_shader/src/shader_cache.rs +++ b/crates/bevy_shader/src/shader_cache.rs @@ -63,7 +63,7 @@ pub struct ShaderCache { &RenderDevice, ShaderCacheSource, &ValidateShader, - ) -> Result, + ) -> Result, #[cfg(feature = "shader_format_wesl")] module_path_to_asset_id: HashMap>, shaders: HashMap, Shader>, @@ -109,7 +109,7 @@ impl ShaderCache { &RenderDevice, ShaderCacheSource, &ValidateShader, - ) -> Result, + ) -> Result, ) -> Self { let capabilities = get_capabilities(features, downlevel); #[cfg(debug_assertions)] @@ -131,16 +131,12 @@ impl ShaderCache { } } - #[expect( - clippy::result_large_err, - reason = "See https://github.com/bevyengine/bevy/issues/19220" - )] fn add_import_to_composer( composer: &mut naga_oil::compose::Composer, import_path_shaders: &HashMap>, shaders: &HashMap, Shader>, import: &ShaderImport, - ) -> Result<(), PipelineCacheError> { + ) -> Result<(), ShaderCacheError> { // Early out if we've already imported this module if composer.contains_module(&import.module_name()) { return Ok(()); @@ -150,34 +146,32 @@ impl ShaderCache { let shader = import_path_shaders .get(import) .and_then(|handle| shaders.get(handle)) - .ok_or(PipelineCacheError::ShaderImportNotYetAvailable)?; + .ok_or(ShaderCacheError::ShaderImportNotYetAvailable)?; // Recurse down to ensure all import dependencies are met for import in &shader.imports { Self::add_import_to_composer(composer, import_path_shaders, shaders, import)?; } - composer.add_composable_module(shader.into())?; + composer + .add_composable_module(shader.into()) + .map_err(Box::new)?; // if we fail to add a module the composer will tell us what is missing Ok(()) } - #[expect( - clippy::result_large_err, - reason = "See https://github.com/bevyengine/bevy/issues/19220" - )] pub fn get( &mut self, render_device: &RenderDevice, pipeline: CachedPipelineId, id: AssetId, shader_defs: &[ShaderDefVal], - ) -> Result, PipelineCacheError> { + ) -> Result, ShaderCacheError> { let shader = self .shaders .get(&id) - .ok_or(PipelineCacheError::ShaderNotLoaded(id))?; + .ok_or(ShaderCacheError::ShaderNotLoaded(id))?; let data = self.data.entry(id).or_default(); let n_asset_imports = shader @@ -190,7 +184,7 @@ impl ShaderCache { .filter(|import| matches!(import, ShaderImport::AssetPath(_))) .count(); if n_asset_imports != n_resolved_asset_imports { - return Err(PipelineCacheError::ShaderImportNotYetAvailable); + return Err(ShaderCacheError::ShaderImportNotYetAvailable); } data.pipelines.insert(pipeline); @@ -268,12 +262,13 @@ impl ShaderCache { }) .collect::>(); - let naga = self.composer.make_naga_module( - naga_oil::compose::NagaModuleDescriptor { + let naga = self + .composer + .make_naga_module(naga_oil::compose::NagaModuleDescriptor { shader_defs, ..shader.into() - }, - )?; + }) + .map_err(Box::new)?; #[cfg(not(feature = "decoupled_naga"))] { @@ -418,21 +413,14 @@ impl<'a> wesl::Resolver for ShaderResolver<'a> { } /// Type of error returned by a `PipelineCache` when the creation of a GPU pipeline object failed. -#[cfg_attr( - not(target_arch = "wasm32"), - expect( - clippy::large_enum_variant, - reason = "See https://github.com/bevyengine/bevy/issues/19220" - ) -)] #[derive(Error, Debug)] -pub enum PipelineCacheError { +pub enum ShaderCacheError { #[error( "Pipeline could not be compiled because the following shader could not be loaded: {0:?}" )] ShaderNotLoaded(AssetId), #[error(transparent)] - ProcessShaderError(#[from] naga_oil::compose::ComposerError), + ProcessShaderError(#[from] Box), #[error("Shader import not yet available.")] ShaderImportNotYetAvailable, #[error("Could not create shader module: {0}")] diff --git a/examples/shader/compute_shader_game_of_life.rs b/examples/shader/compute_shader_game_of_life.rs index e9c3af5481eab..b3f07de48ad4d 100644 --- a/examples/shader/compute_shader_game_of_life.rs +++ b/examples/shader/compute_shader_game_of_life.rs @@ -18,7 +18,7 @@ use bevy::{ texture::GpuImage, Render, RenderApp, RenderStartup, RenderSystems, }, - shader::PipelineCacheError, + shader::ShaderCacheError, }; use std::borrow::Cow; @@ -243,7 +243,7 @@ impl render_graph::Node for GameOfLifeNode { self.state = GameOfLifeState::Init; } // If the shader hasn't loaded yet, just wait. - CachedPipelineState::Err(PipelineCacheError::ShaderNotLoaded(_)) => {} + CachedPipelineState::Err(ShaderCacheError::ShaderNotLoaded(_)) => {} CachedPipelineState::Err(err) => { panic!("Initializing assets/{SHADER_ASSET_PATH}:\n{err}") } diff --git a/release-content/migration-guides/shader_cache_error.md b/release-content/migration-guides/shader_cache_error.md new file mode 100644 index 0000000000000..356055bfd4622 --- /dev/null +++ b/release-content/migration-guides/shader_cache_error.md @@ -0,0 +1,6 @@ +--- +title: "`PipelineCacheError` renamed to `ShaderCacheError`" +pull_requests: [22362] +--- + +`PipelineCacheError` has been renamed to `ShaderCacheError` and the `ProcessShaderError` variant has been `Box`ed.