From adae66ea2d329cadf2c60b9e68af5c4531257fe6 Mon Sep 17 00:00:00 2001 From: atlas Date: Thu, 4 Sep 2025 20:42:21 -0400 Subject: [PATCH 01/23] wip --- crates/bevy_render/src/render_resource/mod.rs | 42 +++++++------- .../src/render_resource/pipeline.rs | 30 +++++++--- .../src/render_resource/pipeline_cache.rs | 55 ++++++++++++++++++- .../bevy_render/src/view/window/screenshot.rs | 14 ++--- 4 files changed, 102 insertions(+), 39 deletions(-) diff --git a/crates/bevy_render/src/render_resource/mod.rs b/crates/bevy_render/src/render_resource/mod.rs index 0a41dfdd17ad9..2d8ddabf2dbf6 100644 --- a/crates/bevy_render/src/render_resource/mod.rs +++ b/crates/bevy_render/src/render_resource/mod.rs @@ -40,27 +40,27 @@ pub use wgpu::{ }, AccelerationStructureFlags, AccelerationStructureGeometryFlags, AccelerationStructureUpdateMode, AdapterInfo as WgpuAdapterInfo, AddressMode, AstcBlock, - AstcChannel, BindGroupDescriptor, BindGroupEntry, BindGroupLayoutDescriptor, - BindGroupLayoutEntry, BindingResource, BindingType, Blas, BlasBuildEntry, BlasGeometries, - BlasGeometrySizeDescriptors, BlasTriangleGeometry, BlasTriangleGeometrySizeDescriptor, - BlendComponent, BlendFactor, BlendOperation, BlendState, BufferAddress, BufferAsyncError, - BufferBinding, BufferBindingType, BufferDescriptor, BufferSize, BufferUsages, ColorTargetState, - ColorWrites, CommandEncoder, CommandEncoderDescriptor, CompareFunction, ComputePass, - ComputePassDescriptor, ComputePipelineDescriptor as RawComputePipelineDescriptor, - CreateBlasDescriptor, CreateTlasDescriptor, DepthBiasState, DepthStencilState, DownlevelFlags, - Extent3d, Face, Features as WgpuFeatures, FilterMode, FragmentState as RawFragmentState, - FrontFace, ImageSubresourceRange, IndexFormat, Limits as WgpuLimits, LoadOp, MapMode, - MultisampleState, Operations, Origin3d, PipelineCompilationOptions, PipelineLayout, - PipelineLayoutDescriptor, PollType, PolygonMode, PrimitiveState, PrimitiveTopology, - PushConstantRange, RenderPassColorAttachment, RenderPassDepthStencilAttachment, - RenderPassDescriptor, RenderPipelineDescriptor as RawRenderPipelineDescriptor, - Sampler as WgpuSampler, SamplerBindingType, SamplerBindingType as WgpuSamplerBindingType, - SamplerDescriptor, ShaderModule, ShaderModuleDescriptor, ShaderSource, ShaderStages, - StencilFaceState, StencilOperation, StencilState, StorageTextureAccess, StoreOp, - TexelCopyBufferInfo, TexelCopyBufferLayout, TexelCopyTextureInfo, TextureAspect, - TextureDescriptor, TextureDimension, TextureFormat, TextureFormatFeatureFlags, - TextureFormatFeatures, TextureSampleType, TextureUsages, TextureView as WgpuTextureView, - TextureViewDescriptor, TextureViewDimension, Tlas, TlasInstance, VertexAttribute, + AstcChannel, BindGroupDescriptor, BindGroupEntry, BindGroupLayoutEntry, BindingResource, + BindingType, Blas, BlasBuildEntry, BlasGeometries, BlasGeometrySizeDescriptors, + BlasTriangleGeometry, BlasTriangleGeometrySizeDescriptor, BlendComponent, BlendFactor, + BlendOperation, BlendState, BufferAddress, BufferAsyncError, BufferBinding, BufferBindingType, + BufferDescriptor, BufferSize, BufferUsages, ColorTargetState, ColorWrites, CommandEncoder, + CommandEncoderDescriptor, CompareFunction, ComputePass, ComputePassDescriptor, + ComputePipelineDescriptor as RawComputePipelineDescriptor, CreateBlasDescriptor, + CreateTlasDescriptor, DepthBiasState, DepthStencilState, DownlevelFlags, Extent3d, Face, + Features as WgpuFeatures, FilterMode, FragmentState as RawFragmentState, FrontFace, + ImageSubresourceRange, IndexFormat, Limits as WgpuLimits, LoadOp, MapMode, MultisampleState, + Operations, Origin3d, PipelineCompilationOptions, PipelineLayout, PipelineLayoutDescriptor, + PollType, PolygonMode, PrimitiveState, PrimitiveTopology, PushConstantRange, + RenderPassColorAttachment, RenderPassDepthStencilAttachment, RenderPassDescriptor, + RenderPipelineDescriptor as RawRenderPipelineDescriptor, Sampler as WgpuSampler, + SamplerBindingType, SamplerBindingType as WgpuSamplerBindingType, SamplerDescriptor, + ShaderModule, ShaderModuleDescriptor, ShaderSource, ShaderStages, StencilFaceState, + StencilOperation, StencilState, StorageTextureAccess, StoreOp, TexelCopyBufferInfo, + TexelCopyBufferLayout, TexelCopyTextureInfo, TextureAspect, TextureDescriptor, + TextureDimension, TextureFormat, TextureFormatFeatureFlags, TextureFormatFeatures, + TextureSampleType, TextureUsages, TextureView as WgpuTextureView, TextureViewDescriptor, + TextureViewDimension, Tlas, TlasInstance, VertexAttribute, VertexBufferLayout as RawVertexBufferLayout, VertexFormat, VertexState as RawVertexState, VertexStepMode, COPY_BUFFER_ALIGNMENT, }; diff --git a/crates/bevy_render/src/render_resource/pipeline.rs b/crates/bevy_render/src/render_resource/pipeline.rs index 7a6669831234f..b699c7b791259 100644 --- a/crates/bevy_render/src/render_resource/pipeline.rs +++ b/crates/bevy_render/src/render_resource/pipeline.rs @@ -1,6 +1,5 @@ -use super::empty_bind_group_layout; use crate::renderer::WgpuWrapper; -use crate::{define_atomic_id, render_resource::BindGroupLayout}; +use crate::define_atomic_id; use alloc::borrow::Cow; use bevy_asset::Handle; use bevy_mesh::VertexBufferLayout; @@ -9,7 +8,8 @@ use core::iter; use core::ops::Deref; use thiserror::Error; use wgpu::{ - ColorTargetState, DepthStencilState, MultisampleState, PrimitiveState, PushConstantRange, + BindGroupLayoutEntry, ColorTargetState, DepthStencilState, MultisampleState, PrimitiveState, + PushConstantRange, }; define_atomic_id!(RenderPipelineId); @@ -87,13 +87,29 @@ impl Deref for ComputePipeline { } } +#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)] +pub struct BindGroupLayoutDescriptor { + /// Debug label of the bind group layout descriptor. This will show up in graphics debuggers for easy identification. + pub label: Option>, + pub entries: Vec, +} + +impl BindGroupLayoutDescriptor { + pub fn new(label: impl Into>, entries: &[BindGroupLayoutEntry]) -> Self { + Self { + label: Some(label.into()), + entries: entries.into(), + } + } +} + /// Describes a render (graphics) pipeline. #[derive(Clone, Debug, PartialEq, Default)] pub struct RenderPipelineDescriptor { /// Debug label of the pipeline. This will show up in graphics debuggers for easy identification. pub label: Option>, /// The layout of bind groups for this pipeline. - pub layout: Vec, + pub layout: Vec, /// The push constant ranges for this pipeline. /// Supply an empty vector if the pipeline doesn't use push constants. pub push_constant_ranges: Vec, @@ -121,8 +137,8 @@ impl RenderPipelineDescriptor { self.fragment.as_mut().ok_or(NoFragmentStateError) } - pub fn set_layout(&mut self, index: usize, layout: BindGroupLayout) { - filling_set_at(&mut self.layout, index, empty_bind_group_layout(), layout); + pub fn set_layout(&mut self, index: usize, layout: BindGroupLayoutDescriptor) { + filling_set_at(&mut self.layout, index, bevy_utils::default(), layout); } } @@ -161,7 +177,7 @@ impl FragmentState { #[derive(Clone, Debug, PartialEq, Eq, Default)] pub struct ComputePipelineDescriptor { pub label: Option>, - pub layout: Vec, + pub layout: Vec, pub push_constant_ranges: Vec, /// The compiled shader module for this stage. pub shader: Handle, diff --git a/crates/bevy_render/src/render_resource/pipeline_cache.rs b/crates/bevy_render/src/render_resource/pipeline_cache.rs index 5a30ab5250508..96a9d10bbc098 100644 --- a/crates/bevy_render/src/render_resource/pipeline_cache.rs +++ b/crates/bevy_render/src/render_resource/pipeline_cache.rs @@ -207,6 +207,29 @@ fn load_module( Ok(shader_module) } +#[derive(Default)] +struct BindGroupLayoutCache { + bgls: HashMap, +} + +impl BindGroupLayoutCache { + fn get( + &mut self, + render_device: &RenderDevice, + descriptor: BindGroupLayoutDescriptor, + ) -> BindGroupLayout { + self.bgls + .entry(descriptor) + .or_insert_with_key(|descriptor| { + render_device.create_bind_group_layout( + descriptor.label.as_ref().map(|s| s.as_ref()), + &descriptor.entries, + ) + }) + .clone() + } +} + /// Cache for render and compute pipelines. /// /// The cache stores existing render and compute pipelines allocated on the GPU, as well as @@ -222,6 +245,7 @@ fn load_module( #[derive(Resource)] pub struct PipelineCache { layout_cache: Arc>, + bindgroup_layout_cache: Arc>, shader_cache: Arc, RenderDevice>>>, device: RenderDevice, pipelines: Vec, @@ -275,6 +299,7 @@ impl PipelineCache { ))), device, layout_cache: default(), + bindgroup_layout_cache: default(), waiting_pipelines: default(), new_pipelines: default(), pipelines: default(), @@ -449,6 +474,16 @@ impl PipelineCache { id } + pub fn get_bind_group_layout( + &self, + bind_group_layout_descriptor: BindGroupLayoutDescriptor, + ) -> BindGroupLayout { + self.bindgroup_layout_cache + .lock() + .unwrap() + .get(&self.device, bind_group_layout_descriptor.clone()) + } + fn set_shader(&mut self, id: AssetId, shader: Shader) { let mut shader_cache = self.shader_cache.lock().unwrap(); let pipelines_to_queue = shader_cache.set_shader(id, shader); @@ -475,6 +510,14 @@ impl PipelineCache { let device = self.device.clone(); let shader_cache = self.shader_cache.clone(); let layout_cache = self.layout_cache.clone(); + let mut bindgroup_layout_cache = self.bindgroup_layout_cache.lock().unwrap(); + let bind_group_layout = descriptor + .layout + .iter() + .map(|bind_group_layout_descriptor| { + bindgroup_layout_cache.get(&self.device, bind_group_layout_descriptor.clone()) + }) + .collect::>(); create_pipeline_task( async move { @@ -512,7 +555,7 @@ impl PipelineCache { } else { Some(layout_cache.get( &device, - &descriptor.layout, + &bind_group_layout, descriptor.push_constant_ranges.to_vec(), )) }; @@ -586,6 +629,14 @@ impl PipelineCache { let device = self.device.clone(); let shader_cache = self.shader_cache.clone(); let layout_cache = self.layout_cache.clone(); + let mut bindgroup_layout_cache = self.bindgroup_layout_cache.lock().unwrap(); + let bind_group_layout = descriptor + .layout + .iter() + .map(|bind_group_layout_descriptor| { + bindgroup_layout_cache.get(&self.device, bind_group_layout_descriptor.clone()) + }) + .collect::>(); create_pipeline_task( async move { @@ -608,7 +659,7 @@ impl PipelineCache { } else { Some(layout_cache.get( &device, - &descriptor.layout, + &bind_group_layout, descriptor.push_constant_ranges.to_vec(), )) }; diff --git a/crates/bevy_render/src/view/window/screenshot.rs b/crates/bevy_render/src/view/window/screenshot.rs index 4418c7d5d74d2..51c1659f376cd 100644 --- a/crates/bevy_render/src/view/window/screenshot.rs +++ b/crates/bevy_render/src/view/window/screenshot.rs @@ -3,7 +3,7 @@ use crate::{ gpu_readback, render_asset::RenderAssets, render_resource::{ - binding_types::texture_2d, BindGroup, BindGroupEntries, BindGroupLayout, + binding_types::texture_2d, BindGroup, BindGroupEntries, BindGroupLayoutDescriptor, BindGroupLayoutEntries, Buffer, BufferUsages, CachedRenderPipelineId, FragmentState, PipelineCache, RenderPipelineDescriptor, SpecializedRenderPipeline, SpecializedRenderPipelines, Texture, TextureUsages, TextureView, VertexState, @@ -376,7 +376,7 @@ fn prepare_screenshot_state( }); let bind_group = render_device.create_bind_group( "screenshot-to-screen-bind-group", - &pipeline.bind_group_layout, + &pipeline_cache.get_bind_group_layout(pipeline.bind_group_layout.clone()), &BindGroupEntries::single(&texture_view), ); let pipeline_id = pipelines.specialize(pipeline_cache, pipeline, format); @@ -432,16 +432,12 @@ impl Plugin for ScreenshotPlugin { #[derive(Resource)] pub struct ScreenshotToScreenPipeline { - pub bind_group_layout: BindGroupLayout, + pub bind_group_layout: BindGroupLayoutDescriptor, pub shader: Handle, } -pub fn init_screenshot_to_screen_pipeline( - mut commands: Commands, - render_device: Res, - asset_server: Res, -) { - let bind_group_layout = render_device.create_bind_group_layout( +pub fn init_screenshot_to_screen_pipeline(mut commands: Commands, asset_server: Res) { + let bind_group_layout = BindGroupLayoutDescriptor::new( "screenshot-to-screen-bgl", &BindGroupLayoutEntries::single( wgpu::ShaderStages::FRAGMENT, From 9699ab518850c487489b7e181cec0e1bc778aace Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Wed, 24 Sep 2025 17:50:41 +0800 Subject: [PATCH 02/23] blit layout descriptor --- crates/bevy_core_pipeline/src/blit/mod.rs | 27 ++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/crates/bevy_core_pipeline/src/blit/mod.rs b/crates/bevy_core_pipeline/src/blit/mod.rs index b7478b8fe2cb8..76c6aaf1d2fea 100644 --- a/crates/bevy_core_pipeline/src/blit/mod.rs +++ b/crates/bevy_core_pipeline/src/blit/mod.rs @@ -91,9 +91,34 @@ impl SpecializedRenderPipeline for BlitPipeline { type Key = BlitPipelineKey; fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { + // TODO: link this to above `BindGroupLayoutEntries` build in `init_blit_pipeline` + + let blit_layout_descriptor : BindGroupLayoutDescriptor = BindGroupLayoutDescriptor { + label: Some("blit".to_string().into()), + entries: vec![ + BindGroupLayoutEntry { + binding: 0, + visibility: ShaderStages::FRAGMENT, + ty: BindingType::Texture { + sample_type: TextureSampleType::Float { filterable: false }, + view_dimension: TextureViewDimension::D2, // TODO: Check + multisampled: true, // TODO: Check + }, + count: None, + }, + BindGroupLayoutEntry { + binding: 1, + visibility: ShaderStages::FRAGMENT, + ty: BindingType::Sampler(SamplerBindingType::NonFiltering), + count: None, + }, + ], + }; + + RenderPipelineDescriptor { label: Some("blit pipeline".into()), - layout: vec![self.layout.clone()], + layout: vec![blit_layout_descriptor], vertex: self.fullscreen_shader.to_vertex_state(), fragment: Some(FragmentState { shader: self.fragment_shader.clone(), From c5635cd62c0d1317903bbf866da69a830f7d57b5 Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 11:51:42 +0800 Subject: [PATCH 03/23] Build bevy_core_pipeline --- crates/bevy_core_pipeline/src/blit/mod.rs | 34 +++--------------- .../src/deferred/copy_lighting_id.rs | 8 ++--- .../src/experimental/mip_generation/mod.rs | 35 ++++++++++--------- .../bevy_core_pipeline/src/oit/resolve/mod.rs | 26 +++++++------- .../src/oit/resolve/node.rs | 3 +- crates/bevy_core_pipeline/src/skybox/mod.rs | 17 ++++----- .../bevy_core_pipeline/src/skybox/prepass.rs | 10 +++--- .../bevy_core_pipeline/src/tonemapping/mod.rs | 6 ++-- .../src/tonemapping/node.rs | 3 +- .../bevy_core_pipeline/src/upscaling/node.rs | 7 ++-- 10 files changed, 65 insertions(+), 84 deletions(-) diff --git a/crates/bevy_core_pipeline/src/blit/mod.rs b/crates/bevy_core_pipeline/src/blit/mod.rs index 76c6aaf1d2fea..f262e1bc48220 100644 --- a/crates/bevy_core_pipeline/src/blit/mod.rs +++ b/crates/bevy_core_pipeline/src/blit/mod.rs @@ -33,7 +33,7 @@ impl Plugin for BlitPlugin { #[derive(Resource)] pub struct BlitPipeline { - pub layout: BindGroupLayout, + pub layout: BindGroupLayoutDescriptor, pub sampler: Sampler, pub fullscreen_shader: FullscreenShader, pub fragment_shader: Handle, @@ -45,7 +45,7 @@ pub fn init_blit_pipeline( fullscreen_shader: Res, asset_server: Res, ) { - let layout = render_device.create_bind_group_layout( + let layout = BindGroupLayoutDescriptor::new( "blit_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, @@ -71,10 +71,11 @@ impl BlitPipeline { &self, render_device: &RenderDevice, src_texture: &TextureView, + pipeline_cache: &PipelineCache, ) -> BindGroup { render_device.create_bind_group( None, - &self.layout, + &pipeline_cache.get_bind_group_layout(self.layout.clone()), &BindGroupEntries::sequential((src_texture, &self.sampler)), ) } @@ -91,34 +92,9 @@ impl SpecializedRenderPipeline for BlitPipeline { type Key = BlitPipelineKey; fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { - // TODO: link this to above `BindGroupLayoutEntries` build in `init_blit_pipeline` - - let blit_layout_descriptor : BindGroupLayoutDescriptor = BindGroupLayoutDescriptor { - label: Some("blit".to_string().into()), - entries: vec![ - BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStages::FRAGMENT, - ty: BindingType::Texture { - sample_type: TextureSampleType::Float { filterable: false }, - view_dimension: TextureViewDimension::D2, // TODO: Check - multisampled: true, // TODO: Check - }, - count: None, - }, - BindGroupLayoutEntry { - binding: 1, - visibility: ShaderStages::FRAGMENT, - ty: BindingType::Sampler(SamplerBindingType::NonFiltering), - count: None, - }, - ], - }; - - RenderPipelineDescriptor { label: Some("blit pipeline".into()), - layout: vec![blit_layout_descriptor], + layout: vec![self.layout.clone()], vertex: self.fullscreen_shader.to_vertex_state(), fragment: Some(FragmentState { shader: self.fragment_shader.clone(), diff --git a/crates/bevy_core_pipeline/src/deferred/copy_lighting_id.rs b/crates/bevy_core_pipeline/src/deferred/copy_lighting_id.rs index 68d1634160f8a..a2b6b9720757c 100644 --- a/crates/bevy_core_pipeline/src/deferred/copy_lighting_id.rs +++ b/crates/bevy_core_pipeline/src/deferred/copy_lighting_id.rs @@ -82,7 +82,8 @@ impl ViewNode for CopyDeferredLightingIdNode { let bind_group = render_context.render_device().create_bind_group( "copy_deferred_lighting_id_bind_group", - ©_deferred_lighting_id_pipeline.layout, + &pipeline_cache + .get_bind_group_layout(copy_deferred_lighting_id_pipeline.layout.clone()), &BindGroupEntries::single(&deferred_lighting_pass_id_texture.texture.default_view), ); @@ -115,18 +116,17 @@ impl ViewNode for CopyDeferredLightingIdNode { #[derive(Resource)] struct CopyDeferredLightingIdPipeline { - layout: BindGroupLayout, + layout: BindGroupLayoutDescriptor, pipeline_id: CachedRenderPipelineId, } pub fn init_copy_deferred_lighting_id_pipeline( mut commands: Commands, - render_device: Res, fullscreen_shader: Res, asset_server: Res, pipeline_cache: Res, ) { - let layout = render_device.create_bind_group_layout( + let layout = BindGroupLayoutDescriptor::new( "copy_deferred_lighting_id_bind_group_layout", &BindGroupLayoutEntries::single( ShaderStages::FRAGMENT, diff --git a/crates/bevy_core_pipeline/src/experimental/mip_generation/mod.rs b/crates/bevy_core_pipeline/src/experimental/mip_generation/mod.rs index 227a3e391a59d..189710593b6ac 100644 --- a/crates/bevy_core_pipeline/src/experimental/mip_generation/mod.rs +++ b/crates/bevy_core_pipeline/src/experimental/mip_generation/mod.rs @@ -25,7 +25,10 @@ use bevy_ecs::{ world::{FromWorld, World}, }; use bevy_math::{uvec2, UVec2, Vec4Swizzles as _}; -use bevy_render::{batching::gpu_preprocessing::GpuPreprocessingSupport, RenderStartup}; +use bevy_render::{ + batching::gpu_preprocessing::GpuPreprocessingSupport, + render_resource::BindGroupLayoutDescriptor, RenderStartup, +}; use bevy_render::{ experimental::occlusion_culling::{ OcclusionCulling, OcclusionCullingSubview, OcclusionCullingSubviewEntities, @@ -283,7 +286,7 @@ fn downsample_depth<'w>( #[derive(Resource)] pub struct DownsampleDepthPipeline { /// The bind group layout for this pipeline. - bind_group_layout: BindGroupLayout, + bind_group_layout: BindGroupLayoutDescriptor, /// A handle that identifies the compiled shader. pipeline_id: Option, /// The shader asset handle. @@ -296,7 +299,10 @@ impl DownsampleDepthPipeline { /// /// This doesn't actually specialize the pipeline; that must be done /// afterward. - fn new(bind_group_layout: BindGroupLayout, shader: Handle) -> DownsampleDepthPipeline { + fn new( + bind_group_layout: BindGroupLayoutDescriptor, + shader: Handle, + ) -> DownsampleDepthPipeline { DownsampleDepthPipeline { bind_group_layout, pipeline_id: None, @@ -352,10 +358,8 @@ fn create_downsample_depth_pipelines( // between the first and second passes, so the only thing we need to // treat specially is the type of the first mip level (non-multisampled // or multisampled). - let standard_bind_group_layout = - create_downsample_depth_bind_group_layout(&render_device, false); - let multisampled_bind_group_layout = - create_downsample_depth_bind_group_layout(&render_device, true); + let standard_bind_group_layout = create_downsample_depth_bind_group_layout(false); + let multisampled_bind_group_layout = create_downsample_depth_bind_group_layout(true); // Create the depth pyramid sampler. This is shared among all shaders. let sampler = render_device.create_sampler(&SamplerDescriptor { @@ -413,11 +417,8 @@ fn create_downsample_depth_pipelines( } /// Creates a single bind group layout for the downsample depth pass. -fn create_downsample_depth_bind_group_layout( - render_device: &RenderDevice, - is_multisampled: bool, -) -> BindGroupLayout { - render_device.create_bind_group_layout( +fn create_downsample_depth_bind_group_layout(is_multisampled: bool) -> BindGroupLayoutDescriptor { + BindGroupLayoutDescriptor::new( if is_multisampled { "downsample multisample depth bind group layout" } else { @@ -737,6 +738,7 @@ fn prepare_downsample_depth_view_bind_groups( mut commands: Commands, render_device: Res, downsample_depth_pipelines: Res, + pipeline_cache: Res, view_depth_textures: Query< ( Entity, @@ -762,13 +764,14 @@ fn prepare_downsample_depth_view_bind_groups( } else { "downsample depth bind group" }, - if is_multisampled { - &downsample_depth_pipelines + &pipeline_cache.get_bind_group_layout(if is_multisampled { + downsample_depth_pipelines .first_multisample .bind_group_layout + .clone() } else { - &downsample_depth_pipelines.first.bind_group_layout - }, + downsample_depth_pipelines.first.bind_group_layout.clone() + }), match (view_depth_texture, shadow_occlusion_culling) { (Some(view_depth_texture), _) => view_depth_texture.view(), (None, Some(shadow_occlusion_culling)) => { diff --git a/crates/bevy_core_pipeline/src/oit/resolve/mod.rs b/crates/bevy_core_pipeline/src/oit/resolve/mod.rs index d1fd3765a7024..65ad52b6e550a 100644 --- a/crates/bevy_core_pipeline/src/oit/resolve/mod.rs +++ b/crates/bevy_core_pipeline/src/oit/resolve/mod.rs @@ -11,9 +11,10 @@ use bevy_image::BevyDefault as _; use bevy_render::{ render_resource::{ binding_types::{storage_buffer_sized, texture_depth_2d, uniform_buffer}, - BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutEntries, BlendComponent, - BlendState, CachedRenderPipelineId, ColorTargetState, ColorWrites, DownlevelFlags, - FragmentState, PipelineCache, RenderPipelineDescriptor, ShaderStages, TextureFormat, + BindGroup, BindGroupEntries, BindGroupLayoutDescriptor, BindGroupLayoutEntries, + BlendComponent, BlendState, CachedRenderPipelineId, ColorTargetState, ColorWrites, + DownlevelFlags, FragmentState, PipelineCache, RenderPipelineDescriptor, ShaderStages, + TextureFormat, }, renderer::{RenderAdapter, RenderDevice}, view::{ExtractedView, ViewTarget, ViewUniform, ViewUniforms}, @@ -57,7 +58,7 @@ impl Plugin for OitResolvePlugin { prepare_oit_resolve_bind_group.in_set(RenderSystems::PrepareBindGroups), ), ) - .init_resource::(); + .insert_resource(OitResolvePipeline::new()); } } @@ -97,16 +98,14 @@ pub struct OitResolveBindGroup(pub BindGroup); #[derive(Resource)] pub struct OitResolvePipeline { /// View bind group layout. - pub view_bind_group_layout: BindGroupLayout, + pub view_bind_group_layout: BindGroupLayoutDescriptor, /// Depth bind group layout. - pub oit_depth_bind_group_layout: BindGroupLayout, + pub oit_depth_bind_group_layout: BindGroupLayoutDescriptor, } -impl FromWorld for OitResolvePipeline { - fn from_world(world: &mut World) -> Self { - let render_device = world.resource::(); - - let view_bind_group_layout = render_device.create_bind_group_layout( +impl OitResolvePipeline { + fn new() -> Self { + let view_bind_group_layout = BindGroupLayoutDescriptor::new( "oit_resolve_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, @@ -120,7 +119,7 @@ impl FromWorld for OitResolvePipeline { ), ); - let oit_depth_bind_group_layout = render_device.create_bind_group_layout( + let oit_depth_bind_group_layout = BindGroupLayoutDescriptor::new( "oit_depth_bind_group_layout", &BindGroupLayoutEntries::single(ShaderStages::FRAGMENT, texture_depth_2d()), ); @@ -238,6 +237,7 @@ pub fn prepare_oit_resolve_bind_group( resolve_pipeline: Res, render_device: Res, view_uniforms: Res, + pipeline_cache: Res, buffers: Res, ) { if let (Some(binding), Some(layers_binding), Some(layer_ids_binding)) = ( @@ -247,7 +247,7 @@ pub fn prepare_oit_resolve_bind_group( ) { let bind_group = render_device.create_bind_group( "oit_resolve_bind_group", - &resolve_pipeline.view_bind_group_layout, + &pipeline_cache.get_bind_group_layout(resolve_pipeline.view_bind_group_layout.clone()), &BindGroupEntries::sequential((binding.clone(), layers_binding, layer_ids_binding)), ); commands.insert_resource(OitResolveBindGroup(bind_group)); diff --git a/crates/bevy_core_pipeline/src/oit/resolve/node.rs b/crates/bevy_core_pipeline/src/oit/resolve/node.rs index 17fbf4f3e2ff5..183f26b148cb7 100644 --- a/crates/bevy_core_pipeline/src/oit/resolve/node.rs +++ b/crates/bevy_core_pipeline/src/oit/resolve/node.rs @@ -55,7 +55,8 @@ impl ViewNode for OitResolveNode { let depth_bind_group = render_context.render_device().create_bind_group( "oit_resolve_depth_bind_group", - &resolve_pipeline.oit_depth_bind_group_layout, + &pipeline_cache + .get_bind_group_layout(resolve_pipeline.oit_depth_bind_group_layout.clone()), &BindGroupEntries::single(depth.view()), ); diff --git a/crates/bevy_core_pipeline/src/skybox/mod.rs b/crates/bevy_core_pipeline/src/skybox/mod.rs index aa35210a0eb1f..46e6b58dc23af 100644 --- a/crates/bevy_core_pipeline/src/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/skybox/mod.rs @@ -149,14 +149,14 @@ pub struct SkyboxUniforms { #[derive(Resource)] struct SkyboxPipeline { - bind_group_layout: BindGroupLayout, + bind_group_layout: BindGroupLayoutDescriptor, shader: Handle, } impl SkyboxPipeline { - fn new(render_device: &RenderDevice, shader: Handle) -> Self { + fn new(shader: Handle) -> Self { Self { - bind_group_layout: render_device.create_bind_group_layout( + bind_group_layout: BindGroupLayoutDescriptor::new( "skybox_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, @@ -174,13 +174,9 @@ impl SkyboxPipeline { } } -fn init_skybox_pipeline( - mut commands: Commands, - render_device: Res, - asset_server: Res, -) { +fn init_skybox_pipeline(mut commands: Commands, asset_server: Res) { let shader = load_embedded_asset!(asset_server.as_ref(), "skybox.wgsl"); - commands.insert_resource(SkyboxPipeline::new(&render_device, shader)); + commands.insert_resource(SkyboxPipeline::new(shader)); } #[derive(PartialEq, Eq, Hash, Clone, Copy)] @@ -278,6 +274,7 @@ fn prepare_skybox_bind_groups( skybox_uniforms: Res>, images: Res>, render_device: Res, + pipeline_cache: Res, views: Query<(Entity, &Skybox, &DynamicUniformIndex)>, ) { for (entity, skybox, skybox_uniform_index) in &views { @@ -288,7 +285,7 @@ fn prepare_skybox_bind_groups( ) { let bind_group = render_device.create_bind_group( "skybox_bind_group", - &pipeline.bind_group_layout, + &pipeline_cache.get_bind_group_layout(pipeline.bind_group_layout.clone()), &BindGroupEntries::sequential(( &skybox.texture_view, &skybox.sampler, diff --git a/crates/bevy_core_pipeline/src/skybox/prepass.rs b/crates/bevy_core_pipeline/src/skybox/prepass.rs index e762412316f84..109c8b647900f 100644 --- a/crates/bevy_core_pipeline/src/skybox/prepass.rs +++ b/crates/bevy_core_pipeline/src/skybox/prepass.rs @@ -10,7 +10,7 @@ use bevy_ecs::{ }; use bevy_render::{ render_resource::{ - binding_types::uniform_buffer, BindGroup, BindGroupEntries, BindGroupLayout, + binding_types::uniform_buffer, BindGroup, BindGroupEntries, BindGroupLayoutDescriptor, BindGroupLayoutEntries, CachedRenderPipelineId, CompareFunction, DepthStencilState, FragmentState, MultisampleState, PipelineCache, RenderPipelineDescriptor, ShaderStages, SpecializedRenderPipeline, SpecializedRenderPipelines, @@ -37,7 +37,7 @@ use crate::{ /// blur is enabled. #[derive(Resource)] pub struct SkyboxPrepassPipeline { - bind_group_layout: BindGroupLayout, + bind_group_layout: BindGroupLayoutDescriptor, fullscreen_shader: FullscreenShader, fragment_shader: Handle, } @@ -61,12 +61,11 @@ pub struct SkyboxPrepassBindGroup(pub BindGroup); pub fn init_skybox_prepass_pipeline( mut commands: Commands, - render_device: Res, fullscreen_shader: Res, asset_server: Res, ) { commands.insert_resource(SkyboxPrepassPipeline { - bind_group_layout: render_device.create_bind_group_layout( + bind_group_layout: BindGroupLayoutDescriptor::new( "skybox_prepass_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, @@ -142,6 +141,7 @@ pub fn prepare_skybox_prepass_bind_groups( view_uniforms: Res, prev_view_uniforms: Res, render_device: Res, + pipeline_cache: Res, views: Query, With)>, ) { for entity in &views { @@ -153,7 +153,7 @@ pub fn prepare_skybox_prepass_bind_groups( }; let bind_group = render_device.create_bind_group( "skybox_prepass_bind_group", - &pipeline.bind_group_layout, + &pipeline_cache.get_bind_group_layout(pipeline.bind_group_layout.clone()), &BindGroupEntries::sequential((view_uniforms, prev_view_uniforms)), ); diff --git a/crates/bevy_core_pipeline/src/tonemapping/mod.rs b/crates/bevy_core_pipeline/src/tonemapping/mod.rs index 8b1379f6b19b2..93681a5c199f4 100644 --- a/crates/bevy_core_pipeline/src/tonemapping/mod.rs +++ b/crates/bevy_core_pipeline/src/tonemapping/mod.rs @@ -104,7 +104,7 @@ impl Plugin for TonemappingPlugin { #[derive(Resource)] pub struct TonemappingPipeline { - texture_bind_group: BindGroupLayout, + texture_bind_group: BindGroupLayoutDescriptor, sampler: Sampler, fullscreen_shader: FullscreenShader, fragment_shader: Handle, @@ -304,8 +304,8 @@ pub fn init_tonemapping_pipeline( let lut_layout_entries = get_lut_bind_group_layout_entries(); entries = entries.extend_with_indices(((3, lut_layout_entries[0]), (4, lut_layout_entries[1]))); - let tonemap_texture_bind_group = render_device - .create_bind_group_layout("tonemapping_hdr_texture_bind_group_layout", &entries); + let tonemap_texture_bind_group = + BindGroupLayoutDescriptor::new("tonemapping_hdr_texture_bind_group_layout", &entries); let sampler = render_device.create_sampler(&SamplerDescriptor::default()); diff --git a/crates/bevy_core_pipeline/src/tonemapping/node.rs b/crates/bevy_core_pipeline/src/tonemapping/node.rs index d14f1251fc4b6..1576f6df54bf2 100644 --- a/crates/bevy_core_pipeline/src/tonemapping/node.rs +++ b/crates/bevy_core_pipeline/src/tonemapping/node.rs @@ -96,7 +96,8 @@ impl ViewNode for TonemappingNode { let bind_group = render_context.render_device().create_bind_group( None, - &tonemapping_pipeline.texture_bind_group, + &pipeline_cache + .get_bind_group_layout(tonemapping_pipeline.texture_bind_group.clone()), &BindGroupEntries::sequential(( view_uniforms, source, diff --git a/crates/bevy_core_pipeline/src/upscaling/node.rs b/crates/bevy_core_pipeline/src/upscaling/node.rs index e00924460c271..f5516245aff7f 100644 --- a/crates/bevy_core_pipeline/src/upscaling/node.rs +++ b/crates/bevy_core_pipeline/src/upscaling/node.rs @@ -57,8 +57,11 @@ impl ViewNode for UpscalingNode { let bind_group = match &mut *cached_bind_group { Some((id, bind_group)) if main_texture_view.id() == *id => bind_group, cached_bind_group => { - let bind_group = blit_pipeline - .create_bind_group(render_context.render_device(), main_texture_view); + let bind_group = blit_pipeline.create_bind_group( + render_context.render_device(), + main_texture_view, + &pipeline_cache, + ); let (_, bind_group) = cached_bind_group.insert((main_texture_view.id(), bind_group)); From e1f8db861661f1d8ecad5f4bf449af77fa93bddc Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 12:21:52 +0800 Subject: [PATCH 04/23] bevy_anti_alias --- .../src/contrast_adaptive_sharpening/mod.rs | 4 +- .../src/contrast_adaptive_sharpening/node.rs | 2 +- crates/bevy_anti_alias/src/fxaa/mod.rs | 4 +- crates/bevy_anti_alias/src/fxaa/node.rs | 2 +- crates/bevy_anti_alias/src/smaa/mod.rs | 61 +++++++++---------- crates/bevy_anti_alias/src/taa/mod.rs | 14 ++--- 6 files changed, 39 insertions(+), 48 deletions(-) diff --git a/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/mod.rs b/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/mod.rs index 43790dc393520..83aa35e94e8bd 100644 --- a/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/mod.rs +++ b/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/mod.rs @@ -157,7 +157,7 @@ impl Plugin for CasPlugin { #[derive(Resource)] pub struct CasPipeline { - texture_bind_group: BindGroupLayout, + texture_bind_group: BindGroupLayoutDescriptor, sampler: Sampler, fullscreen_shader: FullscreenShader, fragment_shader: Handle, @@ -169,7 +169,7 @@ pub fn init_cas_pipeline( fullscreen_shader: Res, asset_server: Res, ) { - let texture_bind_group = render_device.create_bind_group_layout( + let texture_bind_group = BindGroupLayoutDescriptor::new( "sharpening_texture_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, diff --git a/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/node.rs b/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/node.rs index c1e6ccdda02c3..53c2fd687f99f 100644 --- a/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/node.rs +++ b/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/node.rs @@ -83,7 +83,7 @@ impl Node for CasNode { cached_bind_group => { let bind_group = render_context.render_device().create_bind_group( "cas_bind_group", - &sharpening_pipeline.texture_bind_group, + &pipeline_cache.get_bind_group_layout(sharpening_pipeline.texture_bind_group.clone()), &BindGroupEntries::sequential(( view_target.source, &sharpening_pipeline.sampler, diff --git a/crates/bevy_anti_alias/src/fxaa/mod.rs b/crates/bevy_anti_alias/src/fxaa/mod.rs index 075c7a82f610e..302fa572cf0a6 100644 --- a/crates/bevy_anti_alias/src/fxaa/mod.rs +++ b/crates/bevy_anti_alias/src/fxaa/mod.rs @@ -123,7 +123,7 @@ impl Plugin for FxaaPlugin { #[derive(Resource)] pub struct FxaaPipeline { - texture_bind_group: BindGroupLayout, + texture_bind_group: BindGroupLayoutDescriptor, sampler: Sampler, fullscreen_shader: FullscreenShader, fragment_shader: Handle, @@ -135,7 +135,7 @@ pub fn init_fxaa_pipeline( fullscreen_shader: Res, asset_server: Res, ) { - let texture_bind_group = render_device.create_bind_group_layout( + let texture_bind_group = BindGroupLayoutDescriptor::new( "fxaa_texture_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, diff --git a/crates/bevy_anti_alias/src/fxaa/node.rs b/crates/bevy_anti_alias/src/fxaa/node.rs index 54d2afd33e736..f3e61d253efd1 100644 --- a/crates/bevy_anti_alias/src/fxaa/node.rs +++ b/crates/bevy_anti_alias/src/fxaa/node.rs @@ -54,7 +54,7 @@ impl ViewNode for FxaaNode { cached_bind_group => { let bind_group = render_context.render_device().create_bind_group( None, - &fxaa_pipeline.texture_bind_group, + &pipeline_cache.get_bind_group_layout(fxaa_pipeline.texture_bind_group.clone()), &BindGroupEntries::sequential((source, &fxaa_pipeline.sampler)), ); diff --git a/crates/bevy_anti_alias/src/smaa/mod.rs b/crates/bevy_anti_alias/src/smaa/mod.rs index 9d7d7cd6593c5..ddcdf19b6632d 100644 --- a/crates/bevy_anti_alias/src/smaa/mod.rs +++ b/crates/bevy_anti_alias/src/smaa/mod.rs @@ -60,16 +60,7 @@ use bevy_render::{ NodeRunError, RenderGraphContext, RenderGraphExt as _, ViewNode, ViewNodeRunner, }, render_resource::{ - binding_types::{sampler, texture_2d, uniform_buffer}, - AddressMode, BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutEntries, - CachedRenderPipelineId, ColorTargetState, ColorWrites, CompareFunction, DepthStencilState, - DynamicUniformBuffer, FilterMode, FragmentState, LoadOp, Operations, PipelineCache, - RenderPassColorAttachment, RenderPassDepthStencilAttachment, RenderPassDescriptor, - RenderPipeline, RenderPipelineDescriptor, SamplerBindingType, SamplerDescriptor, - ShaderStages, ShaderType, SpecializedRenderPipeline, SpecializedRenderPipelines, - StencilFaceState, StencilOperation, StencilState, StoreOp, TextureDescriptor, - TextureDimension, TextureFormat, TextureSampleType, TextureUsages, TextureView, - VertexState, + binding_types::{sampler, texture_2d, uniform_buffer}, AddressMode, BindGroup, BindGroupEntries, BindGroupLayoutDescriptor, BindGroupLayoutEntries, CachedRenderPipelineId, ColorTargetState, ColorWrites, CompareFunction, DepthStencilState, DynamicUniformBuffer, FilterMode, FragmentState, LoadOp, Operations, PipelineCache, RenderPassColorAttachment, RenderPassDepthStencilAttachment, RenderPassDescriptor, RenderPipeline, RenderPipelineDescriptor, SamplerBindingType, SamplerDescriptor, ShaderStages, ShaderType, SpecializedRenderPipeline, SpecializedRenderPipelines, StencilFaceState, StencilOperation, StencilState, StoreOp, TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType, TextureUsages, TextureView, VertexState }, renderer::{RenderContext, RenderDevice, RenderQueue}, texture::{CachedTexture, GpuImage, TextureCache}, @@ -143,9 +134,9 @@ pub struct SmaaPipelines { /// The pipeline data for phase 1 of SMAA: edge detection. struct SmaaEdgeDetectionPipeline { /// The bind group layout common to all passes. - postprocess_bind_group_layout: BindGroupLayout, + postprocess_bind_group_layout: BindGroupLayoutDescriptor, /// The bind group layout for data specific to this pass. - edge_detection_bind_group_layout: BindGroupLayout, + edge_detection_bind_group_layout: BindGroupLayoutDescriptor, /// The shader asset handle. shader: Handle, } @@ -153,9 +144,9 @@ struct SmaaEdgeDetectionPipeline { /// The pipeline data for phase 2 of SMAA: blending weight calculation. struct SmaaBlendingWeightCalculationPipeline { /// The bind group layout common to all passes. - postprocess_bind_group_layout: BindGroupLayout, + postprocess_bind_group_layout: BindGroupLayoutDescriptor, /// The bind group layout for data specific to this pass. - blending_weight_calculation_bind_group_layout: BindGroupLayout, + blending_weight_calculation_bind_group_layout: BindGroupLayoutDescriptor, /// The shader asset handle. shader: Handle, } @@ -163,9 +154,9 @@ struct SmaaBlendingWeightCalculationPipeline { /// The pipeline data for phase 3 of SMAA: neighborhood blending. struct SmaaNeighborhoodBlendingPipeline { /// The bind group layout common to all passes. - postprocess_bind_group_layout: BindGroupLayout, + postprocess_bind_group_layout: BindGroupLayoutDescriptor, /// The bind group layout for data specific to this pass. - neighborhood_blending_bind_group_layout: BindGroupLayout, + neighborhood_blending_bind_group_layout: BindGroupLayoutDescriptor, /// The shader asset handle. shader: Handle, } @@ -358,11 +349,10 @@ impl Plugin for SmaaPlugin { pub fn init_smaa_pipelines( mut commands: Commands, - render_device: Res, asset_server: Res, ) { // Create the postprocess bind group layout (all passes, bind group 0). - let postprocess_bind_group_layout = render_device.create_bind_group_layout( + let postprocess_bind_group_layout = BindGroupLayoutDescriptor::new( "SMAA postprocess bind group layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, @@ -374,7 +364,7 @@ pub fn init_smaa_pipelines( ); // Create the edge detection bind group layout (pass 1, bind group 1). - let edge_detection_bind_group_layout = render_device.create_bind_group_layout( + let edge_detection_bind_group_layout = BindGroupLayoutDescriptor::new( "SMAA edge detection bind group layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, @@ -383,7 +373,7 @@ pub fn init_smaa_pipelines( ); // Create the blending weight calculation bind group layout (pass 2, bind group 1). - let blending_weight_calculation_bind_group_layout = render_device.create_bind_group_layout( + let blending_weight_calculation_bind_group_layout = BindGroupLayoutDescriptor::new( "SMAA blending weight calculation bind group layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, @@ -397,7 +387,7 @@ pub fn init_smaa_pipelines( ); // Create the neighborhood blending bind group layout (pass 3, bind group 1). - let neighborhood_blending_bind_group_layout = render_device.create_bind_group_layout( + let neighborhood_blending_bind_group_layout = BindGroupLayoutDescriptor::new( "SMAA neighborhood blending bind group layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, @@ -728,6 +718,7 @@ fn prepare_smaa_bind_groups( smaa_pipelines: Res, smaa_luts: Res, images: Res>, + pipeline_cache: Res, view_targets: Query<(Entity, &SmaaTextures), (With, With)>, ) { // Fetch the two lookup textures. These are bundled in this library. @@ -754,16 +745,16 @@ fn prepare_smaa_bind_groups( commands.entity(entity).insert(SmaaBindGroups { edge_detection_bind_group: render_device.create_bind_group( Some("SMAA edge detection bind group"), - &smaa_pipelines + &pipeline_cache.get_bind_group_layout(smaa_pipelines .edge_detection - .edge_detection_bind_group_layout, + .edge_detection_bind_group_layout.clone()), &BindGroupEntries::sequential((&sampler,)), ), blending_weight_calculation_bind_group: render_device.create_bind_group( Some("SMAA blending weight calculation bind group"), - &smaa_pipelines + &pipeline_cache.get_bind_group_layout(smaa_pipelines .blending_weight_calculation - .blending_weight_calculation_bind_group_layout, + .blending_weight_calculation_bind_group_layout.clone()), &BindGroupEntries::sequential(( &smaa_textures.edge_detection_color_texture.default_view, &sampler, @@ -773,9 +764,9 @@ fn prepare_smaa_bind_groups( ), neighborhood_blending_bind_group: render_device.create_bind_group( Some("SMAA neighborhood blending bind group"), - &smaa_pipelines + &pipeline_cache.get_bind_group_layout(smaa_pipelines .neighborhood_blending - .neighborhood_blending_bind_group_layout, + .neighborhood_blending_bind_group_layout.clone()), &BindGroupEntries::sequential(( &smaa_textures.blend_texture.default_view, &sampler, @@ -837,6 +828,7 @@ impl ViewNode for SmaaNode { // Stage 1: Edge detection pass. perform_edge_detection( render_context, + pipeline_cache, smaa_pipelines, smaa_textures, view_smaa_bind_groups, @@ -849,6 +841,7 @@ impl ViewNode for SmaaNode { // Stage 2: Blending weight calculation pass. perform_blending_weight_calculation( render_context, + pipeline_cache, smaa_pipelines, smaa_textures, view_smaa_bind_groups, @@ -861,6 +854,7 @@ impl ViewNode for SmaaNode { // Stage 3: Neighborhood blending pass. perform_neighborhood_blending( render_context, + pipeline_cache, smaa_pipelines, view_smaa_bind_groups, smaa_info_uniform_buffer, @@ -885,6 +879,7 @@ impl ViewNode for SmaaNode { /// examine them. fn perform_edge_detection( render_context: &mut RenderContext, + pipeline_cache: &PipelineCache, smaa_pipelines: &SmaaPipelines, smaa_textures: &SmaaTextures, view_smaa_bind_groups: &SmaaBindGroups, @@ -896,7 +891,7 @@ fn perform_edge_detection( // Create the edge detection bind group. let postprocess_bind_group = render_context.render_device().create_bind_group( None, - &smaa_pipelines.edge_detection.postprocess_bind_group_layout, + &pipeline_cache.get_bind_group_layout(smaa_pipelines.edge_detection.postprocess_bind_group_layout.clone()), &BindGroupEntries::sequential((source, &**smaa_info_uniform_buffer)), ); @@ -939,6 +934,7 @@ fn perform_edge_detection( /// pixels it doesn't need to examine. fn perform_blending_weight_calculation( render_context: &mut RenderContext, + pipeline_cache: &PipelineCache, smaa_pipelines: &SmaaPipelines, smaa_textures: &SmaaTextures, view_smaa_bind_groups: &SmaaBindGroups, @@ -950,9 +946,9 @@ fn perform_blending_weight_calculation( // Create the blending weight calculation bind group. let postprocess_bind_group = render_context.render_device().create_bind_group( None, - &smaa_pipelines + &pipeline_cache.get_bind_group_layout(smaa_pipelines .blending_weight_calculation - .postprocess_bind_group_layout, + .postprocess_bind_group_layout.clone()), &BindGroupEntries::sequential((source, &**smaa_info_uniform_buffer)), ); @@ -998,6 +994,7 @@ fn perform_blending_weight_calculation( /// texture. It's the only phase that writes to the postprocessing destination. fn perform_neighborhood_blending( render_context: &mut RenderContext, + pipeline_cache: &PipelineCache, smaa_pipelines: &SmaaPipelines, view_smaa_bind_groups: &SmaaBindGroups, smaa_info_uniform_buffer: &SmaaInfoUniformBuffer, @@ -1008,9 +1005,9 @@ fn perform_neighborhood_blending( ) { let postprocess_bind_group = render_context.render_device().create_bind_group( None, - &smaa_pipelines + &pipeline_cache.get_bind_group_layout(smaa_pipelines .neighborhood_blending - .postprocess_bind_group_layout, + .postprocess_bind_group_layout.clone()), &BindGroupEntries::sequential((source, &**smaa_info_uniform_buffer)), ); diff --git a/crates/bevy_anti_alias/src/taa/mod.rs b/crates/bevy_anti_alias/src/taa/mod.rs index 44aa6624c1111..dcf396c614abc 100644 --- a/crates/bevy_anti_alias/src/taa/mod.rs +++ b/crates/bevy_anti_alias/src/taa/mod.rs @@ -23,13 +23,7 @@ use bevy_render::{ diagnostic::RecordDiagnostics, render_graph::{NodeRunError, RenderGraphContext, RenderGraphExt, ViewNode, ViewNodeRunner}, render_resource::{ - binding_types::{sampler, texture_2d, texture_depth_2d}, - BindGroupEntries, BindGroupLayout, BindGroupLayoutEntries, CachedRenderPipelineId, - ColorTargetState, ColorWrites, FilterMode, FragmentState, Operations, PipelineCache, - RenderPassColorAttachment, RenderPassDescriptor, RenderPipelineDescriptor, Sampler, - SamplerBindingType, SamplerDescriptor, ShaderStages, SpecializedRenderPipeline, - SpecializedRenderPipelines, TextureDescriptor, TextureDimension, TextureFormat, - TextureSampleType, TextureUsages, + binding_types::{sampler, texture_2d, texture_depth_2d}, BindGroupEntries, BindGroupLayoutDescriptor, BindGroupLayoutEntries, CachedRenderPipelineId, ColorTargetState, ColorWrites, FilterMode, FragmentState, Operations, PipelineCache, RenderPassColorAttachment, RenderPassDescriptor, RenderPipelineDescriptor, Sampler, SamplerBindingType, SamplerDescriptor, ShaderStages, SpecializedRenderPipeline, SpecializedRenderPipelines, TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType, TextureUsages }, renderer::{RenderContext, RenderDevice}, sync_component::SyncComponentPlugin, @@ -186,7 +180,7 @@ impl ViewNode for TemporalAntiAliasNode { let taa_bind_group = render_context.render_device().create_bind_group( "taa_bind_group", - &pipelines.taa_bind_group_layout, + &pipeline_cache.get_bind_group_layout(pipelines.taa_bind_group_layout.clone()), &BindGroupEntries::sequential(( view_target.source, &taa_history_textures.read.default_view, @@ -236,7 +230,7 @@ impl ViewNode for TemporalAntiAliasNode { #[derive(Resource)] struct TaaPipeline { - taa_bind_group_layout: BindGroupLayout, + taa_bind_group_layout: BindGroupLayoutDescriptor, nearest_sampler: Sampler, linear_sampler: Sampler, fullscreen_shader: FullscreenShader, @@ -262,7 +256,7 @@ fn init_taa_pipeline( ..SamplerDescriptor::default() }); - let taa_bind_group_layout = render_device.create_bind_group_layout( + let taa_bind_group_layout = BindGroupLayoutDescriptor::new( "taa_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, From d212d560bcd5fbe8bab5a1eb3bf0f3d47ea94221 Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 12:40:04 +0800 Subject: [PATCH 05/23] bevy_post_process --- .../src/auto_exposure/node.rs | 2 +- .../src/auto_exposure/pipeline.rs | 11 ++--- .../src/bloom/downsampling_pipeline.rs | 4 +- crates/bevy_post_process/src/bloom/mod.rs | 46 +++++++++++-------- .../src/bloom/upsampling_pipeline.rs | 6 +-- crates/bevy_post_process/src/dof/mod.rs | 31 +++++++------ .../bevy_post_process/src/effect_stack/mod.rs | 21 +++++---- .../bevy_post_process/src/motion_blur/node.rs | 2 +- .../src/motion_blur/pipeline.rs | 17 ++++--- .../bevy_post_process/src/msaa_writeback.rs | 7 ++- 10 files changed, 76 insertions(+), 71 deletions(-) diff --git a/crates/bevy_post_process/src/auto_exposure/node.rs b/crates/bevy_post_process/src/auto_exposure/node.rs index c7f88dfb28d6f..6676f5ab46bf1 100644 --- a/crates/bevy_post_process/src/auto_exposure/node.rs +++ b/crates/bevy_post_process/src/auto_exposure/node.rs @@ -103,7 +103,7 @@ impl Node for AutoExposureNode { let compute_bind_group = render_context.render_device().create_bind_group( None, - &pipeline.histogram_layout, + &pipeline_cache.get_bind_group_layout(pipeline.histogram_layout.clone()), &BindGroupEntries::sequential(( &globals_buffer.buffer, &auto_exposure_buffers.settings, diff --git a/crates/bevy_post_process/src/auto_exposure/pipeline.rs b/crates/bevy_post_process/src/auto_exposure/pipeline.rs index 54b4b5accdacd..dc61a17b0e98a 100644 --- a/crates/bevy_post_process/src/auto_exposure/pipeline.rs +++ b/crates/bevy_post_process/src/auto_exposure/pipeline.rs @@ -7,7 +7,6 @@ use bevy_image::Image; use bevy_render::{ globals::GlobalsUniform, render_resource::{binding_types::*, *}, - renderer::RenderDevice, view::ViewUniform, }; use bevy_shader::Shader; @@ -16,7 +15,7 @@ use core::num::NonZero; #[derive(Resource)] pub struct AutoExposurePipeline { - pub histogram_layout: BindGroupLayout, + pub histogram_layout: BindGroupLayoutDescriptor, pub histogram_shader: Handle, } @@ -48,13 +47,9 @@ pub enum AutoExposurePass { pub const HISTOGRAM_BIN_COUNT: u64 = 64; -pub fn init_auto_exposure_pipeline( - mut commands: Commands, - render_device: Res, - asset_server: Res, -) { +pub fn init_auto_exposure_pipeline(mut commands: Commands, asset_server: Res) { commands.insert_resource(AutoExposurePipeline { - histogram_layout: render_device.create_bind_group_layout( + histogram_layout: BindGroupLayoutDescriptor::new( "compute histogram bind group", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, diff --git a/crates/bevy_post_process/src/bloom/downsampling_pipeline.rs b/crates/bevy_post_process/src/bloom/downsampling_pipeline.rs index 2e66e1d25dbaf..4e94743d1f01f 100644 --- a/crates/bevy_post_process/src/bloom/downsampling_pipeline.rs +++ b/crates/bevy_post_process/src/bloom/downsampling_pipeline.rs @@ -27,7 +27,7 @@ pub struct BloomDownsamplingPipelineIds { #[derive(Resource)] pub struct BloomDownsamplingPipeline { /// Layout with a texture, a sampler, and uniforms - pub bind_group_layout: BindGroupLayout, + pub bind_group_layout: BindGroupLayoutDescriptor, pub sampler: Sampler, /// The asset handle for the fullscreen vertex shader. pub fullscreen_shader: FullscreenShader, @@ -60,7 +60,7 @@ pub fn init_bloom_downsampling_pipeline( asset_server: Res, ) { // Bind group layout - let bind_group_layout = render_device.create_bind_group_layout( + let bind_group_layout = BindGroupLayoutDescriptor::new( "bloom_downsampling_bind_group_layout_with_settings", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, diff --git a/crates/bevy_post_process/src/bloom/mod.rs b/crates/bevy_post_process/src/bloom/mod.rs index 5e22bb7c8cadd..565e91ad9e085 100644 --- a/crates/bevy_post_process/src/bloom/mod.rs +++ b/crates/bevy_post_process/src/bloom/mod.rs @@ -177,7 +177,8 @@ impl ViewNode for BloomNode { { let downsampling_first_bind_group = render_device.create_bind_group( "bloom_downsampling_first_bind_group", - &downsampling_pipeline_res.bind_group_layout, + &pipeline_cache + .get_bind_group_layout(downsampling_pipeline_res.bind_group_layout.clone()), &BindGroupEntries::sequential(( // Read from main texture directly view_texture, @@ -428,6 +429,7 @@ fn prepare_bloom_bind_groups( upsampling_pipeline: Res, views: Query<(Entity, &BloomTexture)>, uniforms: Res>, + pipeline_cache: Res, ) { let sampler = &downsampling_pipeline.sampler; @@ -436,28 +438,34 @@ fn prepare_bloom_bind_groups( let mut downsampling_bind_groups = Vec::with_capacity(bind_group_count); for mip in 1..bloom_texture.mip_count { - downsampling_bind_groups.push(render_device.create_bind_group( - "bloom_downsampling_bind_group", - &downsampling_pipeline.bind_group_layout, - &BindGroupEntries::sequential(( - &bloom_texture.view(mip - 1), - sampler, - uniforms.binding().unwrap(), - )), - )); + downsampling_bind_groups.push( + render_device.create_bind_group( + "bloom_downsampling_bind_group", + &pipeline_cache + .get_bind_group_layout(downsampling_pipeline.bind_group_layout.clone()), + &BindGroupEntries::sequential(( + &bloom_texture.view(mip - 1), + sampler, + uniforms.binding().unwrap(), + )), + ), + ); } let mut upsampling_bind_groups = Vec::with_capacity(bind_group_count); for mip in (0..bloom_texture.mip_count).rev() { - upsampling_bind_groups.push(render_device.create_bind_group( - "bloom_upsampling_bind_group", - &upsampling_pipeline.bind_group_layout, - &BindGroupEntries::sequential(( - &bloom_texture.view(mip), - sampler, - uniforms.binding().unwrap(), - )), - )); + upsampling_bind_groups.push( + render_device.create_bind_group( + "bloom_upsampling_bind_group", + &pipeline_cache + .get_bind_group_layout(upsampling_pipeline.bind_group_layout.clone()), + &BindGroupEntries::sequential(( + &bloom_texture.view(mip), + sampler, + uniforms.binding().unwrap(), + )), + ), + ); } commands.entity(entity).insert(BloomBindGroups { diff --git a/crates/bevy_post_process/src/bloom/upsampling_pipeline.rs b/crates/bevy_post_process/src/bloom/upsampling_pipeline.rs index 775ca55fb3529..96f47dac09a48 100644 --- a/crates/bevy_post_process/src/bloom/upsampling_pipeline.rs +++ b/crates/bevy_post_process/src/bloom/upsampling_pipeline.rs @@ -14,7 +14,6 @@ use bevy_render::{ binding_types::{sampler, texture_2d, uniform_buffer}, *, }, - renderer::RenderDevice, view::ViewTarget, }; use bevy_shader::Shader; @@ -28,7 +27,7 @@ pub struct UpsamplingPipelineIds { #[derive(Resource)] pub struct BloomUpsamplingPipeline { - pub bind_group_layout: BindGroupLayout, + pub bind_group_layout: BindGroupLayoutDescriptor, /// The asset handle for the fullscreen vertex shader. pub fullscreen_shader: FullscreenShader, /// The fragment shader asset handle. @@ -43,11 +42,10 @@ pub struct BloomUpsamplingPipelineKeys { pub fn init_bloom_upscaling_pipeline( mut commands: Commands, - render_device: Res, fullscreen_shader: Res, asset_server: Res, ) { - let bind_group_layout = render_device.create_bind_group_layout( + let bind_group_layout = BindGroupLayoutDescriptor::new( "bloom_upsampling_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, diff --git a/crates/bevy_post_process/src/dof/mod.rs b/crates/bevy_post_process/src/dof/mod.rs index 9b0077d8569a3..3f0b85658e118 100644 --- a/crates/bevy_post_process/src/dof/mod.rs +++ b/crates/bevy_post_process/src/dof/mod.rs @@ -41,7 +41,7 @@ use bevy_render::{ binding_types::{ sampler, texture_2d, texture_depth_2d, texture_depth_2d_multisampled, uniform_buffer, }, - BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutEntries, + BindGroup, BindGroupEntries, BindGroupLayoutDescriptor, BindGroupLayoutEntries, CachedRenderPipelineId, ColorTargetState, ColorWrites, FilterMode, FragmentState, LoadOp, Operations, PipelineCache, RenderPassColorAttachment, RenderPassDescriptor, RenderPipelineDescriptor, Sampler, SamplerBindingType, SamplerDescriptor, ShaderStages, @@ -261,7 +261,7 @@ pub struct DepthOfFieldNode; #[derive(Resource, Clone)] pub struct DepthOfFieldGlobalBindGroupLayout { /// The layout. - layout: BindGroupLayout, + layout: BindGroupLayoutDescriptor, /// The sampler used to sample from the color buffer or buffers. color_texture_sampler: Sampler, } @@ -303,12 +303,12 @@ pub struct AuxiliaryDepthOfFieldTexture(CachedTexture); #[derive(Component, Clone)] pub struct ViewDepthOfFieldBindGroupLayouts { /// The bind group layout for passes that take only one input. - single_input: BindGroupLayout, + single_input: BindGroupLayoutDescriptor, /// The bind group layout for the second bokeh pass, which takes two inputs. /// /// This will only be present if bokeh is in use. - dual_input: Option, + dual_input: Option, } /// Information needed to specialize the pipeline corresponding to a pass of the @@ -318,7 +318,7 @@ pub struct DepthOfFieldPipeline { view_bind_group_layouts: ViewDepthOfFieldBindGroupLayouts, /// The bind group layout shared among all invocations of the depth of field /// shader. - global_bind_group_layout: BindGroupLayout, + global_bind_group_layout: BindGroupLayoutDescriptor, /// The asset handle for the fullscreen vertex shader. fullscreen_shader: FullscreenShader, /// The fragment shader asset handle. @@ -388,7 +388,7 @@ impl ViewNode for DepthOfFieldNode { }; render_context.render_device().create_bind_group( Some(pipeline_render_info.view_bind_group_label), - dual_input_bind_group_layout, + &pipeline_cache.get_bind_group_layout(dual_input_bind_group_layout.clone()), &BindGroupEntries::sequential(( view_uniforms_binding, view_depth_texture.view(), @@ -399,7 +399,8 @@ impl ViewNode for DepthOfFieldNode { } else { render_context.render_device().create_bind_group( Some(pipeline_render_info.view_bind_group_label), - &view_bind_group_layouts.single_input, + &pipeline_cache + .get_bind_group_layout(view_bind_group_layouts.single_input.clone()), &BindGroupEntries::sequential(( view_uniforms_binding, view_depth_texture.view(), @@ -510,8 +511,8 @@ impl DepthOfField { pub fn init_dof_global_bind_group_layout(mut commands: Commands, render_device: Res) { // Create the bind group layout that will be shared among all instances // of the depth of field shader. - let layout = render_device.create_bind_group_layout( - Some("depth of field global bind group layout"), + let layout = BindGroupLayoutDescriptor::new( + "depth of field global bind group layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, ( @@ -542,12 +543,11 @@ pub fn init_dof_global_bind_group_layout(mut commands: Commands, render_device: pub fn prepare_depth_of_field_view_bind_group_layouts( mut commands: Commands, view_targets: Query<(Entity, &DepthOfField, &Msaa)>, - render_device: Res, ) { for (view, depth_of_field, msaa) in view_targets.iter() { // Create the bind group layout for the passes that take one input. - let single_input = render_device.create_bind_group_layout( - Some("depth of field bind group layout (single input)"), + let single_input = BindGroupLayoutDescriptor::new( + "depth of field bind group layout (single input)", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, ( @@ -566,8 +566,8 @@ pub fn prepare_depth_of_field_view_bind_group_layouts( // which takes two inputs. We only need to do this if bokeh is in use. let dual_input = match depth_of_field.mode { DepthOfFieldMode::Gaussian => None, - DepthOfFieldMode::Bokeh => Some(render_device.create_bind_group_layout( - Some("depth of field bind group layout (dual input)"), + DepthOfFieldMode::Bokeh => Some(BindGroupLayoutDescriptor::new( + "depth of field bind group layout (dual input)", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, ( @@ -617,6 +617,7 @@ pub fn prepare_depth_of_field_global_bind_group( mut dof_bind_group: ResMut, depth_of_field_uniforms: Res>, render_device: Res, + pipeline_cache: Res, ) { let Some(depth_of_field_uniforms) = depth_of_field_uniforms.binding() else { return; @@ -624,7 +625,7 @@ pub fn prepare_depth_of_field_global_bind_group( **dof_bind_group = Some(render_device.create_bind_group( Some("depth of field global bind group"), - &global_bind_group_layout.layout, + &pipeline_cache.get_bind_group_layout(global_bind_group_layout.layout.clone()), &BindGroupEntries::sequential(( depth_of_field_uniforms, // `dof_params` &global_bind_group_layout.color_texture_sampler, // `color_texture_sampler` diff --git a/crates/bevy_post_process/src/effect_stack/mod.rs b/crates/bevy_post_process/src/effect_stack/mod.rs index 8ad769efaa53a..65f7ada212e3d 100644 --- a/crates/bevy_post_process/src/effect_stack/mod.rs +++ b/crates/bevy_post_process/src/effect_stack/mod.rs @@ -29,12 +29,12 @@ use bevy_render::{ }, render_resource::{ binding_types::{sampler, texture_2d, uniform_buffer}, - BindGroupEntries, BindGroupLayout, BindGroupLayoutEntries, CachedRenderPipelineId, - ColorTargetState, ColorWrites, DynamicUniformBuffer, Extent3d, FilterMode, FragmentState, - Operations, PipelineCache, RenderPassColorAttachment, RenderPassDescriptor, - RenderPipelineDescriptor, Sampler, SamplerBindingType, SamplerDescriptor, ShaderStages, - ShaderType, SpecializedRenderPipeline, SpecializedRenderPipelines, TextureDimension, - TextureFormat, TextureSampleType, + BindGroupEntries, BindGroupLayoutDescriptor, BindGroupLayoutEntries, + CachedRenderPipelineId, ColorTargetState, ColorWrites, DynamicUniformBuffer, Extent3d, + FilterMode, FragmentState, Operations, PipelineCache, RenderPassColorAttachment, + RenderPassDescriptor, RenderPipelineDescriptor, Sampler, SamplerBindingType, + SamplerDescriptor, ShaderStages, ShaderType, SpecializedRenderPipeline, + SpecializedRenderPipelines, TextureDimension, TextureFormat, TextureSampleType, }, renderer::{RenderContext, RenderDevice, RenderQueue}, texture::GpuImage, @@ -125,7 +125,7 @@ pub struct ChromaticAberration { #[derive(Resource)] pub struct PostProcessingPipeline { /// The layout of bind group 0, containing the source, LUT, and settings. - bind_group_layout: BindGroupLayout, + bind_group_layout: BindGroupLayoutDescriptor, /// Specifies how to sample the source framebuffer texture. source_sampler: Sampler, /// Specifies how to sample the chromatic aberration gradient. @@ -263,8 +263,8 @@ pub fn init_post_processing_pipeline( asset_server: Res, ) { // Create our single bind group layout. - let bind_group_layout = render_device.create_bind_group_layout( - Some("postprocessing bind group layout"), + let bind_group_layout = BindGroupLayoutDescriptor::new( + "postprocessing bind group layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, ( @@ -395,7 +395,8 @@ impl ViewNode for PostProcessingNode { let bind_group = render_context.render_device().create_bind_group( Some("postprocessing bind group"), - &post_processing_pipeline.bind_group_layout, + &pipeline_cache + .get_bind_group_layout(post_processing_pipeline.bind_group_layout.clone()), &BindGroupEntries::sequential(( post_process.source, &post_processing_pipeline.source_sampler, diff --git a/crates/bevy_post_process/src/motion_blur/node.rs b/crates/bevy_post_process/src/motion_blur/node.rs index 5ac04df141612..2e827e8c782f4 100644 --- a/crates/bevy_post_process/src/motion_blur/node.rs +++ b/crates/bevy_post_process/src/motion_blur/node.rs @@ -72,7 +72,7 @@ impl ViewNode for MotionBlurNode { let bind_group = render_context.render_device().create_bind_group( Some("motion_blur_bind_group"), - layout, + &pipeline_cache.get_bind_group_layout(layout.clone()), &BindGroupEntries::sequential(( post_process.source, &prepass_motion_vectors_texture.texture.default_view, diff --git a/crates/bevy_post_process/src/motion_blur/pipeline.rs b/crates/bevy_post_process/src/motion_blur/pipeline.rs index dc9dbe8f762f3..de266ad470837 100644 --- a/crates/bevy_post_process/src/motion_blur/pipeline.rs +++ b/crates/bevy_post_process/src/motion_blur/pipeline.rs @@ -15,10 +15,10 @@ use bevy_render::{ sampler, texture_2d, texture_2d_multisampled, texture_depth_2d, texture_depth_2d_multisampled, uniform_buffer_sized, }, - BindGroupLayout, BindGroupLayoutEntries, CachedRenderPipelineId, ColorTargetState, - ColorWrites, FragmentState, PipelineCache, RenderPipelineDescriptor, Sampler, - SamplerBindingType, SamplerDescriptor, ShaderStages, ShaderType, SpecializedRenderPipeline, - SpecializedRenderPipelines, TextureFormat, TextureSampleType, + BindGroupLayoutDescriptor, BindGroupLayoutEntries, CachedRenderPipelineId, + ColorTargetState, ColorWrites, FragmentState, PipelineCache, RenderPipelineDescriptor, + Sampler, SamplerBindingType, SamplerDescriptor, ShaderStages, ShaderType, + SpecializedRenderPipeline, SpecializedRenderPipelines, TextureFormat, TextureSampleType, }, renderer::RenderDevice, view::{ExtractedView, Msaa, ViewTarget}, @@ -31,8 +31,8 @@ use super::MotionBlurUniform; #[derive(Resource)] pub struct MotionBlurPipeline { pub(crate) sampler: Sampler, - pub(crate) layout: BindGroupLayout, - pub(crate) layout_msaa: BindGroupLayout, + pub(crate) layout: BindGroupLayoutDescriptor, + pub(crate) layout_msaa: BindGroupLayoutDescriptor, pub(crate) fullscreen_shader: FullscreenShader, pub(crate) fragment_shader: Handle, } @@ -80,9 +80,8 @@ impl MotionBlurPipeline { ); let sampler = render_device.create_sampler(&SamplerDescriptor::default()); - let layout = render_device.create_bind_group_layout("motion_blur_layout", mb_layout); - let layout_msaa = - render_device.create_bind_group_layout("motion_blur_layout_msaa", mb_layout_msaa); + let layout = BindGroupLayoutDescriptor::new("motion_blur_layout", mb_layout); + let layout_msaa = BindGroupLayoutDescriptor::new("motion_blur_layout_msaa", mb_layout_msaa); Self { sampler, diff --git a/crates/bevy_post_process/src/msaa_writeback.rs b/crates/bevy_post_process/src/msaa_writeback.rs index ddc44896fd20e..8bcf2effae1dc 100644 --- a/crates/bevy_post_process/src/msaa_writeback.rs +++ b/crates/bevy_post_process/src/msaa_writeback.rs @@ -103,8 +103,11 @@ impl ViewNode for MsaaWritebackNode { occlusion_query_set: None, }; - let bind_group = - blit_pipeline.create_bind_group(render_context.render_device(), post_process.source); + let bind_group = blit_pipeline.create_bind_group( + render_context.render_device(), + post_process.source, + &pipeline_cache, + ); let mut render_pass = render_context .command_encoder() From e8556e56b8c1e72148b25afeb7b034b21b9ed619 Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 13:01:19 +0800 Subject: [PATCH 06/23] bevy_sprite_render WIP --- .../src/render_resource/bind_group.rs | 17 +++++++++++++++-- .../bevy_render/src/render_resource/pipeline.rs | 2 +- .../bevy_sprite_render/src/mesh2d/material.rs | 17 ++++++++++++----- crates/bevy_sprite_render/src/mesh2d/mesh.rs | 14 ++++++++------ crates/bevy_sprite_render/src/render/mod.rs | 15 +++++++++------ 5 files changed, 45 insertions(+), 20 deletions(-) diff --git a/crates/bevy_render/src/render_resource/bind_group.rs b/crates/bevy_render/src/render_resource/bind_group.rs index 0cb07e1995330..14155856ff211 100644 --- a/crates/bevy_render/src/render_resource/bind_group.rs +++ b/crates/bevy_render/src/render_resource/bind_group.rs @@ -1,12 +1,13 @@ use crate::{ define_atomic_id, render_asset::RenderAssets, - render_resource::{BindGroupLayout, Buffer, Sampler, TextureView}, + render_resource::{BindGroupLayout, Buffer, PipelineCache, Sampler, TextureView}, renderer::{RenderDevice, WgpuWrapper}, texture::GpuImage, }; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::system::{SystemParam, SystemParamItem}; +use bevy_render::render_resource::BindGroupLayoutDescriptor; pub use bevy_render_macros::AsBindGroup; use core::ops::Deref; use encase::ShaderType; @@ -530,10 +531,13 @@ pub trait AsBindGroup { /// Creates a bind group for `self` matching the layout defined in [`AsBindGroup::bind_group_layout`]. fn as_bind_group( &self, - layout: &BindGroupLayout, + layout_descriptor: &BindGroupLayoutDescriptor, render_device: &RenderDevice, + pipeline_cache: &PipelineCache, param: &mut SystemParamItem<'_, '_, Self::Param>, ) -> Result { + let layout = &pipeline_cache.get_bind_group_layout(layout_descriptor.clone()); + let UnpreparedBindGroup { bindings } = Self::unprepared_bind_group(self, layout, render_device, param, false)?; @@ -586,6 +590,15 @@ pub trait AsBindGroup { ) } + /// Creates the bind group layout descriptor matching all bind groups returned by + /// [`AsBindGroup::as_bind_group_descriptor`] + fn bind_group_layout_descriptor() -> BindGroupLayoutDescriptor + where + Self: Sized, + { + todo!(); + } + /// Returns a vec of bind group layout entries. /// /// Set `force_no_bindless` to true to require that bindless textures *not* diff --git a/crates/bevy_render/src/render_resource/pipeline.rs b/crates/bevy_render/src/render_resource/pipeline.rs index b699c7b791259..98ab1b4d67228 100644 --- a/crates/bevy_render/src/render_resource/pipeline.rs +++ b/crates/bevy_render/src/render_resource/pipeline.rs @@ -1,5 +1,5 @@ -use crate::renderer::WgpuWrapper; use crate::define_atomic_id; +use crate::renderer::WgpuWrapper; use alloc::borrow::Cow; use bevy_asset::Handle; use bevy_mesh::VertexBufferLayout; diff --git a/crates/bevy_sprite_render/src/mesh2d/material.rs b/crates/bevy_sprite_render/src/mesh2d/material.rs index a96c1e01a37e1..a07cac8cedf3c 100644 --- a/crates/bevy_sprite_render/src/mesh2d/material.rs +++ b/crates/bevy_sprite_render/src/mesh2d/material.rs @@ -24,6 +24,7 @@ use bevy_math::FloatOrd; use bevy_mesh::MeshVertexBufferLayoutRef; use bevy_platform::collections::HashMap; use bevy_reflect::{prelude::ReflectDefault, Reflect}; +use bevy_render::render_resource::BindGroupLayoutDescriptor; use bevy_render::{ camera::extract_cameras, mesh::RenderMesh, @@ -36,7 +37,7 @@ use bevy_render::{ TrackedRenderPass, ViewBinnedRenderPhases, ViewSortedRenderPhases, }, render_resource::{ - AsBindGroup, AsBindGroupError, BindGroup, BindGroupId, BindGroupLayout, BindingResources, + AsBindGroup, AsBindGroupError, BindGroup, BindGroupId, BindingResources, CachedRenderPipelineId, PipelineCache, RenderPipelineDescriptor, SpecializedMeshPipeline, SpecializedMeshPipelineError, SpecializedMeshPipelines, }, @@ -380,7 +381,7 @@ pub fn extract_mesh_materials_2d( #[derive(Resource)] pub struct Material2dPipeline { pub mesh2d_pipeline: Mesh2dPipeline, - pub material2d_layout: BindGroupLayout, + pub material2d_layout: BindGroupLayoutDescriptor, pub vertex_shader: Option>, pub fragment_shader: Option>, marker: PhantomData, @@ -478,11 +479,10 @@ where pub fn init_material_2d_pipeline( mut commands: Commands, - render_device: Res, asset_server: Res, mesh_2d_pipeline: Res, ) { - let material2d_layout = M::bind_group_layout(&render_device); + let material2d_layout = M::bind_group_layout_descriptor(); commands.insert_resource(Material2dPipeline:: { mesh2d_pipeline: mesh_2d_pipeline.clone(), @@ -962,6 +962,7 @@ impl RenderAsset for PreparedMaterial2d { type Param = ( SRes, + SRes, SRes>, SRes>, SRes>, @@ -974,6 +975,7 @@ impl RenderAsset for PreparedMaterial2d { _: AssetId, ( render_device, + pipeline_cache, pipeline, opaque_draw_functions, alpha_mask_draw_functions, @@ -983,7 +985,12 @@ impl RenderAsset for PreparedMaterial2d { _: Option<&Self>, ) -> Result> { let bind_group_data = material.bind_group_data(); - match material.as_bind_group(&pipeline.material2d_layout, render_device, material_param) { + match material.as_bind_group( + &pipeline.material2d_layout, + render_device, + pipeline_cache, + material_param, + ) { Ok(prepared) => { let mut mesh_pipeline_key_bits = Mesh2dPipelineKey::empty(); mesh_pipeline_key_bits.insert(alpha_mode_pipeline_key(material.alpha_mode())); diff --git a/crates/bevy_sprite_render/src/mesh2d/mesh.rs b/crates/bevy_sprite_render/src/mesh2d/mesh.rs index 1eff9be1c2904..87620d800269e 100644 --- a/crates/bevy_sprite_render/src/mesh2d/mesh.rs +++ b/crates/bevy_sprite_render/src/mesh2d/mesh.rs @@ -281,8 +281,8 @@ pub fn extract_mesh2d( #[derive(Resource, Clone)] pub struct Mesh2dPipeline { - pub view_layout: BindGroupLayout, - pub mesh_layout: BindGroupLayout, + pub view_layout: BindGroupLayoutDescriptor, + pub mesh_layout: BindGroupLayoutDescriptor, pub shader: Handle, // This dummy white texture is to be used in place of optional textures pub dummy_white_gpu_image: GpuImage, @@ -297,7 +297,7 @@ pub fn init_mesh_2d_pipeline( asset_server: Res, ) { let tonemapping_lut_entries = get_lut_bind_group_layout_entries(); - let view_layout = render_device.create_bind_group_layout( + let view_layout = BindGroupLayoutDescriptor::new( "mesh2d_view_layout", &BindGroupLayoutEntries::sequential( ShaderStages::VERTEX_FRAGMENT, @@ -310,7 +310,7 @@ pub fn init_mesh_2d_pipeline( ), ); - let mesh_layout = render_device.create_bind_group_layout( + let mesh_layout = BindGroupLayoutDescriptor::new( "mesh2d_layout", &BindGroupLayoutEntries::single( ShaderStages::VERTEX_FRAGMENT, @@ -710,13 +710,14 @@ pub fn prepare_mesh2d_bind_group( mut commands: Commands, mesh2d_pipeline: Res, render_device: Res, + pipeline_cache: Res, mesh2d_uniforms: Res>, ) { if let Some(binding) = mesh2d_uniforms.instance_data_binding() { commands.insert_resource(Mesh2dBindGroup { value: render_device.create_bind_group( "mesh2d_bind_group", - &mesh2d_pipeline.mesh_layout, + &pipeline_cache.get_bind_group_layout(mesh2d_pipeline.mesh_layout.clone()), &BindGroupEntries::single(binding), ), }); @@ -731,6 +732,7 @@ pub struct Mesh2dViewBindGroup { pub fn prepare_mesh2d_view_bind_groups( mut commands: Commands, render_device: Res, + pipeline_cache: Res, mesh2d_pipeline: Res, view_uniforms: Res, views: Query<(Entity, &Tonemapping), (With, With)>, @@ -751,7 +753,7 @@ pub fn prepare_mesh2d_view_bind_groups( get_lut_bindings(&images, &tonemapping_luts, tonemapping, &fallback_image); let view_bind_group = render_device.create_bind_group( "mesh2d_view_bind_group", - &mesh2d_pipeline.view_layout, + &pipeline_cache.get_bind_group_layout(mesh2d_pipeline.view_layout.clone()), &BindGroupEntries::sequential(( view_binding.clone(), globals.clone(), diff --git a/crates/bevy_sprite_render/src/render/mod.rs b/crates/bevy_sprite_render/src/render/mod.rs index ad73fa3e4fd1d..4a03d17006cb0 100644 --- a/crates/bevy_sprite_render/src/render/mod.rs +++ b/crates/bevy_sprite_render/src/render/mod.rs @@ -47,8 +47,8 @@ use fixedbitset::FixedBitSet; #[derive(Resource)] pub struct SpritePipeline { - view_layout: BindGroupLayout, - material_layout: BindGroupLayout, + view_layout: BindGroupLayoutDescriptor, + material_layout: BindGroupLayoutDescriptor, shader: Handle, pub dummy_white_gpu_image: GpuImage, } @@ -61,7 +61,7 @@ pub fn init_sprite_pipeline( asset_server: Res, ) { let tonemapping_lut_entries = get_lut_bind_group_layout_entries(); - let view_layout = render_device.create_bind_group_layout( + let view_layout = BindGroupLayoutDescriptor::new( "sprite_view_layout", &BindGroupLayoutEntries::sequential( ShaderStages::VERTEX_FRAGMENT, @@ -73,7 +73,7 @@ pub fn init_sprite_pipeline( ), ); - let material_layout = render_device.create_bind_group_layout( + let material_layout = BindGroupLayoutDescriptor::new( "sprite_material_layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, @@ -603,6 +603,7 @@ pub fn queue_sprites( pub fn prepare_sprite_view_bind_groups( mut commands: Commands, render_device: Res, + pipeline_cache: Res, sprite_pipeline: Res, view_uniforms: Res, views: Query<(Entity, &Tonemapping), With>, @@ -619,7 +620,7 @@ pub fn prepare_sprite_view_bind_groups( get_lut_bindings(&images, &tonemapping_luts, tonemapping, &fallback_image); let view_bind_group = render_device.create_bind_group( "mesh2d_view_bind_group", - &sprite_pipeline.view_layout, + &pipeline_cache.get_bind_group_layout(sprite_pipeline.view_layout.clone()), &BindGroupEntries::sequential((view_binding.clone(), lut_bindings.0, lut_bindings.1)), ); @@ -632,6 +633,7 @@ pub fn prepare_sprite_view_bind_groups( pub fn prepare_sprite_image_bind_groups( render_device: Res, render_queue: Res, + pipeline_cache: Res, mut sprite_meta: ResMut, sprite_pipeline: Res, mut image_bind_groups: ResMut, @@ -701,7 +703,8 @@ pub fn prepare_sprite_image_bind_groups( .or_insert_with(|| { render_device.create_bind_group( "sprite_material_bind_group", - &sprite_pipeline.material_layout, + &pipeline_cache + .get_bind_group_layout(sprite_pipeline.material_layout.clone()), &BindGroupEntries::sequential(( &gpu_image.texture_view, &gpu_image.sampler, From 31d0931f71faaa279952b166110522f9860d0974 Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 13:10:48 +0800 Subject: [PATCH 07/23] bevy_ui_render --- crates/bevy_ui_render/src/box_shadow.rs | 13 ++++---- crates/bevy_ui_render/src/gradient.rs | 13 ++++---- crates/bevy_ui_render/src/lib.rs | 9 ++++-- crates/bevy_ui_render/src/pipeline.rs | 15 ++++------ .../src/ui_material_pipeline.rs | 30 +++++++++++++------ .../src/ui_texture_slice_pipeline.rs | 25 ++++++++-------- 6 files changed, 55 insertions(+), 50 deletions(-) diff --git a/crates/bevy_ui_render/src/box_shadow.rs b/crates/bevy_ui_render/src/box_shadow.rs index 963e44575140e..3a417cc97d77e 100644 --- a/crates/bevy_ui_render/src/box_shadow.rs +++ b/crates/bevy_ui_render/src/box_shadow.rs @@ -105,16 +105,12 @@ impl Default for BoxShadowMeta { #[derive(Resource)] pub struct BoxShadowPipeline { - pub view_layout: BindGroupLayout, + pub view_layout: BindGroupLayoutDescriptor, pub shader: Handle, } -pub fn init_box_shadow_pipeline( - mut commands: Commands, - render_device: Res, - asset_server: Res, -) { - let view_layout = render_device.create_bind_group_layout( +pub fn init_box_shadow_pipeline(mut commands: Commands, asset_server: Res) { + let view_layout = BindGroupLayoutDescriptor::new( "box_shadow_view_layout", &BindGroupLayoutEntries::single( ShaderStages::VERTEX_FRAGMENT, @@ -360,6 +356,7 @@ pub fn prepare_shadows( mut commands: Commands, render_device: Res, render_queue: Res, + pipeline_cache: Res, mut ui_meta: ResMut, mut extracted_shadows: ResMut, view_uniforms: Res, @@ -374,7 +371,7 @@ pub fn prepare_shadows( ui_meta.indices.clear(); ui_meta.view_bind_group = Some(render_device.create_bind_group( "box_shadow_view_bind_group", - &box_shadow_pipeline.view_layout, + &pipeline_cache.get_bind_group_layout(box_shadow_pipeline.view_layout.clone()), &BindGroupEntries::single(view_binding), )); diff --git a/crates/bevy_ui_render/src/gradient.rs b/crates/bevy_ui_render/src/gradient.rs index 75d900fa273a9..34e1eba2ab887 100644 --- a/crates/bevy_ui_render/src/gradient.rs +++ b/crates/bevy_ui_render/src/gradient.rs @@ -95,16 +95,12 @@ impl Default for GradientMeta { #[derive(Resource)] pub struct GradientPipeline { - pub view_layout: BindGroupLayout, + pub view_layout: BindGroupLayoutDescriptor, pub shader: Handle, } -pub fn init_gradient_pipeline( - mut commands: Commands, - render_device: Res, - asset_server: Res, -) { - let view_layout = render_device.create_bind_group_layout( +pub fn init_gradient_pipeline(mut commands: Commands, asset_server: Res) { + let view_layout = BindGroupLayoutDescriptor::new( "ui_gradient_view_layout", &BindGroupLayoutEntries::single( ShaderStages::VERTEX_FRAGMENT, @@ -696,6 +692,7 @@ pub fn prepare_gradient( mut commands: Commands, render_device: Res, render_queue: Res, + pipeline_cache: Res, mut ui_meta: ResMut, mut extracted_gradients: ResMut, mut extracted_color_stops: ResMut, @@ -711,7 +708,7 @@ pub fn prepare_gradient( ui_meta.indices.clear(); ui_meta.view_bind_group = Some(render_device.create_bind_group( "gradient_view_bind_group", - &gradients_pipeline.view_layout, + &pipeline_cache.get_bind_group_layout(gradients_pipeline.view_layout.clone()), &BindGroupEntries::single(view_binding), )); diff --git a/crates/bevy_ui_render/src/lib.rs b/crates/bevy_ui_render/src/lib.rs index 2eb662ae42fa1..60d727563b351 100644 --- a/crates/bevy_ui_render/src/lib.rs +++ b/crates/bevy_ui_render/src/lib.rs @@ -1287,6 +1287,7 @@ pub fn prepare_uinodes( mut commands: Commands, render_device: Res, render_queue: Res, + pipeline_cache: Res, mut ui_meta: ResMut, mut extracted_uinodes: ResMut, view_uniforms: Res, @@ -1317,7 +1318,7 @@ pub fn prepare_uinodes( ui_meta.indices.clear(); ui_meta.view_bind_group = Some(render_device.create_bind_group( "ui_view_bind_group", - &ui_pipeline.view_layout, + &pipeline_cache.get_bind_group_layout(ui_pipeline.view_layout.clone()), &BindGroupEntries::single(view_binding), )); @@ -1365,7 +1366,8 @@ pub fn prepare_uinodes( .or_insert_with(|| { render_device.create_bind_group( "ui_material_bind_group", - &ui_pipeline.image_layout, + &pipeline_cache + .get_bind_group_layout(ui_pipeline.image_layout.clone()), &BindGroupEntries::sequential(( &gpu_image.texture_view, &gpu_image.sampler, @@ -1392,7 +1394,8 @@ pub fn prepare_uinodes( .or_insert_with(|| { render_device.create_bind_group( "ui_material_bind_group", - &ui_pipeline.image_layout, + &pipeline_cache + .get_bind_group_layout(ui_pipeline.image_layout.clone()), &BindGroupEntries::sequential(( &gpu_image.texture_view, &gpu_image.sampler, diff --git a/crates/bevy_ui_render/src/pipeline.rs b/crates/bevy_ui_render/src/pipeline.rs index ca81b62fe067c..559281d2ec6b2 100644 --- a/crates/bevy_ui_render/src/pipeline.rs +++ b/crates/bevy_ui_render/src/pipeline.rs @@ -7,7 +7,6 @@ use bevy_render::{ binding_types::{sampler, texture_2d, uniform_buffer}, *, }, - renderer::RenderDevice, view::{ViewTarget, ViewUniform}, }; use bevy_shader::Shader; @@ -15,17 +14,13 @@ use bevy_utils::default; #[derive(Resource)] pub struct UiPipeline { - pub view_layout: BindGroupLayout, - pub image_layout: BindGroupLayout, + pub view_layout: BindGroupLayoutDescriptor, + pub image_layout: BindGroupLayoutDescriptor, pub shader: Handle, } -pub fn init_ui_pipeline( - mut commands: Commands, - render_device: Res, - asset_server: Res, -) { - let view_layout = render_device.create_bind_group_layout( +pub fn init_ui_pipeline(mut commands: Commands, asset_server: Res) { + let view_layout = BindGroupLayoutDescriptor::new( "ui_view_layout", &BindGroupLayoutEntries::single( ShaderStages::VERTEX_FRAGMENT, @@ -33,7 +28,7 @@ pub fn init_ui_pipeline( ), ); - let image_layout = render_device.create_bind_group_layout( + let image_layout = BindGroupLayoutDescriptor::new( "ui_image_layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, diff --git a/crates/bevy_ui_render/src/ui_material_pipeline.rs b/crates/bevy_ui_render/src/ui_material_pipeline.rs index da047b8129349..207dc01b577b0 100644 --- a/crates/bevy_ui_render/src/ui_material_pipeline.rs +++ b/crates/bevy_ui_render/src/ui_material_pipeline.rs @@ -113,8 +113,8 @@ pub struct UiMaterialBatch { /// Render pipeline data for a given [`UiMaterial`] #[derive(Resource)] pub struct UiMaterialPipeline { - pub ui_layout: BindGroupLayout, - pub view_layout: BindGroupLayout, + pub ui_layout: BindGroupLayoutDescriptor, + pub view_layout: BindGroupLayoutDescriptor, pub vertex_shader: Handle, pub fragment_shader: Handle, marker: PhantomData, @@ -179,12 +179,11 @@ where pub fn init_ui_material_pipeline( mut commands: Commands, - render_device: Res, asset_server: Res, ) { - let ui_layout = M::bind_group_layout(&render_device); + let ui_layout = M::bind_group_layout_descriptor(); - let view_layout = render_device.create_bind_group_layout( + let view_layout = BindGroupLayoutDescriptor::new( "ui_view_layout", &BindGroupLayoutEntries::sequential( ShaderStages::VERTEX_FRAGMENT, @@ -380,6 +379,7 @@ pub fn prepare_uimaterial_nodes( mut commands: Commands, render_device: Res, render_queue: Res, + pipeline_cache: Res, mut ui_meta: ResMut>, mut extracted_uinodes: ResMut>, view_uniforms: Res, @@ -397,7 +397,7 @@ pub fn prepare_uimaterial_nodes( ui_meta.vertices.clear(); ui_meta.view_bind_group = Some(render_device.create_bind_group( "ui_material_view_bind_group", - &ui_material_pipeline.view_layout, + &pipeline_cache.get_bind_group_layout(ui_material_pipeline.view_layout.clone()), &BindGroupEntries::sequential((view_binding, globals_binding)), )); let mut index = 0; @@ -548,16 +548,28 @@ pub struct PreparedUiMaterial { impl RenderAsset for PreparedUiMaterial { type SourceAsset = M; - type Param = (SRes, SRes>, M::Param); + type Param = ( + SRes, + SRes, + SRes>, + M::Param, + ); fn prepare_asset( material: Self::SourceAsset, _: AssetId, - (render_device, pipeline, material_param): &mut SystemParamItem, + (render_device, pipeline_cache, pipeline, material_param): &mut SystemParamItem< + Self::Param, + >, _: Option<&Self>, ) -> Result> { let bind_group_data = material.bind_group_data(); - match material.as_bind_group(&pipeline.ui_layout, render_device, material_param) { + match material.as_bind_group( + &pipeline.ui_layout.clone(), + render_device, + pipeline_cache, + material_param, + ) { Ok(prepared) => Ok(PreparedUiMaterial { bindings: prepared.bindings, bind_group: prepared.bind_group, diff --git a/crates/bevy_ui_render/src/ui_texture_slice_pipeline.rs b/crates/bevy_ui_render/src/ui_texture_slice_pipeline.rs index 62f15ea1c6dbf..c31e54ca27c5f 100644 --- a/crates/bevy_ui_render/src/ui_texture_slice_pipeline.rs +++ b/crates/bevy_ui_render/src/ui_texture_slice_pipeline.rs @@ -103,17 +103,13 @@ pub struct UiTextureSliceImageBindGroups { #[derive(Resource)] pub struct UiTextureSlicePipeline { - pub view_layout: BindGroupLayout, - pub image_layout: BindGroupLayout, + pub view_layout: BindGroupLayoutDescriptor, + pub image_layout: BindGroupLayoutDescriptor, pub shader: Handle, } -pub fn init_ui_texture_slice_pipeline( - mut commands: Commands, - render_device: Res, - asset_server: Res, -) { - let view_layout = render_device.create_bind_group_layout( +pub fn init_ui_texture_slice_pipeline(mut commands: Commands, asset_server: Res) { + let view_layout = BindGroupLayoutDescriptor::new( "ui_texture_slice_view_layout", &BindGroupLayoutEntries::single( ShaderStages::VERTEX_FRAGMENT, @@ -121,7 +117,7 @@ pub fn init_ui_texture_slice_pipeline( ), ); - let image_layout = render_device.create_bind_group_layout( + let image_layout = BindGroupLayoutDescriptor::new( "ui_texture_slice_image_layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, @@ -360,6 +356,7 @@ pub fn prepare_ui_slices( mut commands: Commands, render_device: Res, render_queue: Res, + pipeline_cache: Res, mut ui_meta: ResMut, mut extracted_slices: ResMut, view_uniforms: Res, @@ -390,7 +387,7 @@ pub fn prepare_ui_slices( ui_meta.indices.clear(); ui_meta.view_bind_group = Some(render_device.create_bind_group( "ui_texture_slice_view_bind_group", - &texture_slicer_pipeline.view_layout, + &pipeline_cache.get_bind_group_layout(texture_slicer_pipeline.view_layout.clone()), &BindGroupEntries::single(view_binding), )); @@ -436,7 +433,9 @@ pub fn prepare_ui_slices( .or_insert_with(|| { render_device.create_bind_group( "ui_texture_slice_image_layout", - &texture_slicer_pipeline.image_layout, + &pipeline_cache.get_bind_group_layout( + texture_slicer_pipeline.image_layout.clone(), + ), &BindGroupEntries::sequential(( &gpu_image.texture_view, &gpu_image.sampler, @@ -463,7 +462,9 @@ pub fn prepare_ui_slices( .or_insert_with(|| { render_device.create_bind_group( "ui_texture_slice_image_layout", - &texture_slicer_pipeline.image_layout, + &pipeline_cache.get_bind_group_layout( + texture_slicer_pipeline.image_layout.clone(), + ), &BindGroupEntries::sequential(( &gpu_image.texture_view, &gpu_image.sampler, From b0ee04263e95e9831383d2bdd55deca743ed16e2 Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 13:11:40 +0800 Subject: [PATCH 08/23] bevy_gizmos --- crates/bevy_gizmos/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_gizmos/src/lib.rs b/crates/bevy_gizmos/src/lib.rs index 6eda35ee41df5..fb263e29e9aa9 100755 --- a/crates/bevy_gizmos/src/lib.rs +++ b/crates/bevy_gizmos/src/lib.rs @@ -400,7 +400,7 @@ fn init_line_gizmo_uniform_bind_group_layout( mut commands: Commands, render_device: Res, ) { - let line_layout = render_device.create_bind_group_layout( + let line_layout = BindGroupLayoutDescriptor::new( "LineGizmoUniform layout", &BindGroupLayoutEntries::single( ShaderStages::VERTEX, From 302e34c3ef7c2a78fc5350c337e4e4477a25bc25 Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 14:25:16 +0800 Subject: [PATCH 09/23] bevy_pbr --- crates/bevy_pbr/src/atmosphere/environment.rs | 9 +- crates/bevy_pbr/src/atmosphere/mod.rs | 2 +- crates/bevy_pbr/src/atmosphere/resources.rs | 48 +++--- crates/bevy_pbr/src/deferred/mod.rs | 10 +- crates/bevy_pbr/src/light_probe/generate.rs | 37 ++--- crates/bevy_pbr/src/material.rs | 35 +++- crates/bevy_pbr/src/material_bind_groups.rs | 45 ++++-- .../bevy_pbr/src/meshlet/resource_manager.rs | 34 ++-- crates/bevy_pbr/src/prepass/mod.rs | 58 ++++--- crates/bevy_pbr/src/render/gpu_preprocess.rs | 150 +++++++++++------- crates/bevy_pbr/src/render/mesh.rs | 37 ++++- crates/bevy_pbr/src/render/mesh_bindings.rs | 82 ++++++---- .../bevy_pbr/src/render/mesh_view_bindings.rs | 37 ++--- crates/bevy_pbr/src/ssao/mod.rs | 27 ++-- crates/bevy_pbr/src/ssr/mod.rs | 18 +-- crates/bevy_pbr/src/volumetric_fog/render.rs | 16 +- 16 files changed, 378 insertions(+), 267 deletions(-) diff --git a/crates/bevy_pbr/src/atmosphere/environment.rs b/crates/bevy_pbr/src/atmosphere/environment.rs index ce8370f543d93..dc6e8be6fa50f 100644 --- a/crates/bevy_pbr/src/atmosphere/environment.rs +++ b/crates/bevy_pbr/src/atmosphere/environment.rs @@ -54,7 +54,7 @@ pub(crate) struct AtmosphereProbeBindGroups { #[derive(Resource)] pub struct AtmosphereProbeLayouts { - pub environment: BindGroupLayout, + pub environment: BindGroupLayoutDescriptor, } #[derive(Resource)] @@ -62,8 +62,8 @@ pub struct AtmosphereProbePipeline { pub environment: CachedComputePipelineId, } -pub fn init_atmosphere_probe_layout(mut commands: Commands, render_device: Res) { - let environment = render_device.create_bind_group_layout( +pub fn init_atmosphere_probe_layout(mut commands: Commands) { + let environment = BindGroupLayoutDescriptor::new( "environment_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -103,12 +103,13 @@ pub(super) fn prepare_atmosphere_probe_bind_groups( atmosphere_transforms: Res, atmosphere_uniforms: Res>, settings_uniforms: Res>, + pipeline_cache: Res, mut commands: Commands, ) { for (entity, textures) in &probes { let environment = render_device.create_bind_group( "environment_bind_group", - &layouts.environment, + &pipeline_cache.get_bind_group_layout(layouts.environment.clone()), &BindGroupEntries::sequential(( atmosphere_uniforms.binding().unwrap(), settings_uniforms.binding().unwrap(), diff --git a/crates/bevy_pbr/src/atmosphere/mod.rs b/crates/bevy_pbr/src/atmosphere/mod.rs index 608cf02314bf4..4252134a4c1d5 100644 --- a/crates/bevy_pbr/src/atmosphere/mod.rs +++ b/crates/bevy_pbr/src/atmosphere/mod.rs @@ -137,7 +137,7 @@ impl Plugin for AtmospherePlugin { } render_app - .init_resource::() + .insert_resource(AtmosphereBindGroupLayouts::new()) .init_resource::() .init_resource::() .init_resource::() diff --git a/crates/bevy_pbr/src/atmosphere/resources.rs b/crates/bevy_pbr/src/atmosphere/resources.rs index fe487975e8d6f..a2f8aad78615a 100644 --- a/crates/bevy_pbr/src/atmosphere/resources.rs +++ b/crates/bevy_pbr/src/atmosphere/resources.rs @@ -26,24 +26,23 @@ use super::{Atmosphere, GpuAtmosphereSettings}; #[derive(Resource)] pub(crate) struct AtmosphereBindGroupLayouts { - pub transmittance_lut: BindGroupLayout, - pub multiscattering_lut: BindGroupLayout, - pub sky_view_lut: BindGroupLayout, - pub aerial_view_lut: BindGroupLayout, + pub transmittance_lut: BindGroupLayoutDescriptor, + pub multiscattering_lut: BindGroupLayoutDescriptor, + pub sky_view_lut: BindGroupLayoutDescriptor, + pub aerial_view_lut: BindGroupLayoutDescriptor, } #[derive(Resource)] pub(crate) struct RenderSkyBindGroupLayouts { - pub render_sky: BindGroupLayout, - pub render_sky_msaa: BindGroupLayout, + pub render_sky: BindGroupLayoutDescriptor, + pub render_sky_msaa: BindGroupLayoutDescriptor, pub fullscreen_shader: FullscreenShader, pub fragment_shader: Handle, } -impl FromWorld for AtmosphereBindGroupLayouts { - fn from_world(world: &mut World) -> Self { - let render_device = world.resource::(); - let transmittance_lut = render_device.create_bind_group_layout( +impl AtmosphereBindGroupLayouts { + pub fn new() -> Self { + let transmittance_lut = BindGroupLayoutDescriptor::new( "transmittance_lut_bind_group_layout", &BindGroupLayoutEntries::with_indices( ShaderStages::COMPUTE, @@ -62,7 +61,7 @@ impl FromWorld for AtmosphereBindGroupLayouts { ), ); - let multiscattering_lut = render_device.create_bind_group_layout( + let multiscattering_lut = BindGroupLayoutDescriptor::new( "multiscattering_lut_bind_group_layout", &BindGroupLayoutEntries::with_indices( ShaderStages::COMPUTE, @@ -83,7 +82,7 @@ impl FromWorld for AtmosphereBindGroupLayouts { ), ); - let sky_view_lut = render_device.create_bind_group_layout( + let sky_view_lut = BindGroupLayoutDescriptor::new( "sky_view_lut_bind_group_layout", &BindGroupLayoutEntries::with_indices( ShaderStages::COMPUTE, @@ -108,7 +107,7 @@ impl FromWorld for AtmosphereBindGroupLayouts { ), ); - let aerial_view_lut = render_device.create_bind_group_layout( + let aerial_view_lut = BindGroupLayoutDescriptor::new( "aerial_view_lut_bind_group_layout", &BindGroupLayoutEntries::with_indices( ShaderStages::COMPUTE, @@ -144,8 +143,7 @@ impl FromWorld for AtmosphereBindGroupLayouts { impl FromWorld for RenderSkyBindGroupLayouts { fn from_world(world: &mut World) -> Self { - let render_device = world.resource::(); - let render_sky = render_device.create_bind_group_layout( + let render_sky = BindGroupLayoutDescriptor::new( "render_sky_bind_group_layout", &BindGroupLayoutEntries::with_indices( ShaderStages::FRAGMENT, @@ -176,7 +174,7 @@ impl FromWorld for RenderSkyBindGroupLayouts { ), ); - let render_sky_msaa = render_device.create_bind_group_layout( + let render_sky_msaa = BindGroupLayoutDescriptor::new( "render_sky_msaa_bind_group_layout", &BindGroupLayoutEntries::with_indices( ShaderStages::FRAGMENT, @@ -578,7 +576,7 @@ pub(super) fn prepare_atmosphere_bind_groups( atmosphere_transforms: Res, atmosphere_uniforms: Res>, settings_uniforms: Res>, - + pipeline_cache: Res, mut commands: Commands, ) { if views.iter().len() == 0 { @@ -611,7 +609,7 @@ pub(super) fn prepare_atmosphere_bind_groups( for (entity, textures, view_depth_texture, msaa) in &views { let transmittance_lut = render_device.create_bind_group( "transmittance_lut_bind_group", - &layouts.transmittance_lut, + &pipeline_cache.get_bind_group_layout(layouts.transmittance_lut.clone()), &BindGroupEntries::with_indices(( (0, atmosphere_binding.clone()), (1, settings_binding.clone()), @@ -621,7 +619,7 @@ pub(super) fn prepare_atmosphere_bind_groups( let multiscattering_lut = render_device.create_bind_group( "multiscattering_lut_bind_group", - &layouts.multiscattering_lut, + &pipeline_cache.get_bind_group_layout(layouts.multiscattering_lut.clone()), &BindGroupEntries::with_indices(( (0, atmosphere_binding.clone()), (1, settings_binding.clone()), @@ -633,7 +631,7 @@ pub(super) fn prepare_atmosphere_bind_groups( let sky_view_lut = render_device.create_bind_group( "sky_view_lut_bind_group", - &layouts.sky_view_lut, + &pipeline_cache.get_bind_group_layout(layouts.sky_view_lut.clone()), &BindGroupEntries::with_indices(( (0, atmosphere_binding.clone()), (1, settings_binding.clone()), @@ -650,7 +648,7 @@ pub(super) fn prepare_atmosphere_bind_groups( let aerial_view_lut = render_device.create_bind_group( "sky_view_lut_bind_group", - &layouts.aerial_view_lut, + &pipeline_cache.get_bind_group_layout(layouts.aerial_view_lut.clone()), &BindGroupEntries::with_indices(( (0, atmosphere_binding.clone()), (1, settings_binding.clone()), @@ -666,11 +664,11 @@ pub(super) fn prepare_atmosphere_bind_groups( let render_sky = render_device.create_bind_group( "render_sky_bind_group", - if *msaa == Msaa::Off { - &render_sky_layouts.render_sky + &pipeline_cache.get_bind_group_layout(if *msaa == Msaa::Off { + render_sky_layouts.render_sky.clone() } else { - &render_sky_layouts.render_sky_msaa - }, + render_sky_layouts.render_sky_msaa.clone() + }), &BindGroupEntries::with_indices(( (0, atmosphere_binding.clone()), (1, settings_binding.clone()), diff --git a/crates/bevy_pbr/src/deferred/mod.rs b/crates/bevy_pbr/src/deferred/mod.rs index 2eee4303795b3..348aca0107ad8 100644 --- a/crates/bevy_pbr/src/deferred/mod.rs +++ b/crates/bevy_pbr/src/deferred/mod.rs @@ -26,7 +26,7 @@ use bevy_render::{ }, render_graph::{NodeRunError, RenderGraphContext, RenderGraphExt, ViewNode, ViewNodeRunner}, render_resource::{binding_types::uniform_buffer, *}, - renderer::{RenderContext, RenderDevice}, + renderer::RenderContext, view::{ExtractedView, ViewTarget, ViewUniformOffset}, Render, RenderApp, RenderSystems, }; @@ -182,7 +182,8 @@ impl ViewNode for DeferredOpaquePass3dPbrLightingNode { let bind_group_2 = render_context.render_device().create_bind_group( "deferred_lighting_layout_group_2", - &deferred_lighting_layout.bind_group_layout_2, + &pipeline_cache + .get_bind_group_layout(deferred_lighting_layout.bind_group_layout_2.clone()), &BindGroupEntries::single(deferred_lighting_pass_id_binding), ); @@ -228,7 +229,7 @@ impl ViewNode for DeferredOpaquePass3dPbrLightingNode { #[derive(Resource)] pub struct DeferredLightingLayout { mesh_pipeline: MeshPipeline, - bind_group_layout_2: BindGroupLayout, + bind_group_layout_2: BindGroupLayoutDescriptor, deferred_lighting_shader: Handle, } @@ -396,11 +397,10 @@ impl SpecializedRenderPipeline for DeferredLightingLayout { pub fn init_deferred_lighting_layout( mut commands: Commands, - render_device: Res, mesh_pipeline: Res, asset_server: Res, ) { - let layout = render_device.create_bind_group_layout( + let layout = BindGroupLayoutDescriptor::new( "deferred_lighting_layout", &BindGroupLayoutEntries::single( ShaderStages::VERTEX_FRAGMENT, diff --git a/crates/bevy_pbr/src/light_probe/generate.rs b/crates/bevy_pbr/src/light_probe/generate.rs index 8e87b2916372d..284de836190bd 100644 --- a/crates/bevy_pbr/src/light_probe/generate.rs +++ b/crates/bevy_pbr/src/light_probe/generate.rs @@ -30,7 +30,7 @@ use bevy_render::{ render_asset::RenderAssets, render_graph::{Node, NodeRunError, RenderGraphContext, RenderGraphExt, RenderLabel}, render_resource::{ - binding_types::*, AddressMode, BindGroup, BindGroupEntries, BindGroupLayout, + binding_types::*, AddressMode, BindGroup, BindGroupEntries, BindGroupLayoutDescriptor, BindGroupLayoutEntries, CachedComputePipelineId, ComputePassDescriptor, ComputePipelineDescriptor, DownlevelFlags, Extent3d, FilterMode, PipelineCache, Sampler, SamplerBindingType, SamplerDescriptor, ShaderStages, ShaderType, StorageTextureAccess, @@ -77,11 +77,11 @@ pub enum GeneratorNode { /// Stores the bind group layouts for the environment map generation pipelines #[derive(Resource)] pub struct GeneratorBindGroupLayouts { - pub downsampling_first: BindGroupLayout, - pub downsampling_second: BindGroupLayout, - pub radiance: BindGroupLayout, - pub irradiance: BindGroupLayout, - pub copy: BindGroupLayout, + pub downsampling_first: BindGroupLayoutDescriptor, + pub downsampling_second: BindGroupLayoutDescriptor, + pub radiance: BindGroupLayoutDescriptor, + pub irradiance: BindGroupLayoutDescriptor, + pub copy: BindGroupLayoutDescriptor, } /// Samplers for the environment map generation pipelines @@ -210,7 +210,7 @@ pub fn initialize_generated_environment_map_resources( // Bind group layouts let (downsampling_first, downsampling_second) = if combine_bind_group { // One big bind group layout containing all outputs 1–12 - let downsampling = render_device.create_bind_group_layout( + let downsampling = BindGroupLayoutDescriptor::new( "downsampling_bind_group_layout_combined", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -241,7 +241,7 @@ pub fn initialize_generated_environment_map_resources( } else { // Split layout: first pass outputs 1–6, second pass outputs 7–12 (input mip6 read-only) - let downsampling_first = render_device.create_bind_group_layout( + let downsampling_first = BindGroupLayoutDescriptor::new( "downsampling_first_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -260,7 +260,7 @@ pub fn initialize_generated_environment_map_resources( ), ); - let downsampling_second = render_device.create_bind_group_layout( + let downsampling_second = BindGroupLayoutDescriptor::new( "downsampling_second_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -281,7 +281,7 @@ pub fn initialize_generated_environment_map_resources( (downsampling_first, downsampling_second) }; - let radiance = render_device.create_bind_group_layout( + let radiance = BindGroupLayoutDescriptor::new( "radiance_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -300,7 +300,7 @@ pub fn initialize_generated_environment_map_resources( ), ); - let irradiance = render_device.create_bind_group_layout( + let irradiance = BindGroupLayoutDescriptor::new( "irradiance_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -319,7 +319,7 @@ pub fn initialize_generated_environment_map_resources( ), ); - let copy = render_device.create_bind_group_layout( + let copy = BindGroupLayoutDescriptor::new( "copy_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -595,6 +595,7 @@ pub fn prepare_generated_environment_map_bind_groups( With, >, render_device: Res, + pipeline_cache: Res, queue: Res, layouts: Res, samplers: Res, @@ -654,7 +655,7 @@ pub fn prepare_generated_environment_map_bind_groups( // Combined layout expects destinations 1–12 in both bind groups let bind_group = render_device.create_bind_group( "downsampling_bind_group_combined_first", - &layouts.downsampling_first, + &pipeline_cache.get_bind_group_layout(layouts.downsampling_first.clone()), &BindGroupEntries::sequential(( &samplers.linear, &downsampling_constants_buffer, @@ -687,7 +688,7 @@ pub fn prepare_generated_environment_map_bind_groups( // Split layout (current behavior) let first = render_device.create_bind_group( "downsampling_first_bind_group", - &layouts.downsampling_first, + &pipeline_cache.get_bind_group_layout(layouts.downsampling_first.clone()), &BindGroupEntries::sequential(( &samplers.linear, &downsampling_constants_buffer, @@ -703,7 +704,7 @@ pub fn prepare_generated_environment_map_bind_groups( let second = render_device.create_bind_group( "downsampling_second_bind_group", - &layouts.downsampling_second, + &pipeline_cache.get_bind_group_layout(layouts.downsampling_second.clone()), &BindGroupEntries::sequential(( &samplers.linear, &downsampling_constants_buffer, @@ -756,7 +757,7 @@ pub fn prepare_generated_environment_map_bind_groups( ); let bind_group = render_device.create_bind_group( Some(format!("radiance_bind_group_mip_{mip}").as_str()), - &layouts.radiance, + &pipeline_cache.get_bind_group_layout(layouts.radiance.clone()), &BindGroupEntries::sequential(( &textures.environment_map.default_view, &samplers.linear, @@ -793,7 +794,7 @@ pub fn prepare_generated_environment_map_bind_groups( let irradiance_bind_group = render_device.create_bind_group( "irradiance_bind_group", - &layouts.irradiance, + &pipeline_cache.get_bind_group_layout(layouts.irradiance.clone()), &BindGroupEntries::sequential(( &textures.environment_map.default_view, &samplers.linear, @@ -816,7 +817,7 @@ pub fn prepare_generated_environment_map_bind_groups( let copy_bind_group = render_device.create_bind_group( "copy_bind_group", - &layouts.copy, + &pipeline_cache.get_bind_group_layout(layouts.copy.clone()), &BindGroupEntries::with_indices(((0, &src_view), (1, &dst_view))), ); diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index c6e7ac597c7a6..356db5b36ce2a 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -412,7 +412,7 @@ fn add_material_bind_group_allocator( material_uses_bindless_resources::(&render_device) .then(|| M::bindless_descriptor()) .flatten(), - M::bind_group_layout(&render_device), + M::bind_group_layout_descriptor(), M::bindless_slot_count(), ), ); @@ -1409,7 +1409,7 @@ pub struct MaterialProperties { /// rendering to take place in a separate [`Transmissive3d`] pass. pub reads_view_transmission_texture: bool, pub render_phase_type: RenderPhaseType, - pub material_layout: Option, + pub material_layout: Option, /// Backing array is a size of 4 because the `StandardMaterial` needs 4 draw functions by default pub draw_functions: SmallVec<[(InternedDrawFunctionLabel, DrawFunctionId); 4]>, /// Backing array is a size of 3 because the `StandardMaterial` has 3 custom shaders (`frag`, `prepass_frag`, `deferred_frag`) which is the @@ -1498,6 +1498,7 @@ where type Param = ( SRes, + SRes, SRes, SResMut, SResMut, @@ -1523,6 +1524,7 @@ where material_id: AssetId, ( render_device, + pipeline_cache, default_opaque_render_method, bind_group_allocators, render_material_bindings, @@ -1539,7 +1541,7 @@ where (shadows_enabled, prepass_enabled, material_param), ): &mut SystemParamItem, ) -> Result> { - let material_layout = M::bind_group_layout(render_device); + let material_layout = M::bind_group_layout_descriptor(); let shadows_enabled = shadows_enabled.is_some(); let prepass_enabled = prepass_enabled.is_some(); @@ -1674,8 +1676,14 @@ where ) } - match material.unprepared_bind_group(&material_layout, render_device, material_param, false) - { + let actual_material_layout = pipeline_cache.get_bind_group_layout(material_layout.clone()); + + match material.unprepared_bind_group( + &actual_material_layout, + render_device, + material_param, + false, + ) { Ok(unprepared) => { let bind_group_allocator = bind_group_allocators.get_mut(&TypeId::of::()).unwrap(); @@ -1727,7 +1735,12 @@ where // and is requesting a fully-custom bind group. Invoke // `as_bind_group` as requested, and store the resulting bind // group in the slot. - match material.as_bind_group(&material_layout, render_device, material_param) { + match material.as_bind_group( + &material_layout, + render_device, + pipeline_cache, + material_param, + ) { Ok(prepared_bind_group) => { let bind_group_allocator = bind_group_allocators.get_mut(&TypeId::of::()).unwrap(); @@ -1771,7 +1784,7 @@ where fn unload_asset( source_asset: AssetId, - (_, _, bind_group_allocators, render_material_bindings, ..): &mut SystemParamItem< + (_, _, _, bind_group_allocators, render_material_bindings, ..): &mut SystemParamItem< Self::Param, >, ) { @@ -1789,11 +1802,17 @@ where pub fn prepare_material_bind_groups( mut allocators: ResMut, render_device: Res, + pipeline_cache: Res, fallback_image: Res, fallback_resources: Res, ) { for (_, allocator) in allocators.iter_mut() { - allocator.prepare_bind_groups(&render_device, &fallback_resources, &fallback_image); + allocator.prepare_bind_groups( + &render_device, + &pipeline_cache, + &fallback_resources, + &fallback_image, + ); } } diff --git a/crates/bevy_pbr/src/material_bind_groups.rs b/crates/bevy_pbr/src/material_bind_groups.rs index 0851760bbfd03..5949bb81c2c8d 100644 --- a/crates/bevy_pbr/src/material_bind_groups.rs +++ b/crates/bevy_pbr/src/material_bind_groups.rs @@ -12,10 +12,10 @@ use bevy_ecs::{ }; use bevy_platform::collections::{HashMap, HashSet}; use bevy_reflect::{prelude::ReflectDefault, Reflect}; -use bevy_render::render_resource::BindlessSlabResourceLimit; +use bevy_render::render_resource::{BindlessSlabResourceLimit, PipelineCache}; use bevy_render::{ render_resource::{ - BindGroup, BindGroupEntry, BindGroupLayout, BindingNumber, BindingResource, + BindGroup, BindGroupEntry, BindGroupLayoutDescriptor, BindingNumber, BindingResource, BindingResources, BindlessDescriptor, BindlessIndex, BindlessIndexTableDescriptor, BindlessResourceType, Buffer, BufferBinding, BufferDescriptor, BufferId, BufferInitDescriptor, BufferUsages, CompareFunction, FilterMode, OwnedBindingResource, @@ -56,7 +56,7 @@ pub struct MaterialBindGroupBindlessAllocator { /// The slabs, each of which contains a bind group. slabs: Vec, /// The layout of the bind groups that we produce. - bind_group_layout: BindGroupLayout, + bind_group_layout: BindGroupLayoutDescriptor, /// Information about the bindless resources in the material. /// /// We use this information to create and maintain bind groups. @@ -201,7 +201,7 @@ enum MaterialNonBindlessAllocatedBindGroup { /// The unprepared bind group, including extra data. bind_group: UnpreparedBindGroup, /// The layout of that bind group. - layout: BindGroupLayout, + layout: BindGroupLayoutDescriptor, }, /// A bind group that's already been prepared. Prepared { @@ -459,7 +459,7 @@ impl MaterialBindGroupAllocator { render_device: &RenderDevice, label: Option<&'static str>, bindless_descriptor: Option, - bind_group_layout: BindGroupLayout, + bind_group_layout: BindGroupLayoutDescriptor, slab_capacity: Option, ) -> MaterialBindGroupAllocator { if let Some(bindless_descriptor) = bindless_descriptor { @@ -500,7 +500,7 @@ impl MaterialBindGroupAllocator { pub fn allocate_unprepared( &mut self, unprepared_bind_group: UnpreparedBindGroup, - bind_group_layout: &BindGroupLayout, + bind_group_layout: &BindGroupLayoutDescriptor, ) -> MaterialBindingId { match *self { MaterialBindGroupAllocator::Bindless( @@ -558,6 +558,7 @@ impl MaterialBindGroupAllocator { pub fn prepare_bind_groups( &mut self, render_device: &RenderDevice, + pipeline_cache: &PipelineCache, fallback_bindless_resources: &FallbackBindlessResources, fallback_image: &FallbackImage, ) { @@ -566,12 +567,14 @@ impl MaterialBindGroupAllocator { ref mut material_bind_group_bindless_allocator, ) => material_bind_group_bindless_allocator.prepare_bind_groups( render_device, + pipeline_cache, fallback_bindless_resources, fallback_image, ), MaterialBindGroupAllocator::NonBindless( ref mut material_bind_group_non_bindless_allocator, - ) => material_bind_group_non_bindless_allocator.prepare_bind_groups(render_device), + ) => material_bind_group_non_bindless_allocator + .prepare_bind_groups(render_device, pipeline_cache), } } @@ -729,7 +732,7 @@ impl MaterialBindGroupBindlessAllocator { render_device: &RenderDevice, label: Option<&'static str>, bindless_descriptor: BindlessDescriptor, - bind_group_layout: BindGroupLayout, + bind_group_layout: BindGroupLayoutDescriptor, slab_capacity: Option, ) -> MaterialBindGroupBindlessAllocator { let fallback_buffers = bindless_descriptor @@ -829,12 +832,14 @@ impl MaterialBindGroupBindlessAllocator { fn prepare_bind_groups( &mut self, render_device: &RenderDevice, + pipeline_cache: &PipelineCache, fallback_bindless_resources: &FallbackBindlessResources, fallback_image: &FallbackImage, ) { for slab in &mut self.slabs { slab.prepare( render_device, + pipeline_cache, self.label, &self.bind_group_layout, fallback_bindless_resources, @@ -1160,8 +1165,9 @@ impl MaterialBindlessSlab { fn prepare( &mut self, render_device: &RenderDevice, + pipeline_cache: &PipelineCache, label: Option<&'static str>, - bind_group_layout: &BindGroupLayout, + bind_group_layout: &BindGroupLayoutDescriptor, fallback_bindless_resources: &FallbackBindlessResources, fallback_buffers: &HashMap, fallback_image: &FallbackImage, @@ -1181,6 +1187,7 @@ impl MaterialBindlessSlab { // Create the bind group if needed. self.prepare_bind_group( render_device, + pipeline_cache, label, bind_group_layout, fallback_bindless_resources, @@ -1196,8 +1203,9 @@ impl MaterialBindlessSlab { fn prepare_bind_group( &mut self, render_device: &RenderDevice, + pipeline_cache: &PipelineCache, label: Option<&'static str>, - bind_group_layout: &BindGroupLayout, + bind_group_layout: &BindGroupLayoutDescriptor, fallback_bindless_resources: &FallbackBindlessResources, fallback_buffers: &HashMap, fallback_image: &FallbackImage, @@ -1263,8 +1271,11 @@ impl MaterialBindlessSlab { }); } - self.bind_group = - Some(render_device.create_bind_group(label, bind_group_layout, &bind_group_entries)); + self.bind_group = Some(render_device.create_bind_group( + label, + &pipeline_cache.get_bind_group_layout(bind_group_layout.clone()), + &bind_group_entries, + )); } /// Writes any buffers that we're managing to the GPU. @@ -1810,7 +1821,7 @@ impl MaterialBindGroupNonBindlessAllocator { fn allocate_unprepared( &mut self, unprepared_bind_group: UnpreparedBindGroup, - bind_group_layout: BindGroupLayout, + bind_group_layout: BindGroupLayoutDescriptor, ) -> MaterialBindingId { self.allocate(MaterialNonBindlessAllocatedBindGroup::Unprepared { bind_group: unprepared_bind_group, @@ -1856,7 +1867,11 @@ impl MaterialBindGroupNonBindlessAllocator { /// Unprepared bind groups can be added to this allocator with /// [`Self::allocate_unprepared`]. Such bind groups will defer being /// prepared until the next time this method is called. - fn prepare_bind_groups(&mut self, render_device: &RenderDevice) { + fn prepare_bind_groups( + &mut self, + render_device: &RenderDevice, + pipeline_cache: &PipelineCache, + ) { for bind_group_index in mem::take(&mut self.to_prepare) { let Some(MaterialNonBindlessAllocatedBindGroup::Unprepared { bind_group: unprepared_bind_group, @@ -1905,7 +1920,7 @@ impl MaterialBindGroupNonBindlessAllocator { // Create the bind group. let bind_group = render_device.create_bind_group( self.label, - &bind_group_layout, + &pipeline_cache.get_bind_group_layout(bind_group_layout.clone()), &bind_group_entries, ); diff --git a/crates/bevy_pbr/src/meshlet/resource_manager.rs b/crates/bevy_pbr/src/meshlet/resource_manager.rs index 927e2bc88b67d..ce7b9edda3b14 100644 --- a/crates/bevy_pbr/src/meshlet/resource_manager.rs +++ b/crates/bevy_pbr/src/meshlet/resource_manager.rs @@ -134,7 +134,7 @@ impl ResourceManager { previous_depth_pyramids: EntityHashMap::default(), // TODO: Buffer min sizes - clear_visibility_buffer_bind_group_layout: render_device.create_bind_group_layout( + clear_visibility_buffer_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_clear_visibility_buffer_bind_group_layout", &BindGroupLayoutEntries::single( ShaderStages::COMPUTE, @@ -149,7 +149,7 @@ impl ResourceManager { texture_storage_2d(TextureFormat::R32Uint, StorageTextureAccess::WriteOnly), ), ), - first_instance_cull_bind_group_layout: render_device.create_bind_group_layout( + first_instance_cull_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_first_instance_culling_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -170,7 +170,7 @@ impl ResourceManager { ), ), ), - second_instance_cull_bind_group_layout: render_device.create_bind_group_layout( + second_instance_cull_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_second_instance_culling_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -190,7 +190,7 @@ impl ResourceManager { ), ), ), - first_bvh_cull_bind_group_layout: render_device.create_bind_group_layout( + first_bvh_cull_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_first_bvh_culling_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -215,7 +215,7 @@ impl ResourceManager { ), ), ), - second_bvh_cull_bind_group_layout: render_device.create_bind_group_layout( + second_bvh_cull_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_second_bvh_culling_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -237,7 +237,7 @@ impl ResourceManager { ), ), ), - first_meshlet_cull_bind_group_layout: render_device.create_bind_group_layout( + first_meshlet_cull_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_first_meshlet_culling_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -258,7 +258,7 @@ impl ResourceManager { ), ), ), - second_meshlet_cull_bind_group_layout: render_device.create_bind_group_layout( + second_meshlet_cull_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_second_meshlet_culling_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -277,7 +277,7 @@ impl ResourceManager { ), ), ), - downsample_depth_bind_group_layout: render_device.create_bind_group_layout( + downsample_depth_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_downsample_depth_bind_group_layout", &BindGroupLayoutEntries::sequential(ShaderStages::COMPUTE, { let write_only_r32float = || { @@ -304,7 +304,7 @@ impl ResourceManager { ) }), ), - downsample_depth_shadow_view_bind_group_layout: render_device.create_bind_group_layout( + downsample_depth_shadow_view_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_downsample_depth_shadow_view_bind_group_layout", &BindGroupLayoutEntries::sequential(ShaderStages::COMPUTE, { let write_only_r32float = || { @@ -331,7 +331,7 @@ impl ResourceManager { ) }), ), - visibility_buffer_raster_bind_group_layout: render_device.create_bind_group_layout( + visibility_buffer_raster_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_visibility_buffer_raster_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT | ShaderStages::VERTEX | ShaderStages::COMPUTE, @@ -369,21 +369,21 @@ impl ResourceManager { ), ), ), - resolve_depth_bind_group_layout: render_device.create_bind_group_layout( + resolve_depth_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_resolve_depth_bind_group_layout", &BindGroupLayoutEntries::single( ShaderStages::FRAGMENT, texture_storage_2d(TextureFormat::R64Uint, StorageTextureAccess::ReadOnly), ), ), - resolve_depth_shadow_view_bind_group_layout: render_device.create_bind_group_layout( + resolve_depth_shadow_view_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_resolve_depth_shadow_view_bind_group_layout", &BindGroupLayoutEntries::single( ShaderStages::FRAGMENT, texture_storage_2d(TextureFormat::R32Uint, StorageTextureAccess::ReadOnly), ), ), - resolve_material_depth_bind_group_layout: render_device.create_bind_group_layout( + resolve_material_depth_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_resolve_material_depth_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, @@ -394,7 +394,7 @@ impl ResourceManager { ), ), ), - material_shade_bind_group_layout: render_device.create_bind_group_layout( + material_shade_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_mesh_material_shade_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, @@ -411,7 +411,7 @@ impl ResourceManager { ), ), fill_counts_bind_group_layout: if needs_dispatch_remap { - render_device.create_bind_group_layout( + BindGroupLayoutDescriptor::new( "meshlet_fill_counts_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -424,7 +424,7 @@ impl ResourceManager { ), ) } else { - render_device.create_bind_group_layout( + BindGroupLayoutDescriptor::new( "meshlet_fill_counts_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -437,7 +437,7 @@ impl ResourceManager { ) }, remap_1d_to_2d_dispatch_bind_group_layout: needs_dispatch_remap.then(|| { - render_device.create_bind_group_layout( + BindGroupLayoutDescriptor::new( "meshlet_remap_1d_to_2d_dispatch_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, diff --git a/crates/bevy_pbr/src/prepass/mod.rs b/crates/bevy_pbr/src/prepass/mod.rs index 69113359f5808..7c7e36d5d168e 100644 --- a/crates/bevy_pbr/src/prepass/mod.rs +++ b/crates/bevy_pbr/src/prepass/mod.rs @@ -247,10 +247,10 @@ pub fn update_mesh_previous_global_transforms( #[derive(Resource, Clone)] pub struct PrepassPipeline { - pub view_layout_motion_vectors: BindGroupLayout, - pub view_layout_no_motion_vectors: BindGroupLayout, + pub view_layout_motion_vectors: BindGroupLayoutDescriptor, + pub view_layout_no_motion_vectors: BindGroupLayoutDescriptor, pub mesh_layouts: MeshLayouts, - pub empty_layout: BindGroupLayout, + pub empty_layout: BindGroupLayoutDescriptor, pub default_prepass_shader: Handle, /// Whether skins will use uniform buffers on account of storage buffers @@ -276,7 +276,7 @@ pub fn init_prepass_pipeline( let visibility_ranges_buffer_binding_type = render_device.get_supported_read_only_binding_type(VISIBILITY_RANGES_STORAGE_BUFFER_COUNT); - let view_layout_motion_vectors = render_device.create_bind_group_layout( + let view_layout_motion_vectors = BindGroupLayoutDescriptor::new( "prepass_view_layout_motion_vectors", &BindGroupLayoutEntries::with_indices( ShaderStages::VERTEX_FRAGMENT, @@ -301,7 +301,7 @@ pub fn init_prepass_pipeline( ), ); - let view_layout_no_motion_vectors = render_device.create_bind_group_layout( + let view_layout_no_motion_vectors = BindGroupLayoutDescriptor::new( "prepass_view_layout_no_motion_vectors", &BindGroupLayoutEntries::with_indices( ShaderStages::VERTEX_FRAGMENT, @@ -335,7 +335,7 @@ pub fn init_prepass_pipeline( skins_use_uniform_buffers: skin::skins_use_uniform_buffers(&render_device), depth_clip_control_supported, binding_arrays_are_usable: binding_arrays_are_usable(&render_device, &render_adapter), - empty_layout: render_device.create_bind_group_layout("prepass_empty_layout", &[]), + empty_layout: BindGroupLayoutDescriptor::new("prepass_empty_layout", &[]), material_pipeline: material_pipeline.clone(), }); } @@ -702,11 +702,12 @@ pub struct PrepassViewBindGroup { pub fn init_prepass_view_bind_group( mut commands: Commands, render_device: Res, + pipeline_cache: Res, pipeline: Res, ) { let empty_bind_group = render_device.create_bind_group( "prepass_view_empty_bind_group", - &pipeline.empty_layout, + &pipeline_cache.get_bind_group_layout(pipeline.empty_layout.clone()), &[], ); commands.insert_resource(PrepassViewBindGroup { @@ -718,6 +719,7 @@ pub fn init_prepass_view_bind_group( pub fn prepare_prepass_view_bind_group( render_device: Res, + pipeline_cache: Res, prepass_pipeline: Res, view_uniforms: Res, globals_buffer: Res, @@ -730,27 +732,33 @@ pub fn prepare_prepass_view_bind_group( globals_buffer.buffer.binding(), visibility_ranges.buffer().buffer(), ) { - prepass_view_bind_group.no_motion_vectors = Some(render_device.create_bind_group( - "prepass_view_no_motion_vectors_bind_group", - &prepass_pipeline.view_layout_no_motion_vectors, - &BindGroupEntries::with_indices(( - (0, view_binding.clone()), - (1, globals_binding.clone()), - (14, visibility_ranges_buffer.as_entire_binding()), - )), - )); - - if let Some(previous_view_uniforms_binding) = previous_view_uniforms.uniforms.binding() { - prepass_view_bind_group.motion_vectors = Some(render_device.create_bind_group( - "prepass_view_motion_vectors_bind_group", - &prepass_pipeline.view_layout_motion_vectors, + prepass_view_bind_group.no_motion_vectors = Some( + render_device.create_bind_group( + "prepass_view_no_motion_vectors_bind_group", + &pipeline_cache + .get_bind_group_layout(prepass_pipeline.view_layout_no_motion_vectors.clone()), &BindGroupEntries::with_indices(( - (0, view_binding), - (1, globals_binding), - (2, previous_view_uniforms_binding), + (0, view_binding.clone()), + (1, globals_binding.clone()), (14, visibility_ranges_buffer.as_entire_binding()), )), - )); + ), + ); + + if let Some(previous_view_uniforms_binding) = previous_view_uniforms.uniforms.binding() { + prepass_view_bind_group.motion_vectors = Some( + render_device.create_bind_group( + "prepass_view_motion_vectors_bind_group", + &pipeline_cache + .get_bind_group_layout(prepass_pipeline.view_layout_motion_vectors.clone()), + &BindGroupEntries::with_indices(( + (0, view_binding), + (1, globals_binding), + (2, previous_view_uniforms_binding), + (14, visibility_ranges_buffer.as_entire_binding()), + )), + ), + ); } } } diff --git a/crates/bevy_pbr/src/render/gpu_preprocess.rs b/crates/bevy_pbr/src/render/gpu_preprocess.rs index 54ac96242e41e..1410e989bc55c 100644 --- a/crates/bevy_pbr/src/render/gpu_preprocess.rs +++ b/crates/bevy_pbr/src/render/gpu_preprocess.rs @@ -40,8 +40,8 @@ use bevy_render::{ render_graph::{Node, NodeRunError, RenderGraphContext, RenderGraphExt}, render_resource::{ binding_types::{storage_buffer, storage_buffer_read_only, texture_2d, uniform_buffer}, - BindGroup, BindGroupEntries, BindGroupLayout, BindingResource, Buffer, BufferBinding, - CachedComputePipelineId, ComputePassDescriptor, ComputePipelineDescriptor, + BindGroup, BindGroupEntries, BindGroupLayoutDescriptor, BindingResource, Buffer, + BufferBinding, CachedComputePipelineId, ComputePassDescriptor, ComputePipelineDescriptor, DynamicBindGroupLayoutEntries, PipelineCache, PushConstantRange, RawBufferVec, ShaderStages, ShaderType, SpecializedComputePipeline, SpecializedComputePipelines, TextureSampleType, UninitBufferVec, @@ -244,7 +244,7 @@ pub struct PreprocessPhasePipelines { /// The pipeline for the GPU mesh preprocessing shader. pub struct PreprocessPipeline { /// The bind group layout for the compute shader. - pub bind_group_layout: BindGroupLayout, + pub bind_group_layout: BindGroupLayoutDescriptor, /// The shader asset handle. pub shader: Handle, /// The pipeline ID for the compute shader. @@ -260,7 +260,7 @@ pub struct PreprocessPipeline { #[derive(Clone)] pub struct ResetIndirectBatchSetsPipeline { /// The bind group layout for the compute shader. - pub bind_group_layout: BindGroupLayout, + pub bind_group_layout: BindGroupLayoutDescriptor, /// The shader asset handle. pub shader: Handle, /// The pipeline ID for the compute shader. @@ -273,7 +273,7 @@ pub struct ResetIndirectBatchSetsPipeline { #[derive(Clone)] pub struct BuildIndirectParametersPipeline { /// The bind group layout for the compute shader. - pub bind_group_layout: BindGroupLayout, + pub bind_group_layout: BindGroupLayoutDescriptor, /// The shader asset handle. pub shader: Handle, /// The pipeline ID for the compute shader. @@ -1299,8 +1299,6 @@ impl SpecializedComputePipeline for PreprocessPipeline { impl FromWorld for PreprocessPipelines { fn from_world(world: &mut World) -> Self { - let render_device = world.resource::(); - // GPU culling bind group parameters are a superset of those in the CPU // culling (direct) shader. let direct_bind_group_layout_entries = preprocess_direct_bind_group_layout_entries(); @@ -1329,36 +1327,34 @@ impl FromWorld for PreprocessPipelines { .extend_sequential((storage_buffer::(false),)); // Create the bind group layouts. - let direct_bind_group_layout = render_device.create_bind_group_layout( + let direct_bind_group_layout = BindGroupLayoutDescriptor::new( "build mesh uniforms direct bind group layout", &direct_bind_group_layout_entries, ); - let gpu_frustum_culling_bind_group_layout = render_device.create_bind_group_layout( + let gpu_frustum_culling_bind_group_layout = BindGroupLayoutDescriptor::new( "build mesh uniforms GPU frustum culling bind group layout", &gpu_frustum_culling_bind_group_layout_entries, ); - let gpu_early_occlusion_culling_bind_group_layout = render_device.create_bind_group_layout( + let gpu_early_occlusion_culling_bind_group_layout = BindGroupLayoutDescriptor::new( "build mesh uniforms GPU early occlusion culling bind group layout", &gpu_early_occlusion_culling_bind_group_layout_entries, ); - let gpu_late_occlusion_culling_bind_group_layout = render_device.create_bind_group_layout( + let gpu_late_occlusion_culling_bind_group_layout = BindGroupLayoutDescriptor::new( "build mesh uniforms GPU late occlusion culling bind group layout", &gpu_late_occlusion_culling_bind_group_layout_entries, ); - let reset_indirect_batch_sets_bind_group_layout = render_device.create_bind_group_layout( + let reset_indirect_batch_sets_bind_group_layout = BindGroupLayoutDescriptor::new( "reset indirect batch sets bind group layout", &reset_indirect_batch_sets_bind_group_layout_entries, ); - let build_indexed_indirect_params_bind_group_layout = render_device - .create_bind_group_layout( - "build indexed indirect parameters bind group layout", - &build_indexed_indirect_params_bind_group_layout_entries, - ); - let build_non_indexed_indirect_params_bind_group_layout = render_device - .create_bind_group_layout( - "build non-indexed indirect parameters bind group layout", - &build_non_indexed_indirect_params_bind_group_layout_entries, - ); + let build_indexed_indirect_params_bind_group_layout = BindGroupLayoutDescriptor::new( + "build indexed indirect parameters bind group layout", + &build_indexed_indirect_params_bind_group_layout_entries, + ); + let build_non_indexed_indirect_params_bind_group_layout = BindGroupLayoutDescriptor::new( + "build non-indexed indirect parameters bind group layout", + &build_non_indexed_indirect_params_bind_group_layout_entries, + ); let preprocess_shader = load_embedded_asset!(world, "mesh_preprocess.wgsl"); let reset_indirect_batch_sets_shader = @@ -1753,6 +1749,7 @@ pub fn prepare_preprocess_bind_groups( views: Query<(Entity, &ExtractedView)>, view_depth_pyramids: Query<(&ViewDepthPyramid, &PreviousViewUniformOffset)>, render_device: Res, + pipeline_cache: Res, batched_instance_buffers: Res>, indirect_parameters_buffers: Res, mesh_culling_data_buffer: Res, @@ -1812,6 +1809,7 @@ pub fn prepare_preprocess_bind_groups( late_indexed_indirect_parameters_buffer, late_non_indexed_indirect_parameters_buffer, render_device: &render_device, + pipeline_cache: &pipeline_cache, phase_indirect_parameters_buffers, mesh_culling_data_buffer: &mesh_culling_data_buffer, view_uniforms: &view_uniforms, @@ -1879,6 +1877,7 @@ pub fn prepare_preprocess_bind_groups( create_build_indirect_parameters_bind_groups( &mut commands, &render_device, + &pipeline_cache, &pipelines, current_input_buffer, &indirect_parameters_buffers, @@ -1901,6 +1900,8 @@ struct PreprocessBindGroupBuilder<'a> { &'a RawBufferVec, /// The device. render_device: &'a RenderDevice, + /// The pipeline cache + pipeline_cache: &'a PipelineCache, /// The buffers that store indirect draw parameters. phase_indirect_parameters_buffers: &'a UntypedPhaseIndirectParametersBuffers, /// The GPU buffer that stores the information needed to cull each mesh. @@ -1943,7 +1944,9 @@ impl<'a> PreprocessBindGroupBuilder<'a> { Some(PhasePreprocessBindGroups::Direct( self.render_device.create_bind_group( "preprocess_direct_bind_group", - &self.pipelines.direct_preprocess.bind_group_layout, + &self.pipeline_cache.get_bind_group_layout( + self.pipelines.direct_preprocess.bind_group_layout.clone(), + ), &BindGroupEntries::with_indices(( (0, self.view_uniforms.uniforms.binding()?), (3, self.current_input_buffer.as_entire_binding()), @@ -2052,10 +2055,12 @@ impl<'a> PreprocessBindGroupBuilder<'a> { Some( self.render_device.create_bind_group( "preprocess_early_indexed_gpu_occlusion_culling_bind_group", - &self - .pipelines - .early_gpu_occlusion_culling_preprocess - .bind_group_layout, + &self.pipeline_cache.get_bind_group_layout( + self.pipelines + .early_gpu_occlusion_culling_preprocess + .bind_group_layout + .clone(), + ), &BindGroupEntries::with_indices(( (3, self.current_input_buffer.as_entire_binding()), (4, self.previous_input_buffer.as_entire_binding()), @@ -2150,10 +2155,12 @@ impl<'a> PreprocessBindGroupBuilder<'a> { Some( self.render_device.create_bind_group( "preprocess_early_non_indexed_gpu_occlusion_culling_bind_group", - &self - .pipelines - .early_gpu_occlusion_culling_preprocess - .bind_group_layout, + &self.pipeline_cache.get_bind_group_layout( + self.pipelines + .early_gpu_occlusion_culling_preprocess + .bind_group_layout + .clone(), + ), &BindGroupEntries::with_indices(( (3, self.current_input_buffer.as_entire_binding()), (4, self.previous_input_buffer.as_entire_binding()), @@ -2245,10 +2252,12 @@ impl<'a> PreprocessBindGroupBuilder<'a> { Some( self.render_device.create_bind_group( "preprocess_late_indexed_gpu_occlusion_culling_bind_group", - &self - .pipelines - .late_gpu_occlusion_culling_preprocess - .bind_group_layout, + &self.pipeline_cache.get_bind_group_layout( + self.pipelines + .late_gpu_occlusion_culling_preprocess + .bind_group_layout + .clone(), + ), &BindGroupEntries::with_indices(( (3, self.current_input_buffer.as_entire_binding()), (4, self.previous_input_buffer.as_entire_binding()), @@ -2332,10 +2341,12 @@ impl<'a> PreprocessBindGroupBuilder<'a> { Some( self.render_device.create_bind_group( "preprocess_late_non_indexed_gpu_occlusion_culling_bind_group", - &self - .pipelines - .late_gpu_occlusion_culling_preprocess - .bind_group_layout, + &self.pipeline_cache.get_bind_group_layout( + self.pipelines + .late_gpu_occlusion_culling_preprocess + .bind_group_layout + .clone(), + ), &BindGroupEntries::with_indices(( (3, self.current_input_buffer.as_entire_binding()), (4, self.previous_input_buffer.as_entire_binding()), @@ -2430,10 +2441,12 @@ impl<'a> PreprocessBindGroupBuilder<'a> { Some( self.render_device.create_bind_group( "preprocess_gpu_indexed_frustum_culling_bind_group", - &self - .pipelines - .gpu_frustum_culling_preprocess - .bind_group_layout, + &self.pipeline_cache.get_bind_group_layout( + self.pipelines + .gpu_frustum_culling_preprocess + .bind_group_layout + .clone(), + ), &BindGroupEntries::with_indices(( (3, self.current_input_buffer.as_entire_binding()), (4, self.previous_input_buffer.as_entire_binding()), @@ -2493,10 +2506,12 @@ impl<'a> PreprocessBindGroupBuilder<'a> { Some( self.render_device.create_bind_group( "preprocess_gpu_non_indexed_frustum_culling_bind_group", - &self - .pipelines - .gpu_frustum_culling_preprocess - .bind_group_layout, + &self.pipeline_cache.get_bind_group_layout( + self.pipelines + .gpu_frustum_culling_preprocess + .bind_group_layout + .clone(), + ), &BindGroupEntries::with_indices(( (3, self.current_input_buffer.as_entire_binding()), (4, self.previous_input_buffer.as_entire_binding()), @@ -2528,6 +2543,7 @@ impl<'a> PreprocessBindGroupBuilder<'a> { fn create_build_indirect_parameters_bind_groups( commands: &mut Commands, render_device: &RenderDevice, + pipeline_cache: &PipelineCache, pipelines: &PreprocessPipelines, current_input_buffer: &Buffer, indirect_parameters_buffers: &IndirectParametersBuffers, @@ -2547,10 +2563,13 @@ fn create_build_indirect_parameters_bind_groups( "reset_indexed_indirect_batch_sets_bind_group", // The early bind group is good for the main phase and late // phase too. They bind the same buffers. - &pipelines - .early_phase - .reset_indirect_batch_sets - .bind_group_layout, + &pipeline_cache.get_bind_group_layout( + pipelines + .early_phase + .reset_indirect_batch_sets + .bind_group_layout + .clone(), + ), &BindGroupEntries::sequential(( indexed_batch_sets_buffer.as_entire_binding(), )), @@ -2568,10 +2587,13 @@ fn create_build_indirect_parameters_bind_groups( "reset_non_indexed_indirect_batch_sets_bind_group", // The early bind group is good for the main phase and late // phase too. They bind the same buffers. - &pipelines - .early_phase - .reset_indirect_batch_sets - .bind_group_layout, + &pipeline_cache.get_bind_group_layout( + pipelines + .early_phase + .reset_indirect_batch_sets + .bind_group_layout + .clone(), + ), &BindGroupEntries::sequential(( non_indexed_batch_sets_buffer.as_entire_binding(), )), @@ -2600,9 +2622,12 @@ fn create_build_indirect_parameters_bind_groups( "build_indexed_indirect_parameters_bind_group", // The frustum culling bind group is good for occlusion culling // too. They bind the same buffers. - &pipelines - .gpu_frustum_culling_build_indexed_indirect_params - .bind_group_layout, + &pipeline_cache.get_bind_group_layout( + pipelines + .gpu_frustum_culling_build_indexed_indirect_params + .bind_group_layout + .clone(), + ), &BindGroupEntries::sequential(( current_input_buffer.as_entire_binding(), // Don't use `as_entire_binding` here; the shader reads @@ -2655,9 +2680,12 @@ fn create_build_indirect_parameters_bind_groups( "build_non_indexed_indirect_parameters_bind_group", // The frustum culling bind group is good for occlusion culling // too. They bind the same buffers. - &pipelines - .gpu_frustum_culling_build_non_indexed_indirect_params - .bind_group_layout, + &pipeline_cache.get_bind_group_layout( + pipelines + .gpu_frustum_culling_build_non_indexed_indirect_params + .bind_group_layout + .clone(), + ), &BindGroupEntries::sequential(( current_input_buffer.as_entire_binding(), // Don't use `as_entire_binding` here; the shader reads diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index ce511c2fed791..1ef120403e711 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -2227,7 +2227,7 @@ pub fn setup_morph_and_skinning_defs( shader_defs: &mut Vec, vertex_attributes: &mut Vec, skins_use_uniform_buffers: bool, -) -> BindGroupLayout { +) -> BindGroupLayoutDescriptor { let is_morphed = key.intersects(MeshPipelineKey::MORPH_TARGETS); let is_lightmapped = key.intersects(MeshPipelineKey::LIGHTMAPPED); let motion_vector_prepass = key.intersects(MeshPipelineKey::MOTION_VECTOR_PREPASS); @@ -2722,6 +2722,7 @@ pub fn prepare_mesh_bind_groups( meshes: Res>, mesh_pipeline: Res, render_device: Res, + pipeline_cache: Res, cpu_batched_instance_buffer: Option< Res>, >, @@ -2744,6 +2745,7 @@ pub fn prepare_mesh_bind_groups( &meshes, &mesh_pipeline, &render_device, + &pipeline_cache, &skins_uniform, &weights_uniform, &mut render_lightmaps, @@ -2774,6 +2776,7 @@ pub fn prepare_mesh_bind_groups( &meshes, &mesh_pipeline, &render_device, + &pipeline_cache, &skins_uniform, &weights_uniform, &mut render_lightmaps, @@ -2794,6 +2797,7 @@ fn prepare_mesh_bind_groups_for_phase( meshes: &RenderAssets, mesh_pipeline: &MeshPipeline, render_device: &RenderDevice, + pipeline_cache: &PipelineCache, skins_uniform: &SkinUniforms, weights_uniform: &MorphUniforms, render_lightmaps: &mut RenderLightmaps, @@ -2802,7 +2806,7 @@ fn prepare_mesh_bind_groups_for_phase( // TODO: Reuse allocations. let mut groups = MeshPhaseBindGroups { - model_only: Some(layouts.model_only(render_device, &model)), + model_only: Some(layouts.model_only(render_device, pipeline_cache, &model)), ..default() }; @@ -2810,8 +2814,14 @@ fn prepare_mesh_bind_groups_for_phase( // (the latter being for motion vector computation). let (skin, prev_skin) = (&skins_uniform.current_buffer, &skins_uniform.prev_buffer); groups.skinned = Some(MeshBindGroupPair { - motion_vectors: layouts.skinned_motion(render_device, &model, skin, prev_skin), - no_motion_vectors: layouts.skinned(render_device, &model, skin), + motion_vectors: layouts.skinned_motion( + render_device, + pipeline_cache, + &model, + skin, + prev_skin, + ), + no_motion_vectors: layouts.skinned(render_device, pipeline_cache, &model, skin), }); // Create the morphed bind groups just like we did for the skinned bind @@ -2825,6 +2835,7 @@ fn prepare_mesh_bind_groups_for_phase( MeshBindGroupPair { motion_vectors: layouts.morphed_skinned_motion( render_device, + pipeline_cache, &model, skin, weights, @@ -2834,6 +2845,7 @@ fn prepare_mesh_bind_groups_for_phase( ), no_motion_vectors: layouts.morphed_skinned( render_device, + pipeline_cache, &model, skin, weights, @@ -2844,12 +2856,19 @@ fn prepare_mesh_bind_groups_for_phase( MeshBindGroupPair { motion_vectors: layouts.morphed_motion( render_device, + pipeline_cache, &model, weights, targets, prev_weights, ), - no_motion_vectors: layouts.morphed(render_device, &model, weights, targets), + no_motion_vectors: layouts.morphed( + render_device, + pipeline_cache, + &model, + weights, + targets, + ), } }; groups.morph_targets.insert(id, bind_group_pair); @@ -2862,7 +2881,13 @@ fn prepare_mesh_bind_groups_for_phase( for (lightmap_slab_id, lightmap_slab) in render_lightmaps.slabs.iter_mut().enumerate() { groups.lightmaps.insert( LightmapSlabIndex(NonMaxU32::new(lightmap_slab_id as u32).unwrap()), - layouts.lightmapped(render_device, &model, lightmap_slab, bindless_supported), + layouts.lightmapped( + render_device, + pipeline_cache, + &model, + lightmap_slab, + bindless_supported, + ), ); } diff --git a/crates/bevy_pbr/src/render/mesh_bindings.rs b/crates/bevy_pbr/src/render/mesh_bindings.rs index a80cdf547ac83..0936fc20f6bdc 100644 --- a/crates/bevy_pbr/src/render/mesh_bindings.rs +++ b/crates/bevy_pbr/src/render/mesh_bindings.rs @@ -164,37 +164,37 @@ mod entry { #[derive(Clone)] pub struct MeshLayouts { /// The mesh model uniform (transform) and nothing else. - pub model_only: BindGroupLayout, + pub model_only: BindGroupLayoutDescriptor, /// Includes the lightmap texture and uniform. - pub lightmapped: BindGroupLayout, + pub lightmapped: BindGroupLayoutDescriptor, /// Also includes the uniform for skinning - pub skinned: BindGroupLayout, + pub skinned: BindGroupLayoutDescriptor, /// Like [`MeshLayouts::skinned`], but includes slots for the previous /// frame's joint matrices, so that we can compute motion vectors. - pub skinned_motion: BindGroupLayout, + pub skinned_motion: BindGroupLayoutDescriptor, /// Also includes the uniform and [`MorphAttributes`] for morph targets. /// /// [`MorphAttributes`]: bevy_mesh::morph::MorphAttributes - pub morphed: BindGroupLayout, + pub morphed: BindGroupLayoutDescriptor, /// Like [`MeshLayouts::morphed`], but includes a slot for the previous /// frame's morph weights, so that we can compute motion vectors. - pub morphed_motion: BindGroupLayout, + pub morphed_motion: BindGroupLayoutDescriptor, /// Also includes both uniforms for skinning and morph targets, also the /// morph target [`MorphAttributes`] binding. /// /// [`MorphAttributes`]: bevy_mesh::morph::MorphAttributes - pub morphed_skinned: BindGroupLayout, + pub morphed_skinned: BindGroupLayoutDescriptor, /// Like [`MeshLayouts::morphed_skinned`], but includes slots for the /// previous frame's joint matrices and morph weights, so that we can /// compute motion vectors. - pub morphed_skinned_motion: BindGroupLayout, + pub morphed_skinned_motion: BindGroupLayoutDescriptor, } impl MeshLayouts { @@ -216,8 +216,8 @@ impl MeshLayouts { // ---------- create individual BindGroupLayouts ---------- - fn model_only_layout(render_device: &RenderDevice) -> BindGroupLayout { - render_device.create_bind_group_layout( + fn model_only_layout(render_device: &RenderDevice) -> BindGroupLayoutDescriptor { + BindGroupLayoutDescriptor::new( "mesh_layout", &BindGroupLayoutEntries::single( ShaderStages::empty(), @@ -227,8 +227,8 @@ impl MeshLayouts { } /// Creates the layout for skinned meshes. - fn skinned_layout(render_device: &RenderDevice) -> BindGroupLayout { - render_device.create_bind_group_layout( + fn skinned_layout(render_device: &RenderDevice) -> BindGroupLayoutDescriptor { + BindGroupLayoutDescriptor::new( "skinned_mesh_layout", &BindGroupLayoutEntries::with_indices( ShaderStages::VERTEX, @@ -243,8 +243,8 @@ impl MeshLayouts { /// Creates the layout for skinned meshes with the infrastructure to compute /// motion vectors. - fn skinned_motion_layout(render_device: &RenderDevice) -> BindGroupLayout { - render_device.create_bind_group_layout( + fn skinned_motion_layout(render_device: &RenderDevice) -> BindGroupLayoutDescriptor { + BindGroupLayoutDescriptor::new( "skinned_motion_mesh_layout", &BindGroupLayoutEntries::with_indices( ShaderStages::VERTEX, @@ -260,8 +260,8 @@ impl MeshLayouts { } /// Creates the layout for meshes with morph targets. - fn morphed_layout(render_device: &RenderDevice) -> BindGroupLayout { - render_device.create_bind_group_layout( + fn morphed_layout(render_device: &RenderDevice) -> BindGroupLayoutDescriptor { + BindGroupLayoutDescriptor::new( "morphed_mesh_layout", &BindGroupLayoutEntries::with_indices( ShaderStages::VERTEX, @@ -277,8 +277,8 @@ impl MeshLayouts { /// Creates the layout for meshes with morph targets and the infrastructure /// to compute motion vectors. - fn morphed_motion_layout(render_device: &RenderDevice) -> BindGroupLayout { - render_device.create_bind_group_layout( + fn morphed_motion_layout(render_device: &RenderDevice) -> BindGroupLayoutDescriptor { + BindGroupLayoutDescriptor::new( "morphed_mesh_layout", &BindGroupLayoutEntries::with_indices( ShaderStages::VERTEX, @@ -296,8 +296,8 @@ impl MeshLayouts { /// Creates the bind group layout for meshes with both skins and morph /// targets. - fn morphed_skinned_layout(render_device: &RenderDevice) -> BindGroupLayout { - render_device.create_bind_group_layout( + fn morphed_skinned_layout(render_device: &RenderDevice) -> BindGroupLayoutDescriptor { + BindGroupLayoutDescriptor::new( "morphed_skinned_mesh_layout", &BindGroupLayoutEntries::with_indices( ShaderStages::VERTEX, @@ -315,8 +315,8 @@ impl MeshLayouts { /// Creates the bind group layout for meshes with both skins and morph /// targets, in addition to the infrastructure to compute motion vectors. - fn morphed_skinned_motion_layout(render_device: &RenderDevice) -> BindGroupLayout { - render_device.create_bind_group_layout( + fn morphed_skinned_motion_layout(render_device: &RenderDevice) -> BindGroupLayoutDescriptor { + BindGroupLayoutDescriptor::new( "morphed_skinned_motion_mesh_layout", &BindGroupLayoutEntries::with_indices( ShaderStages::VERTEX, @@ -339,9 +339,9 @@ impl MeshLayouts { fn lightmapped_layout( render_device: &RenderDevice, render_adapter: &RenderAdapter, - ) -> BindGroupLayout { + ) -> BindGroupLayoutDescriptor { if binding_arrays_are_usable(render_device, render_adapter) { - render_device.create_bind_group_layout( + BindGroupLayoutDescriptor::new( "lightmapped_mesh_layout", &BindGroupLayoutEntries::with_indices( ShaderStages::VERTEX, @@ -353,7 +353,7 @@ impl MeshLayouts { ), ) } else { - render_device.create_bind_group_layout( + BindGroupLayoutDescriptor::new( "lightmapped_mesh_layout", &BindGroupLayoutEntries::with_indices( ShaderStages::VERTEX, @@ -369,10 +369,15 @@ impl MeshLayouts { // ---------- BindGroup methods ---------- - pub fn model_only(&self, render_device: &RenderDevice, model: &BindingResource) -> BindGroup { + pub fn model_only( + &self, + render_device: &RenderDevice, + pipeline_cache: &PipelineCache, + model: &BindingResource, + ) -> BindGroup { render_device.create_bind_group( "model_only_mesh_bind_group", - &self.model_only, + &pipeline_cache.get_bind_group_layout(self.model_only.clone()), &[entry::model(0, model.clone())], ) } @@ -380,6 +385,7 @@ impl MeshLayouts { pub fn lightmapped( &self, render_device: &RenderDevice, + pipeline_cache: &PipelineCache, model: &BindingResource, lightmap_slab: &LightmapSlab, bindless_lightmaps: bool, @@ -388,7 +394,7 @@ impl MeshLayouts { let (texture_views, samplers) = lightmap_slab.build_binding_arrays(); render_device.create_bind_group( "lightmapped_mesh_bind_group", - &self.lightmapped, + &pipeline_cache.get_bind_group_layout(self.lightmapped.clone()), &[ entry::model(0, model.clone()), entry::lightmaps_texture_view_array(4, &texture_views), @@ -399,7 +405,7 @@ impl MeshLayouts { let (texture_view, sampler) = lightmap_slab.bindings_for_first_lightmap(); render_device.create_bind_group( "lightmapped_mesh_bind_group", - &self.lightmapped, + &pipeline_cache.get_bind_group_layout(self.lightmapped.clone()), &[ entry::model(0, model.clone()), entry::lightmaps_texture_view(4, texture_view), @@ -413,12 +419,13 @@ impl MeshLayouts { pub fn skinned( &self, render_device: &RenderDevice, + pipeline_cache: &PipelineCache, model: &BindingResource, current_skin: &Buffer, ) -> BindGroup { render_device.create_bind_group( "skinned_mesh_bind_group", - &self.skinned, + &pipeline_cache.get_bind_group_layout(self.skinned.clone()), &[ entry::model(0, model.clone()), entry::skinning(render_device, 1, current_skin), @@ -436,13 +443,14 @@ impl MeshLayouts { pub fn skinned_motion( &self, render_device: &RenderDevice, + pipeline_cache: &PipelineCache, model: &BindingResource, current_skin: &Buffer, prev_skin: &Buffer, ) -> BindGroup { render_device.create_bind_group( "skinned_motion_mesh_bind_group", - &self.skinned_motion, + &pipeline_cache.get_bind_group_layout(self.skinned_motion.clone()), &[ entry::model(0, model.clone()), entry::skinning(render_device, 1, current_skin), @@ -455,13 +463,14 @@ impl MeshLayouts { pub fn morphed( &self, render_device: &RenderDevice, + pipeline_cache: &PipelineCache, model: &BindingResource, current_weights: &Buffer, targets: &TextureView, ) -> BindGroup { render_device.create_bind_group( "morphed_mesh_bind_group", - &self.morphed, + &pipeline_cache.get_bind_group_layout(self.morphed.clone()), &[ entry::model(0, model.clone()), entry::weights(2, current_weights), @@ -480,6 +489,7 @@ impl MeshLayouts { pub fn morphed_motion( &self, render_device: &RenderDevice, + pipeline_cache: &PipelineCache, model: &BindingResource, current_weights: &Buffer, targets: &TextureView, @@ -487,7 +497,7 @@ impl MeshLayouts { ) -> BindGroup { render_device.create_bind_group( "morphed_motion_mesh_bind_group", - &self.morphed_motion, + &pipeline_cache.get_bind_group_layout(self.morphed_motion.clone()), &[ entry::model(0, model.clone()), entry::weights(2, current_weights), @@ -501,6 +511,7 @@ impl MeshLayouts { pub fn morphed_skinned( &self, render_device: &RenderDevice, + pipeline_cache: &PipelineCache, model: &BindingResource, current_skin: &Buffer, current_weights: &Buffer, @@ -508,7 +519,7 @@ impl MeshLayouts { ) -> BindGroup { render_device.create_bind_group( "morphed_skinned_mesh_bind_group", - &self.morphed_skinned, + &pipeline_cache.get_bind_group_layout(self.morphed_skinned.clone()), &[ entry::model(0, model.clone()), entry::skinning(render_device, 1, current_skin), @@ -528,6 +539,7 @@ impl MeshLayouts { pub fn morphed_skinned_motion( &self, render_device: &RenderDevice, + pipeline_cache: &PipelineCache, model: &BindingResource, current_skin: &Buffer, current_weights: &Buffer, @@ -537,7 +549,7 @@ impl MeshLayouts { ) -> BindGroup { render_device.create_bind_group( "morphed_skinned_motion_mesh_bind_group", - &self.morphed_skinned_motion, + &pipeline_cache.get_bind_group_layout(self.morphed_skinned_motion.clone()), &[ entry::model(0, model.clone()), entry::skinning(render_device, 1, current_skin), diff --git a/crates/bevy_pbr/src/render/mesh_view_bindings.rs b/crates/bevy_pbr/src/render/mesh_view_bindings.rs index 5c1e0e8a47b7b..28e30dfc245fa 100644 --- a/crates/bevy_pbr/src/render/mesh_view_bindings.rs +++ b/crates/bevy_pbr/src/render/mesh_view_bindings.rs @@ -58,9 +58,9 @@ use {crate::MESH_PIPELINE_VIEW_LAYOUT_SAFE_MAX_TEXTURES, bevy_utils::once, traci #[derive(Clone)] pub struct MeshPipelineViewLayout { - pub main_layout: BindGroupLayout, - pub binding_array_layout: BindGroupLayout, - pub empty_layout: BindGroupLayout, + pub main_layout: BindGroupLayoutDescriptor, + pub binding_array_layout: BindGroupLayoutDescriptor, + pub empty_layout: BindGroupLayoutDescriptor, #[cfg(debug_assertions)] pub texture_count: usize, @@ -457,14 +457,12 @@ impl FromWorld for MeshPipelineViewLayouts { .count(); MeshPipelineViewLayout { - main_layout: render_device - .create_bind_group_layout(key.label().as_str(), &entries[0]), - binding_array_layout: render_device.create_bind_group_layout( - format!("{}_binding_array", key.label()).as_str(), + main_layout: BindGroupLayoutDescriptor::new(key.label(), &entries[0]), + binding_array_layout: BindGroupLayoutDescriptor::new( + format!("{}_binding_array", key.label()), &entries[1], ), - empty_layout: render_device - .create_bind_group_layout(format!("{}_empty", key.label()).as_str(), &[]), + empty_layout: BindGroupLayoutDescriptor::new(format!("{}_empty", key.label()), &[]), #[cfg(debug_assertions)] texture_count, } @@ -518,13 +516,12 @@ pub fn generate_view_layouts( .count(); MeshPipelineViewLayout { - main_layout: render_device.create_bind_group_layout(key.label().as_str(), &entries[0]), - binding_array_layout: render_device.create_bind_group_layout( - format!("{}_binding_array", key.label()).as_str(), + main_layout: BindGroupLayoutDescriptor::new(key.label(), &entries[0]), + binding_array_layout: BindGroupLayoutDescriptor::new( + format!("{}_binding_array", key.label()), &entries[1], ), - empty_layout: render_device - .create_bind_group_layout(format!("{}_empty", key.label()).as_str(), &[]), + empty_layout: BindGroupLayoutDescriptor::new(format!("{}_empty", key.label()), &[]), #[cfg(debug_assertions)] texture_count, } @@ -540,7 +537,11 @@ pub struct MeshViewBindGroup { pub fn prepare_mesh_view_bind_groups( mut commands: Commands, - (render_device, render_adapter): (Res, Res), + (render_device, pipeline_cache, render_adapter): ( + Res, + Res, + Res, + ), mesh_pipeline: Res, shadow_samplers: Res, (light_meta, global_light_meta): (Res, Res), @@ -799,17 +800,17 @@ pub fn prepare_mesh_view_bind_groups( commands.entity(entity).insert(MeshViewBindGroup { main: render_device.create_bind_group( "mesh_view_bind_group", - &layout.main_layout, + &pipeline_cache.get_bind_group_layout(layout.main_layout.clone()), &entries, ), binding_array: render_device.create_bind_group( "mesh_view_bind_group_binding_array", - &layout.binding_array_layout, + &pipeline_cache.get_bind_group_layout(layout.binding_array_layout.clone()), &entries_binding_array, ), empty: render_device.create_bind_group( "mesh_view_bind_group_empty", - &layout.empty_layout, + &pipeline_cache.get_bind_group_layout(layout.empty_layout.clone()), &[], ), }); diff --git a/crates/bevy_pbr/src/ssao/mod.rs b/crates/bevy_pbr/src/ssao/mod.rs index d9f24d4999aa7..f590b48d6498e 100644 --- a/crates/bevy_pbr/src/ssao/mod.rs +++ b/crates/bevy_pbr/src/ssao/mod.rs @@ -289,10 +289,10 @@ struct SsaoPipelines { preprocess_depth_pipeline: CachedComputePipelineId, spatial_denoise_pipeline: CachedComputePipelineId, - common_bind_group_layout: BindGroupLayout, - preprocess_depth_bind_group_layout: BindGroupLayout, - ssao_bind_group_layout: BindGroupLayout, - spatial_denoise_bind_group_layout: BindGroupLayout, + common_bind_group_layout: BindGroupLayoutDescriptor, + preprocess_depth_bind_group_layout: BindGroupLayoutDescriptor, + ssao_bind_group_layout: BindGroupLayoutDescriptor, + spatial_denoise_bind_group_layout: BindGroupLayoutDescriptor, hilbert_index_lut: TextureView, point_clamp_sampler: Sampler, @@ -346,7 +346,7 @@ impl FromWorld for SsaoPipelines { ..Default::default() }); - let common_bind_group_layout = render_device.create_bind_group_layout( + let common_bind_group_layout = BindGroupLayoutDescriptor::new( "ssao_common_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -358,7 +358,7 @@ impl FromWorld for SsaoPipelines { ), ); - let preprocess_depth_bind_group_layout = render_device.create_bind_group_layout( + let preprocess_depth_bind_group_layout = BindGroupLayoutDescriptor::new( "ssao_preprocess_depth_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -373,7 +373,7 @@ impl FromWorld for SsaoPipelines { ), ); - let ssao_bind_group_layout = render_device.create_bind_group_layout( + let ssao_bind_group_layout = BindGroupLayoutDescriptor::new( "ssao_ssao_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -389,7 +389,7 @@ impl FromWorld for SsaoPipelines { ), ); - let spatial_denoise_bind_group_layout = render_device.create_bind_group_layout( + let spatial_denoise_bind_group_layout = BindGroupLayoutDescriptor::new( "ssao_spatial_denoise_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -639,6 +639,7 @@ fn prepare_ssao_bind_groups( pipelines: Res, view_uniforms: Res, global_uniforms: Res, + pipeline_cache: Res, views: Query<( Entity, &ScreenSpaceAmbientOcclusionResources, @@ -655,7 +656,7 @@ fn prepare_ssao_bind_groups( for (entity, ssao_resources, prepass_textures) in &views { let common_bind_group = render_device.create_bind_group( "ssao_common_bind_group", - &pipelines.common_bind_group_layout, + &pipeline_cache.get_bind_group_layout(pipelines.common_bind_group_layout.clone()), &BindGroupEntries::sequential(( &pipelines.point_clamp_sampler, &pipelines.linear_clamp_sampler, @@ -679,7 +680,8 @@ fn prepare_ssao_bind_groups( let preprocess_depth_bind_group = render_device.create_bind_group( "ssao_preprocess_depth_bind_group", - &pipelines.preprocess_depth_bind_group_layout, + &pipeline_cache + .get_bind_group_layout(pipelines.preprocess_depth_bind_group_layout.clone()), &BindGroupEntries::sequential(( prepass_textures.depth_view().unwrap(), &create_depth_view(0), @@ -692,7 +694,7 @@ fn prepare_ssao_bind_groups( let ssao_bind_group = render_device.create_bind_group( "ssao_ssao_bind_group", - &pipelines.ssao_bind_group_layout, + &pipeline_cache.get_bind_group_layout(pipelines.ssao_bind_group_layout.clone()), &BindGroupEntries::sequential(( &ssao_resources.preprocessed_depth_texture.default_view, prepass_textures.normal_view().unwrap(), @@ -706,7 +708,8 @@ fn prepare_ssao_bind_groups( let spatial_denoise_bind_group = render_device.create_bind_group( "ssao_spatial_denoise_bind_group", - &pipelines.spatial_denoise_bind_group_layout, + &pipeline_cache + .get_bind_group_layout(pipelines.spatial_denoise_bind_group_layout.clone()), &BindGroupEntries::sequential(( &ssao_resources.ssao_noisy_texture.default_view, &ssao_resources.depth_differences_texture.default_view, diff --git a/crates/bevy_pbr/src/ssr/mod.rs b/crates/bevy_pbr/src/ssr/mod.rs index f39cf417c2492..0669d7f157291 100644 --- a/crates/bevy_pbr/src/ssr/mod.rs +++ b/crates/bevy_pbr/src/ssr/mod.rs @@ -31,12 +31,12 @@ use bevy_render::{ NodeRunError, RenderGraph, RenderGraphContext, RenderGraphExt, ViewNode, ViewNodeRunner, }, render_resource::{ - binding_types, AddressMode, BindGroupEntries, BindGroupLayout, BindGroupLayoutEntries, - CachedRenderPipelineId, ColorTargetState, ColorWrites, DynamicUniformBuffer, FilterMode, - FragmentState, Operations, PipelineCache, RenderPassColorAttachment, RenderPassDescriptor, - RenderPipelineDescriptor, Sampler, SamplerBindingType, SamplerDescriptor, ShaderStages, - ShaderType, SpecializedRenderPipeline, SpecializedRenderPipelines, TextureFormat, - TextureSampleType, + binding_types, AddressMode, BindGroupEntries, BindGroupLayoutDescriptor, + BindGroupLayoutEntries, CachedRenderPipelineId, ColorTargetState, ColorWrites, + DynamicUniformBuffer, FilterMode, FragmentState, Operations, PipelineCache, + RenderPassColorAttachment, RenderPassDescriptor, RenderPipelineDescriptor, Sampler, + SamplerBindingType, SamplerDescriptor, ShaderStages, ShaderType, SpecializedRenderPipeline, + SpecializedRenderPipelines, TextureFormat, TextureSampleType, }, renderer::{RenderAdapter, RenderContext, RenderDevice, RenderQueue}, view::{ExtractedView, Msaa, ViewTarget, ViewUniformOffset}, @@ -156,7 +156,7 @@ pub struct ScreenSpaceReflectionsPipeline { color_sampler: Sampler, depth_linear_sampler: Sampler, depth_nearest_sampler: Sampler, - bind_group_layout: BindGroupLayout, + bind_group_layout: BindGroupLayoutDescriptor, binding_arrays_are_usable: bool, fullscreen_shader: FullscreenShader, fragment_shader: Handle, @@ -292,7 +292,7 @@ impl ViewNode for ScreenSpaceReflectionsNode { let ssr_pipeline = world.resource::(); let ssr_bind_group = render_context.render_device().create_bind_group( "SSR bind group", - &ssr_pipeline.bind_group_layout, + &pipeline_cache.get_bind_group_layout(ssr_pipeline.bind_group_layout.clone()), &BindGroupEntries::sequential(( postprocess.source, &ssr_pipeline.color_sampler, @@ -351,7 +351,7 @@ pub fn init_screen_space_reflections_pipeline( asset_server: Res, ) { // Create the bind group layout. - let bind_group_layout = render_device.create_bind_group_layout( + let bind_group_layout = BindGroupLayoutDescriptor::new( "SSR bind group layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, diff --git a/crates/bevy_pbr/src/volumetric_fog/render.rs b/crates/bevy_pbr/src/volumetric_fog/render.rs index 0c558fe2e804d..f2e61249e93ea 100644 --- a/crates/bevy_pbr/src/volumetric_fog/render.rs +++ b/crates/bevy_pbr/src/volumetric_fog/render.rs @@ -30,10 +30,10 @@ use bevy_render::{ binding_types::{ sampler, texture_3d, texture_depth_2d, texture_depth_2d_multisampled, uniform_buffer, }, - BindGroupLayout, BindGroupLayoutEntries, BindingResource, BlendComponent, BlendFactor, - BlendOperation, BlendState, CachedRenderPipelineId, ColorTargetState, ColorWrites, - DynamicBindGroupEntries, DynamicUniformBuffer, Face, FragmentState, LoadOp, Operations, - PipelineCache, PrimitiveState, RenderPassColorAttachment, RenderPassDescriptor, + BindGroupLayoutDescriptor, BindGroupLayoutEntries, BindingResource, BlendComponent, + BlendFactor, BlendOperation, BlendState, CachedRenderPipelineId, ColorTargetState, + ColorWrites, DynamicBindGroupEntries, DynamicUniformBuffer, Face, FragmentState, LoadOp, + Operations, PipelineCache, PrimitiveState, RenderPassColorAttachment, RenderPassDescriptor, RenderPipelineDescriptor, SamplerBindingType, ShaderStages, ShaderType, SpecializedRenderPipeline, SpecializedRenderPipelines, StoreOp, TextureFormat, TextureSampleType, TextureUsages, VertexState, @@ -105,7 +105,8 @@ pub struct VolumetricFogPipeline { /// All bind group layouts. /// /// Since there aren't too many of these, we precompile them all. - volumetric_view_bind_group_layouts: [BindGroupLayout; VOLUMETRIC_FOG_BIND_GROUP_LAYOUT_COUNT], + volumetric_view_bind_group_layouts: + [BindGroupLayoutDescriptor; VOLUMETRIC_FOG_BIND_GROUP_LAYOUT_COUNT], // The shader asset handle. shader: Handle, @@ -204,7 +205,6 @@ pub struct VolumetricFogUniformBuffer(pub DynamicUniformBuffer, mesh_view_layouts: Res, asset_server: Res, ) { @@ -249,7 +249,7 @@ pub fn init_volumetric_fog_pipeline( // Create the bind group layout. let description = flags.bind_group_layout_description(); - render_device.create_bind_group_layout(&*description, &bind_group_layout_entries) + BindGroupLayoutDescriptor::new(description, &bind_group_layout_entries) }); commands.insert_resource(VolumetricFogPipeline { @@ -431,7 +431,7 @@ impl ViewNode for VolumetricFogNode { let volumetric_view_bind_group = render_context.render_device().create_bind_group( None, - volumetric_view_bind_group_layout, + &pipeline_cache.get_bind_group_layout(volumetric_view_bind_group_layout.clone()), &bind_group_entries, ); From 66212d079661410ac0162ca992eb8245e1925365 Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 14:27:32 +0800 Subject: [PATCH 10/23] bevy_solari --- crates/bevy_solari/src/pathtracer/node.rs | 15 ++++---- crates/bevy_solari/src/realtime/node.rs | 43 ++++++++++++----------- crates/bevy_solari/src/scene/binder.rs | 14 ++++---- crates/bevy_solari/src/scene/mod.rs | 2 +- 4 files changed, 36 insertions(+), 38 deletions(-) diff --git a/crates/bevy_solari/src/pathtracer/node.rs b/crates/bevy_solari/src/pathtracer/node.rs index 325ea42dac6a9..9ef10873c1088 100644 --- a/crates/bevy_solari/src/pathtracer/node.rs +++ b/crates/bevy_solari/src/pathtracer/node.rs @@ -10,11 +10,11 @@ use bevy_render::{ render_graph::{NodeRunError, RenderGraphContext, ViewNode}, render_resource::{ binding_types::{texture_storage_2d, uniform_buffer}, - BindGroupEntries, BindGroupLayout, BindGroupLayoutEntries, CachedComputePipelineId, - ComputePassDescriptor, ComputePipelineDescriptor, ImageSubresourceRange, PipelineCache, - ShaderStages, StorageTextureAccess, TextureFormat, + BindGroupEntries, BindGroupLayoutDescriptor, BindGroupLayoutEntries, + CachedComputePipelineId, ComputePassDescriptor, ComputePipelineDescriptor, + ImageSubresourceRange, PipelineCache, ShaderStages, StorageTextureAccess, TextureFormat, }, - renderer::{RenderContext, RenderDevice}, + renderer::RenderContext, view::{ViewTarget, ViewUniform, ViewUniformOffset, ViewUniforms}, }; use bevy_utils::default; @@ -27,7 +27,7 @@ pub mod graph { } pub struct PathtracerNode { - bind_group_layout: BindGroupLayout, + bind_group_layout: BindGroupLayoutDescriptor, pipeline: CachedComputePipelineId, } @@ -63,7 +63,7 @@ impl ViewNode for PathtracerNode { let bind_group = render_context.render_device().create_bind_group( "pathtracer_bind_group", - &self.bind_group_layout, + &pipeline_cache.get_bind_group_layout(self.bind_group_layout.clone()), &BindGroupEntries::sequential(( &accumulation_texture.0.default_view, view_target.get_unsampled_color_attachment().view, @@ -95,11 +95,10 @@ impl ViewNode for PathtracerNode { impl FromWorld for PathtracerNode { fn from_world(world: &mut World) -> Self { - let render_device = world.resource::(); let pipeline_cache = world.resource::(); let scene_bindings = world.resource::(); - let bind_group_layout = render_device.create_bind_group_layout( + let bind_group_layout = BindGroupLayoutDescriptor::new( "pathtracer_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, diff --git a/crates/bevy_solari/src/realtime/node.rs b/crates/bevy_solari/src/realtime/node.rs index 1de282ed4192e..ca4273b02944a 100644 --- a/crates/bevy_solari/src/realtime/node.rs +++ b/crates/bevy_solari/src/realtime/node.rs @@ -22,11 +22,11 @@ use bevy_render::{ binding_types::{ storage_buffer_sized, texture_2d, texture_depth_2d, texture_storage_2d, uniform_buffer, }, - BindGroupEntries, BindGroupLayout, BindGroupLayoutEntries, CachedComputePipelineId, - ComputePassDescriptor, ComputePipelineDescriptor, PipelineCache, PushConstantRange, - ShaderStages, StorageTextureAccess, TextureFormat, TextureSampleType, + BindGroupEntries, BindGroupLayoutDescriptor, BindGroupLayoutEntries, + CachedComputePipelineId, ComputePassDescriptor, ComputePipelineDescriptor, PipelineCache, + PushConstantRange, ShaderStages, StorageTextureAccess, TextureFormat, TextureSampleType, }, - renderer::{RenderContext, RenderDevice}, + renderer::RenderContext, view::{ViewTarget, ViewUniform, ViewUniformOffset, ViewUniforms}, }; use bevy_shader::{Shader, ShaderDefVal}; @@ -40,10 +40,10 @@ pub mod graph { } pub struct SolariLightingNode { - bind_group_layout: BindGroupLayout, - bind_group_layout_world_cache_active_cells_dispatch: BindGroupLayout, + bind_group_layout: BindGroupLayoutDescriptor, + bind_group_layout_world_cache_active_cells_dispatch: BindGroupLayoutDescriptor, #[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))] - bind_group_layout_resolve_dlss_rr_textures: BindGroupLayout, + bind_group_layout_resolve_dlss_rr_textures: BindGroupLayoutDescriptor, decay_world_cache_pipeline: CachedComputePipelineId, compact_world_cache_single_block_pipeline: CachedComputePipelineId, compact_world_cache_blocks_pipeline: CachedComputePipelineId, @@ -159,7 +159,7 @@ impl ViewNode for SolariLightingNode { let s = solari_lighting_resources; let bind_group = render_context.render_device().create_bind_group( "solari_lighting_bind_group", - &self.bind_group_layout, + &pipeline_cache.get_bind_group_layout(self.bind_group_layout.clone()), &BindGroupEntries::sequential(( view_target.get_unsampled_color_attachment().view, s.light_tile_samples.as_entire_binding(), @@ -189,7 +189,10 @@ impl ViewNode for SolariLightingNode { let bind_group_world_cache_active_cells_dispatch = render_context.render_device().create_bind_group( "solari_lighting_bind_group_world_cache_active_cells_dispatch", - &self.bind_group_layout_world_cache_active_cells_dispatch, + &pipeline_cache.get_bind_group_layout( + self.bind_group_layout_world_cache_active_cells_dispatch + .clone(), + ), &BindGroupEntries::single(s.world_cache_active_cells_dispatch.as_entire_binding()), ); #[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))] @@ -338,11 +341,10 @@ impl ViewNode for SolariLightingNode { impl FromWorld for SolariLightingNode { fn from_world(world: &mut World) -> Self { - let render_device = world.resource::(); let pipeline_cache = world.resource::(); let scene_bindings = world.resource::(); - let bind_group_layout = render_device.create_bind_group_layout( + let bind_group_layout = BindGroupLayoutDescriptor::new( "solari_lighting_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -377,17 +379,16 @@ impl FromWorld for SolariLightingNode { ), ); - let bind_group_layout_world_cache_active_cells_dispatch = render_device - .create_bind_group_layout( - "solari_lighting_bind_group_layout_world_cache_active_cells_dispatch", - &BindGroupLayoutEntries::single( - ShaderStages::COMPUTE, - storage_buffer_sized(false, None), - ), - ); + let bind_group_layout_world_cache_active_cells_dispatch = BindGroupLayoutDescriptor::new( + "solari_lighting_bind_group_layout_world_cache_active_cells_dispatch", + &BindGroupLayoutEntries::single( + ShaderStages::COMPUTE, + storage_buffer_sized(false, None), + ), + ); #[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))] - let bind_group_layout_resolve_dlss_rr_textures = render_device.create_bind_group_layout( + let bind_group_layout_resolve_dlss_rr_textures = BindGroupLayoutDescriptor::new( "solari_lighting_bind_group_layout_resolve_dlss_rr_textures", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, @@ -403,7 +404,7 @@ impl FromWorld for SolariLightingNode { let create_pipeline = |label: &'static str, entry_point: &'static str, shader: Handle, - extra_bind_group_layout: Option<&BindGroupLayout>, + extra_bind_group_layout: Option<&BindGroupLayoutDescriptor>, extra_shader_defs: Vec| { let mut layout = vec![ scene_bindings.bind_group_layout.clone(), diff --git a/crates/bevy_solari/src/scene/binder.rs b/crates/bevy_solari/src/scene/binder.rs index e2ba4d751e862..d1f2b813ec763 100644 --- a/crates/bevy_solari/src/scene/binder.rs +++ b/crates/bevy_solari/src/scene/binder.rs @@ -5,7 +5,6 @@ use bevy_ecs::{ entity::{Entity, EntityHashMap}, resource::Resource, system::{Query, Res, ResMut}, - world::{FromWorld, World}, }; use bevy_math::{ops::cos, Mat4, Vec3}; use bevy_pbr::{ExtractedDirectionalLight, MeshMaterial3d, StandardMaterial}; @@ -29,7 +28,7 @@ const LIGHT_NOT_PRESENT_THIS_FRAME: u32 = u32::MAX; #[derive(Resource)] pub struct RaytracingSceneBindings { pub bind_group: Option, - pub bind_group_layout: BindGroupLayout, + pub bind_group_layout: BindGroupLayoutDescriptor, previous_frame_light_entities: Vec, } @@ -47,6 +46,7 @@ pub fn prepare_raytracing_scene_bindings( texture_assets: Res>, fallback_texture: Res, render_device: Res, + pipeline_cache: Res, render_queue: Res, mut raytracing_scene_bindings: ResMut, ) { @@ -258,7 +258,7 @@ pub fn prepare_raytracing_scene_bindings( raytracing_scene_bindings.bind_group = Some(render_device.create_bind_group( "raytracing_scene_bind_group", - &raytracing_scene_bindings.bind_group_layout, + &pipeline_cache.get_bind_group_layout(raytracing_scene_bindings.bind_group_layout.clone()), &BindGroupEntries::sequential(( vertex_buffers.as_slice(), index_buffers.as_slice(), @@ -276,13 +276,11 @@ pub fn prepare_raytracing_scene_bindings( )); } -impl FromWorld for RaytracingSceneBindings { - fn from_world(world: &mut World) -> Self { - let render_device = world.resource::(); - +impl RaytracingSceneBindings { + pub fn new() -> Self { Self { bind_group: None, - bind_group_layout: render_device.create_bind_group_layout( + bind_group_layout: BindGroupLayoutDescriptor::new( "raytracing_scene_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, diff --git a/crates/bevy_solari/src/scene/mod.rs b/crates/bevy_solari/src/scene/mod.rs index a6ddc12d6ed40..e744f3293a4f9 100644 --- a/crates/bevy_solari/src/scene/mod.rs +++ b/crates/bevy_solari/src/scene/mod.rs @@ -60,7 +60,7 @@ impl Plugin for RaytracingScenePlugin { render_app .init_resource::() .init_resource::() - .init_resource::() + .insert_resource(RaytracingSceneBindings::new()) .add_systems(ExtractSchedule, extract_raytracing_scene) .add_systems( Render, From 77c2407a7ce18ef634f21c79d3d52ffea32d5567 Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 14:27:47 +0800 Subject: [PATCH 11/23] bevy_anti_alias fmt --- .../src/contrast_adaptive_sharpening/node.rs | 3 +- crates/bevy_anti_alias/src/smaa/mod.rs | 68 +++++++++++++------ crates/bevy_anti_alias/src/taa/mod.rs | 8 ++- 3 files changed, 56 insertions(+), 23 deletions(-) diff --git a/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/node.rs b/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/node.rs index 53c2fd687f99f..2a53689e54e19 100644 --- a/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/node.rs +++ b/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/node.rs @@ -83,7 +83,8 @@ impl Node for CasNode { cached_bind_group => { let bind_group = render_context.render_device().create_bind_group( "cas_bind_group", - &pipeline_cache.get_bind_group_layout(sharpening_pipeline.texture_bind_group.clone()), + &pipeline_cache + .get_bind_group_layout(sharpening_pipeline.texture_bind_group.clone()), &BindGroupEntries::sequential(( view_target.source, &sharpening_pipeline.sampler, diff --git a/crates/bevy_anti_alias/src/smaa/mod.rs b/crates/bevy_anti_alias/src/smaa/mod.rs index ddcdf19b6632d..3c930b50d570b 100644 --- a/crates/bevy_anti_alias/src/smaa/mod.rs +++ b/crates/bevy_anti_alias/src/smaa/mod.rs @@ -60,7 +60,16 @@ use bevy_render::{ NodeRunError, RenderGraphContext, RenderGraphExt as _, ViewNode, ViewNodeRunner, }, render_resource::{ - binding_types::{sampler, texture_2d, uniform_buffer}, AddressMode, BindGroup, BindGroupEntries, BindGroupLayoutDescriptor, BindGroupLayoutEntries, CachedRenderPipelineId, ColorTargetState, ColorWrites, CompareFunction, DepthStencilState, DynamicUniformBuffer, FilterMode, FragmentState, LoadOp, Operations, PipelineCache, RenderPassColorAttachment, RenderPassDepthStencilAttachment, RenderPassDescriptor, RenderPipeline, RenderPipelineDescriptor, SamplerBindingType, SamplerDescriptor, ShaderStages, ShaderType, SpecializedRenderPipeline, SpecializedRenderPipelines, StencilFaceState, StencilOperation, StencilState, StoreOp, TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType, TextureUsages, TextureView, VertexState + binding_types::{sampler, texture_2d, uniform_buffer}, + AddressMode, BindGroup, BindGroupEntries, BindGroupLayoutDescriptor, + BindGroupLayoutEntries, CachedRenderPipelineId, ColorTargetState, ColorWrites, + CompareFunction, DepthStencilState, DynamicUniformBuffer, FilterMode, FragmentState, + LoadOp, Operations, PipelineCache, RenderPassColorAttachment, + RenderPassDepthStencilAttachment, RenderPassDescriptor, RenderPipeline, + RenderPipelineDescriptor, SamplerBindingType, SamplerDescriptor, ShaderStages, ShaderType, + SpecializedRenderPipeline, SpecializedRenderPipelines, StencilFaceState, StencilOperation, + StencilState, StoreOp, TextureDescriptor, TextureDimension, TextureFormat, + TextureSampleType, TextureUsages, TextureView, VertexState, }, renderer::{RenderContext, RenderDevice, RenderQueue}, texture::{CachedTexture, GpuImage, TextureCache}, @@ -347,10 +356,7 @@ impl Plugin for SmaaPlugin { } } -pub fn init_smaa_pipelines( - mut commands: Commands, - asset_server: Res, -) { +pub fn init_smaa_pipelines(mut commands: Commands, asset_server: Res) { // Create the postprocess bind group layout (all passes, bind group 0). let postprocess_bind_group_layout = BindGroupLayoutDescriptor::new( "SMAA postprocess bind group layout", @@ -745,16 +751,22 @@ fn prepare_smaa_bind_groups( commands.entity(entity).insert(SmaaBindGroups { edge_detection_bind_group: render_device.create_bind_group( Some("SMAA edge detection bind group"), - &pipeline_cache.get_bind_group_layout(smaa_pipelines - .edge_detection - .edge_detection_bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout( + smaa_pipelines + .edge_detection + .edge_detection_bind_group_layout + .clone(), + ), &BindGroupEntries::sequential((&sampler,)), ), blending_weight_calculation_bind_group: render_device.create_bind_group( Some("SMAA blending weight calculation bind group"), - &pipeline_cache.get_bind_group_layout(smaa_pipelines - .blending_weight_calculation - .blending_weight_calculation_bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout( + smaa_pipelines + .blending_weight_calculation + .blending_weight_calculation_bind_group_layout + .clone(), + ), &BindGroupEntries::sequential(( &smaa_textures.edge_detection_color_texture.default_view, &sampler, @@ -764,9 +776,12 @@ fn prepare_smaa_bind_groups( ), neighborhood_blending_bind_group: render_device.create_bind_group( Some("SMAA neighborhood blending bind group"), - &pipeline_cache.get_bind_group_layout(smaa_pipelines - .neighborhood_blending - .neighborhood_blending_bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout( + smaa_pipelines + .neighborhood_blending + .neighborhood_blending_bind_group_layout + .clone(), + ), &BindGroupEntries::sequential(( &smaa_textures.blend_texture.default_view, &sampler, @@ -891,7 +906,12 @@ fn perform_edge_detection( // Create the edge detection bind group. let postprocess_bind_group = render_context.render_device().create_bind_group( None, - &pipeline_cache.get_bind_group_layout(smaa_pipelines.edge_detection.postprocess_bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout( + smaa_pipelines + .edge_detection + .postprocess_bind_group_layout + .clone(), + ), &BindGroupEntries::sequential((source, &**smaa_info_uniform_buffer)), ); @@ -946,9 +966,12 @@ fn perform_blending_weight_calculation( // Create the blending weight calculation bind group. let postprocess_bind_group = render_context.render_device().create_bind_group( None, - &pipeline_cache.get_bind_group_layout(smaa_pipelines - .blending_weight_calculation - .postprocess_bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout( + smaa_pipelines + .blending_weight_calculation + .postprocess_bind_group_layout + .clone(), + ), &BindGroupEntries::sequential((source, &**smaa_info_uniform_buffer)), ); @@ -1005,9 +1028,12 @@ fn perform_neighborhood_blending( ) { let postprocess_bind_group = render_context.render_device().create_bind_group( None, - &pipeline_cache.get_bind_group_layout(smaa_pipelines - .neighborhood_blending - .postprocess_bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout( + smaa_pipelines + .neighborhood_blending + .postprocess_bind_group_layout + .clone(), + ), &BindGroupEntries::sequential((source, &**smaa_info_uniform_buffer)), ); diff --git a/crates/bevy_anti_alias/src/taa/mod.rs b/crates/bevy_anti_alias/src/taa/mod.rs index dcf396c614abc..c3532297a0d6c 100644 --- a/crates/bevy_anti_alias/src/taa/mod.rs +++ b/crates/bevy_anti_alias/src/taa/mod.rs @@ -23,7 +23,13 @@ use bevy_render::{ diagnostic::RecordDiagnostics, render_graph::{NodeRunError, RenderGraphContext, RenderGraphExt, ViewNode, ViewNodeRunner}, render_resource::{ - binding_types::{sampler, texture_2d, texture_depth_2d}, BindGroupEntries, BindGroupLayoutDescriptor, BindGroupLayoutEntries, CachedRenderPipelineId, ColorTargetState, ColorWrites, FilterMode, FragmentState, Operations, PipelineCache, RenderPassColorAttachment, RenderPassDescriptor, RenderPipelineDescriptor, Sampler, SamplerBindingType, SamplerDescriptor, ShaderStages, SpecializedRenderPipeline, SpecializedRenderPipelines, TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType, TextureUsages + binding_types::{sampler, texture_2d, texture_depth_2d}, + BindGroupEntries, BindGroupLayoutDescriptor, BindGroupLayoutEntries, + CachedRenderPipelineId, ColorTargetState, ColorWrites, FilterMode, FragmentState, + Operations, PipelineCache, RenderPassColorAttachment, RenderPassDescriptor, + RenderPipelineDescriptor, Sampler, SamplerBindingType, SamplerDescriptor, ShaderStages, + SpecializedRenderPipeline, SpecializedRenderPipelines, TextureDescriptor, TextureDimension, + TextureFormat, TextureSampleType, TextureUsages, }, renderer::{RenderContext, RenderDevice}, sync_component::SyncComponentPlugin, From 8e1ff54c37e52f7c626f8617083a506ab3d83a1e Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 14:31:56 +0800 Subject: [PATCH 12/23] bevy_gizmos --- crates/bevy_gizmos/src/lib.rs | 17 ++++++++--------- crates/bevy_gizmos/src/pipeline_2d.rs | 4 ++-- crates/bevy_gizmos/src/pipeline_3d.rs | 4 ++-- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/crates/bevy_gizmos/src/lib.rs b/crates/bevy_gizmos/src/lib.rs index fb263e29e9aa9..a5503e20535c1 100755 --- a/crates/bevy_gizmos/src/lib.rs +++ b/crates/bevy_gizmos/src/lib.rs @@ -90,6 +90,8 @@ use bevy_ecs::{ system::{Res, ResMut}, }; use bevy_reflect::TypePath; +#[cfg(feature = "bevy_render")] +use bevy_render::render_resource::{BindGroupLayoutDescriptor, PipelineCache}; #[cfg(all( feature = "bevy_render", @@ -118,9 +120,8 @@ use { render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets}, render_phase::{PhaseItem, RenderCommand, RenderCommandResult, TrackedRenderPass}, render_resource::{ - binding_types::uniform_buffer, BindGroup, BindGroupEntries, BindGroupLayout, - BindGroupLayoutEntries, Buffer, BufferInitDescriptor, BufferUsages, ShaderStages, - ShaderType, VertexFormat, + binding_types::uniform_buffer, BindGroup, BindGroupEntries, BindGroupLayoutEntries, + Buffer, BufferInitDescriptor, BufferUsages, ShaderStages, ShaderType, VertexFormat, }, renderer::RenderDevice, sync_world::{MainEntity, TemporaryRenderEntity}, @@ -396,10 +397,7 @@ fn update_gizmo_meshes( } #[cfg(feature = "bevy_render")] -fn init_line_gizmo_uniform_bind_group_layout( - mut commands: Commands, - render_device: Res, -) { +fn init_line_gizmo_uniform_bind_group_layout(mut commands: Commands) { let line_layout = BindGroupLayoutDescriptor::new( "LineGizmoUniform layout", &BindGroupLayoutEntries::single( @@ -592,7 +590,7 @@ impl RenderAsset for GpuLineGizmo { #[cfg(feature = "bevy_render")] #[derive(Resource)] struct LineGizmoUniformBindgroupLayout { - layout: BindGroupLayout, + layout: BindGroupLayoutDescriptor, } #[cfg(feature = "bevy_render")] @@ -606,13 +604,14 @@ fn prepare_line_gizmo_bind_group( mut commands: Commands, line_gizmo_uniform_layout: Res, render_device: Res, + pipeline_cache: Res, line_gizmo_uniforms: Res>, ) { if let Some(binding) = line_gizmo_uniforms.uniforms().binding() { commands.insert_resource(LineGizmoUniformBindgroup { bindgroup: render_device.create_bind_group( "LineGizmoUniform bindgroup", - &line_gizmo_uniform_layout.layout, + &pipeline_cache.get_bind_group_layout(line_gizmo_uniform_layout.layout.clone()), &BindGroupEntries::single(binding), ), }); diff --git a/crates/bevy_gizmos/src/pipeline_2d.rs b/crates/bevy_gizmos/src/pipeline_2d.rs index 48cd53c4e1420..f5749cf0fd473 100644 --- a/crates/bevy_gizmos/src/pipeline_2d.rs +++ b/crates/bevy_gizmos/src/pipeline_2d.rs @@ -78,7 +78,7 @@ impl Plugin for LineGizmo2dPlugin { #[derive(Clone, Resource)] struct LineGizmoPipeline { mesh_pipeline: Mesh2dPipeline, - uniform_layout: BindGroupLayout, + uniform_layout: BindGroupLayoutDescriptor, shader: Handle, } @@ -181,7 +181,7 @@ impl SpecializedRenderPipeline for LineGizmoPipeline { #[derive(Clone, Resource)] struct LineJointGizmoPipeline { mesh_pipeline: Mesh2dPipeline, - uniform_layout: BindGroupLayout, + uniform_layout: BindGroupLayoutDescriptor, shader: Handle, } diff --git a/crates/bevy_gizmos/src/pipeline_3d.rs b/crates/bevy_gizmos/src/pipeline_3d.rs index ded286949ac5e..1fd1c92293020 100644 --- a/crates/bevy_gizmos/src/pipeline_3d.rs +++ b/crates/bevy_gizmos/src/pipeline_3d.rs @@ -70,7 +70,7 @@ impl Plugin for LineGizmo3dPlugin { #[derive(Clone, Resource)] struct LineGizmoPipeline { mesh_pipeline: MeshPipeline, - uniform_layout: BindGroupLayout, + uniform_layout: BindGroupLayoutDescriptor, shader: Handle, } @@ -170,7 +170,7 @@ impl SpecializedRenderPipeline for LineGizmoPipeline { #[derive(Clone, Resource)] struct LineJointGizmoPipeline { mesh_pipeline: MeshPipeline, - uniform_layout: BindGroupLayout, + uniform_layout: BindGroupLayoutDescriptor, shader: Handle, } From bb4c7b78809c96cae3de695828ac50d12b80b334 Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 16:01:25 +0800 Subject: [PATCH 13/23] Less clone --- .../src/contrast_adaptive_sharpening/node.rs | 3 +- crates/bevy_anti_alias/src/fxaa/node.rs | 2 +- crates/bevy_anti_alias/src/smaa/mod.rs | 33 ++++------ crates/bevy_anti_alias/src/taa/mod.rs | 2 +- crates/bevy_core_pipeline/src/blit/mod.rs | 2 +- .../src/deferred/copy_lighting_id.rs | 3 +- .../src/experimental/mip_generation/mod.rs | 5 +- .../bevy_core_pipeline/src/oit/resolve/mod.rs | 2 +- .../src/oit/resolve/node.rs | 2 +- crates/bevy_core_pipeline/src/skybox/mod.rs | 2 +- .../bevy_core_pipeline/src/skybox/prepass.rs | 2 +- .../src/tonemapping/node.rs | 3 +- crates/bevy_gizmos/src/lib.rs | 2 +- crates/bevy_pbr/src/atmosphere/environment.rs | 2 +- crates/bevy_pbr/src/atmosphere/resources.rs | 12 ++-- crates/bevy_pbr/src/deferred/mod.rs | 3 +- crates/bevy_pbr/src/light_probe/generate.rs | 12 ++-- crates/bevy_pbr/src/material.rs | 2 +- crates/bevy_pbr/src/material_bind_groups.rs | 4 +- crates/bevy_pbr/src/prepass/mod.rs | 44 ++++++------- crates/bevy_pbr/src/render/gpu_preprocess.rs | 62 +++++++++---------- crates/bevy_pbr/src/render/mesh_bindings.rs | 18 +++--- .../bevy_pbr/src/render/mesh_view_bindings.rs | 6 +- crates/bevy_pbr/src/ssao/mod.rs | 10 ++- crates/bevy_pbr/src/ssr/mod.rs | 2 +- crates/bevy_pbr/src/volumetric_fog/render.rs | 2 +- .../src/auto_exposure/node.rs | 2 +- crates/bevy_post_process/src/bloom/mod.rs | 44 ++++++------- crates/bevy_post_process/src/dof/mod.rs | 7 +-- .../bevy_post_process/src/effect_stack/mod.rs | 3 +- .../bevy_post_process/src/motion_blur/node.rs | 2 +- .../src/render_resource/bind_group.rs | 4 +- .../src/render_resource/pipeline_cache.rs | 3 +- .../bevy_render/src/view/window/screenshot.rs | 2 +- crates/bevy_sprite_render/src/mesh2d/mesh.rs | 4 +- crates/bevy_sprite_render/src/render/mod.rs | 5 +- crates/bevy_ui_render/src/box_shadow.rs | 2 +- crates/bevy_ui_render/src/gradient.rs | 2 +- crates/bevy_ui_render/src/lib.rs | 6 +- .../src/ui_material_pipeline.rs | 2 +- .../src/ui_texture_slice_pipeline.rs | 6 +- 41 files changed, 151 insertions(+), 185 deletions(-) diff --git a/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/node.rs b/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/node.rs index 2a53689e54e19..170a939127956 100644 --- a/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/node.rs +++ b/crates/bevy_anti_alias/src/contrast_adaptive_sharpening/node.rs @@ -83,8 +83,7 @@ impl Node for CasNode { cached_bind_group => { let bind_group = render_context.render_device().create_bind_group( "cas_bind_group", - &pipeline_cache - .get_bind_group_layout(sharpening_pipeline.texture_bind_group.clone()), + &pipeline_cache.get_bind_group_layout(&sharpening_pipeline.texture_bind_group), &BindGroupEntries::sequential(( view_target.source, &sharpening_pipeline.sampler, diff --git a/crates/bevy_anti_alias/src/fxaa/node.rs b/crates/bevy_anti_alias/src/fxaa/node.rs index f3e61d253efd1..bf520b776c4c5 100644 --- a/crates/bevy_anti_alias/src/fxaa/node.rs +++ b/crates/bevy_anti_alias/src/fxaa/node.rs @@ -54,7 +54,7 @@ impl ViewNode for FxaaNode { cached_bind_group => { let bind_group = render_context.render_device().create_bind_group( None, - &pipeline_cache.get_bind_group_layout(fxaa_pipeline.texture_bind_group.clone()), + &pipeline_cache.get_bind_group_layout(&fxaa_pipeline.texture_bind_group), &BindGroupEntries::sequential((source, &fxaa_pipeline.sampler)), ); diff --git a/crates/bevy_anti_alias/src/smaa/mod.rs b/crates/bevy_anti_alias/src/smaa/mod.rs index 3c930b50d570b..57190b1b93106 100644 --- a/crates/bevy_anti_alias/src/smaa/mod.rs +++ b/crates/bevy_anti_alias/src/smaa/mod.rs @@ -752,20 +752,18 @@ fn prepare_smaa_bind_groups( edge_detection_bind_group: render_device.create_bind_group( Some("SMAA edge detection bind group"), &pipeline_cache.get_bind_group_layout( - smaa_pipelines + &smaa_pipelines .edge_detection - .edge_detection_bind_group_layout - .clone(), + .edge_detection_bind_group_layout, ), &BindGroupEntries::sequential((&sampler,)), ), blending_weight_calculation_bind_group: render_device.create_bind_group( Some("SMAA blending weight calculation bind group"), &pipeline_cache.get_bind_group_layout( - smaa_pipelines + &smaa_pipelines .blending_weight_calculation - .blending_weight_calculation_bind_group_layout - .clone(), + .blending_weight_calculation_bind_group_layout, ), &BindGroupEntries::sequential(( &smaa_textures.edge_detection_color_texture.default_view, @@ -777,10 +775,9 @@ fn prepare_smaa_bind_groups( neighborhood_blending_bind_group: render_device.create_bind_group( Some("SMAA neighborhood blending bind group"), &pipeline_cache.get_bind_group_layout( - smaa_pipelines + &smaa_pipelines .neighborhood_blending - .neighborhood_blending_bind_group_layout - .clone(), + .neighborhood_blending_bind_group_layout, ), &BindGroupEntries::sequential(( &smaa_textures.blend_texture.default_view, @@ -906,12 +903,8 @@ fn perform_edge_detection( // Create the edge detection bind group. let postprocess_bind_group = render_context.render_device().create_bind_group( None, - &pipeline_cache.get_bind_group_layout( - smaa_pipelines - .edge_detection - .postprocess_bind_group_layout - .clone(), - ), + &pipeline_cache + .get_bind_group_layout(&smaa_pipelines.edge_detection.postprocess_bind_group_layout), &BindGroupEntries::sequential((source, &**smaa_info_uniform_buffer)), ); @@ -967,10 +960,9 @@ fn perform_blending_weight_calculation( let postprocess_bind_group = render_context.render_device().create_bind_group( None, &pipeline_cache.get_bind_group_layout( - smaa_pipelines + &smaa_pipelines .blending_weight_calculation - .postprocess_bind_group_layout - .clone(), + .postprocess_bind_group_layout, ), &BindGroupEntries::sequential((source, &**smaa_info_uniform_buffer)), ); @@ -1029,10 +1021,9 @@ fn perform_neighborhood_blending( let postprocess_bind_group = render_context.render_device().create_bind_group( None, &pipeline_cache.get_bind_group_layout( - smaa_pipelines + &smaa_pipelines .neighborhood_blending - .postprocess_bind_group_layout - .clone(), + .postprocess_bind_group_layout, ), &BindGroupEntries::sequential((source, &**smaa_info_uniform_buffer)), ); diff --git a/crates/bevy_anti_alias/src/taa/mod.rs b/crates/bevy_anti_alias/src/taa/mod.rs index c3532297a0d6c..e396e9accd67b 100644 --- a/crates/bevy_anti_alias/src/taa/mod.rs +++ b/crates/bevy_anti_alias/src/taa/mod.rs @@ -186,7 +186,7 @@ impl ViewNode for TemporalAntiAliasNode { let taa_bind_group = render_context.render_device().create_bind_group( "taa_bind_group", - &pipeline_cache.get_bind_group_layout(pipelines.taa_bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&pipelines.taa_bind_group_layout), &BindGroupEntries::sequential(( view_target.source, &taa_history_textures.read.default_view, diff --git a/crates/bevy_core_pipeline/src/blit/mod.rs b/crates/bevy_core_pipeline/src/blit/mod.rs index f262e1bc48220..0bf0ca7aae91f 100644 --- a/crates/bevy_core_pipeline/src/blit/mod.rs +++ b/crates/bevy_core_pipeline/src/blit/mod.rs @@ -75,7 +75,7 @@ impl BlitPipeline { ) -> BindGroup { render_device.create_bind_group( None, - &pipeline_cache.get_bind_group_layout(self.layout.clone()), + &pipeline_cache.get_bind_group_layout(&self.layout), &BindGroupEntries::sequential((src_texture, &self.sampler)), ) } diff --git a/crates/bevy_core_pipeline/src/deferred/copy_lighting_id.rs b/crates/bevy_core_pipeline/src/deferred/copy_lighting_id.rs index a2b6b9720757c..1889fc33ce6d9 100644 --- a/crates/bevy_core_pipeline/src/deferred/copy_lighting_id.rs +++ b/crates/bevy_core_pipeline/src/deferred/copy_lighting_id.rs @@ -82,8 +82,7 @@ impl ViewNode for CopyDeferredLightingIdNode { let bind_group = render_context.render_device().create_bind_group( "copy_deferred_lighting_id_bind_group", - &pipeline_cache - .get_bind_group_layout(copy_deferred_lighting_id_pipeline.layout.clone()), + &pipeline_cache.get_bind_group_layout(©_deferred_lighting_id_pipeline.layout), &BindGroupEntries::single(&deferred_lighting_pass_id_texture.texture.default_view), ); diff --git a/crates/bevy_core_pipeline/src/experimental/mip_generation/mod.rs b/crates/bevy_core_pipeline/src/experimental/mip_generation/mod.rs index 189710593b6ac..25e4e04ce84e8 100644 --- a/crates/bevy_core_pipeline/src/experimental/mip_generation/mod.rs +++ b/crates/bevy_core_pipeline/src/experimental/mip_generation/mod.rs @@ -765,12 +765,11 @@ fn prepare_downsample_depth_view_bind_groups( "downsample depth bind group" }, &pipeline_cache.get_bind_group_layout(if is_multisampled { - downsample_depth_pipelines + &downsample_depth_pipelines .first_multisample .bind_group_layout - .clone() } else { - downsample_depth_pipelines.first.bind_group_layout.clone() + &downsample_depth_pipelines.first.bind_group_layout }), match (view_depth_texture, shadow_occlusion_culling) { (Some(view_depth_texture), _) => view_depth_texture.view(), diff --git a/crates/bevy_core_pipeline/src/oit/resolve/mod.rs b/crates/bevy_core_pipeline/src/oit/resolve/mod.rs index 65ad52b6e550a..41dd16390d420 100644 --- a/crates/bevy_core_pipeline/src/oit/resolve/mod.rs +++ b/crates/bevy_core_pipeline/src/oit/resolve/mod.rs @@ -247,7 +247,7 @@ pub fn prepare_oit_resolve_bind_group( ) { let bind_group = render_device.create_bind_group( "oit_resolve_bind_group", - &pipeline_cache.get_bind_group_layout(resolve_pipeline.view_bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&resolve_pipeline.view_bind_group_layout), &BindGroupEntries::sequential((binding.clone(), layers_binding, layer_ids_binding)), ); commands.insert_resource(OitResolveBindGroup(bind_group)); diff --git a/crates/bevy_core_pipeline/src/oit/resolve/node.rs b/crates/bevy_core_pipeline/src/oit/resolve/node.rs index 183f26b148cb7..4aa1ee201c8f6 100644 --- a/crates/bevy_core_pipeline/src/oit/resolve/node.rs +++ b/crates/bevy_core_pipeline/src/oit/resolve/node.rs @@ -56,7 +56,7 @@ impl ViewNode for OitResolveNode { let depth_bind_group = render_context.render_device().create_bind_group( "oit_resolve_depth_bind_group", &pipeline_cache - .get_bind_group_layout(resolve_pipeline.oit_depth_bind_group_layout.clone()), + .get_bind_group_layout(&resolve_pipeline.oit_depth_bind_group_layout), &BindGroupEntries::single(depth.view()), ); diff --git a/crates/bevy_core_pipeline/src/skybox/mod.rs b/crates/bevy_core_pipeline/src/skybox/mod.rs index 46e6b58dc23af..88b2bf9f6e43c 100644 --- a/crates/bevy_core_pipeline/src/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/skybox/mod.rs @@ -285,7 +285,7 @@ fn prepare_skybox_bind_groups( ) { let bind_group = render_device.create_bind_group( "skybox_bind_group", - &pipeline_cache.get_bind_group_layout(pipeline.bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&pipeline.bind_group_layout), &BindGroupEntries::sequential(( &skybox.texture_view, &skybox.sampler, diff --git a/crates/bevy_core_pipeline/src/skybox/prepass.rs b/crates/bevy_core_pipeline/src/skybox/prepass.rs index 109c8b647900f..8eb51c10e2067 100644 --- a/crates/bevy_core_pipeline/src/skybox/prepass.rs +++ b/crates/bevy_core_pipeline/src/skybox/prepass.rs @@ -153,7 +153,7 @@ pub fn prepare_skybox_prepass_bind_groups( }; let bind_group = render_device.create_bind_group( "skybox_prepass_bind_group", - &pipeline_cache.get_bind_group_layout(pipeline.bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&pipeline.bind_group_layout), &BindGroupEntries::sequential((view_uniforms, prev_view_uniforms)), ); diff --git a/crates/bevy_core_pipeline/src/tonemapping/node.rs b/crates/bevy_core_pipeline/src/tonemapping/node.rs index 1576f6df54bf2..19fb63b6347e8 100644 --- a/crates/bevy_core_pipeline/src/tonemapping/node.rs +++ b/crates/bevy_core_pipeline/src/tonemapping/node.rs @@ -96,8 +96,7 @@ impl ViewNode for TonemappingNode { let bind_group = render_context.render_device().create_bind_group( None, - &pipeline_cache - .get_bind_group_layout(tonemapping_pipeline.texture_bind_group.clone()), + &pipeline_cache.get_bind_group_layout(&tonemapping_pipeline.texture_bind_group), &BindGroupEntries::sequential(( view_uniforms, source, diff --git a/crates/bevy_gizmos/src/lib.rs b/crates/bevy_gizmos/src/lib.rs index a5503e20535c1..c17ec5d578439 100755 --- a/crates/bevy_gizmos/src/lib.rs +++ b/crates/bevy_gizmos/src/lib.rs @@ -611,7 +611,7 @@ fn prepare_line_gizmo_bind_group( commands.insert_resource(LineGizmoUniformBindgroup { bindgroup: render_device.create_bind_group( "LineGizmoUniform bindgroup", - &pipeline_cache.get_bind_group_layout(line_gizmo_uniform_layout.layout.clone()), + &pipeline_cache.get_bind_group_layout(&line_gizmo_uniform_layout.layout), &BindGroupEntries::single(binding), ), }); diff --git a/crates/bevy_pbr/src/atmosphere/environment.rs b/crates/bevy_pbr/src/atmosphere/environment.rs index dc6e8be6fa50f..211cce3a4b7b2 100644 --- a/crates/bevy_pbr/src/atmosphere/environment.rs +++ b/crates/bevy_pbr/src/atmosphere/environment.rs @@ -109,7 +109,7 @@ pub(super) fn prepare_atmosphere_probe_bind_groups( for (entity, textures) in &probes { let environment = render_device.create_bind_group( "environment_bind_group", - &pipeline_cache.get_bind_group_layout(layouts.environment.clone()), + &pipeline_cache.get_bind_group_layout(&layouts.environment), &BindGroupEntries::sequential(( atmosphere_uniforms.binding().unwrap(), settings_uniforms.binding().unwrap(), diff --git a/crates/bevy_pbr/src/atmosphere/resources.rs b/crates/bevy_pbr/src/atmosphere/resources.rs index a2f8aad78615a..5c409046c0b74 100644 --- a/crates/bevy_pbr/src/atmosphere/resources.rs +++ b/crates/bevy_pbr/src/atmosphere/resources.rs @@ -609,7 +609,7 @@ pub(super) fn prepare_atmosphere_bind_groups( for (entity, textures, view_depth_texture, msaa) in &views { let transmittance_lut = render_device.create_bind_group( "transmittance_lut_bind_group", - &pipeline_cache.get_bind_group_layout(layouts.transmittance_lut.clone()), + &pipeline_cache.get_bind_group_layout(&layouts.transmittance_lut), &BindGroupEntries::with_indices(( (0, atmosphere_binding.clone()), (1, settings_binding.clone()), @@ -619,7 +619,7 @@ pub(super) fn prepare_atmosphere_bind_groups( let multiscattering_lut = render_device.create_bind_group( "multiscattering_lut_bind_group", - &pipeline_cache.get_bind_group_layout(layouts.multiscattering_lut.clone()), + &pipeline_cache.get_bind_group_layout(&layouts.multiscattering_lut), &BindGroupEntries::with_indices(( (0, atmosphere_binding.clone()), (1, settings_binding.clone()), @@ -631,7 +631,7 @@ pub(super) fn prepare_atmosphere_bind_groups( let sky_view_lut = render_device.create_bind_group( "sky_view_lut_bind_group", - &pipeline_cache.get_bind_group_layout(layouts.sky_view_lut.clone()), + &pipeline_cache.get_bind_group_layout(&layouts.sky_view_lut), &BindGroupEntries::with_indices(( (0, atmosphere_binding.clone()), (1, settings_binding.clone()), @@ -648,7 +648,7 @@ pub(super) fn prepare_atmosphere_bind_groups( let aerial_view_lut = render_device.create_bind_group( "sky_view_lut_bind_group", - &pipeline_cache.get_bind_group_layout(layouts.aerial_view_lut.clone()), + &pipeline_cache.get_bind_group_layout(&layouts.aerial_view_lut), &BindGroupEntries::with_indices(( (0, atmosphere_binding.clone()), (1, settings_binding.clone()), @@ -665,9 +665,9 @@ pub(super) fn prepare_atmosphere_bind_groups( let render_sky = render_device.create_bind_group( "render_sky_bind_group", &pipeline_cache.get_bind_group_layout(if *msaa == Msaa::Off { - render_sky_layouts.render_sky.clone() + &render_sky_layouts.render_sky } else { - render_sky_layouts.render_sky_msaa.clone() + &render_sky_layouts.render_sky_msaa }), &BindGroupEntries::with_indices(( (0, atmosphere_binding.clone()), diff --git a/crates/bevy_pbr/src/deferred/mod.rs b/crates/bevy_pbr/src/deferred/mod.rs index 348aca0107ad8..bbce8dc909fa3 100644 --- a/crates/bevy_pbr/src/deferred/mod.rs +++ b/crates/bevy_pbr/src/deferred/mod.rs @@ -182,8 +182,7 @@ impl ViewNode for DeferredOpaquePass3dPbrLightingNode { let bind_group_2 = render_context.render_device().create_bind_group( "deferred_lighting_layout_group_2", - &pipeline_cache - .get_bind_group_layout(deferred_lighting_layout.bind_group_layout_2.clone()), + &pipeline_cache.get_bind_group_layout(&deferred_lighting_layout.bind_group_layout_2), &BindGroupEntries::single(deferred_lighting_pass_id_binding), ); diff --git a/crates/bevy_pbr/src/light_probe/generate.rs b/crates/bevy_pbr/src/light_probe/generate.rs index 284de836190bd..ba54ad14bc09e 100644 --- a/crates/bevy_pbr/src/light_probe/generate.rs +++ b/crates/bevy_pbr/src/light_probe/generate.rs @@ -655,7 +655,7 @@ pub fn prepare_generated_environment_map_bind_groups( // Combined layout expects destinations 1–12 in both bind groups let bind_group = render_device.create_bind_group( "downsampling_bind_group_combined_first", - &pipeline_cache.get_bind_group_layout(layouts.downsampling_first.clone()), + &pipeline_cache.get_bind_group_layout(&layouts.downsampling_first), &BindGroupEntries::sequential(( &samplers.linear, &downsampling_constants_buffer, @@ -688,7 +688,7 @@ pub fn prepare_generated_environment_map_bind_groups( // Split layout (current behavior) let first = render_device.create_bind_group( "downsampling_first_bind_group", - &pipeline_cache.get_bind_group_layout(layouts.downsampling_first.clone()), + &pipeline_cache.get_bind_group_layout(&layouts.downsampling_first), &BindGroupEntries::sequential(( &samplers.linear, &downsampling_constants_buffer, @@ -704,7 +704,7 @@ pub fn prepare_generated_environment_map_bind_groups( let second = render_device.create_bind_group( "downsampling_second_bind_group", - &pipeline_cache.get_bind_group_layout(layouts.downsampling_second.clone()), + &pipeline_cache.get_bind_group_layout(&layouts.downsampling_second), &BindGroupEntries::sequential(( &samplers.linear, &downsampling_constants_buffer, @@ -757,7 +757,7 @@ pub fn prepare_generated_environment_map_bind_groups( ); let bind_group = render_device.create_bind_group( Some(format!("radiance_bind_group_mip_{mip}").as_str()), - &pipeline_cache.get_bind_group_layout(layouts.radiance.clone()), + &pipeline_cache.get_bind_group_layout(&layouts.radiance), &BindGroupEntries::sequential(( &textures.environment_map.default_view, &samplers.linear, @@ -794,7 +794,7 @@ pub fn prepare_generated_environment_map_bind_groups( let irradiance_bind_group = render_device.create_bind_group( "irradiance_bind_group", - &pipeline_cache.get_bind_group_layout(layouts.irradiance.clone()), + &pipeline_cache.get_bind_group_layout(&layouts.irradiance), &BindGroupEntries::sequential(( &textures.environment_map.default_view, &samplers.linear, @@ -817,7 +817,7 @@ pub fn prepare_generated_environment_map_bind_groups( let copy_bind_group = render_device.create_bind_group( "copy_bind_group", - &pipeline_cache.get_bind_group_layout(layouts.copy.clone()), + &pipeline_cache.get_bind_group_layout(&layouts.copy), &BindGroupEntries::with_indices(((0, &src_view), (1, &dst_view))), ); diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index 356db5b36ce2a..dc378f9bcf8bc 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -1676,7 +1676,7 @@ where ) } - let actual_material_layout = pipeline_cache.get_bind_group_layout(material_layout.clone()); + let actual_material_layout = pipeline_cache.get_bind_group_layout(&material_layout); match material.unprepared_bind_group( &actual_material_layout, diff --git a/crates/bevy_pbr/src/material_bind_groups.rs b/crates/bevy_pbr/src/material_bind_groups.rs index 5949bb81c2c8d..1967410cd3430 100644 --- a/crates/bevy_pbr/src/material_bind_groups.rs +++ b/crates/bevy_pbr/src/material_bind_groups.rs @@ -1273,7 +1273,7 @@ impl MaterialBindlessSlab { self.bind_group = Some(render_device.create_bind_group( label, - &pipeline_cache.get_bind_group_layout(bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&bind_group_layout), &bind_group_entries, )); } @@ -1920,7 +1920,7 @@ impl MaterialBindGroupNonBindlessAllocator { // Create the bind group. let bind_group = render_device.create_bind_group( self.label, - &pipeline_cache.get_bind_group_layout(bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&bind_group_layout), &bind_group_entries, ); diff --git a/crates/bevy_pbr/src/prepass/mod.rs b/crates/bevy_pbr/src/prepass/mod.rs index 7c7e36d5d168e..317e6a6b06165 100644 --- a/crates/bevy_pbr/src/prepass/mod.rs +++ b/crates/bevy_pbr/src/prepass/mod.rs @@ -707,7 +707,7 @@ pub fn init_prepass_view_bind_group( ) { let empty_bind_group = render_device.create_bind_group( "prepass_view_empty_bind_group", - &pipeline_cache.get_bind_group_layout(pipeline.empty_layout.clone()), + &pipeline_cache.get_bind_group_layout(&pipeline.empty_layout), &[], ); commands.insert_resource(PrepassViewBindGroup { @@ -732,33 +732,27 @@ pub fn prepare_prepass_view_bind_group( globals_buffer.buffer.binding(), visibility_ranges.buffer().buffer(), ) { - prepass_view_bind_group.no_motion_vectors = Some( - render_device.create_bind_group( - "prepass_view_no_motion_vectors_bind_group", - &pipeline_cache - .get_bind_group_layout(prepass_pipeline.view_layout_no_motion_vectors.clone()), + prepass_view_bind_group.no_motion_vectors = Some(render_device.create_bind_group( + "prepass_view_no_motion_vectors_bind_group", + &pipeline_cache.get_bind_group_layout(&prepass_pipeline.view_layout_no_motion_vectors), + &BindGroupEntries::with_indices(( + (0, view_binding.clone()), + (1, globals_binding.clone()), + (14, visibility_ranges_buffer.as_entire_binding()), + )), + )); + + if let Some(previous_view_uniforms_binding) = previous_view_uniforms.uniforms.binding() { + prepass_view_bind_group.motion_vectors = Some(render_device.create_bind_group( + "prepass_view_motion_vectors_bind_group", + &pipeline_cache.get_bind_group_layout(&prepass_pipeline.view_layout_motion_vectors), &BindGroupEntries::with_indices(( - (0, view_binding.clone()), - (1, globals_binding.clone()), + (0, view_binding), + (1, globals_binding), + (2, previous_view_uniforms_binding), (14, visibility_ranges_buffer.as_entire_binding()), )), - ), - ); - - if let Some(previous_view_uniforms_binding) = previous_view_uniforms.uniforms.binding() { - prepass_view_bind_group.motion_vectors = Some( - render_device.create_bind_group( - "prepass_view_motion_vectors_bind_group", - &pipeline_cache - .get_bind_group_layout(prepass_pipeline.view_layout_motion_vectors.clone()), - &BindGroupEntries::with_indices(( - (0, view_binding), - (1, globals_binding), - (2, previous_view_uniforms_binding), - (14, visibility_ranges_buffer.as_entire_binding()), - )), - ), - ); + )); } } } diff --git a/crates/bevy_pbr/src/render/gpu_preprocess.rs b/crates/bevy_pbr/src/render/gpu_preprocess.rs index 1410e989bc55c..04abbaca71d25 100644 --- a/crates/bevy_pbr/src/render/gpu_preprocess.rs +++ b/crates/bevy_pbr/src/render/gpu_preprocess.rs @@ -1944,9 +1944,9 @@ impl<'a> PreprocessBindGroupBuilder<'a> { Some(PhasePreprocessBindGroups::Direct( self.render_device.create_bind_group( "preprocess_direct_bind_group", - &self.pipeline_cache.get_bind_group_layout( - self.pipelines.direct_preprocess.bind_group_layout.clone(), - ), + &self + .pipeline_cache + .get_bind_group_layout(&self.pipelines.direct_preprocess.bind_group_layout), &BindGroupEntries::with_indices(( (0, self.view_uniforms.uniforms.binding()?), (3, self.current_input_buffer.as_entire_binding()), @@ -2056,10 +2056,10 @@ impl<'a> PreprocessBindGroupBuilder<'a> { self.render_device.create_bind_group( "preprocess_early_indexed_gpu_occlusion_culling_bind_group", &self.pipeline_cache.get_bind_group_layout( - self.pipelines + &self + .pipelines .early_gpu_occlusion_culling_preprocess - .bind_group_layout - .clone(), + .bind_group_layout, ), &BindGroupEntries::with_indices(( (3, self.current_input_buffer.as_entire_binding()), @@ -2156,10 +2156,10 @@ impl<'a> PreprocessBindGroupBuilder<'a> { self.render_device.create_bind_group( "preprocess_early_non_indexed_gpu_occlusion_culling_bind_group", &self.pipeline_cache.get_bind_group_layout( - self.pipelines + &self + .pipelines .early_gpu_occlusion_culling_preprocess - .bind_group_layout - .clone(), + .bind_group_layout, ), &BindGroupEntries::with_indices(( (3, self.current_input_buffer.as_entire_binding()), @@ -2253,10 +2253,10 @@ impl<'a> PreprocessBindGroupBuilder<'a> { self.render_device.create_bind_group( "preprocess_late_indexed_gpu_occlusion_culling_bind_group", &self.pipeline_cache.get_bind_group_layout( - self.pipelines + &self + .pipelines .late_gpu_occlusion_culling_preprocess - .bind_group_layout - .clone(), + .bind_group_layout, ), &BindGroupEntries::with_indices(( (3, self.current_input_buffer.as_entire_binding()), @@ -2342,10 +2342,10 @@ impl<'a> PreprocessBindGroupBuilder<'a> { self.render_device.create_bind_group( "preprocess_late_non_indexed_gpu_occlusion_culling_bind_group", &self.pipeline_cache.get_bind_group_layout( - self.pipelines + &self + .pipelines .late_gpu_occlusion_culling_preprocess - .bind_group_layout - .clone(), + .bind_group_layout, ), &BindGroupEntries::with_indices(( (3, self.current_input_buffer.as_entire_binding()), @@ -2442,10 +2442,10 @@ impl<'a> PreprocessBindGroupBuilder<'a> { self.render_device.create_bind_group( "preprocess_gpu_indexed_frustum_culling_bind_group", &self.pipeline_cache.get_bind_group_layout( - self.pipelines + &self + .pipelines .gpu_frustum_culling_preprocess - .bind_group_layout - .clone(), + .bind_group_layout, ), &BindGroupEntries::with_indices(( (3, self.current_input_buffer.as_entire_binding()), @@ -2507,10 +2507,10 @@ impl<'a> PreprocessBindGroupBuilder<'a> { self.render_device.create_bind_group( "preprocess_gpu_non_indexed_frustum_culling_bind_group", &self.pipeline_cache.get_bind_group_layout( - self.pipelines + &self + .pipelines .gpu_frustum_culling_preprocess - .bind_group_layout - .clone(), + .bind_group_layout, ), &BindGroupEntries::with_indices(( (3, self.current_input_buffer.as_entire_binding()), @@ -2564,11 +2564,10 @@ fn create_build_indirect_parameters_bind_groups( // The early bind group is good for the main phase and late // phase too. They bind the same buffers. &pipeline_cache.get_bind_group_layout( - pipelines + &pipelines .early_phase .reset_indirect_batch_sets - .bind_group_layout - .clone(), + .bind_group_layout, ), &BindGroupEntries::sequential(( indexed_batch_sets_buffer.as_entire_binding(), @@ -2588,11 +2587,10 @@ fn create_build_indirect_parameters_bind_groups( // The early bind group is good for the main phase and late // phase too. They bind the same buffers. &pipeline_cache.get_bind_group_layout( - pipelines + &pipelines .early_phase .reset_indirect_batch_sets - .bind_group_layout - .clone(), + .bind_group_layout, ), &BindGroupEntries::sequential(( non_indexed_batch_sets_buffer.as_entire_binding(), @@ -2623,10 +2621,9 @@ fn create_build_indirect_parameters_bind_groups( // The frustum culling bind group is good for occlusion culling // too. They bind the same buffers. &pipeline_cache.get_bind_group_layout( - pipelines + &pipelines .gpu_frustum_culling_build_indexed_indirect_params - .bind_group_layout - .clone(), + .bind_group_layout, ), &BindGroupEntries::sequential(( current_input_buffer.as_entire_binding(), @@ -2681,10 +2678,9 @@ fn create_build_indirect_parameters_bind_groups( // The frustum culling bind group is good for occlusion culling // too. They bind the same buffers. &pipeline_cache.get_bind_group_layout( - pipelines + &pipelines .gpu_frustum_culling_build_non_indexed_indirect_params - .bind_group_layout - .clone(), + .bind_group_layout, ), &BindGroupEntries::sequential(( current_input_buffer.as_entire_binding(), diff --git a/crates/bevy_pbr/src/render/mesh_bindings.rs b/crates/bevy_pbr/src/render/mesh_bindings.rs index 0936fc20f6bdc..acaa31c312390 100644 --- a/crates/bevy_pbr/src/render/mesh_bindings.rs +++ b/crates/bevy_pbr/src/render/mesh_bindings.rs @@ -377,7 +377,7 @@ impl MeshLayouts { ) -> BindGroup { render_device.create_bind_group( "model_only_mesh_bind_group", - &pipeline_cache.get_bind_group_layout(self.model_only.clone()), + &pipeline_cache.get_bind_group_layout(&self.model_only), &[entry::model(0, model.clone())], ) } @@ -394,7 +394,7 @@ impl MeshLayouts { let (texture_views, samplers) = lightmap_slab.build_binding_arrays(); render_device.create_bind_group( "lightmapped_mesh_bind_group", - &pipeline_cache.get_bind_group_layout(self.lightmapped.clone()), + &pipeline_cache.get_bind_group_layout(&self.lightmapped), &[ entry::model(0, model.clone()), entry::lightmaps_texture_view_array(4, &texture_views), @@ -405,7 +405,7 @@ impl MeshLayouts { let (texture_view, sampler) = lightmap_slab.bindings_for_first_lightmap(); render_device.create_bind_group( "lightmapped_mesh_bind_group", - &pipeline_cache.get_bind_group_layout(self.lightmapped.clone()), + &pipeline_cache.get_bind_group_layout(&self.lightmapped), &[ entry::model(0, model.clone()), entry::lightmaps_texture_view(4, texture_view), @@ -425,7 +425,7 @@ impl MeshLayouts { ) -> BindGroup { render_device.create_bind_group( "skinned_mesh_bind_group", - &pipeline_cache.get_bind_group_layout(self.skinned.clone()), + &pipeline_cache.get_bind_group_layout(&self.skinned), &[ entry::model(0, model.clone()), entry::skinning(render_device, 1, current_skin), @@ -450,7 +450,7 @@ impl MeshLayouts { ) -> BindGroup { render_device.create_bind_group( "skinned_motion_mesh_bind_group", - &pipeline_cache.get_bind_group_layout(self.skinned_motion.clone()), + &pipeline_cache.get_bind_group_layout(&self.skinned_motion), &[ entry::model(0, model.clone()), entry::skinning(render_device, 1, current_skin), @@ -470,7 +470,7 @@ impl MeshLayouts { ) -> BindGroup { render_device.create_bind_group( "morphed_mesh_bind_group", - &pipeline_cache.get_bind_group_layout(self.morphed.clone()), + &pipeline_cache.get_bind_group_layout(&self.morphed), &[ entry::model(0, model.clone()), entry::weights(2, current_weights), @@ -497,7 +497,7 @@ impl MeshLayouts { ) -> BindGroup { render_device.create_bind_group( "morphed_motion_mesh_bind_group", - &pipeline_cache.get_bind_group_layout(self.morphed_motion.clone()), + &pipeline_cache.get_bind_group_layout(&self.morphed_motion), &[ entry::model(0, model.clone()), entry::weights(2, current_weights), @@ -519,7 +519,7 @@ impl MeshLayouts { ) -> BindGroup { render_device.create_bind_group( "morphed_skinned_mesh_bind_group", - &pipeline_cache.get_bind_group_layout(self.morphed_skinned.clone()), + &pipeline_cache.get_bind_group_layout(&self.morphed_skinned), &[ entry::model(0, model.clone()), entry::skinning(render_device, 1, current_skin), @@ -549,7 +549,7 @@ impl MeshLayouts { ) -> BindGroup { render_device.create_bind_group( "morphed_skinned_motion_mesh_bind_group", - &pipeline_cache.get_bind_group_layout(self.morphed_skinned_motion.clone()), + &pipeline_cache.get_bind_group_layout(&self.morphed_skinned_motion), &[ entry::model(0, model.clone()), entry::skinning(render_device, 1, current_skin), diff --git a/crates/bevy_pbr/src/render/mesh_view_bindings.rs b/crates/bevy_pbr/src/render/mesh_view_bindings.rs index 28e30dfc245fa..3550e4c8eb0d4 100644 --- a/crates/bevy_pbr/src/render/mesh_view_bindings.rs +++ b/crates/bevy_pbr/src/render/mesh_view_bindings.rs @@ -800,17 +800,17 @@ pub fn prepare_mesh_view_bind_groups( commands.entity(entity).insert(MeshViewBindGroup { main: render_device.create_bind_group( "mesh_view_bind_group", - &pipeline_cache.get_bind_group_layout(layout.main_layout.clone()), + &pipeline_cache.get_bind_group_layout(&layout.main_layout), &entries, ), binding_array: render_device.create_bind_group( "mesh_view_bind_group_binding_array", - &pipeline_cache.get_bind_group_layout(layout.binding_array_layout.clone()), + &pipeline_cache.get_bind_group_layout(&layout.binding_array_layout), &entries_binding_array, ), empty: render_device.create_bind_group( "mesh_view_bind_group_empty", - &pipeline_cache.get_bind_group_layout(layout.empty_layout.clone()), + &pipeline_cache.get_bind_group_layout(&layout.empty_layout), &[], ), }); diff --git a/crates/bevy_pbr/src/ssao/mod.rs b/crates/bevy_pbr/src/ssao/mod.rs index f590b48d6498e..e903792aed05a 100644 --- a/crates/bevy_pbr/src/ssao/mod.rs +++ b/crates/bevy_pbr/src/ssao/mod.rs @@ -656,7 +656,7 @@ fn prepare_ssao_bind_groups( for (entity, ssao_resources, prepass_textures) in &views { let common_bind_group = render_device.create_bind_group( "ssao_common_bind_group", - &pipeline_cache.get_bind_group_layout(pipelines.common_bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&pipelines.common_bind_group_layout), &BindGroupEntries::sequential(( &pipelines.point_clamp_sampler, &pipelines.linear_clamp_sampler, @@ -680,8 +680,7 @@ fn prepare_ssao_bind_groups( let preprocess_depth_bind_group = render_device.create_bind_group( "ssao_preprocess_depth_bind_group", - &pipeline_cache - .get_bind_group_layout(pipelines.preprocess_depth_bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&pipelines.preprocess_depth_bind_group_layout), &BindGroupEntries::sequential(( prepass_textures.depth_view().unwrap(), &create_depth_view(0), @@ -694,7 +693,7 @@ fn prepare_ssao_bind_groups( let ssao_bind_group = render_device.create_bind_group( "ssao_ssao_bind_group", - &pipeline_cache.get_bind_group_layout(pipelines.ssao_bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&pipelines.ssao_bind_group_layout), &BindGroupEntries::sequential(( &ssao_resources.preprocessed_depth_texture.default_view, prepass_textures.normal_view().unwrap(), @@ -708,8 +707,7 @@ fn prepare_ssao_bind_groups( let spatial_denoise_bind_group = render_device.create_bind_group( "ssao_spatial_denoise_bind_group", - &pipeline_cache - .get_bind_group_layout(pipelines.spatial_denoise_bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&pipelines.spatial_denoise_bind_group_layout), &BindGroupEntries::sequential(( &ssao_resources.ssao_noisy_texture.default_view, &ssao_resources.depth_differences_texture.default_view, diff --git a/crates/bevy_pbr/src/ssr/mod.rs b/crates/bevy_pbr/src/ssr/mod.rs index 0669d7f157291..b752b3daf9214 100644 --- a/crates/bevy_pbr/src/ssr/mod.rs +++ b/crates/bevy_pbr/src/ssr/mod.rs @@ -292,7 +292,7 @@ impl ViewNode for ScreenSpaceReflectionsNode { let ssr_pipeline = world.resource::(); let ssr_bind_group = render_context.render_device().create_bind_group( "SSR bind group", - &pipeline_cache.get_bind_group_layout(ssr_pipeline.bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&ssr_pipeline.bind_group_layout), &BindGroupEntries::sequential(( postprocess.source, &ssr_pipeline.color_sampler, diff --git a/crates/bevy_pbr/src/volumetric_fog/render.rs b/crates/bevy_pbr/src/volumetric_fog/render.rs index f2e61249e93ea..ff0942772f456 100644 --- a/crates/bevy_pbr/src/volumetric_fog/render.rs +++ b/crates/bevy_pbr/src/volumetric_fog/render.rs @@ -431,7 +431,7 @@ impl ViewNode for VolumetricFogNode { let volumetric_view_bind_group = render_context.render_device().create_bind_group( None, - &pipeline_cache.get_bind_group_layout(volumetric_view_bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&volumetric_view_bind_group_layout), &bind_group_entries, ); diff --git a/crates/bevy_post_process/src/auto_exposure/node.rs b/crates/bevy_post_process/src/auto_exposure/node.rs index 6676f5ab46bf1..a59a05d79b58e 100644 --- a/crates/bevy_post_process/src/auto_exposure/node.rs +++ b/crates/bevy_post_process/src/auto_exposure/node.rs @@ -103,7 +103,7 @@ impl Node for AutoExposureNode { let compute_bind_group = render_context.render_device().create_bind_group( None, - &pipeline_cache.get_bind_group_layout(pipeline.histogram_layout.clone()), + &pipeline_cache.get_bind_group_layout(&pipeline.histogram_layout), &BindGroupEntries::sequential(( &globals_buffer.buffer, &auto_exposure_buffers.settings, diff --git a/crates/bevy_post_process/src/bloom/mod.rs b/crates/bevy_post_process/src/bloom/mod.rs index 565e91ad9e085..a35e716ecdb8c 100644 --- a/crates/bevy_post_process/src/bloom/mod.rs +++ b/crates/bevy_post_process/src/bloom/mod.rs @@ -178,7 +178,7 @@ impl ViewNode for BloomNode { let downsampling_first_bind_group = render_device.create_bind_group( "bloom_downsampling_first_bind_group", &pipeline_cache - .get_bind_group_layout(downsampling_pipeline_res.bind_group_layout.clone()), + .get_bind_group_layout(&downsampling_pipeline_res.bind_group_layout), &BindGroupEntries::sequential(( // Read from main texture directly view_texture, @@ -438,34 +438,28 @@ fn prepare_bloom_bind_groups( let mut downsampling_bind_groups = Vec::with_capacity(bind_group_count); for mip in 1..bloom_texture.mip_count { - downsampling_bind_groups.push( - render_device.create_bind_group( - "bloom_downsampling_bind_group", - &pipeline_cache - .get_bind_group_layout(downsampling_pipeline.bind_group_layout.clone()), - &BindGroupEntries::sequential(( - &bloom_texture.view(mip - 1), - sampler, - uniforms.binding().unwrap(), - )), - ), - ); + downsampling_bind_groups.push(render_device.create_bind_group( + "bloom_downsampling_bind_group", + &pipeline_cache.get_bind_group_layout(&downsampling_pipeline.bind_group_layout), + &BindGroupEntries::sequential(( + &bloom_texture.view(mip - 1), + sampler, + uniforms.binding().unwrap(), + )), + )); } let mut upsampling_bind_groups = Vec::with_capacity(bind_group_count); for mip in (0..bloom_texture.mip_count).rev() { - upsampling_bind_groups.push( - render_device.create_bind_group( - "bloom_upsampling_bind_group", - &pipeline_cache - .get_bind_group_layout(upsampling_pipeline.bind_group_layout.clone()), - &BindGroupEntries::sequential(( - &bloom_texture.view(mip), - sampler, - uniforms.binding().unwrap(), - )), - ), - ); + upsampling_bind_groups.push(render_device.create_bind_group( + "bloom_upsampling_bind_group", + &pipeline_cache.get_bind_group_layout(&upsampling_pipeline.bind_group_layout), + &BindGroupEntries::sequential(( + &bloom_texture.view(mip), + sampler, + uniforms.binding().unwrap(), + )), + )); } commands.entity(entity).insert(BloomBindGroups { diff --git a/crates/bevy_post_process/src/dof/mod.rs b/crates/bevy_post_process/src/dof/mod.rs index 3f0b85658e118..7460f96f06619 100644 --- a/crates/bevy_post_process/src/dof/mod.rs +++ b/crates/bevy_post_process/src/dof/mod.rs @@ -388,7 +388,7 @@ impl ViewNode for DepthOfFieldNode { }; render_context.render_device().create_bind_group( Some(pipeline_render_info.view_bind_group_label), - &pipeline_cache.get_bind_group_layout(dual_input_bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&dual_input_bind_group_layout), &BindGroupEntries::sequential(( view_uniforms_binding, view_depth_texture.view(), @@ -399,8 +399,7 @@ impl ViewNode for DepthOfFieldNode { } else { render_context.render_device().create_bind_group( Some(pipeline_render_info.view_bind_group_label), - &pipeline_cache - .get_bind_group_layout(view_bind_group_layouts.single_input.clone()), + &pipeline_cache.get_bind_group_layout(&view_bind_group_layouts.single_input), &BindGroupEntries::sequential(( view_uniforms_binding, view_depth_texture.view(), @@ -625,7 +624,7 @@ pub fn prepare_depth_of_field_global_bind_group( **dof_bind_group = Some(render_device.create_bind_group( Some("depth of field global bind group"), - &pipeline_cache.get_bind_group_layout(global_bind_group_layout.layout.clone()), + &pipeline_cache.get_bind_group_layout(&global_bind_group_layout.layout), &BindGroupEntries::sequential(( depth_of_field_uniforms, // `dof_params` &global_bind_group_layout.color_texture_sampler, // `color_texture_sampler` diff --git a/crates/bevy_post_process/src/effect_stack/mod.rs b/crates/bevy_post_process/src/effect_stack/mod.rs index 65f7ada212e3d..444377781b83d 100644 --- a/crates/bevy_post_process/src/effect_stack/mod.rs +++ b/crates/bevy_post_process/src/effect_stack/mod.rs @@ -395,8 +395,7 @@ impl ViewNode for PostProcessingNode { let bind_group = render_context.render_device().create_bind_group( Some("postprocessing bind group"), - &pipeline_cache - .get_bind_group_layout(post_processing_pipeline.bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&post_processing_pipeline.bind_group_layout), &BindGroupEntries::sequential(( post_process.source, &post_processing_pipeline.source_sampler, diff --git a/crates/bevy_post_process/src/motion_blur/node.rs b/crates/bevy_post_process/src/motion_blur/node.rs index 2e827e8c782f4..89adfe0e0c6d0 100644 --- a/crates/bevy_post_process/src/motion_blur/node.rs +++ b/crates/bevy_post_process/src/motion_blur/node.rs @@ -72,7 +72,7 @@ impl ViewNode for MotionBlurNode { let bind_group = render_context.render_device().create_bind_group( Some("motion_blur_bind_group"), - &pipeline_cache.get_bind_group_layout(layout.clone()), + &pipeline_cache.get_bind_group_layout(&layout), &BindGroupEntries::sequential(( post_process.source, &prepass_motion_vectors_texture.texture.default_view, diff --git a/crates/bevy_render/src/render_resource/bind_group.rs b/crates/bevy_render/src/render_resource/bind_group.rs index 14155856ff211..19b28e15557f1 100644 --- a/crates/bevy_render/src/render_resource/bind_group.rs +++ b/crates/bevy_render/src/render_resource/bind_group.rs @@ -536,7 +536,7 @@ pub trait AsBindGroup { pipeline_cache: &PipelineCache, param: &mut SystemParamItem<'_, '_, Self::Param>, ) -> Result { - let layout = &pipeline_cache.get_bind_group_layout(layout_descriptor.clone()); + let layout = &pipeline_cache.get_bind_group_layout(layout_descriptor); let UnpreparedBindGroup { bindings } = Self::unprepared_bind_group(self, layout, render_device, param, false)?; @@ -591,7 +591,7 @@ pub trait AsBindGroup { } /// Creates the bind group layout descriptor matching all bind groups returned by - /// [`AsBindGroup::as_bind_group_descriptor`] + /// [`AsBindGroup::as_bind_group`] fn bind_group_layout_descriptor() -> BindGroupLayoutDescriptor where Self: Sized, diff --git a/crates/bevy_render/src/render_resource/pipeline_cache.rs b/crates/bevy_render/src/render_resource/pipeline_cache.rs index 96a9d10bbc098..d3abfd68bc314 100644 --- a/crates/bevy_render/src/render_resource/pipeline_cache.rs +++ b/crates/bevy_render/src/render_resource/pipeline_cache.rs @@ -222,6 +222,7 @@ impl BindGroupLayoutCache { .entry(descriptor) .or_insert_with_key(|descriptor| { render_device.create_bind_group_layout( + #[expect(clippy::redundant_closure_for_method_calls, reason = "TODO")] descriptor.label.as_ref().map(|s| s.as_ref()), &descriptor.entries, ) @@ -476,7 +477,7 @@ impl PipelineCache { pub fn get_bind_group_layout( &self, - bind_group_layout_descriptor: BindGroupLayoutDescriptor, + bind_group_layout_descriptor: &BindGroupLayoutDescriptor, ) -> BindGroupLayout { self.bindgroup_layout_cache .lock() diff --git a/crates/bevy_render/src/view/window/screenshot.rs b/crates/bevy_render/src/view/window/screenshot.rs index 51c1659f376cd..82fb927479fa6 100644 --- a/crates/bevy_render/src/view/window/screenshot.rs +++ b/crates/bevy_render/src/view/window/screenshot.rs @@ -376,7 +376,7 @@ fn prepare_screenshot_state( }); let bind_group = render_device.create_bind_group( "screenshot-to-screen-bind-group", - &pipeline_cache.get_bind_group_layout(pipeline.bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&pipeline.bind_group_layout), &BindGroupEntries::single(&texture_view), ); let pipeline_id = pipelines.specialize(pipeline_cache, pipeline, format); diff --git a/crates/bevy_sprite_render/src/mesh2d/mesh.rs b/crates/bevy_sprite_render/src/mesh2d/mesh.rs index 87620d800269e..d73cd731ae872 100644 --- a/crates/bevy_sprite_render/src/mesh2d/mesh.rs +++ b/crates/bevy_sprite_render/src/mesh2d/mesh.rs @@ -717,7 +717,7 @@ pub fn prepare_mesh2d_bind_group( commands.insert_resource(Mesh2dBindGroup { value: render_device.create_bind_group( "mesh2d_bind_group", - &pipeline_cache.get_bind_group_layout(mesh2d_pipeline.mesh_layout.clone()), + &pipeline_cache.get_bind_group_layout(&mesh2d_pipeline.mesh_layout), &BindGroupEntries::single(binding), ), }); @@ -753,7 +753,7 @@ pub fn prepare_mesh2d_view_bind_groups( get_lut_bindings(&images, &tonemapping_luts, tonemapping, &fallback_image); let view_bind_group = render_device.create_bind_group( "mesh2d_view_bind_group", - &pipeline_cache.get_bind_group_layout(mesh2d_pipeline.view_layout.clone()), + &pipeline_cache.get_bind_group_layout(&mesh2d_pipeline.view_layout), &BindGroupEntries::sequential(( view_binding.clone(), globals.clone(), diff --git a/crates/bevy_sprite_render/src/render/mod.rs b/crates/bevy_sprite_render/src/render/mod.rs index 4a03d17006cb0..8dddb37ad2978 100644 --- a/crates/bevy_sprite_render/src/render/mod.rs +++ b/crates/bevy_sprite_render/src/render/mod.rs @@ -620,7 +620,7 @@ pub fn prepare_sprite_view_bind_groups( get_lut_bindings(&images, &tonemapping_luts, tonemapping, &fallback_image); let view_bind_group = render_device.create_bind_group( "mesh2d_view_bind_group", - &pipeline_cache.get_bind_group_layout(sprite_pipeline.view_layout.clone()), + &pipeline_cache.get_bind_group_layout(&sprite_pipeline.view_layout), &BindGroupEntries::sequential((view_binding.clone(), lut_bindings.0, lut_bindings.1)), ); @@ -703,8 +703,7 @@ pub fn prepare_sprite_image_bind_groups( .or_insert_with(|| { render_device.create_bind_group( "sprite_material_bind_group", - &pipeline_cache - .get_bind_group_layout(sprite_pipeline.material_layout.clone()), + &pipeline_cache.get_bind_group_layout(&sprite_pipeline.material_layout), &BindGroupEntries::sequential(( &gpu_image.texture_view, &gpu_image.sampler, diff --git a/crates/bevy_ui_render/src/box_shadow.rs b/crates/bevy_ui_render/src/box_shadow.rs index 3a417cc97d77e..157d9306cc67f 100644 --- a/crates/bevy_ui_render/src/box_shadow.rs +++ b/crates/bevy_ui_render/src/box_shadow.rs @@ -371,7 +371,7 @@ pub fn prepare_shadows( ui_meta.indices.clear(); ui_meta.view_bind_group = Some(render_device.create_bind_group( "box_shadow_view_bind_group", - &pipeline_cache.get_bind_group_layout(box_shadow_pipeline.view_layout.clone()), + &pipeline_cache.get_bind_group_layout(&box_shadow_pipeline.view_layout), &BindGroupEntries::single(view_binding), )); diff --git a/crates/bevy_ui_render/src/gradient.rs b/crates/bevy_ui_render/src/gradient.rs index 34e1eba2ab887..6d32274fc4f72 100644 --- a/crates/bevy_ui_render/src/gradient.rs +++ b/crates/bevy_ui_render/src/gradient.rs @@ -708,7 +708,7 @@ pub fn prepare_gradient( ui_meta.indices.clear(); ui_meta.view_bind_group = Some(render_device.create_bind_group( "gradient_view_bind_group", - &pipeline_cache.get_bind_group_layout(gradients_pipeline.view_layout.clone()), + &pipeline_cache.get_bind_group_layout(&gradients_pipeline.view_layout), &BindGroupEntries::single(view_binding), )); diff --git a/crates/bevy_ui_render/src/lib.rs b/crates/bevy_ui_render/src/lib.rs index 60d727563b351..3337eeab0dd72 100644 --- a/crates/bevy_ui_render/src/lib.rs +++ b/crates/bevy_ui_render/src/lib.rs @@ -1318,7 +1318,7 @@ pub fn prepare_uinodes( ui_meta.indices.clear(); ui_meta.view_bind_group = Some(render_device.create_bind_group( "ui_view_bind_group", - &pipeline_cache.get_bind_group_layout(ui_pipeline.view_layout.clone()), + &pipeline_cache.get_bind_group_layout(&ui_pipeline.view_layout), &BindGroupEntries::single(view_binding), )); @@ -1367,7 +1367,7 @@ pub fn prepare_uinodes( render_device.create_bind_group( "ui_material_bind_group", &pipeline_cache - .get_bind_group_layout(ui_pipeline.image_layout.clone()), + .get_bind_group_layout(&ui_pipeline.image_layout), &BindGroupEntries::sequential(( &gpu_image.texture_view, &gpu_image.sampler, @@ -1395,7 +1395,7 @@ pub fn prepare_uinodes( render_device.create_bind_group( "ui_material_bind_group", &pipeline_cache - .get_bind_group_layout(ui_pipeline.image_layout.clone()), + .get_bind_group_layout(&ui_pipeline.image_layout), &BindGroupEntries::sequential(( &gpu_image.texture_view, &gpu_image.sampler, diff --git a/crates/bevy_ui_render/src/ui_material_pipeline.rs b/crates/bevy_ui_render/src/ui_material_pipeline.rs index 207dc01b577b0..8e4b5b3ceb38c 100644 --- a/crates/bevy_ui_render/src/ui_material_pipeline.rs +++ b/crates/bevy_ui_render/src/ui_material_pipeline.rs @@ -397,7 +397,7 @@ pub fn prepare_uimaterial_nodes( ui_meta.vertices.clear(); ui_meta.view_bind_group = Some(render_device.create_bind_group( "ui_material_view_bind_group", - &pipeline_cache.get_bind_group_layout(ui_material_pipeline.view_layout.clone()), + &pipeline_cache.get_bind_group_layout(&ui_material_pipeline.view_layout), &BindGroupEntries::sequential((view_binding, globals_binding)), )); let mut index = 0; diff --git a/crates/bevy_ui_render/src/ui_texture_slice_pipeline.rs b/crates/bevy_ui_render/src/ui_texture_slice_pipeline.rs index c31e54ca27c5f..ff1e056562914 100644 --- a/crates/bevy_ui_render/src/ui_texture_slice_pipeline.rs +++ b/crates/bevy_ui_render/src/ui_texture_slice_pipeline.rs @@ -387,7 +387,7 @@ pub fn prepare_ui_slices( ui_meta.indices.clear(); ui_meta.view_bind_group = Some(render_device.create_bind_group( "ui_texture_slice_view_bind_group", - &pipeline_cache.get_bind_group_layout(texture_slicer_pipeline.view_layout.clone()), + &pipeline_cache.get_bind_group_layout(&texture_slicer_pipeline.view_layout), &BindGroupEntries::single(view_binding), )); @@ -434,7 +434,7 @@ pub fn prepare_ui_slices( render_device.create_bind_group( "ui_texture_slice_image_layout", &pipeline_cache.get_bind_group_layout( - texture_slicer_pipeline.image_layout.clone(), + &texture_slicer_pipeline.image_layout, ), &BindGroupEntries::sequential(( &gpu_image.texture_view, @@ -463,7 +463,7 @@ pub fn prepare_ui_slices( render_device.create_bind_group( "ui_texture_slice_image_layout", &pipeline_cache.get_bind_group_layout( - texture_slicer_pipeline.image_layout.clone(), + &texture_slicer_pipeline.image_layout, ), &BindGroupEntries::sequential(( &gpu_image.texture_view, From 3768a46127a937004c72a8cfd6b31d8cdb2cc11c Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 16:42:00 +0800 Subject: [PATCH 14/23] bevy_solari clone-less --- crates/bevy_solari/src/pathtracer/node.rs | 2 +- crates/bevy_solari/src/realtime/node.rs | 2 +- crates/bevy_solari/src/scene/binder.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/bevy_solari/src/pathtracer/node.rs b/crates/bevy_solari/src/pathtracer/node.rs index 9ef10873c1088..1c5ec8e72092b 100644 --- a/crates/bevy_solari/src/pathtracer/node.rs +++ b/crates/bevy_solari/src/pathtracer/node.rs @@ -63,7 +63,7 @@ impl ViewNode for PathtracerNode { let bind_group = render_context.render_device().create_bind_group( "pathtracer_bind_group", - &pipeline_cache.get_bind_group_layout(self.bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&self.bind_group_layout), &BindGroupEntries::sequential(( &accumulation_texture.0.default_view, view_target.get_unsampled_color_attachment().view, diff --git a/crates/bevy_solari/src/realtime/node.rs b/crates/bevy_solari/src/realtime/node.rs index ca4273b02944a..fd3f7024485ca 100644 --- a/crates/bevy_solari/src/realtime/node.rs +++ b/crates/bevy_solari/src/realtime/node.rs @@ -159,7 +159,7 @@ impl ViewNode for SolariLightingNode { let s = solari_lighting_resources; let bind_group = render_context.render_device().create_bind_group( "solari_lighting_bind_group", - &pipeline_cache.get_bind_group_layout(self.bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&self.bind_group_layout), &BindGroupEntries::sequential(( view_target.get_unsampled_color_attachment().view, s.light_tile_samples.as_entire_binding(), diff --git a/crates/bevy_solari/src/scene/binder.rs b/crates/bevy_solari/src/scene/binder.rs index d1f2b813ec763..0071e7135b52f 100644 --- a/crates/bevy_solari/src/scene/binder.rs +++ b/crates/bevy_solari/src/scene/binder.rs @@ -258,7 +258,7 @@ pub fn prepare_raytracing_scene_bindings( raytracing_scene_bindings.bind_group = Some(render_device.create_bind_group( "raytracing_scene_bind_group", - &pipeline_cache.get_bind_group_layout(raytracing_scene_bindings.bind_group_layout.clone()), + &pipeline_cache.get_bind_group_layout(&raytracing_scene_bindings.bind_group_layout), &BindGroupEntries::sequential(( vertex_buffers.as_slice(), index_buffers.as_slice(), From 15f7e36b7756255b1506b970e19153533adbded9 Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 17:08:22 +0800 Subject: [PATCH 15/23] More fixes --- crates/bevy_core_pipeline/src/upscaling/node.rs | 2 +- crates/bevy_pbr/src/material_bind_groups.rs | 2 +- crates/bevy_pbr/src/volumetric_fog/render.rs | 2 +- crates/bevy_post_process/src/dof/mod.rs | 2 +- crates/bevy_post_process/src/motion_blur/node.rs | 2 +- crates/bevy_post_process/src/msaa_writeback.rs | 2 +- crates/bevy_solari/src/realtime/node.rs | 3 +-- 7 files changed, 7 insertions(+), 8 deletions(-) diff --git a/crates/bevy_core_pipeline/src/upscaling/node.rs b/crates/bevy_core_pipeline/src/upscaling/node.rs index f5516245aff7f..3d7b2c9905068 100644 --- a/crates/bevy_core_pipeline/src/upscaling/node.rs +++ b/crates/bevy_core_pipeline/src/upscaling/node.rs @@ -60,7 +60,7 @@ impl ViewNode for UpscalingNode { let bind_group = blit_pipeline.create_bind_group( render_context.render_device(), main_texture_view, - &pipeline_cache, + pipeline_cache, ); let (_, bind_group) = diff --git a/crates/bevy_pbr/src/material_bind_groups.rs b/crates/bevy_pbr/src/material_bind_groups.rs index 1967410cd3430..e38439734ef8e 100644 --- a/crates/bevy_pbr/src/material_bind_groups.rs +++ b/crates/bevy_pbr/src/material_bind_groups.rs @@ -1273,7 +1273,7 @@ impl MaterialBindlessSlab { self.bind_group = Some(render_device.create_bind_group( label, - &pipeline_cache.get_bind_group_layout(&bind_group_layout), + &pipeline_cache.get_bind_group_layout(bind_group_layout), &bind_group_entries, )); } diff --git a/crates/bevy_pbr/src/volumetric_fog/render.rs b/crates/bevy_pbr/src/volumetric_fog/render.rs index ff0942772f456..f33210cba2f02 100644 --- a/crates/bevy_pbr/src/volumetric_fog/render.rs +++ b/crates/bevy_pbr/src/volumetric_fog/render.rs @@ -431,7 +431,7 @@ impl ViewNode for VolumetricFogNode { let volumetric_view_bind_group = render_context.render_device().create_bind_group( None, - &pipeline_cache.get_bind_group_layout(&volumetric_view_bind_group_layout), + &pipeline_cache.get_bind_group_layout(volumetric_view_bind_group_layout), &bind_group_entries, ); diff --git a/crates/bevy_post_process/src/dof/mod.rs b/crates/bevy_post_process/src/dof/mod.rs index 7460f96f06619..4cff455fe7fde 100644 --- a/crates/bevy_post_process/src/dof/mod.rs +++ b/crates/bevy_post_process/src/dof/mod.rs @@ -388,7 +388,7 @@ impl ViewNode for DepthOfFieldNode { }; render_context.render_device().create_bind_group( Some(pipeline_render_info.view_bind_group_label), - &pipeline_cache.get_bind_group_layout(&dual_input_bind_group_layout), + &pipeline_cache.get_bind_group_layout(dual_input_bind_group_layout), &BindGroupEntries::sequential(( view_uniforms_binding, view_depth_texture.view(), diff --git a/crates/bevy_post_process/src/motion_blur/node.rs b/crates/bevy_post_process/src/motion_blur/node.rs index 89adfe0e0c6d0..179cb01e00ff3 100644 --- a/crates/bevy_post_process/src/motion_blur/node.rs +++ b/crates/bevy_post_process/src/motion_blur/node.rs @@ -72,7 +72,7 @@ impl ViewNode for MotionBlurNode { let bind_group = render_context.render_device().create_bind_group( Some("motion_blur_bind_group"), - &pipeline_cache.get_bind_group_layout(&layout), + &pipeline_cache.get_bind_group_layout(layout), &BindGroupEntries::sequential(( post_process.source, &prepass_motion_vectors_texture.texture.default_view, diff --git a/crates/bevy_post_process/src/msaa_writeback.rs b/crates/bevy_post_process/src/msaa_writeback.rs index 8bcf2effae1dc..859515ff5aee3 100644 --- a/crates/bevy_post_process/src/msaa_writeback.rs +++ b/crates/bevy_post_process/src/msaa_writeback.rs @@ -106,7 +106,7 @@ impl ViewNode for MsaaWritebackNode { let bind_group = blit_pipeline.create_bind_group( render_context.render_device(), post_process.source, - &pipeline_cache, + pipeline_cache, ); let mut render_pass = render_context diff --git a/crates/bevy_solari/src/realtime/node.rs b/crates/bevy_solari/src/realtime/node.rs index fd3f7024485ca..25f446821be99 100644 --- a/crates/bevy_solari/src/realtime/node.rs +++ b/crates/bevy_solari/src/realtime/node.rs @@ -190,8 +190,7 @@ impl ViewNode for SolariLightingNode { render_context.render_device().create_bind_group( "solari_lighting_bind_group_world_cache_active_cells_dispatch", &pipeline_cache.get_bind_group_layout( - self.bind_group_layout_world_cache_active_cells_dispatch - .clone(), + &self.bind_group_layout_world_cache_active_cells_dispatch, ), &BindGroupEntries::single(s.world_cache_active_cells_dispatch.as_entire_binding()), ); From 0df6e82b021c84dd3334a27b92ab7d5477337963 Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 17:40:55 +0800 Subject: [PATCH 16/23] Meshlet fixes --- .../bevy_pbr/src/meshlet/resource_manager.rs | 85 +++++++++---------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/crates/bevy_pbr/src/meshlet/resource_manager.rs b/crates/bevy_pbr/src/meshlet/resource_manager.rs index ce7b9edda3b14..fab9530e52fdb 100644 --- a/crates/bevy_pbr/src/meshlet/resource_manager.rs +++ b/crates/bevy_pbr/src/meshlet/resource_manager.rs @@ -50,24 +50,24 @@ pub struct ResourceManager { previous_depth_pyramids: EntityHashMap, // Bind group layouts - pub clear_visibility_buffer_bind_group_layout: BindGroupLayout, - pub clear_visibility_buffer_shadow_view_bind_group_layout: BindGroupLayout, - pub first_instance_cull_bind_group_layout: BindGroupLayout, - pub second_instance_cull_bind_group_layout: BindGroupLayout, - pub first_bvh_cull_bind_group_layout: BindGroupLayout, - pub second_bvh_cull_bind_group_layout: BindGroupLayout, - pub first_meshlet_cull_bind_group_layout: BindGroupLayout, - pub second_meshlet_cull_bind_group_layout: BindGroupLayout, - pub visibility_buffer_raster_bind_group_layout: BindGroupLayout, - pub visibility_buffer_raster_shadow_view_bind_group_layout: BindGroupLayout, - pub downsample_depth_bind_group_layout: BindGroupLayout, - pub downsample_depth_shadow_view_bind_group_layout: BindGroupLayout, - pub resolve_depth_bind_group_layout: BindGroupLayout, - pub resolve_depth_shadow_view_bind_group_layout: BindGroupLayout, - pub resolve_material_depth_bind_group_layout: BindGroupLayout, - pub material_shade_bind_group_layout: BindGroupLayout, - pub fill_counts_bind_group_layout: BindGroupLayout, - pub remap_1d_to_2d_dispatch_bind_group_layout: Option, + pub clear_visibility_buffer_bind_group_layout: BindGroupLayoutDescriptor, + pub clear_visibility_buffer_shadow_view_bind_group_layout: BindGroupLayoutDescriptor, + pub first_instance_cull_bind_group_layout: BindGroupLayoutDescriptor, + pub second_instance_cull_bind_group_layout: BindGroupLayoutDescriptor, + pub first_bvh_cull_bind_group_layout: BindGroupLayoutDescriptor, + pub second_bvh_cull_bind_group_layout: BindGroupLayoutDescriptor, + pub first_meshlet_cull_bind_group_layout: BindGroupLayoutDescriptor, + pub second_meshlet_cull_bind_group_layout: BindGroupLayoutDescriptor, + pub visibility_buffer_raster_bind_group_layout: BindGroupLayoutDescriptor, + pub visibility_buffer_raster_shadow_view_bind_group_layout: BindGroupLayoutDescriptor, + pub downsample_depth_bind_group_layout: BindGroupLayoutDescriptor, + pub downsample_depth_shadow_view_bind_group_layout: BindGroupLayoutDescriptor, + pub resolve_depth_bind_group_layout: BindGroupLayoutDescriptor, + pub resolve_depth_shadow_view_bind_group_layout: BindGroupLayoutDescriptor, + pub resolve_material_depth_bind_group_layout: BindGroupLayoutDescriptor, + pub material_shade_bind_group_layout: BindGroupLayoutDescriptor, + pub fill_counts_bind_group_layout: BindGroupLayoutDescriptor, + pub remap_1d_to_2d_dispatch_bind_group_layout: Option, } impl ResourceManager { @@ -141,8 +141,7 @@ impl ResourceManager { texture_storage_2d(TextureFormat::R64Uint, StorageTextureAccess::WriteOnly), ), ), - clear_visibility_buffer_shadow_view_bind_group_layout: render_device - .create_bind_group_layout( + clear_visibility_buffer_shadow_view_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_clear_visibility_buffer_shadow_view_bind_group_layout", &BindGroupLayoutEntries::single( ShaderStages::COMPUTE, @@ -348,8 +347,7 @@ impl ResourceManager { ), ), ), - visibility_buffer_raster_shadow_view_bind_group_layout: render_device - .create_bind_group_layout( + visibility_buffer_raster_shadow_view_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_visibility_buffer_raster_shadow_view_bind_group_layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT | ShaderStages::VERTEX | ShaderStages::COMPUTE, @@ -805,6 +803,7 @@ pub fn prepare_meshlet_view_bind_groups( view_uniforms: Res, previous_view_uniforms: Res, render_device: Res, + pipeline_cache: Res, mut commands: Commands, ) { let (Some(view_uniforms), Some(previous_view_uniforms)) = ( @@ -818,17 +817,17 @@ pub fn prepare_meshlet_view_bind_groups( for (view_entity, view_resources) in &views { let clear_visibility_buffer = render_device.create_bind_group( "meshlet_clear_visibility_buffer_bind_group", - if view_resources.not_shadow_view { + &pipeline_cache.get_bind_group_layout(if view_resources.not_shadow_view { &resource_manager.clear_visibility_buffer_bind_group_layout } else { &resource_manager.clear_visibility_buffer_shadow_view_bind_group_layout - }, + }), &BindGroupEntries::single(&view_resources.visibility_buffer.default_view), ); let first_instance_cull = render_device.create_bind_group( "meshlet_first_instance_cull_bind_group", - &resource_manager.first_instance_cull_bind_group_layout, + &pipeline_cache.get_bind_group_layout(&resource_manager.first_instance_cull_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.previous_depth_pyramid, view_uniforms.clone(), @@ -852,7 +851,7 @@ pub fn prepare_meshlet_view_bind_groups( let second_instance_cull = render_device.create_bind_group( "meshlet_second_instance_cull_bind_group", - &resource_manager.second_instance_cull_bind_group_layout, + &pipeline_cache.get_bind_group_layout(&resource_manager.second_instance_cull_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.previous_depth_pyramid, view_uniforms.clone(), @@ -875,7 +874,7 @@ pub fn prepare_meshlet_view_bind_groups( let first_bvh_cull_ping = render_device.create_bind_group( "meshlet_first_bvh_cull_ping_bind_group", - &resource_manager.first_bvh_cull_bind_group_layout, + &pipeline_cache.get_bind_group_layout(&resource_manager.first_bvh_cull_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.previous_depth_pyramid, view_uniforms.clone(), @@ -911,7 +910,7 @@ pub fn prepare_meshlet_view_bind_groups( let first_bvh_cull_pong = render_device.create_bind_group( "meshlet_first_bvh_cull_pong_bind_group", - &resource_manager.first_bvh_cull_bind_group_layout, + &pipeline_cache.get_bind_group_layout(&resource_manager.first_bvh_cull_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.previous_depth_pyramid, view_uniforms.clone(), @@ -947,7 +946,7 @@ pub fn prepare_meshlet_view_bind_groups( let second_bvh_cull_ping = render_device.create_bind_group( "meshlet_second_bvh_cull_ping_bind_group", - &resource_manager.second_bvh_cull_bind_group_layout, + &pipeline_cache.get_bind_group_layout(&resource_manager.second_bvh_cull_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.previous_depth_pyramid, view_uniforms.clone(), @@ -978,7 +977,7 @@ pub fn prepare_meshlet_view_bind_groups( let second_bvh_cull_pong = render_device.create_bind_group( "meshlet_second_bvh_cull_pong_bind_group", - &resource_manager.second_bvh_cull_bind_group_layout, + &pipeline_cache.get_bind_group_layout(&resource_manager.second_bvh_cull_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.previous_depth_pyramid, view_uniforms.clone(), @@ -1009,7 +1008,7 @@ pub fn prepare_meshlet_view_bind_groups( let first_meshlet_cull = render_device.create_bind_group( "meshlet_first_meshlet_cull_bind_group", - &resource_manager.first_meshlet_cull_bind_group_layout, + &pipeline_cache.get_bind_group_layout(&resource_manager.first_meshlet_cull_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.previous_depth_pyramid, view_uniforms.clone(), @@ -1039,7 +1038,7 @@ pub fn prepare_meshlet_view_bind_groups( let second_meshlet_cull = render_device.create_bind_group( "meshlet_second_meshlet_cull_bind_group", - &resource_manager.second_meshlet_cull_bind_group_layout, + &pipeline_cache.get_bind_group_layout(&resource_manager.second_meshlet_cull_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.previous_depth_pyramid, view_uniforms.clone(), @@ -1066,22 +1065,22 @@ pub fn prepare_meshlet_view_bind_groups( let downsample_depth = view_resources.depth_pyramid.create_bind_group( &render_device, "meshlet_downsample_depth_bind_group", - if view_resources.not_shadow_view { + &pipeline_cache.get_bind_group_layout(if view_resources.not_shadow_view { &resource_manager.downsample_depth_bind_group_layout } else { &resource_manager.downsample_depth_shadow_view_bind_group_layout - }, + }), &view_resources.visibility_buffer.default_view, &resource_manager.depth_pyramid_sampler, ); let visibility_buffer_raster = render_device.create_bind_group( "meshlet_visibility_raster_buffer_bind_group", - if view_resources.not_shadow_view { + &pipeline_cache.get_bind_group_layout(if view_resources.not_shadow_view { &resource_manager.visibility_buffer_raster_bind_group_layout } else { &resource_manager.visibility_buffer_raster_shadow_view_bind_group_layout - }, + }), &BindGroupEntries::sequential(( resource_manager .visibility_buffer_raster_clusters @@ -1103,18 +1102,18 @@ pub fn prepare_meshlet_view_bind_groups( let resolve_depth = render_device.create_bind_group( "meshlet_resolve_depth_bind_group", - if view_resources.not_shadow_view { + &pipeline_cache.get_bind_group_layout(if view_resources.not_shadow_view { &resource_manager.resolve_depth_bind_group_layout } else { &resource_manager.resolve_depth_shadow_view_bind_group_layout - }, + }), &BindGroupEntries::single(&view_resources.visibility_buffer.default_view), ); let resolve_material_depth = view_resources.material_depth.as_ref().map(|_| { render_device.create_bind_group( "meshlet_resolve_material_depth_bind_group", - &resource_manager.resolve_material_depth_bind_group_layout, + &pipeline_cache.get_bind_group_layout(&resource_manager.resolve_material_depth_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.visibility_buffer.default_view, resource_manager @@ -1128,7 +1127,7 @@ pub fn prepare_meshlet_view_bind_groups( let material_shade = view_resources.material_depth.as_ref().map(|_| { render_device.create_bind_group( "meshlet_mesh_material_shade_bind_group", - &resource_manager.material_shade_bind_group_layout, + &pipeline_cache.get_bind_group_layout(&resource_manager.material_shade_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.visibility_buffer.default_view, resource_manager @@ -1150,7 +1149,7 @@ pub fn prepare_meshlet_view_bind_groups( .map(|layout| { render_device.create_bind_group( "meshlet_remap_1d_to_2d_dispatch_bind_group", - layout, + &pipeline_cache.get_bind_group_layout(layout), &BindGroupEntries::sequential(( view_resources .visibility_buffer_software_raster_indirect_args @@ -1168,7 +1167,7 @@ pub fn prepare_meshlet_view_bind_groups( { render_device.create_bind_group( "meshlet_fill_counts_bind_group", - &resource_manager.fill_counts_bind_group_layout, + &pipeline_cache.get_bind_group_layout(&resource_manager.fill_counts_bind_group_layout), &BindGroupEntries::sequential(( view_resources .visibility_buffer_software_raster_indirect_args @@ -1187,7 +1186,7 @@ pub fn prepare_meshlet_view_bind_groups( } else { render_device.create_bind_group( "meshlet_fill_counts_bind_group", - &resource_manager.fill_counts_bind_group_layout, + &pipeline_cache.get_bind_group_layout(&resource_manager.fill_counts_bind_group_layout), &BindGroupEntries::sequential(( view_resources .visibility_buffer_software_raster_indirect_args From 7b61ec24ffed7302edf8f5ca897800f3de6c280d Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 17:47:04 +0800 Subject: [PATCH 17/23] fmt --- .../bevy_pbr/src/meshlet/resource_manager.rs | 78 +++++++++++-------- 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/crates/bevy_pbr/src/meshlet/resource_manager.rs b/crates/bevy_pbr/src/meshlet/resource_manager.rs index fab9530e52fdb..e733588554a59 100644 --- a/crates/bevy_pbr/src/meshlet/resource_manager.rs +++ b/crates/bevy_pbr/src/meshlet/resource_manager.rs @@ -142,12 +142,12 @@ impl ResourceManager { ), ), clear_visibility_buffer_shadow_view_bind_group_layout: BindGroupLayoutDescriptor::new( - "meshlet_clear_visibility_buffer_shadow_view_bind_group_layout", - &BindGroupLayoutEntries::single( - ShaderStages::COMPUTE, - texture_storage_2d(TextureFormat::R32Uint, StorageTextureAccess::WriteOnly), - ), + "meshlet_clear_visibility_buffer_shadow_view_bind_group_layout", + &BindGroupLayoutEntries::single( + ShaderStages::COMPUTE, + texture_storage_2d(TextureFormat::R32Uint, StorageTextureAccess::WriteOnly), ), + ), first_instance_cull_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_first_instance_culling_bind_group_layout", &BindGroupLayoutEntries::sequential( @@ -348,25 +348,22 @@ impl ResourceManager { ), ), visibility_buffer_raster_shadow_view_bind_group_layout: BindGroupLayoutDescriptor::new( - "meshlet_visibility_buffer_raster_shadow_view_bind_group_layout", - &BindGroupLayoutEntries::sequential( - ShaderStages::FRAGMENT | ShaderStages::VERTEX | ShaderStages::COMPUTE, - ( - storage_buffer_read_only_sized(false, None), - storage_buffer_read_only_sized(false, None), - storage_buffer_read_only_sized(false, None), - storage_buffer_read_only_sized(false, None), - storage_buffer_read_only_sized(false, None), - storage_buffer_read_only_sized(false, None), - storage_buffer_read_only_sized(false, None), - texture_storage_2d( - TextureFormat::R32Uint, - StorageTextureAccess::Atomic, - ), - uniform_buffer::(true), - ), + "meshlet_visibility_buffer_raster_shadow_view_bind_group_layout", + &BindGroupLayoutEntries::sequential( + ShaderStages::FRAGMENT | ShaderStages::VERTEX | ShaderStages::COMPUTE, + ( + storage_buffer_read_only_sized(false, None), + storage_buffer_read_only_sized(false, None), + storage_buffer_read_only_sized(false, None), + storage_buffer_read_only_sized(false, None), + storage_buffer_read_only_sized(false, None), + storage_buffer_read_only_sized(false, None), + storage_buffer_read_only_sized(false, None), + texture_storage_2d(TextureFormat::R32Uint, StorageTextureAccess::Atomic), + uniform_buffer::(true), ), ), + ), resolve_depth_bind_group_layout: BindGroupLayoutDescriptor::new( "meshlet_resolve_depth_bind_group_layout", &BindGroupLayoutEntries::single( @@ -827,7 +824,8 @@ pub fn prepare_meshlet_view_bind_groups( let first_instance_cull = render_device.create_bind_group( "meshlet_first_instance_cull_bind_group", - &pipeline_cache.get_bind_group_layout(&resource_manager.first_instance_cull_bind_group_layout), + &pipeline_cache + .get_bind_group_layout(&resource_manager.first_instance_cull_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.previous_depth_pyramid, view_uniforms.clone(), @@ -851,7 +849,8 @@ pub fn prepare_meshlet_view_bind_groups( let second_instance_cull = render_device.create_bind_group( "meshlet_second_instance_cull_bind_group", - &pipeline_cache.get_bind_group_layout(&resource_manager.second_instance_cull_bind_group_layout), + &pipeline_cache + .get_bind_group_layout(&resource_manager.second_instance_cull_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.previous_depth_pyramid, view_uniforms.clone(), @@ -874,7 +873,8 @@ pub fn prepare_meshlet_view_bind_groups( let first_bvh_cull_ping = render_device.create_bind_group( "meshlet_first_bvh_cull_ping_bind_group", - &pipeline_cache.get_bind_group_layout(&resource_manager.first_bvh_cull_bind_group_layout), + &pipeline_cache + .get_bind_group_layout(&resource_manager.first_bvh_cull_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.previous_depth_pyramid, view_uniforms.clone(), @@ -910,7 +910,8 @@ pub fn prepare_meshlet_view_bind_groups( let first_bvh_cull_pong = render_device.create_bind_group( "meshlet_first_bvh_cull_pong_bind_group", - &pipeline_cache.get_bind_group_layout(&resource_manager.first_bvh_cull_bind_group_layout), + &pipeline_cache + .get_bind_group_layout(&resource_manager.first_bvh_cull_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.previous_depth_pyramid, view_uniforms.clone(), @@ -946,7 +947,8 @@ pub fn prepare_meshlet_view_bind_groups( let second_bvh_cull_ping = render_device.create_bind_group( "meshlet_second_bvh_cull_ping_bind_group", - &pipeline_cache.get_bind_group_layout(&resource_manager.second_bvh_cull_bind_group_layout), + &pipeline_cache + .get_bind_group_layout(&resource_manager.second_bvh_cull_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.previous_depth_pyramid, view_uniforms.clone(), @@ -977,7 +979,8 @@ pub fn prepare_meshlet_view_bind_groups( let second_bvh_cull_pong = render_device.create_bind_group( "meshlet_second_bvh_cull_pong_bind_group", - &pipeline_cache.get_bind_group_layout(&resource_manager.second_bvh_cull_bind_group_layout), + &pipeline_cache + .get_bind_group_layout(&resource_manager.second_bvh_cull_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.previous_depth_pyramid, view_uniforms.clone(), @@ -1008,7 +1011,8 @@ pub fn prepare_meshlet_view_bind_groups( let first_meshlet_cull = render_device.create_bind_group( "meshlet_first_meshlet_cull_bind_group", - &pipeline_cache.get_bind_group_layout(&resource_manager.first_meshlet_cull_bind_group_layout), + &pipeline_cache + .get_bind_group_layout(&resource_manager.first_meshlet_cull_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.previous_depth_pyramid, view_uniforms.clone(), @@ -1038,7 +1042,8 @@ pub fn prepare_meshlet_view_bind_groups( let second_meshlet_cull = render_device.create_bind_group( "meshlet_second_meshlet_cull_bind_group", - &pipeline_cache.get_bind_group_layout(&resource_manager.second_meshlet_cull_bind_group_layout), + &pipeline_cache + .get_bind_group_layout(&resource_manager.second_meshlet_cull_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.previous_depth_pyramid, view_uniforms.clone(), @@ -1113,7 +1118,9 @@ pub fn prepare_meshlet_view_bind_groups( let resolve_material_depth = view_resources.material_depth.as_ref().map(|_| { render_device.create_bind_group( "meshlet_resolve_material_depth_bind_group", - &pipeline_cache.get_bind_group_layout(&resource_manager.resolve_material_depth_bind_group_layout), + &pipeline_cache.get_bind_group_layout( + &resource_manager.resolve_material_depth_bind_group_layout, + ), &BindGroupEntries::sequential(( &view_resources.visibility_buffer.default_view, resource_manager @@ -1127,7 +1134,8 @@ pub fn prepare_meshlet_view_bind_groups( let material_shade = view_resources.material_depth.as_ref().map(|_| { render_device.create_bind_group( "meshlet_mesh_material_shade_bind_group", - &pipeline_cache.get_bind_group_layout(&resource_manager.material_shade_bind_group_layout), + &pipeline_cache + .get_bind_group_layout(&resource_manager.material_shade_bind_group_layout), &BindGroupEntries::sequential(( &view_resources.visibility_buffer.default_view, resource_manager @@ -1167,7 +1175,8 @@ pub fn prepare_meshlet_view_bind_groups( { render_device.create_bind_group( "meshlet_fill_counts_bind_group", - &pipeline_cache.get_bind_group_layout(&resource_manager.fill_counts_bind_group_layout), + &pipeline_cache + .get_bind_group_layout(&resource_manager.fill_counts_bind_group_layout), &BindGroupEntries::sequential(( view_resources .visibility_buffer_software_raster_indirect_args @@ -1186,7 +1195,8 @@ pub fn prepare_meshlet_view_bind_groups( } else { render_device.create_bind_group( "meshlet_fill_counts_bind_group", - &pipeline_cache.get_bind_group_layout(&resource_manager.fill_counts_bind_group_layout), + &pipeline_cache + .get_bind_group_layout(&resource_manager.fill_counts_bind_group_layout), &BindGroupEntries::sequential(( view_resources .visibility_buffer_software_raster_indirect_args From 1f0b279c1192e173117870f3ab9bb88b8c1a9b01 Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 17:54:00 +0800 Subject: [PATCH 18/23] Solari binder new --- crates/bevy_solari/src/scene/binder.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/bevy_solari/src/scene/binder.rs b/crates/bevy_solari/src/scene/binder.rs index 0071e7135b52f..75228750a76cb 100644 --- a/crates/bevy_solari/src/scene/binder.rs +++ b/crates/bevy_solari/src/scene/binder.rs @@ -306,6 +306,12 @@ impl RaytracingSceneBindings { } } +impl Default for RaytracingSceneBindings { + fn default() -> Self { + Self::new() + } +} + struct CachedBindingArray { map: HashMap, vec: Vec, From ff8bc258a6c263cbfc863e80ba72adc4728422b4 Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Thu, 25 Sep 2025 18:35:59 +0800 Subject: [PATCH 19/23] Examples fixes --- examples/3d/manual_material.rs | 6 +++--- examples/shader/compute_shader_game_of_life.rs | 10 +++++----- examples/shader/gpu_readback.rs | 10 +++++----- examples/shader_advanced/custom_post_processing.rs | 6 +++--- examples/shader_advanced/texture_binding_array.rs | 5 +++-- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/examples/3d/manual_material.rs b/examples/3d/manual_material.rs index 8d90fe9ad79f5..bffed0677dfc8 100644 --- a/examples/3d/manual_material.rs +++ b/examples/3d/manual_material.rs @@ -21,7 +21,7 @@ use bevy::{ render_phase::DrawFunctions, render_resource::{ binding_types::{sampler, texture_2d}, - AsBindGroup, BindGroupLayout, BindGroupLayoutEntries, BindingResources, + AsBindGroup, BindGroupLayoutDescriptor, BindGroupLayoutEntries, BindingResources, OwnedBindingResource, Sampler, SamplerBindingType, SamplerDescriptor, ShaderStages, TextureSampleType, TextureViewDimension, UnpreparedBindGroup, }, @@ -77,7 +77,7 @@ fn init_image_material_resources( render_device: Res, mut bind_group_allocators: ResMut, ) { - let bind_group_layout = render_device.create_bind_group_layout( + let bind_group_layout = BindGroupLayoutDescriptor::new( "image_material_layout", &BindGroupLayoutEntries::sequential( ShaderStages::FRAGMENT, @@ -98,7 +98,7 @@ fn init_image_material_resources( } #[derive(Resource)] -struct ImageMaterialBindGroupLayout(BindGroupLayout); +struct ImageMaterialBindGroupLayout(BindGroupLayoutDescriptor); #[derive(Resource)] struct ImageMaterialBindGroupSampler(Sampler); diff --git a/examples/shader/compute_shader_game_of_life.rs b/examples/shader/compute_shader_game_of_life.rs index 377c0e0ad1223..b79d1f7a201d7 100644 --- a/examples/shader/compute_shader_game_of_life.rs +++ b/examples/shader/compute_shader_game_of_life.rs @@ -136,6 +136,7 @@ fn prepare_bind_group( game_of_life_images: Res, game_of_life_uniforms: Res, render_device: Res, + pipeline_cache: Res, queue: Res, ) { let view_a = gpu_images.get(&game_of_life_images.texture_a).unwrap(); @@ -148,7 +149,7 @@ fn prepare_bind_group( let bind_group_0 = render_device.create_bind_group( None, - &pipeline.texture_bind_group_layout, + &pipeline_cache.get_bind_group_layout(&pipeline.texture_bind_group_layout), &BindGroupEntries::sequential(( &view_a.texture_view, &view_b.texture_view, @@ -157,7 +158,7 @@ fn prepare_bind_group( ); let bind_group_1 = render_device.create_bind_group( None, - &pipeline.texture_bind_group_layout, + &pipeline_cache.get_bind_group_layout(&pipeline.texture_bind_group_layout), &BindGroupEntries::sequential(( &view_b.texture_view, &view_a.texture_view, @@ -169,18 +170,17 @@ fn prepare_bind_group( #[derive(Resource)] struct GameOfLifePipeline { - texture_bind_group_layout: BindGroupLayout, + texture_bind_group_layout: BindGroupLayoutDescriptor, init_pipeline: CachedComputePipelineId, update_pipeline: CachedComputePipelineId, } fn init_game_of_life_pipeline( mut commands: Commands, - render_device: Res, asset_server: Res, pipeline_cache: Res, ) { - let texture_bind_group_layout = render_device.create_bind_group_layout( + let texture_bind_group_layout = BindGroupLayoutDescriptor::new( "GameOfLifeImages", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, diff --git a/examples/shader/gpu_readback.rs b/examples/shader/gpu_readback.rs index 8984256a5ee45..78b5393658304 100644 --- a/examples/shader/gpu_readback.rs +++ b/examples/shader/gpu_readback.rs @@ -153,6 +153,7 @@ fn prepare_bind_group( mut commands: Commands, pipeline: Res, render_device: Res, + pipeline_cache: Res, buffer: Res, image: Res, buffers: Res>, @@ -162,7 +163,7 @@ fn prepare_bind_group( let image = images.get(&image.0).unwrap(); let bind_group = render_device.create_bind_group( None, - &pipeline.layout, + &pipeline_cache.get_bind_group_layout(&pipeline.layout), &BindGroupEntries::sequential(( buffer.buffer.as_entire_buffer_binding(), image.texture_view.into_binding(), @@ -173,18 +174,17 @@ fn prepare_bind_group( #[derive(Resource)] struct ComputePipeline { - layout: BindGroupLayout, + layout: BindGroupLayoutDescriptor, pipeline: CachedComputePipelineId, } fn init_compute_pipeline( mut commands: Commands, - render_device: Res, asset_server: Res, pipeline_cache: Res, ) { - let layout = render_device.create_bind_group_layout( - None, + let layout = BindGroupLayoutDescriptor::new( + "", &BindGroupLayoutEntries::sequential( ShaderStages::COMPUTE, ( diff --git a/examples/shader_advanced/custom_post_processing.rs b/examples/shader_advanced/custom_post_processing.rs index 806a84378535f..f92b0a347c72a 100644 --- a/examples/shader_advanced/custom_post_processing.rs +++ b/examples/shader_advanced/custom_post_processing.rs @@ -178,7 +178,7 @@ impl ViewNode for PostProcessNode { // is to make sure you get it during the node execution. let bind_group = render_context.render_device().create_bind_group( "post_process_bind_group", - &post_process_pipeline.layout, + &pipeline_cache.get_bind_group_layout(&post_process_pipeline.layout), // It's important for this to match the BindGroupLayout defined in the PostProcessPipeline &BindGroupEntries::sequential(( // Make sure to use the source view @@ -222,7 +222,7 @@ impl ViewNode for PostProcessNode { // This contains global data used by the render pipeline. This will be created once on startup. #[derive(Resource)] struct PostProcessPipeline { - layout: BindGroupLayout, + layout: BindGroupLayoutDescriptor, sampler: Sampler, pipeline_id: CachedRenderPipelineId, } @@ -235,7 +235,7 @@ fn init_post_process_pipeline( pipeline_cache: Res, ) { // We need to define the bind group layout used for our pipeline - let layout = render_device.create_bind_group_layout( + let layout = BindGroupLayoutDescriptor::new( "post_process_bind_group_layout", &BindGroupLayoutEntries::sequential( // The layout entries will only be visible in the fragment stage diff --git a/examples/shader_advanced/texture_binding_array.rs b/examples/shader_advanced/texture_binding_array.rs index 73094628c0d18..a774de5a70749 100644 --- a/examples/shader_advanced/texture_binding_array.rs +++ b/examples/shader_advanced/texture_binding_array.rs @@ -102,8 +102,9 @@ impl AsBindGroup for BindlessMaterial { fn as_bind_group( &self, - layout: &BindGroupLayout, + layout: &BindGroupLayoutDescriptor, render_device: &RenderDevice, + pipeline_cache: &PipelineCache, (image_assets, fallback_image): &mut SystemParamItem<'_, '_, Self::Param>, ) -> Result { // retrieve the render resources from handles @@ -129,7 +130,7 @@ impl AsBindGroup for BindlessMaterial { let bind_group = render_device.create_bind_group( "bindless_material_bind_group", - layout, + &pipeline_cache.get_bind_group_layout(layout), &BindGroupEntries::sequential((&textures[..], &fallback_image.sampler)), ); From 3bae3f4ec49ee08b32ca50f56eb44d30ffb93968 Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Fri, 26 Sep 2025 23:47:06 +0800 Subject: [PATCH 20/23] Use RenderDevice to determine if bindless supported --- crates/bevy_pbr/src/material.rs | 4 ++-- crates/bevy_render/src/render_resource/bind_group.rs | 8 ++++++-- crates/bevy_sprite_render/src/mesh2d/material.rs | 3 ++- crates/bevy_ui_render/src/ui_material_pipeline.rs | 3 ++- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index dc378f9bcf8bc..8c5b79b3bbede 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -412,7 +412,7 @@ fn add_material_bind_group_allocator( material_uses_bindless_resources::(&render_device) .then(|| M::bindless_descriptor()) .flatten(), - M::bind_group_layout_descriptor(), + M::bind_group_layout_descriptor(&render_device), M::bindless_slot_count(), ), ); @@ -1541,7 +1541,6 @@ where (shadows_enabled, prepass_enabled, material_param), ): &mut SystemParamItem, ) -> Result> { - let material_layout = M::bind_group_layout_descriptor(); let shadows_enabled = shadows_enabled.is_some(); let prepass_enabled = prepass_enabled.is_some(); @@ -1676,6 +1675,7 @@ where ) } + let material_layout = M::bind_group_layout_descriptor(render_device); let actual_material_layout = pipeline_cache.get_bind_group_layout(&material_layout); match material.unprepared_bind_group( diff --git a/crates/bevy_render/src/render_resource/bind_group.rs b/crates/bevy_render/src/render_resource/bind_group.rs index 19b28e15557f1..1a6fc0295d453 100644 --- a/crates/bevy_render/src/render_resource/bind_group.rs +++ b/crates/bevy_render/src/render_resource/bind_group.rs @@ -592,11 +592,15 @@ pub trait AsBindGroup { /// Creates the bind group layout descriptor matching all bind groups returned by /// [`AsBindGroup::as_bind_group`] - fn bind_group_layout_descriptor() -> BindGroupLayoutDescriptor + /// TODO: we only need `RenderDevice` to determine if bindless is supported + fn bind_group_layout_descriptor(render_device: &RenderDevice) -> BindGroupLayoutDescriptor where Self: Sized, { - todo!(); + BindGroupLayoutDescriptor { + label: Self::label().map_or(None, |f| Some(f.into())), + entries: Self::bind_group_layout_entries(render_device, false), + } } /// Returns a vec of bind group layout entries. diff --git a/crates/bevy_sprite_render/src/mesh2d/material.rs b/crates/bevy_sprite_render/src/mesh2d/material.rs index a07cac8cedf3c..079b050c0f10a 100644 --- a/crates/bevy_sprite_render/src/mesh2d/material.rs +++ b/crates/bevy_sprite_render/src/mesh2d/material.rs @@ -480,9 +480,10 @@ where pub fn init_material_2d_pipeline( mut commands: Commands, asset_server: Res, + render_device: Res, mesh_2d_pipeline: Res, ) { - let material2d_layout = M::bind_group_layout_descriptor(); + let material2d_layout = M::bind_group_layout_descriptor(&render_device); commands.insert_resource(Material2dPipeline:: { mesh2d_pipeline: mesh_2d_pipeline.clone(), diff --git a/crates/bevy_ui_render/src/ui_material_pipeline.rs b/crates/bevy_ui_render/src/ui_material_pipeline.rs index 8e4b5b3ceb38c..7c32b90918805 100644 --- a/crates/bevy_ui_render/src/ui_material_pipeline.rs +++ b/crates/bevy_ui_render/src/ui_material_pipeline.rs @@ -180,8 +180,9 @@ where pub fn init_ui_material_pipeline( mut commands: Commands, asset_server: Res, + render_device: Res, ) { - let ui_layout = M::bind_group_layout_descriptor(); + let ui_layout = M::bind_group_layout_descriptor(&render_device); let view_layout = BindGroupLayoutDescriptor::new( "ui_view_layout", From 49b30920d43f5f53f4fe9d707f5d4604b75c6944 Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Fri, 26 Sep 2025 23:52:04 +0800 Subject: [PATCH 21/23] fmt --- crates/bevy_pbr/src/material.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index 8c5b79b3bbede..eb01811e0ec7f 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -1541,7 +1541,6 @@ where (shadows_enabled, prepass_enabled, material_param), ): &mut SystemParamItem, ) -> Result> { - let shadows_enabled = shadows_enabled.is_some(); let prepass_enabled = prepass_enabled.is_some(); From 3632bbf2f11323cee71886395b9b10ebf776cf7d Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Sat, 27 Sep 2025 00:02:24 +0800 Subject: [PATCH 22/23] Expect clippy --- crates/bevy_render/src/render_resource/bind_group.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/bevy_render/src/render_resource/bind_group.rs b/crates/bevy_render/src/render_resource/bind_group.rs index 1a6fc0295d453..aef8b833f5d3e 100644 --- a/crates/bevy_render/src/render_resource/bind_group.rs +++ b/crates/bevy_render/src/render_resource/bind_group.rs @@ -598,6 +598,7 @@ pub trait AsBindGroup { Self: Sized, { BindGroupLayoutDescriptor { + #[expect(clippy::option_map_or_none, reason="TODO")] label: Self::label().map_or(None, |f| Some(f.into())), entries: Self::bind_group_layout_entries(render_device, false), } From 48213e32e9029e93991ab5dc359a888fd3b885b1 Mon Sep 17 00:00:00 2001 From: Daniel Skates Date: Sat, 27 Sep 2025 07:18:54 +0800 Subject: [PATCH 23/23] fmt --- crates/bevy_render/src/render_resource/bind_group.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_render/src/render_resource/bind_group.rs b/crates/bevy_render/src/render_resource/bind_group.rs index aef8b833f5d3e..a62cf80b544d8 100644 --- a/crates/bevy_render/src/render_resource/bind_group.rs +++ b/crates/bevy_render/src/render_resource/bind_group.rs @@ -598,7 +598,7 @@ pub trait AsBindGroup { Self: Sized, { BindGroupLayoutDescriptor { - #[expect(clippy::option_map_or_none, reason="TODO")] + #[expect(clippy::option_map_or_none, reason = "TODO")] label: Self::label().map_or(None, |f| Some(f.into())), entries: Self::bind_group_layout_entries(render_device, false), }