From 7a71873a32cfe493b0fd0d15bbc198892a014e88 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Mon, 11 May 2020 13:55:23 -0700 Subject: [PATCH] RenderResourceAssignment refactor --- crates/bevy_pbr/src/nodes/lights_node.rs | 13 +- crates/bevy_render/src/pipeline/pipeline.rs | 44 +++---- .../src/pipeline/pipeline_compiler.rs | 7 +- .../src/render_graph/nodes/camera2d_node.rs | 14 ++- .../src/render_graph/nodes/camera_node.rs | 16 ++- .../src/render_graph/nodes/uniform_node.rs | 82 ++++++------ .../render_resource_assignments.rs | 117 ++++++++++-------- .../src/render_resource/resource_info.rs | 1 + .../headless_render_resource_context.rs | 6 +- .../src/renderer/wgpu_render_context.rs | 6 +- .../renderer/wgpu_render_resource_context.rs | 70 ++++------- crates/bevy_wgpu/src/wgpu_render_pass.rs | 14 +-- 12 files changed, 206 insertions(+), 184 deletions(-) diff --git a/crates/bevy_pbr/src/nodes/lights_node.rs b/crates/bevy_pbr/src/nodes/lights_node.rs index e0ebeb70aa..9b1d6594fd 100644 --- a/crates/bevy_pbr/src/nodes/lights_node.rs +++ b/crates/bevy_pbr/src/nodes/lights_node.rs @@ -1,6 +1,8 @@ use bevy_render::{ render_graph::{CommandQueue, Node, ResourceSlots, SystemNode}, - render_resource::{resource_name, BufferInfo, BufferUsage, RenderResourceAssignments}, + render_resource::{ + resource_name, BufferInfo, BufferUsage, RenderResourceAssignment, RenderResourceAssignments, + }, renderer::{RenderContext, RenderResources}, }; @@ -78,7 +80,14 @@ impl SystemNode for LightsNode { | BufferUsage::COPY_DST, ..Default::default() }); - render_resource_assignments.set(resource_name::uniform::LIGHTS, buffer); + render_resource_assignments.set( + resource_name::uniform::LIGHTS, + RenderResourceAssignment::Buffer { + resource: buffer, + range: 0..light_uniform_size as u64, + dynamic_index: None, + }, + ); light_buffer = Some(buffer); } diff --git a/crates/bevy_render/src/pipeline/pipeline.rs b/crates/bevy_render/src/pipeline/pipeline.rs index 71e18ec00d..98cffbc929 100644 --- a/crates/bevy_render/src/pipeline/pipeline.rs +++ b/crates/bevy_render/src/pipeline/pipeline.rs @@ -4,12 +4,15 @@ use super::{ CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, IndexFormat, PrimitiveTopology, RasterizationStateDescriptor, StencilStateFaceDescriptor, }, - PipelineLayout, VertexBufferDescriptors, BindType, + BindType, PipelineLayout, VertexBufferDescriptors, }; use crate::{ - render_resource::{ResourceInfo, RenderResourceAssignments, BufferInfo}, + render_resource::{ + BufferInfo, RenderResourceAssignment, RenderResourceAssignments, ResourceInfo, + }, + renderer::RenderResourceContext, shader::{Shader, ShaderStages}, - texture::TextureFormat, renderer::RenderResourceContext, + texture::TextureFormat, }; use bevy_asset::AssetStorage; @@ -134,21 +137,21 @@ impl PipelineDescriptor { } /// Reflects the pipeline layout from its shaders. - /// + /// /// If `bevy_conventions` is true, it will be assumed that the shader follows "bevy shader conventions". These allow /// richer reflection, such as inferred Vertex Buffer names and inferred instancing. /// /// If `vertex_buffer_descriptors` is set, the pipeline's vertex buffers /// will inherit their layouts from global descriptors, otherwise the layout will be assumed to be complete / local. /// - /// If `dynamic_uniform_lookup` is set, shader uniforms will be set to "dynamic" if there is a matching "dynamic uniform" + /// If `render_resource_assignments` is set, shader uniforms will be set to "dynamic" if there is a matching "dynamic uniform" /// render resource. pub fn reflect_layout( &mut self, shaders: &AssetStorage, bevy_conventions: bool, vertex_buffer_descriptors: Option<&VertexBufferDescriptors>, - dynamic_uniform_lookup: Option<(&RenderResourceAssignments, &dyn RenderResourceContext)>, + render_resource_assignments: Option<&RenderResourceAssignments>, ) { let vertex_spirv = shaders.get(&self.shader_stages.vertex).unwrap(); let fragment_spirv = self @@ -167,30 +170,23 @@ impl PipelineDescriptor { layout.sync_vertex_buffer_descriptors(vertex_buffer_descriptors); } - if let Some((render_resource_assignments, render_resource_context)) = dynamic_uniform_lookup { + if let Some(render_resource_assignments) = render_resource_assignments + { // set binding uniforms to dynamic if render resource assignments use dynamic // TODO: this breaks down if different assignments have different "dynamic" status or if the dynamic status changes. // the fix would be to add "dynamic bindings" to the existing shader_def sets. this would ensure new pipelines are generated // for all permutations of dynamic/non-dynamic for bind_group in layout.bind_groups.iter_mut() { for binding in bind_group.bindings.iter_mut() { - if let Some(render_resource) = render_resource_assignments.get(&binding.name) { - render_resource_context.get_resource_info( - render_resource, - &mut |resource_info| { - if let Some(ResourceInfo::Buffer(BufferInfo { - is_dynamic, .. - })) = resource_info - { - if let BindType::Uniform { - ref mut dynamic, .. - } = binding.bind_type - { - *dynamic = *is_dynamic - } - } - }, - ); + if let Some(RenderResourceAssignment::Buffer { dynamic_index: Some(_), .. }) = + render_resource_assignments.get(&binding.name) + { + if let BindType::Uniform { + ref mut dynamic, .. + } = binding.bind_type + { + *dynamic = true; + } } } } diff --git a/crates/bevy_render/src/pipeline/pipeline_compiler.rs b/crates/bevy_render/src/pipeline/pipeline_compiler.rs index c2fbb492e0..13966575de 100644 --- a/crates/bevy_render/src/pipeline/pipeline_compiler.rs +++ b/crates/bevy_render/src/pipeline/pipeline_compiler.rs @@ -84,7 +84,6 @@ impl PipelineCompiler { &mut self, vertex_buffer_descriptors: &VertexBufferDescriptors, shaders: &mut AssetStorage, - render_resource_context: &dyn RenderResourceContext, pipeline_descriptor: &PipelineDescriptor, render_resource_assignments: &RenderResourceAssignments, ) -> PipelineDescriptor { @@ -115,7 +114,7 @@ impl PipelineCompiler { shaders, true, Some(vertex_buffer_descriptors), - Some((render_resource_assignments, render_resource_context)), + Some(render_resource_assignments), ); compiled_pipeline_descriptor.primitive_topology = render_resource_assignments @@ -128,7 +127,6 @@ impl PipelineCompiler { &mut self, vertex_buffer_descriptors: &VertexBufferDescriptors, shader_pipeline_assignments: &mut PipelineAssignments, - render_resource_context: &dyn RenderResourceContext, pipeline_storage: &mut AssetStorage, shader_storage: &mut AssetStorage, pipelines: &[Handle], @@ -154,7 +152,6 @@ impl PipelineCompiler { let compiled_pipeline = self.compile_pipeline( vertex_buffer_descriptors, shader_storage, - render_resource_context, pipeline_descriptor, render_resource_assignments, ); @@ -230,7 +227,6 @@ pub fn update_shader_assignments(world: &mut World, resources: &Resources) { let mut pipeline_compiler = resources.get_mut::().unwrap(); let mut shader_storage = resources.get_mut::>().unwrap(); let vertex_buffer_descriptors = resources.get::().unwrap(); - let render_resources = resources.get::().unwrap(); let mut pipeline_descriptor_storage = resources .get_mut::>() .unwrap(); @@ -248,7 +244,6 @@ pub fn update_shader_assignments(world: &mut World, resources: &Resources) { pipeline_compiler.update_shader_assignments( &vertex_buffer_descriptors, &mut shader_pipeline_assignments, - &*render_resources.context, &mut pipeline_descriptor_storage, &mut shader_storage, &renderable.pipelines, diff --git a/crates/bevy_render/src/render_graph/nodes/camera2d_node.rs b/crates/bevy_render/src/render_graph/nodes/camera2d_node.rs index 5ce7990a7c..c766becd6c 100644 --- a/crates/bevy_render/src/render_graph/nodes/camera2d_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/camera2d_node.rs @@ -4,7 +4,7 @@ use bevy_window::WindowResized; use crate::{ camera::{ActiveCamera2d, Camera}, render_graph::{CommandQueue, Node, ResourceSlots, SystemNode}, - render_resource::{resource_name, BufferInfo, BufferUsage, RenderResourceAssignments}, + render_resource::{resource_name, BufferInfo, BufferUsage, RenderResourceAssignments, RenderResourceAssignment}, renderer::{RenderContext, RenderResources}, }; @@ -52,12 +52,20 @@ impl SystemNode for Camera2dNode { query| { let render_resources = &render_resource_context.context; if camera_buffer.is_none() { + let size = std::mem::size_of::<[[f32; 4]; 4]>(); let buffer = render_resources.create_buffer(BufferInfo { - size: std::mem::size_of::<[[f32; 4]; 4]>(), + size, buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, ..Default::default() }); - render_resource_assignments.set(resource_name::uniform::CAMERA2D, buffer); + render_resource_assignments.set( + resource_name::uniform::CAMERA2D, + RenderResourceAssignment::Buffer { + resource: buffer, + range: 0..size as u64, + dynamic_index: None, + }, + ); camera_buffer = Some(buffer); } diff --git a/crates/bevy_render/src/render_graph/nodes/camera_node.rs b/crates/bevy_render/src/render_graph/nodes/camera_node.rs index da35b1365c..d0bed5ac1a 100644 --- a/crates/bevy_render/src/render_graph/nodes/camera_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/camera_node.rs @@ -1,6 +1,8 @@ use crate::{ render_graph::{CommandQueue, Node, ResourceSlots, SystemNode}, - render_resource::{resource_name, BufferInfo, BufferUsage, RenderResourceAssignments}, + render_resource::{ + resource_name, BufferInfo, BufferUsage, RenderResourceAssignment, RenderResourceAssignments, + }, renderer::{RenderContext, RenderResources}, ActiveCamera, Camera, }; @@ -52,12 +54,20 @@ impl SystemNode for CameraNode { query| { let render_resources = &render_resource_context.context; if camera_buffer.is_none() { + let size = std::mem::size_of::<[[f32; 4]; 4]>(); let buffer = render_resources.create_buffer(BufferInfo { - size: std::mem::size_of::<[[f32; 4]; 4]>(), + size, buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, ..Default::default() }); - render_resource_assignments.set(resource_name::uniform::CAMERA, buffer); + render_resource_assignments.set( + resource_name::uniform::CAMERA, + RenderResourceAssignment::Buffer { + resource: buffer, + range: 0..size as u64, + dynamic_index: None, + }, + ); camera_buffer = Some(buffer); } diff --git a/crates/bevy_render/src/render_graph/nodes/uniform_node.rs b/crates/bevy_render/src/render_graph/nodes/uniform_node.rs index 23a884a266..eeec5a9e19 100644 --- a/crates/bevy_render/src/render_graph/nodes/uniform_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/uniform_node.rs @@ -2,8 +2,8 @@ use crate::{ pipeline::VertexBufferDescriptors, render_graph::{CommandQueue, Node, ResourceSlots, SystemNode}, render_resource::{ - BufferArrayInfo, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignments, - RenderResourceAssignmentsId, ResourceInfo, + BufferArrayInfo, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignment, + RenderResourceAssignments, RenderResourceAssignmentsId, ResourceInfo, }, renderer::{RenderContext, RenderResourceContext, RenderResources}, shader::{AsUniforms, FieldBindType}, @@ -224,42 +224,40 @@ where let (_name, uniform_buffer_status) = self.uniform_arrays[i].as_mut().unwrap(); let (target_buffer, target_offset) = if dynamic_uniforms { let buffer = uniform_buffer_status.buffer.unwrap(); - let mut offset = 0; - render_resources.get_resource_info(buffer, &mut |resource_info| { - if let Some(ResourceInfo::Buffer(BufferInfo { - array_info: Some(ref array_info), - is_dynamic: true, - .. - })) = resource_info - { - let index = uniform_buffer_status - .get_or_assign_index(render_resource_assignments.id); - render_resource_assignments.set_indexed( - &field_info.uniform_name, - buffer, - (index * array_info.item_size) as u32, - ); - offset = index * uniform_buffer_status.aligned_size; - } else { - panic!("Expected a dynamic uniform buffer"); - } - }); - (buffer, offset) + let index = uniform_buffer_status + .get_or_assign_index(render_resource_assignments.id); + render_resource_assignments.set( + &field_info.uniform_name, + RenderResourceAssignment::Buffer { + resource: buffer, + dynamic_index: Some( + (index * uniform_buffer_status.aligned_size) as u32, + ), + range: 0..size as u64, + }, + ); + (buffer, index * uniform_buffer_status.aligned_size) } else { - let resource = match render_resource_assignments - .get(field_info.uniform_name) - { - Some(render_resource) => render_resource, - None => { - let resource = render_resources.create_buffer(BufferInfo { - size, - buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, - ..Default::default() - }); - render_resource_assignments.set(&field_info.uniform_name, resource); - resource - } - }; + let resource = + match render_resource_assignments.get(field_info.uniform_name) { + Some(assignment) => assignment.get_resource(), + None => { + let resource = render_resources.create_buffer(BufferInfo { + size, + buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, + ..Default::default() + }); + render_resource_assignments.set( + &field_info.uniform_name, + RenderResourceAssignment::Buffer { + resource, + range: 0..size as u64, + dynamic_index: None, + }, + ); + resource + } + }; (resource, 0) }; @@ -791,8 +789,14 @@ fn setup_uniform_texture_resources( } }; - render_resource_assignments.set(field_info.texture_name, texture_resource); - render_resource_assignments.set(field_info.sampler_name, sampler_resource); + render_resource_assignments.set( + field_info.texture_name, + RenderResourceAssignment::Texture(texture_resource), + ); + render_resource_assignments.set( + field_info.sampler_name, + RenderResourceAssignment::Sampler(sampler_resource), + ); } _ => {} } diff --git a/crates/bevy_render/src/render_resource/render_resource_assignments.rs b/crates/bevy_render/src/render_resource/render_resource_assignments.rs index a707b549c6..a08f29a4ce 100644 --- a/crates/bevy_render/src/render_resource/render_resource_assignments.rs +++ b/crates/bevy_render/src/render_resource/render_resource_assignments.rs @@ -2,46 +2,63 @@ use super::RenderResource; use crate::pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineSpecialization}; use std::{ collections::{hash_map::DefaultHasher, HashMap, HashSet}, - hash::{Hash, Hasher}, + hash::{Hash, Hasher}, ops::Range, }; use uuid::Uuid; +#[derive(Clone, Eq, PartialEq, Debug)] +pub enum RenderResourceAssignment { + Buffer { + resource: RenderResource, + range: Range, + dynamic_index: Option, + }, + Texture(RenderResource), + Sampler(RenderResource), +} + +impl RenderResourceAssignment { + pub fn get_resource(&self) -> RenderResource { + match self { + RenderResourceAssignment::Buffer { resource, .. } => *resource, + RenderResourceAssignment::Texture(resource) => *resource, + RenderResourceAssignment::Sampler(resource) => *resource, + } + } +} + +#[derive(Eq, PartialEq, Debug)] +pub struct RenderResourceSet { + pub id: RenderResourceSetId, + pub dynamic_uniform_indices: Option>, +} + // PERF: if the assignments are scoped to a specific pipeline layout, then names could be replaced with indices here for a perf boost #[derive(Eq, PartialEq, Debug, Default)] pub struct RenderResourceAssignments { pub id: RenderResourceAssignmentsId, - render_resources: HashMap)>, + render_resources: HashMap, vertex_buffers: HashMap)>, bind_group_resource_sets: - HashMap>)>, + HashMap, dirty_bind_groups: HashSet, pub pipeline_specialization: PipelineSpecialization, } impl RenderResourceAssignments { - pub fn get(&self, name: &str) -> Option { - self.render_resources.get(name).map(|(r, _i)| *r) + pub fn get(&self, name: &str) -> Option<&RenderResourceAssignment> { + self.render_resources.get(name) } - pub fn get_indexed(&self, name: &str) -> Option<(RenderResource, Option)> { - self.render_resources.get(name).cloned() - } - - pub fn set(&mut self, name: &str, resource: RenderResource) { - self.try_set_dirty(name, resource); + pub fn set(&mut self, name: &str, assignment: RenderResourceAssignment) { + self.try_set_dirty(name, &assignment); self.render_resources - .insert(name.to_string(), (resource, None)); + .insert(name.to_string(), assignment); } - pub fn set_indexed(&mut self, name: &str, resource: RenderResource, index: u32) { - self.try_set_dirty(name, resource); - self.render_resources - .insert(name.to_string(), (resource, Some(index))); - } - - fn try_set_dirty(&mut self, name: &str, resource: RenderResource) { - if let Some((render_resource, _)) = self.render_resources.get(name) { - if *render_resource != resource { + fn try_set_dirty(&mut self, name: &str, assignment: &RenderResourceAssignment) { + if let Some(current_assignment) = self.render_resources.get(name) { + if current_assignment != assignment { // TODO: this is pretty crude. can we do better? for bind_group_id in self.bind_group_resource_sets.keys() { self.dirty_bind_groups.insert(*bind_group_id); @@ -76,53 +93,55 @@ impl RenderResourceAssignments { .contains_key(&bind_group_descriptor.id) || self.dirty_bind_groups.contains(&bind_group_descriptor.id) { - let result = self.generate_render_resource_set_id(bind_group_descriptor); - if let Some((set_id, indices)) = result { + let resource_set = self.generate_render_resource_set(bind_group_descriptor); + if let Some(resource_set) = resource_set { + let id = resource_set.id; self.bind_group_resource_sets - .insert(bind_group_descriptor.id, (set_id, indices)); - Some(set_id) + .insert(bind_group_descriptor.id, resource_set); + Some(id) } else { None } } else { self.bind_group_resource_sets .get(&bind_group_descriptor.id) - .map(|(set_id, _indices)| *set_id) + .map(|set| set.id) } } - pub fn get_render_resource_set_id( + pub fn get_render_resource_set( &self, bind_group_descriptor_id: BindGroupDescriptorId, - ) -> Option<&(RenderResourceSetId, Option>)> { + ) -> Option<&RenderResourceSet> { self.bind_group_resource_sets.get(&bind_group_descriptor_id) } - fn generate_render_resource_set_id( + fn generate_render_resource_set( &self, bind_group_descriptor: &BindGroupDescriptor, - ) -> Option<(RenderResourceSetId, Option>)> { + ) -> Option { let mut hasher = DefaultHasher::new(); let mut indices = Vec::new(); for binding_descriptor in bind_group_descriptor.bindings.iter() { - if let Some((render_resource, index)) = self.get_indexed(&binding_descriptor.name) { - render_resource.hash(&mut hasher); - if let Some(index) = index { - indices.push(index); + if let Some(assignment) = self.get(&binding_descriptor.name) { + let resource = assignment.get_resource(); + resource.hash(&mut hasher); + if let RenderResourceAssignment::Buffer { dynamic_index: Some(index), .. } = assignment { + indices.push(*index); } } else { return None; } } - Some(( - RenderResourceSetId(hasher.finish()), - if indices.is_empty() { + Some(RenderResourceSet { + id: RenderResourceSetId(hasher.finish()), + dynamic_uniform_indices: if indices.is_empty() { None } else { Some(indices) }, - )) + }) } } @@ -176,22 +195,22 @@ mod tests { ], ); - let resource1 = RenderResource::new(); - let resource2 = RenderResource::new(); - let resource3 = RenderResource::new(); - let resource4 = RenderResource::new(); + let resource1 = RenderResourceAssignment::Texture(RenderResource::new()); + let resource2 = RenderResourceAssignment::Texture(RenderResource::new()); + let resource3 = RenderResourceAssignment::Texture(RenderResource::new()); + let resource4 = RenderResourceAssignment::Texture(RenderResource::new()); let mut assignments = RenderResourceAssignments::default(); - assignments.set("a", resource1); - assignments.set("b", resource2); + assignments.set("a", resource1.clone()); + assignments.set("b", resource2.clone()); let mut different_assignments = RenderResourceAssignments::default(); - different_assignments.set("a", resource3); - different_assignments.set("b", resource4); + different_assignments.set("a", resource3.clone()); + different_assignments.set("b", resource4.clone()); let mut equal_assignments = RenderResourceAssignments::default(); - equal_assignments.set("a", resource1); - equal_assignments.set("b", resource2); + equal_assignments.set("a", resource1.clone()); + equal_assignments.set("b", resource2.clone()); let set_id = assignments.update_render_resource_set_id(&bind_group_descriptor); assert_ne!(set_id, None); @@ -206,7 +225,7 @@ mod tests { assert_eq!(equal_set_id, set_id); let mut unmatched_assignments = RenderResourceAssignments::default(); - unmatched_assignments.set("a", resource1); + unmatched_assignments.set("a", resource1.clone()); let unmatched_set_id = unmatched_assignments.update_render_resource_set_id(&bind_group_descriptor); assert_eq!(unmatched_set_id, None); diff --git a/crates/bevy_render/src/render_resource/resource_info.rs b/crates/bevy_render/src/render_resource/resource_info.rs index e6bbadacb7..d9ffc2f450 100644 --- a/crates/bevy_render/src/render_resource/resource_info.rs +++ b/crates/bevy_render/src/render_resource/resource_info.rs @@ -10,6 +10,7 @@ pub struct BufferArrayInfo { pub struct BufferInfo { pub size: usize, pub buffer_usage: BufferUsage, + // TODO: remove array info and is_dynamic pub array_info: Option, pub is_dynamic: bool, } diff --git a/crates/bevy_render/src/renderer/headless_render_resource_context.rs b/crates/bevy_render/src/renderer/headless_render_resource_context.rs index 14616c7b6f..5e0666917a 100644 --- a/crates/bevy_render/src/renderer/headless_render_resource_context.rs +++ b/crates/bevy_render/src/renderer/headless_render_resource_context.rs @@ -121,10 +121,10 @@ impl RenderResourceContext for HeadlessRenderResourceContext { bind_group_descriptor: &BindGroupDescriptor, render_resource_assignments: &RenderResourceAssignments, ) -> Option { - if let Some((render_resource_set_id, _indices)) = - render_resource_assignments.get_render_resource_set_id(bind_group_descriptor.id) + if let Some(resource_set) = + render_resource_assignments.get_render_resource_set(bind_group_descriptor.id) { - Some(*render_resource_set_id) + Some(resource_set.id) } else { None } diff --git a/crates/bevy_wgpu/src/renderer/wgpu_render_context.rs b/crates/bevy_wgpu/src/renderer/wgpu_render_context.rs index 485dd79cab..5016ecee8a 100644 --- a/crates/bevy_wgpu/src/renderer/wgpu_render_context.rs +++ b/crates/bevy_wgpu/src/renderer/wgpu_render_context.rs @@ -6,7 +6,7 @@ use bevy_render::{ PassDescriptor, RenderPass, RenderPassColorAttachmentDescriptor, RenderPassDepthStencilAttachmentDescriptor, TextureAttachment, }, - render_resource::{RenderResource, RenderResourceAssignments}, + render_resource::{RenderResource, RenderResourceAssignments, RenderResourceAssignment}, renderer::{RenderContext, RenderResourceContext}, texture::{Extent3d, TextureDescriptor}, }; @@ -195,8 +195,8 @@ fn get_texture_view<'a>( ) -> &'a wgpu::TextureView { match attachment { TextureAttachment::Name(name) => match global_render_resource_assignments.get(&name) { - Some(resource) => refs.textures.get(&resource).unwrap(), - None => { + Some(RenderResourceAssignment::Texture(resource)) => refs.textures.get(&resource).unwrap(), + _ => { panic!("Color attachment {} does not exist", name); } }, diff --git a/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs b/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs index 0eaa4b94fb..b20687336b 100644 --- a/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs +++ b/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs @@ -7,7 +7,8 @@ use bevy_asset::{AssetStorage, Handle, HandleUntyped}; use bevy_render::{ pipeline::{BindGroupDescriptor, BindType, PipelineDescriptor}, render_resource::{ - BufferInfo, RenderResource, RenderResourceAssignments, RenderResourceSetId, ResourceInfo, + BufferInfo, RenderResource, RenderResourceAssignment, RenderResourceAssignments, + RenderResourceSetId, ResourceInfo, }, renderer::RenderResourceContext, shader::Shader, @@ -287,11 +288,7 @@ impl RenderResourceContext for WgpuRenderResourceContext { handle_info(info); } - fn create_shader_module_from_source( - &self, - shader_handle: Handle, - shader: &Shader, - ) { + fn create_shader_module_from_source(&self, shader_handle: Handle, shader: &Shader) { let mut shader_modules = self.resources.shader_modules.write().unwrap(); let shader_module = self.device.create_shader_module(&shader.get_spirv(None)); shader_modules.insert(shader_handle, shader_module); @@ -484,21 +481,20 @@ impl RenderResourceContext for WgpuRenderResourceContext { bind_group_descriptor: &BindGroupDescriptor, render_resource_assignments: &RenderResourceAssignments, ) -> Option { - if let Some((render_resource_set_id, _indices)) = - render_resource_assignments.get_render_resource_set_id(bind_group_descriptor.id) + if let Some(render_resource_set) = + render_resource_assignments.get_render_resource_set(bind_group_descriptor.id) { if !self .resources - .has_bind_group(bind_group_descriptor.id, *render_resource_set_id) + .has_bind_group(bind_group_descriptor.id, render_resource_set.id) { log::trace!( "start creating bind group for RenderResourceSet {:?}", - render_resource_set_id + render_resource_set.id ); let texture_views = self.resources.texture_views.read().unwrap(); let samplers = self.resources.samplers.read().unwrap(); let buffers = self.resources.buffers.read().unwrap(); - let resource_info = self.resources.resource_info.read().unwrap(); let bind_group_layouts = self.resources.bind_group_layouts.read().unwrap(); let mut bind_groups = self.resources.bind_groups.write().unwrap(); @@ -506,43 +502,27 @@ impl RenderResourceContext for WgpuRenderResourceContext { .bindings .iter() .map(|binding| { - if let Some(resource) = render_resource_assignments.get(&binding.name) { - let info = resource_info - .get(&resource) - .expect("referenced resource does not exist"); + if let Some(assignment) = render_resource_assignments.get(&binding.name) { log::trace!( - "found binding {} ({}) resource: {:?} {:?}", + "found binding {} ({}) assignment: {:?}", binding.index, binding.name, - resource, - resource_info + assignment, ); - let wgpu_resource = match &binding.bind_type { - BindType::SampledTexture { .. } => { - if let ResourceInfo::Texture = info { - let texture = texture_views.get(&resource).unwrap(); - wgpu::BindingResource::TextureView(texture) - } else { - panic!("expected a Texture resource"); - } + let wgpu_resource = match assignment { + RenderResourceAssignment::Texture(resource) => { + let texture = texture_views.get(&resource).unwrap(); + wgpu::BindingResource::TextureView(texture) } - BindType::Sampler { .. } => { - if let ResourceInfo::Sampler = info { - let sampler = samplers.get(&resource).unwrap(); - wgpu::BindingResource::Sampler(sampler) - } else { - panic!("expected a Sampler resource"); - } + RenderResourceAssignment::Sampler(resource) => { + let sampler = samplers.get(&resource).unwrap(); + wgpu::BindingResource::Sampler(sampler) } - BindType::Uniform { .. } => { - if let ResourceInfo::Buffer(buffer_info) = info { - let buffer = buffers.get(&resource).unwrap(); - wgpu::BindingResource::Buffer { - buffer, - range: 0..buffer_info.size as u64, - } - } else { - panic!("expected a Buffer resource"); + RenderResourceAssignment::Buffer { resource, range , .. } => { + let buffer = buffers.get(&resource).unwrap(); + wgpu::BindingResource::Buffer { + buffer, + range: range.clone(), } } _ => panic!("unsupported bind type"), @@ -574,12 +554,12 @@ impl RenderResourceContext for WgpuRenderResourceContext { .or_insert_with(|| WgpuBindGroupInfo::default()); bind_group_info .bind_groups - .insert(*render_resource_set_id, wgpu_bind_group); + .insert(render_resource_set.id, wgpu_bind_group); log::trace!( "created bind group for RenderResourceSet {:?}", - render_resource_set_id + render_resource_set.id ); - return Some(*render_resource_set_id); + return Some(render_resource_set.id); } } diff --git a/crates/bevy_wgpu/src/wgpu_render_pass.rs b/crates/bevy_wgpu/src/wgpu_render_pass.rs index 05307b34a1..661e6958ea 100644 --- a/crates/bevy_wgpu/src/wgpu_render_pass.rs +++ b/crates/bevy_wgpu/src/wgpu_render_pass.rs @@ -89,17 +89,17 @@ impl<'a> RenderPass for WgpuRenderPass<'a> { } for bind_group in pipeline_layout.bind_groups.iter() { - if let Some((render_resource_set_id, dynamic_uniform_indices)) = - render_resource_assignments.get_render_resource_set_id(bind_group.id) + if let Some(resource_set) = + render_resource_assignments.get_render_resource_set(bind_group.id) { if let Some(bind_group_info) = self.render_resources.bind_groups.get(&bind_group.id) { if let Some(wgpu_bind_group) = - bind_group_info.bind_groups.get(render_resource_set_id) + bind_group_info.bind_groups.get(&resource_set.id) { const EMPTY: &'static [u32] = &[]; let dynamic_uniform_indices = - if let Some(dynamic_uniform_indices) = dynamic_uniform_indices { + if let Some(ref dynamic_uniform_indices) = resource_set.dynamic_uniform_indices { dynamic_uniform_indices.as_slice() } else { EMPTY @@ -110,7 +110,7 @@ impl<'a> RenderPass for WgpuRenderPass<'a> { if let Some(bound_render_resource_set) = self.bound_bind_groups.get(&bind_group.index) { - if *bound_render_resource_set == *render_resource_set_id + if *bound_render_resource_set == resource_set.id && dynamic_uniform_indices.len() == 0 { continue; @@ -119,7 +119,7 @@ impl<'a> RenderPass for WgpuRenderPass<'a> { if dynamic_uniform_indices.len() == 0 { self.bound_bind_groups - .insert(bind_group.index, *render_resource_set_id); + .insert(bind_group.index, resource_set.id); } else { self.bound_bind_groups.remove(&bind_group.index); } @@ -128,7 +128,7 @@ impl<'a> RenderPass for WgpuRenderPass<'a> { "set bind group {} {:?}: {:?}", bind_group.index, dynamic_uniform_indices, - render_resource_set_id + resource_set.id ); self.render_pass.set_bind_group( bind_group.index,