diff --git a/crates/bevy_pbr/src/nodes/lights_node.rs b/crates/bevy_pbr/src/nodes/lights_node.rs index d003f36658..0e7e78502a 100644 --- a/crates/bevy_pbr/src/nodes/lights_node.rs +++ b/crates/bevy_pbr/src/nodes/lights_node.rs @@ -83,7 +83,7 @@ impl SystemNode for LightsNode { render_resource_assignments.set( uniform::LIGHTS, RenderResourceAssignment::Buffer { - resource: buffer, + buffer, range: 0..light_uniform_size as u64, dynamic_index: None, }, diff --git a/crates/bevy_render/src/draw.rs b/crates/bevy_render/src/draw.rs index ccc38c001d..91ab5df2b8 100644 --- a/crates/bevy_render/src/draw.rs +++ b/crates/bevy_render/src/draw.rs @@ -1,8 +1,8 @@ use crate::{ pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineDescriptor}, render_resource::{ - BufferUsage, RenderResource, RenderResourceAssignment, RenderResourceAssignments, - RenderResourceId, RenderResourceSet, RenderResourceSetId, ResourceInfo, SharedBuffers, + BufferId, BufferUsage, RenderResource, RenderResourceAssignment, RenderResourceAssignments, + RenderResourceSet, RenderResourceSetId, SharedBuffers, }, renderer::{RenderResourceContext, RenderResources}, }; @@ -22,11 +22,11 @@ pub enum RenderCommand { }, SetVertexBuffer { slot: u32, - buffer: RenderResourceId, + buffer: BufferId, offset: u64, }, SetIndexBuffer { - buffer: RenderResourceId, + buffer: BufferId, offset: u64, }, SetBindGroup { @@ -154,7 +154,7 @@ impl<'a> DrawContext<'a> { Ok(()) } - pub fn set_vertex_buffer(&mut self, slot: u32, buffer: RenderResourceId, offset: u64) { + pub fn set_vertex_buffer(&mut self, slot: u32, buffer: BufferId, offset: u64) { self.render_command(RenderCommand::SetVertexBuffer { slot, buffer, @@ -162,7 +162,7 @@ impl<'a> DrawContext<'a> { }); } - pub fn set_index_buffer(&mut self, buffer: RenderResourceId, offset: u64) { + pub fn set_index_buffer(&mut self, buffer: BufferId, offset: u64) { self.render_command(RenderCommand::SetIndexBuffer { buffer, offset }); } @@ -230,15 +230,13 @@ impl Drawable for RenderPipelines { { draw.set_vertex_buffer(slot as u32, vertex_buffer, 0); if let Some(index_buffer) = index_buffer { - draw.render_resource_context.get_resource_info( - index_buffer, - &mut |resource_info| match resource_info { - Some(ResourceInfo::Buffer(Some(buffer_info))) => { - indices = 0..(buffer_info.size / 2) as u32; - } - _ => panic!("expected a buffer type"), - }, - ); + if let Some(buffer_info) = + draw.render_resource_context.get_buffer_info(index_buffer) + { + indices = 0..(buffer_info.size / 2) as u32; + } else { + panic!("expected buffer type"); + } draw.set_index_buffer(index_buffer, 0); } } diff --git a/crates/bevy_render/src/mesh.rs b/crates/bevy_render/src/mesh.rs index 15ed416545..7fb9c339f8 100644 --- a/crates/bevy_render/src/mesh.rs +++ b/crates/bevy_render/src/mesh.rs @@ -3,7 +3,7 @@ use crate::{ state_descriptors::{IndexFormat, PrimitiveTopology}, AsVertexBufferDescriptor, VertexBufferDescriptor, VertexBufferDescriptors, VertexFormat, }, - render_resource::{BufferInfo, BufferUsage}, + render_resource::{BufferInfo, BufferUsage, RenderResourceId}, renderer::{RenderResourceContext, RenderResources}, RenderPipelines, Vertex, }; @@ -324,12 +324,16 @@ fn remove_current_mesh_resources( render_resources: &dyn RenderResourceContext, handle: Handle, ) { - if let Some(resource) = render_resources.get_asset_resource(handle, VERTEX_BUFFER_ASSET_INDEX) { - render_resources.remove_buffer(resource); + if let Some(RenderResourceId::Buffer(buffer)) = + render_resources.get_asset_resource(handle, VERTEX_BUFFER_ASSET_INDEX) + { + render_resources.remove_buffer(buffer); render_resources.remove_asset_resource(handle, VERTEX_BUFFER_ASSET_INDEX); } - if let Some(resource) = render_resources.get_asset_resource(handle, INDEX_BUFFER_ASSET_INDEX) { - render_resources.remove_buffer(resource); + if let Some(RenderResourceId::Buffer(buffer)) = + render_resources.get_asset_resource(handle, INDEX_BUFFER_ASSET_INDEX) + { + render_resources.remove_buffer(buffer); render_resources.remove_asset_resource(handle, INDEX_BUFFER_ASSET_INDEX); } } @@ -390,12 +394,12 @@ pub fn mesh_resource_provider_system(resources: &mut Resources) -> Box Box Option { - if let TextureAttachment::RenderResource(render_resource) = self { - Some(*render_resource) + pub fn get_texture_id(&self) -> Option { + if let TextureAttachment::Id(texture_id) = self { + Some(*texture_id) } else { None } diff --git a/crates/bevy_render/src/pass/render_pass.rs b/crates/bevy_render/src/pass/render_pass.rs index 16c753819f..a0e2dd2179 100644 --- a/crates/bevy_render/src/pass/render_pass.rs +++ b/crates/bevy_render/src/pass/render_pass.rs @@ -1,6 +1,6 @@ use crate::{ pipeline::{PipelineDescriptor, BindGroupDescriptorId}, - render_resource::{RenderResourceId, RenderResourceSetId}, + render_resource::{RenderResourceSetId, BufferId}, renderer::RenderContext, }; use bevy_asset::Handle; @@ -8,8 +8,8 @@ use std::ops::Range; pub trait RenderPass { fn get_render_context(&self) -> &dyn RenderContext; - fn set_index_buffer(&mut self, resource: RenderResourceId, offset: u64); - fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResourceId, offset: u64); + fn set_index_buffer(&mut self, buffer: BufferId, offset: u64); + fn set_vertex_buffer(&mut self, start_slot: u32, buffer: BufferId, offset: u64); fn set_pipeline(&mut self, pipeline_handle: Handle); fn set_viewport(&mut self, x: f32, y: f32, w: f32, h: f32, min_depth: f32, max_depth: f32); fn set_stencil_reference(&mut self, reference: u32); diff --git a/crates/bevy_render/src/render_graph/command.rs b/crates/bevy_render/src/render_graph/command.rs index 36409b9672..9a7de22daa 100644 --- a/crates/bevy_render/src/render_graph/command.rs +++ b/crates/bevy_render/src/render_graph/command.rs @@ -1,26 +1,26 @@ -use crate::{render_resource::RenderResourceId, renderer::RenderContext, texture::Extent3d}; +use crate::{render_resource::{BufferId, TextureId}, renderer::RenderContext, texture::Extent3d}; use std::sync::{Arc, Mutex}; #[derive(Clone, Debug)] pub enum Command { CopyBufferToBuffer { - source_buffer: RenderResourceId, + source_buffer: BufferId, source_offset: u64, - destination_buffer: RenderResourceId, + destination_buffer: BufferId, destination_offset: u64, size: u64, }, CopyBufferToTexture { - source_buffer: RenderResourceId, + source_buffer: BufferId, source_offset: u64, source_bytes_per_row: u32, - destination_texture: RenderResourceId, + destination_texture: TextureId, destination_origin: [u32; 3], destination_mip_level: u32, size: Extent3d, }, // TODO: Frees probably don't need to be queued? - FreeBuffer(RenderResourceId), + FreeBuffer(BufferId), } #[derive(Default, Clone)] @@ -36,9 +36,9 @@ impl CommandQueue { pub fn copy_buffer_to_buffer( &mut self, - source_buffer: RenderResourceId, + source_buffer: BufferId, source_offset: u64, - destination_buffer: RenderResourceId, + destination_buffer: BufferId, destination_offset: u64, size: u64, ) { @@ -53,10 +53,10 @@ impl CommandQueue { pub fn copy_buffer_to_texture( &mut self, - source_buffer: RenderResourceId, + source_buffer: BufferId, source_offset: u64, source_bytes_per_row: u32, - destination_texture: RenderResourceId, + destination_texture: TextureId, destination_origin: [u32; 3], destination_mip_level: u32, size: Extent3d, @@ -72,7 +72,7 @@ impl CommandQueue { }); } - pub fn free_buffer(&mut self, buffer: RenderResourceId) { + pub fn free_buffer(&mut self, buffer: BufferId) { self.push(Command::FreeBuffer(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 84828cc383..250b19717a 100644 --- a/crates/bevy_render/src/render_graph/nodes/camera_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/camera_node.rs @@ -64,7 +64,7 @@ impl SystemNode for CameraNode { render_resource_assignments.set( &uniform_name, RenderResourceAssignment::Buffer { - resource: buffer, + buffer, range: 0..size as u64, dynamic_index: None, }, diff --git a/crates/bevy_render/src/render_graph/nodes/pass_node.rs b/crates/bevy_render/src/render_graph/nodes/pass_node.rs index 7800ab7f66..2f50ee3acd 100644 --- a/crates/bevy_render/src/render_graph/nodes/pass_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/pass_node.rs @@ -3,9 +3,7 @@ use crate::{ pass::{PassDescriptor, TextureAttachment}, pipeline::PipelineDescriptor, render_graph::{Node, ResourceSlotInfo, ResourceSlots}, - render_resource::{ - RenderResourceAssignments, RenderResourceId, RenderResourceSetId, ResourceInfo, - }, + render_resource::{BufferId, RenderResourceAssignments, RenderResourceSetId, ResourceInfo}, renderer::RenderContext, }; use bevy_asset::{Assets, Handle}; @@ -73,7 +71,7 @@ impl Node for MainPassNode { for (i, color_attachment) in self.descriptor.color_attachments.iter_mut().enumerate() { if let Some(input_index) = self.color_attachment_input_indices[i] { color_attachment.attachment = - TextureAttachment::RenderResource(input.get(input_index).unwrap()); + TextureAttachment::Id(input.get(input_index).unwrap().get_texture().unwrap()); } } @@ -82,7 +80,8 @@ impl Node for MainPassNode { .depth_stencil_attachment .as_mut() .unwrap() - .attachment = TextureAttachment::RenderResource(input.get(input_index).unwrap()); + .attachment = + TextureAttachment::Id(input.get(input_index).unwrap().get_texture().unwrap()); } render_context.begin_pass( @@ -159,8 +158,8 @@ impl Node for MainPassNode { struct DrawState { pipeline: Option>, bind_groups: Vec>, - vertex_buffers: Vec>, - index_buffer: Option, + vertex_buffers: Vec>, + index_buffer: Option, } impl DrawState { @@ -168,11 +167,11 @@ impl DrawState { self.bind_groups[index as usize] = Some(render_resource_set); } - pub fn set_vertex_buffer(&mut self, index: u32, buffer: RenderResourceId) { + pub fn set_vertex_buffer(&mut self, index: u32, buffer: BufferId) { self.vertex_buffers[index as usize] = Some(buffer); } - pub fn set_index_buffer(&mut self, buffer: RenderResourceId) { + pub fn set_index_buffer(&mut self, buffer: BufferId) { self.index_buffer = Some(buffer); } diff --git a/crates/bevy_render/src/render_graph/nodes/render_resources_node.rs b/crates/bevy_render/src/render_graph/nodes/render_resources_node.rs index db13f6c08a..7072c791c1 100644 --- a/crates/bevy_render/src/render_graph/nodes/render_resources_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/render_resources_node.rs @@ -3,7 +3,7 @@ use crate::{ render_graph::{CommandQueue, Node, ResourceSlots, SystemNode}, render_resource::{ self, BufferInfo, BufferUsage, RenderResourceAssignment, RenderResourceAssignments, - RenderResourceAssignmentsId, RenderResourceHints, RenderResourceId, + RenderResourceAssignmentsId, RenderResourceHints, }, renderer::{RenderContext, RenderResourceContext, RenderResources}, texture, @@ -11,13 +11,13 @@ use crate::{ use bevy_asset::{Assets, Handle}; use legion::prelude::*; -use render_resource::ResourceInfo; +use render_resource::{BufferId, ResourceInfo}; use std::{collections::HashMap, marker::PhantomData}; pub const BIND_BUFFER_ALIGNMENT: usize = 256; #[derive(Debug)] struct QueuedBufferWrite { - buffer: RenderResourceId, + buffer: BufferId, target_offset: usize, source_offset: usize, size: usize, @@ -29,7 +29,7 @@ struct BufferArrayStatus { item_size: usize, aligned_size: usize, staging_buffer_offset: usize, - buffer: Option, + buffer: Option, queued_buffer_writes: Vec, current_item_count: usize, current_item_capacity: usize, @@ -214,7 +214,7 @@ where render_resource_assignments.set( render_resource_name, RenderResourceAssignment::Buffer { - resource: buffer, + buffer, dynamic_index: Some( (index * uniform_buffer_status.aligned_size) as u32, ), @@ -228,21 +228,18 @@ where if let Some(assignment) = render_resource_assignments.get(render_resource_name) { - let resource = assignment.get_resource(); - render_resources.get_resource_info(resource, &mut |info| { - if let Some(ResourceInfo::Buffer(Some(BufferInfo { - size: current_size, - .. - }))) = info - { - if size == *current_size { - matching_buffer = Some(resource); - } else { - // TODO: if get_resource_info returns a type instead of taking a closure, move buffer free here - buffer_to_remove = Some(resource); - } + let buffer_id = assignment.get_buffer().unwrap(); + if let Some(BufferInfo { + size: current_size, .. + }) = render_resources.get_buffer_info(buffer_id) + { + if size == current_size { + matching_buffer = Some(buffer_id); + } else { + // TODO: if get_resource_info returns a type instead of taking a closure, move buffer free here + buffer_to_remove = Some(buffer_id); } - }) + } } if let Some(buffer) = buffer_to_remove { @@ -261,7 +258,7 @@ where } } - let resource = render_resources.create_buffer(BufferInfo { + let buffer = render_resources.create_buffer(BufferInfo { size, buffer_usage: BufferUsage::COPY_DST | usage, ..Default::default() @@ -270,12 +267,12 @@ where render_resource_assignments.set( render_resource_name, RenderResourceAssignment::Buffer { - resource, + buffer, range, dynamic_index: None, }, ); - resource + buffer }; (resource, 0) @@ -308,7 +305,7 @@ where fn copy_staging_buffer_to_final_buffers( &mut self, command_queue: &mut CommandQueue, - staging_buffer: RenderResourceId, + staging_buffer: BufferId, ) { for uniform_buffer_status in self.uniform_arrays.iter_mut() { if let Some((_name, buffer_array_status)) = uniform_buffer_status { @@ -636,11 +633,11 @@ fn setup_uniform_texture_resources( render_resource_assignments.set( render_resource_name, - RenderResourceAssignment::Texture(texture_resource), + RenderResourceAssignment::Texture(texture_resource.get_texture().unwrap()), ); render_resource_assignments.set( &sampler_name, - RenderResourceAssignment::Sampler(sampler_resource), + RenderResourceAssignment::Sampler(sampler_resource.get_sampler().unwrap()), ); continue; } diff --git a/crates/bevy_render/src/render_graph/nodes/texture_copy_node.rs b/crates/bevy_render/src/render_graph/nodes/texture_copy_node.rs index 853dd29aca..f61b8ba376 100644 --- a/crates/bevy_render/src/render_graph/nodes/texture_copy_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/texture_copy_node.rs @@ -60,7 +60,7 @@ impl Node for TextureCopyNode { texture_buffer, 0, (format_size * aligned_width) as u32, - texture_resource, + texture_resource.get_texture().unwrap(), [0, 0, 0], 0, texture_descriptor.size.clone(), diff --git a/crates/bevy_render/src/render_graph/nodes/window_swapchain_node.rs b/crates/bevy_render/src/render_graph/nodes/window_swapchain_node.rs index 29b0a9ff02..31cc872953 100644 --- a/crates/bevy_render/src/render_graph/nodes/window_swapchain_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/window_swapchain_node.rs @@ -1,6 +1,6 @@ use crate::{ render_graph::{Node, ResourceSlotInfo, ResourceSlots}, - render_resource::ResourceInfo, + render_resource::{RenderResourceId, ResourceInfo}, renderer::RenderContext, }; use bevy_app::{EventReader, Events}; @@ -70,6 +70,6 @@ impl Node for WindowSwapChainNode { } let swap_chain_texture = render_resources.next_swap_chain_texture(window.id); - output.set(WINDOW_TEXTURE, swap_chain_texture); + output.set(WINDOW_TEXTURE, RenderResourceId::Texture(swap_chain_texture)); } } diff --git a/crates/bevy_render/src/render_graph/nodes/window_texture_node.rs b/crates/bevy_render/src/render_graph/nodes/window_texture_node.rs index 196f6a1f45..70be9f93e2 100644 --- a/crates/bevy_render/src/render_graph/nodes/window_texture_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/window_texture_node.rs @@ -1,6 +1,6 @@ use crate::{ render_graph::{Node, ResourceSlotInfo, ResourceSlots}, - render_resource::ResourceInfo, + render_resource::{RenderResourceId, ResourceInfo}, renderer::RenderContext, texture::TextureDescriptor, }; @@ -67,14 +67,14 @@ impl Node for WindowTextureNode { .is_some() { let render_resources = render_context.resources_mut(); - if let Some(old_texture) = output.get(WINDOW_TEXTURE) { + if let Some(RenderResourceId::Texture(old_texture)) = output.get(WINDOW_TEXTURE) { render_resources.remove_texture(old_texture); } self.descriptor.size.width = window.width; self.descriptor.size.height = window.height; let texture_resource = render_resources.create_texture(self.descriptor); - output.set(WINDOW_TEXTURE, texture_resource); + output.set(WINDOW_TEXTURE, RenderResourceId::Texture(texture_resource)); } } } diff --git a/crates/bevy_render/src/render_resource/buffer.rs b/crates/bevy_render/src/render_resource/buffer.rs index 87ea3e3e2a..0fb5f424be 100644 --- a/crates/bevy_render/src/render_resource/buffer.rs +++ b/crates/bevy_render/src/render_resource/buffer.rs @@ -1,3 +1,15 @@ +use uuid::Uuid; + +#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)] +pub struct BufferId(Uuid); + +impl BufferId { + pub fn new() -> Self { + BufferId(Uuid::new_v4()) + } +} + + bitflags::bitflags! { #[repr(transparent)] #[cfg_attr(feature = "trace", derive(Serialize))] diff --git a/crates/bevy_render/src/render_resource/mod.rs b/crates/bevy_render/src/render_resource/mod.rs index 419f8c6d1b..4ceb985507 100644 --- a/crates/bevy_render/src/render_resource/mod.rs +++ b/crates/bevy_render/src/render_resource/mod.rs @@ -1,4 +1,5 @@ mod buffer; +mod texture; mod shared_buffer; mod render_resource; mod render_resource_set; @@ -7,6 +8,7 @@ mod resource_info; mod systems; pub use buffer::*; +pub use texture::*; pub use shared_buffer::*; pub use render_resource::*; pub use render_resource_set::*; diff --git a/crates/bevy_render/src/render_resource/render_resource.rs b/crates/bevy_render/src/render_resource/render_resource.rs index 145875760c..6fc8544ab9 100644 --- a/crates/bevy_render/src/render_resource/render_resource.rs +++ b/crates/bevy_render/src/render_resource/render_resource.rs @@ -1,18 +1,59 @@ -use super::ResourceInfo; +use super::{BufferId, ResourceInfo, SamplerId, TextureId}; use crate::texture::Texture; use bevy_asset::Handle; -use uuid::Uuid; use bevy_core::bytes::{Byteable, Bytes}; pub use bevy_derive::{RenderResource, RenderResources}; use glam::{Mat4, Vec2, Vec3, Vec4}; -#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)] -pub struct RenderResourceId(Uuid); +#[derive(Debug, Clone, Hash, Eq, PartialEq)] +pub enum RenderResourceId { + Buffer(BufferId), + Texture(TextureId), + Sampler(SamplerId), +} + +impl From for RenderResourceId { + fn from(value: BufferId) -> Self { + RenderResourceId::Buffer(value) + } +} + +impl From for RenderResourceId { + fn from(value: TextureId) -> Self { + RenderResourceId::Texture(value) + } +} + +impl From for RenderResourceId { + fn from(value: SamplerId) -> Self { + RenderResourceId::Sampler(value) + } +} impl RenderResourceId { - pub fn new() -> Self { - RenderResourceId(Uuid::new_v4()) + pub fn get_texture(&self) -> Option { + if let RenderResourceId::Texture(id) = self{ + Some(*id) + } else { + None + } + } + + pub fn get_buffer(&self) -> Option { + if let RenderResourceId::Buffer(id) = self{ + Some(*id) + } else { + None + } + } + + pub fn get_sampler(&self) -> Option { + if let RenderResourceId::Sampler(id) = self{ + Some(*id) + } else { + None + } } } 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 d2f176d670..bed9f688d0 100644 --- a/crates/bevy_render/src/render_resource/render_resource_assignments.rs +++ b/crates/bevy_render/src/render_resource/render_resource_assignments.rs @@ -1,4 +1,4 @@ -use super::{RenderResourceId, RenderResourceSet, RenderResourceSetId}; +use super::{BufferId, RenderResourceId, RenderResourceSet, RenderResourceSetId, SamplerId, TextureId}; use crate::pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineSpecialization}; use std::{ collections::{HashMap, HashSet}, @@ -10,20 +10,36 @@ use uuid::Uuid; #[derive(Clone, Eq, PartialEq, Debug)] pub enum RenderResourceAssignment { Buffer { - resource: RenderResourceId, + buffer: BufferId, range: Range, dynamic_index: Option, }, - Texture(RenderResourceId), - Sampler(RenderResourceId), + Texture(TextureId), + Sampler(SamplerId), } impl RenderResourceAssignment { - pub fn get_resource(&self) -> RenderResourceId { - match self { - RenderResourceAssignment::Buffer { resource, .. } => *resource, - RenderResourceAssignment::Texture(resource) => *resource, - RenderResourceAssignment::Sampler(resource) => *resource, + pub fn get_texture(&self) -> Option { + if let RenderResourceAssignment::Texture(texture) = self{ + Some(*texture) + } else { + None + } + } + + pub fn get_buffer(&self) -> Option { + if let RenderResourceAssignment::Buffer{ buffer, ..} = self{ + Some(*buffer) + } else { + None + } + } + + pub fn get_sampler(&self) -> Option { + if let RenderResourceAssignment::Sampler(sampler) = self{ + Some(*sampler) + } else { + None } } } @@ -32,18 +48,18 @@ impl Hash for RenderResourceAssignment { fn hash(&self, state: &mut H) { match self { RenderResourceAssignment::Buffer { - resource, + buffer, range, dynamic_index: _, // dynamic_index is not a part of the binding } => { - resource.hash(state); + RenderResourceId::from(*buffer).hash(state); range.hash(state); } - RenderResourceAssignment::Texture(resource) => { - resource.hash(state); + RenderResourceAssignment::Texture(texture) => { + RenderResourceId::from(*texture).hash(state); } - RenderResourceAssignment::Sampler(resource) => { - resource.hash(state); + RenderResourceAssignment::Sampler(sampler) => { + RenderResourceId::from(*sampler).hash(state); } } } @@ -62,7 +78,7 @@ pub struct RenderResourceAssignments { // TODO: remove this. it shouldn't be needed anymore pub id: RenderResourceAssignmentsId, render_resources: HashMap, - vertex_buffers: HashMap)>, + vertex_buffers: HashMap)>, render_resource_sets: HashMap, bind_group_render_resource_sets: HashMap, dirty_render_resource_sets: HashSet, @@ -102,21 +118,18 @@ impl RenderResourceAssignments { } } - pub fn get_vertex_buffer( - &self, - name: &str, - ) -> Option<(RenderResourceId, Option)> { + pub fn get_vertex_buffer(&self, name: &str) -> Option<(BufferId, Option)> { self.vertex_buffers.get(name).cloned() } pub fn set_vertex_buffer( &mut self, name: &str, - vertices_resource: RenderResourceId, - indices_resource: Option, + vertex_buffer: BufferId, + index_buffer: Option, ) { self.vertex_buffers - .insert(name.to_string(), (vertices_resource, indices_resource)); + .insert(name.to_string(), (vertex_buffer, index_buffer)); } fn create_render_resource_set( @@ -234,10 +247,10 @@ mod tests { ], ); - let resource1 = RenderResourceAssignment::Texture(RenderResourceId::new()); - let resource2 = RenderResourceAssignment::Texture(RenderResourceId::new()); - let resource3 = RenderResourceAssignment::Texture(RenderResourceId::new()); - let resource4 = RenderResourceAssignment::Texture(RenderResourceId::new()); + let resource1 = RenderResourceAssignment::Texture(TextureId::new()); + let resource2 = RenderResourceAssignment::Texture(TextureId::new()); + let resource3 = RenderResourceAssignment::Texture(TextureId::new()); + let resource4 = RenderResourceAssignment::Texture(TextureId::new()); let mut assignments = RenderResourceAssignments::default(); assignments.set("a", resource1.clone()); diff --git a/crates/bevy_render/src/render_resource/render_resource_set.rs b/crates/bevy_render/src/render_resource/render_resource_set.rs index 8dec1c0dea..f38e1a6684 100644 --- a/crates/bevy_render/src/render_resource/render_resource_set.rs +++ b/crates/bevy_render/src/render_resource/render_resource_set.rs @@ -1,4 +1,4 @@ -use super::{RenderResourceAssignment, RenderResourceId}; +use super::{BufferId, RenderResourceAssignment, SamplerId, TextureId}; use std::{ collections::hash_map::DefaultHasher, hash::{Hash, Hasher}, @@ -52,24 +52,19 @@ impl RenderResourceSetBuilder { self } - pub fn add_texture(self, index: u32, render_resource: RenderResourceId) -> Self { - self.add_assignment(index, RenderResourceAssignment::Texture(render_resource)) + pub fn add_texture(self, index: u32, texture: TextureId) -> Self { + self.add_assignment(index, RenderResourceAssignment::Texture(texture)) } - pub fn add_sampler(self, index: u32, render_resource: RenderResourceId) -> Self { - self.add_assignment(index, RenderResourceAssignment::Sampler(render_resource)) + pub fn add_sampler(self, index: u32, sampler: SamplerId) -> Self { + self.add_assignment(index, RenderResourceAssignment::Sampler(sampler)) } - pub fn add_buffer( - self, - index: u32, - render_resource: RenderResourceId, - range: Range, - ) -> Self { + pub fn add_buffer(self, index: u32, buffer: BufferId, range: Range) -> Self { self.add_assignment( index, RenderResourceAssignment::Buffer { - resource: render_resource, + buffer, range, dynamic_index: None, }, @@ -79,14 +74,14 @@ impl RenderResourceSetBuilder { pub fn add_dynamic_buffer( self, index: u32, - render_resource: RenderResourceId, + buffer: BufferId, range: Range, dynamic_index: u32, ) -> Self { self.add_assignment( index, RenderResourceAssignment::Buffer { - resource: render_resource, + buffer, range, dynamic_index: Some(dynamic_index), }, diff --git a/crates/bevy_render/src/render_resource/shared_buffer.rs b/crates/bevy_render/src/render_resource/shared_buffer.rs index a22e46ce70..ee814eb981 100644 --- a/crates/bevy_render/src/render_resource/shared_buffer.rs +++ b/crates/bevy_render/src/render_resource/shared_buffer.rs @@ -1,4 +1,4 @@ -use super::{BufferInfo, RenderResource, RenderResourceAssignment, RenderResourceId}; +use super::{BufferId, BufferInfo, RenderResource, RenderResourceAssignment}; use crate::{render_resource::BufferUsage, renderer::RenderResourceContext}; use legion::systems::Res; use std::sync::{Arc, RwLock}; @@ -8,7 +8,7 @@ use std::sync::{Arc, RwLock}; // buffer mapping yet. pub struct SharedBuffers { render_resource_context: Box, - buffers: Arc>>, + buffers: Arc>>, } impl SharedBuffers { @@ -27,14 +27,17 @@ impl SharedBuffers { if let Some(size) = render_resource.buffer_byte_len() { // PERF: this buffer will be slow let buffer = self.render_resource_context.create_buffer_mapped( - BufferInfo { size, buffer_usage: buffer_usage | BufferUsage::COPY_SRC | BufferUsage::COPY_DST }, + BufferInfo { + size, + buffer_usage: buffer_usage | BufferUsage::COPY_SRC | BufferUsage::COPY_DST, + }, &mut |data, _renderer| { render_resource.write_buffer_bytes(data); }, ); self.buffers.write().unwrap().push(buffer); Some(RenderResourceAssignment::Buffer { - resource: buffer, + buffer, range: 0..size as u64, dynamic_index: None, }) diff --git a/crates/bevy_render/src/render_resource/texture.rs b/crates/bevy_render/src/render_resource/texture.rs new file mode 100644 index 0000000000..5e20227e65 --- /dev/null +++ b/crates/bevy_render/src/render_resource/texture.rs @@ -0,0 +1,19 @@ +use uuid::Uuid; + +#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)] +pub struct TextureId(Uuid); + +impl TextureId { + pub fn new() -> Self { + TextureId(Uuid::new_v4()) + } +} + +#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)] +pub struct SamplerId(Uuid); + +impl SamplerId { + pub fn new() -> Self { + SamplerId(Uuid::new_v4()) + } +} 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 299283bb1f..0a446281f5 100644 --- a/crates/bevy_render/src/renderer/headless_render_resource_context.rs +++ b/crates/bevy_render/src/renderer/headless_render_resource_context.rs @@ -1,7 +1,7 @@ use super::RenderResourceContext; use crate::{ pipeline::{BindGroupDescriptorId, PipelineDescriptor}, - render_resource::{BufferInfo, RenderResourceId, RenderResourceSet, ResourceInfo}, + render_resource::{BufferId, BufferInfo, RenderResourceId, RenderResourceSet, SamplerId, TextureId}, shader::Shader, texture::{SamplerDescriptor, TextureDescriptor}, }; @@ -14,72 +14,66 @@ use std::{ #[derive(Default)] pub struct HeadlessRenderResourceContext { - resource_info: Arc>>, + buffer_info: Arc>>, + texture_descriptors: Arc>>, pub asset_resources: Arc>>, } impl HeadlessRenderResourceContext { - pub fn add_resource_info(&self, resource: RenderResourceId, resource_info: ResourceInfo) { - self.resource_info + pub fn add_buffer_info(&self, buffer: BufferId, info: BufferInfo) { + self.buffer_info.write().unwrap().insert(buffer, info); + } + + pub fn add_texture_descriptor(&self, texture: TextureId, descriptor: TextureDescriptor) { + self.texture_descriptors .write() .unwrap() - .insert(resource, resource_info); + .insert(texture, descriptor); } } impl RenderResourceContext for HeadlessRenderResourceContext { fn create_swap_chain(&self, _window: &Window) {} - fn next_swap_chain_texture(&self, _window_id: WindowId) -> RenderResourceId { - RenderResourceId::new() + fn next_swap_chain_texture(&self, _window_id: WindowId) -> TextureId { + TextureId::new() } - fn drop_swap_chain_texture(&self, _render_resource: RenderResourceId) {} + fn drop_swap_chain_texture(&self, _render_resource: TextureId) {} fn drop_all_swap_chain_textures(&self) {} - fn create_sampler(&self, _sampler_descriptor: &SamplerDescriptor) -> RenderResourceId { - let resource = RenderResourceId::new(); - self.add_resource_info(resource, ResourceInfo::Sampler); - resource + fn create_sampler(&self, _sampler_descriptor: &SamplerDescriptor) -> SamplerId { + SamplerId::new() } - fn create_texture(&self, texture_descriptor: TextureDescriptor) -> RenderResourceId { - let resource = RenderResourceId::new(); - self.add_resource_info(resource, ResourceInfo::Texture(Some(texture_descriptor))); - resource + fn create_texture(&self, texture_descriptor: TextureDescriptor) -> TextureId { + let texture = TextureId::new(); + self.add_texture_descriptor(texture, texture_descriptor); + texture } - fn create_buffer(&self, buffer_info: BufferInfo) -> RenderResourceId { - let resource = RenderResourceId::new(); - self.add_resource_info(resource, ResourceInfo::Buffer(Some(buffer_info))); - resource + fn create_buffer(&self, buffer_info: BufferInfo) -> BufferId { + let buffer = BufferId::new(); + self.add_buffer_info(buffer, buffer_info); + buffer } fn create_buffer_mapped( &self, buffer_info: BufferInfo, setup_data: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext), - ) -> RenderResourceId { + ) -> BufferId { let mut buffer = vec![0; buffer_info.size]; setup_data(&mut buffer, self); - RenderResourceId::new() + BufferId::new() } - fn create_buffer_with_data(&self, buffer_info: BufferInfo, _data: &[u8]) -> RenderResourceId { - let resource = RenderResourceId::new(); - self.add_resource_info(resource, ResourceInfo::Buffer(Some(buffer_info))); - resource + fn create_buffer_with_data(&self, buffer_info: BufferInfo, _data: &[u8]) -> BufferId { + let buffer = BufferId::new(); + self.add_buffer_info(buffer, buffer_info); + buffer } fn create_shader_module(&self, _shader_handle: Handle, _shaders: &Assets) {} - fn remove_buffer(&self, resource: RenderResourceId) { - self.resource_info.write().unwrap().remove(&resource); + fn remove_buffer(&self, buffer: BufferId) { + self.buffer_info.write().unwrap().remove(&buffer); } - fn remove_texture(&self, resource: RenderResourceId) { - self.resource_info.write().unwrap().remove(&resource); - } - fn remove_sampler(&self, resource: RenderResourceId) { - self.resource_info.write().unwrap().remove(&resource); - } - fn get_resource_info( - &self, - resource: RenderResourceId, - handle_info: &mut dyn FnMut(Option<&ResourceInfo>), - ) { - handle_info(self.resource_info.read().unwrap().get(&resource)); + fn remove_texture(&self, texture: TextureId) { + self.texture_descriptors.write().unwrap().remove(&texture); } + fn remove_sampler(&self, _sampler: SamplerId) {} fn set_asset_resource_untyped( &self, handle: HandleUntyped, @@ -91,11 +85,7 @@ impl RenderResourceContext for HeadlessRenderResourceContext { .unwrap() .insert((handle, index), render_resource); } - fn get_asset_resource_untyped( - &self, - handle: HandleUntyped, - index: usize, - ) -> Option { + fn get_asset_resource_untyped(&self, handle: HandleUntyped, index: usize) -> Option { self.asset_resources .write() .unwrap() @@ -123,4 +113,7 @@ impl RenderResourceContext for HeadlessRenderResourceContext { .remove(&(handle, index)); } fn clear_bind_groups(&self) {} + fn get_buffer_info(&self, buffer: BufferId) -> Option { + self.buffer_info.read().unwrap().get(&buffer).cloned() + } } diff --git a/crates/bevy_render/src/renderer/render_context.rs b/crates/bevy_render/src/renderer/render_context.rs index 88c0567287..1016daa967 100644 --- a/crates/bevy_render/src/renderer/render_context.rs +++ b/crates/bevy_render/src/renderer/render_context.rs @@ -1,8 +1,8 @@ use super::RenderResourceContext; use crate::{ pass::{PassDescriptor, RenderPass}, - render_resource::{RenderResourceId, RenderResourceAssignments}, - texture::{Extent3d}, + render_resource::{BufferId, RenderResourceAssignments, TextureId}, + texture::Extent3d, }; pub trait RenderContext { @@ -10,18 +10,18 @@ pub trait RenderContext { fn resources_mut(&mut self) -> &mut dyn RenderResourceContext; fn copy_buffer_to_buffer( &mut self, - source_buffer: RenderResourceId, + source_buffer: BufferId, source_offset: u64, - destination_buffer: RenderResourceId, + destination_buffer: BufferId, destination_offset: u64, size: u64, ); fn copy_buffer_to_texture( &mut self, - source_buffer: RenderResourceId, + source_buffer: BufferId, source_offset: u64, source_bytes_per_row: u32, - destination_texture: RenderResourceId, + destination_texture: TextureId, destination_origin: [u32; 3], destination_mip_level: u32, size: Extent3d, diff --git a/crates/bevy_render/src/renderer/render_resource_context.rs b/crates/bevy_render/src/renderer/render_resource_context.rs index a939952aa1..4412dfb449 100644 --- a/crates/bevy_render/src/renderer/render_resource_context.rs +++ b/crates/bevy_render/src/renderer/render_resource_context.rs @@ -1,6 +1,6 @@ use crate::{ pipeline::{BindGroupDescriptorId, PipelineDescriptor}, - render_resource::{BufferInfo, RenderResourceId, RenderResourceSet, ResourceInfo}, + render_resource::{BufferId, BufferInfo, RenderResourceId, RenderResourceSet, SamplerId, TextureId}, shader::Shader, texture::{SamplerDescriptor, TextureDescriptor}, }; @@ -25,40 +25,28 @@ impl RenderResources { pub trait RenderResourceContext: Downcast + Send + Sync + 'static { fn create_swap_chain(&self, window: &Window); - fn next_swap_chain_texture(&self, window_id: WindowId) -> RenderResourceId; - fn drop_swap_chain_texture(&self, resource: RenderResourceId); + fn next_swap_chain_texture(&self, window_id: WindowId) -> TextureId; + fn drop_swap_chain_texture(&self, resource: TextureId); fn drop_all_swap_chain_textures(&self); - fn create_sampler(&self, sampler_descriptor: &SamplerDescriptor) -> RenderResourceId; - fn create_texture(&self, texture_descriptor: TextureDescriptor) -> RenderResourceId; - fn create_buffer(&self, buffer_info: BufferInfo) -> RenderResourceId; + fn create_sampler(&self, sampler_descriptor: &SamplerDescriptor) -> SamplerId; + fn create_texture(&self, texture_descriptor: TextureDescriptor) -> TextureId; + fn create_buffer(&self, buffer_info: BufferInfo) -> BufferId; // TODO: remove RenderResourceContext here fn create_buffer_mapped( &self, buffer_info: BufferInfo, setup_data: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext), - ) -> RenderResourceId; - fn create_buffer_with_data(&self, buffer_info: BufferInfo, data: &[u8]) -> RenderResourceId; + ) -> BufferId; + fn create_buffer_with_data(&self, buffer_info: BufferInfo, data: &[u8]) -> BufferId; fn create_shader_module(&self, shader_handle: Handle, shaders: &Assets); fn create_shader_module_from_source(&self, shader_handle: Handle, shader: &Shader); - fn remove_buffer(&self, resource: RenderResourceId); - fn remove_texture(&self, resource: RenderResourceId); - fn remove_sampler(&self, resource: RenderResourceId); - fn get_resource_info( - &self, - resource: RenderResourceId, - handle_info: &mut dyn FnMut(Option<&ResourceInfo>), - ); - fn set_asset_resource_untyped( - &self, - handle: HandleUntyped, - resource: RenderResourceId, - index: usize, - ); - fn get_asset_resource_untyped( - &self, - handle: HandleUntyped, - index: usize, - ) -> Option; + fn remove_buffer(&self, buffer: BufferId); + fn remove_texture(&self, texture: TextureId); + fn remove_sampler(&self, sampler: SamplerId); + fn get_buffer_info(&self, buffer: BufferId) -> Option; + + fn set_asset_resource_untyped(&self, handle: HandleUntyped, resource: RenderResourceId, index: usize); + fn get_asset_resource_untyped(&self, handle: HandleUntyped, index: usize) -> Option; fn remove_asset_resource_untyped(&self, handle: HandleUntyped, index: usize); fn create_render_pipeline( &self, diff --git a/crates/bevy_render/src/texture/texture.rs b/crates/bevy_render/src/texture/texture.rs index bc53ce75e9..a895417b74 100644 --- a/crates/bevy_render/src/texture/texture.rs +++ b/crates/bevy_render/src/texture/texture.rs @@ -1,7 +1,7 @@ use super::{SamplerDescriptor, TextureDescriptor}; use crate::{ renderer::{RenderResourceContext, RenderResources}, - render_resource::{ResourceInfo, RenderResource}, + render_resource::{ResourceInfo, RenderResource, RenderResourceId}, }; use bevy_app::{EventReader, Events}; use bevy_asset::{AssetEvent, Assets, Handle}; @@ -81,12 +81,12 @@ impl Texture { render_resources.set_asset_resource( *texture_handle, - texture_resource, + RenderResourceId::Texture(texture_resource), TEXTURE_ASSET_INDEX, ); render_resources.set_asset_resource( *texture_handle, - sampler_resource, + RenderResourceId::Sampler(sampler_resource), SAMPLER_ASSET_INDEX, ); } @@ -97,11 +97,11 @@ impl Texture { render_resources: &dyn RenderResourceContext, handle: Handle, ) { - if let Some(resource) = render_resources.get_asset_resource(handle, TEXTURE_ASSET_INDEX) { + if let Some(RenderResourceId::Texture(resource)) = render_resources.get_asset_resource(handle, TEXTURE_ASSET_INDEX) { render_resources.remove_texture(resource); render_resources.remove_asset_resource(handle, TEXTURE_ASSET_INDEX); } - if let Some(resource) = render_resources.get_asset_resource(handle, SAMPLER_ASSET_INDEX) { + if let Some(RenderResourceId::Sampler(resource)) = render_resources.get_asset_resource(handle, SAMPLER_ASSET_INDEX) { render_resources.remove_sampler(resource); render_resources.remove_asset_resource(handle, SAMPLER_ASSET_INDEX); } diff --git a/crates/bevy_wgpu/src/renderer/wgpu_render_context.rs b/crates/bevy_wgpu/src/renderer/wgpu_render_context.rs index b63a6dae2c..b1116e8e6c 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::{RenderResourceAssignment, RenderResourceAssignments, RenderResourceId}, + render_resource::{BufferId, RenderResourceAssignment, RenderResourceAssignments, TextureId}, renderer::{RenderContext, RenderResourceContext}, texture::Extent3d, }; @@ -73,9 +73,9 @@ impl WgpuRenderContext { impl RenderContext for WgpuRenderContext { fn copy_buffer_to_buffer( &mut self, - source_buffer: RenderResourceId, + source_buffer: BufferId, source_offset: u64, - destination_buffer: RenderResourceId, + destination_buffer: BufferId, destination_offset: u64, size: u64, ) { @@ -91,10 +91,10 @@ impl RenderContext for WgpuRenderContext { fn copy_buffer_to_texture( &mut self, - source_buffer: RenderResourceId, + source_buffer: BufferId, source_offset: u64, source_bytes_per_row: u32, - destination_texture: RenderResourceId, + destination_texture: TextureId, destination_origin: [u32; 3], destination_mip_level: u32, size: Extent3d, @@ -187,7 +187,7 @@ fn get_texture_view<'a>( panic!("Color attachment {} does not exist", name); } }, - TextureAttachment::RenderResource(render_resource) => refs.textures.get(&render_resource).unwrap_or_else(|| &refs.swap_chain_frames.get(&render_resource).unwrap().output.view), + TextureAttachment::Id(render_resource) => refs.textures.get(&render_resource).unwrap_or_else(|| &refs.swap_chain_frames.get(&render_resource).unwrap().output.view), TextureAttachment::Input(_) => panic!("Encountered unset TextureAttachment::Input. The RenderGraph executor should always set TextureAttachment::Inputs to TextureAttachment::RenderResource before running. This is a bug"), } } 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 7ee42c136a..be84876955 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::{Assets, Handle, HandleUntyped}; use bevy_render::{ pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineDescriptor}, render_resource::{ - BufferInfo, RenderResourceAssignment, RenderResourceId, RenderResourceSet, ResourceInfo, + BufferId, BufferInfo, RenderResourceId, RenderResourceAssignment, RenderResourceSet, SamplerId, + TextureId, }, renderer::RenderResourceContext, shader::Shader, @@ -38,9 +39,9 @@ impl WgpuRenderResourceContext { pub fn copy_buffer_to_buffer( &self, command_encoder: &mut wgpu::CommandEncoder, - source_buffer: RenderResourceId, + source_buffer: BufferId, source_offset: u64, - destination_buffer: RenderResourceId, + destination_buffer: BufferId, destination_offset: u64, size: u64, ) { @@ -60,10 +61,10 @@ impl WgpuRenderResourceContext { pub fn copy_buffer_to_texture( &self, command_encoder: &mut wgpu::CommandEncoder, - source_buffer: RenderResourceId, + source_buffer: BufferId, source_offset: u64, source_bytes_per_row: u32, - destination_texture: RenderResourceId, + destination_texture: TextureId, destination_origin: [u32; 3], // TODO: replace with math type destination_mip_level: u32, size: Extent3d, @@ -128,38 +129,36 @@ impl WgpuRenderResourceContext { } impl RenderResourceContext for WgpuRenderResourceContext { - fn create_sampler(&self, sampler_descriptor: &SamplerDescriptor) -> RenderResourceId { + fn create_sampler(&self, sampler_descriptor: &SamplerDescriptor) -> SamplerId { let mut samplers = self.resources.samplers.write().unwrap(); - let mut resource_info = self.resources.resource_info.write().unwrap(); let descriptor: wgpu::SamplerDescriptor = (*sampler_descriptor).wgpu_into(); let sampler = self.device.create_sampler(&descriptor); - let resource = RenderResourceId::new(); - samplers.insert(resource, sampler); - resource_info.insert(resource, ResourceInfo::Sampler); - resource + let id = SamplerId::new(); + samplers.insert(id, sampler); + id } - fn create_texture(&self, texture_descriptor: TextureDescriptor) -> RenderResourceId { + fn create_texture(&self, texture_descriptor: TextureDescriptor) -> TextureId { let mut textures = self.resources.textures.write().unwrap(); let mut texture_views = self.resources.texture_views.write().unwrap(); - let mut resource_info = self.resources.resource_info.write().unwrap(); + let mut texture_descriptors = self.resources.texture_descriptors.write().unwrap(); let descriptor: wgpu::TextureDescriptor = (&texture_descriptor).wgpu_into(); let texture = self.device.create_texture(&descriptor); let texture_view = texture.create_default_view(); - let resource = RenderResourceId::new(); - resource_info.insert(resource, ResourceInfo::Texture(Some(texture_descriptor))); - texture_views.insert(resource, texture_view); - textures.insert(resource, texture); - resource + let id = TextureId::new(); + texture_descriptors.insert(id, texture_descriptor); + texture_views.insert(id, texture_view); + textures.insert(id, texture); + id } - fn create_buffer(&self, buffer_info: BufferInfo) -> RenderResourceId { + fn create_buffer(&self, buffer_info: BufferInfo) -> BufferId { // TODO: consider moving this below "create" for efficiency - let mut resource_info = self.resources.resource_info.write().unwrap(); + let mut buffer_infos = self.resources.buffer_infos.write().unwrap(); let mut buffers = self.resources.buffers.write().unwrap(); let buffer = self.device.create_buffer(&wgpu::BufferDescriptor { @@ -169,17 +168,17 @@ impl RenderResourceContext for WgpuRenderResourceContext { mapped_at_creation: false, }); - let resource = RenderResourceId::new(); - resource_info.insert(resource, ResourceInfo::Buffer(Some(buffer_info))); - buffers.insert(resource, buffer); - resource + let id = BufferId::new(); + buffer_infos.insert(id, buffer_info); + buffers.insert(id, buffer); + id } fn create_buffer_mapped( &self, buffer_info: BufferInfo, setup_data: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext), - ) -> RenderResourceId { + ) -> BufferId { let usage: wgpu::BufferUsage = buffer_info.buffer_usage.wgpu_into(); let buffer = self.device.create_buffer(&wgpu::BufferDescriptor { size: buffer_info.size as u64, @@ -198,21 +197,17 @@ impl RenderResourceContext for WgpuRenderResourceContext { } buffer.unmap(); - let resource = RenderResourceId::new(); - let mut resource_info = self.resources.resource_info.write().unwrap(); + let id = BufferId::new(); + let mut buffer_infos = self.resources.buffer_infos.write().unwrap(); let mut buffers = self.resources.buffers.write().unwrap(); - resource_info.insert(resource, ResourceInfo::Buffer(Some(buffer_info))); - buffers.insert(resource, buffer); - resource + buffer_infos.insert(id, buffer_info); + buffers.insert(id, buffer); + id } - fn create_buffer_with_data( - &self, - mut buffer_info: BufferInfo, - data: &[u8], - ) -> RenderResourceId { + fn create_buffer_with_data(&self, mut buffer_info: BufferInfo, data: &[u8]) -> BufferId { // TODO: consider moving this below "create" for efficiency - let mut resource_info = self.resources.resource_info.write().unwrap(); + let mut buffer_infos = self.resources.buffer_infos.write().unwrap(); let mut buffers = self.resources.buffers.write().unwrap(); buffer_info.size = data.len(); @@ -220,46 +215,33 @@ impl RenderResourceContext for WgpuRenderResourceContext { .device .create_buffer_with_data(data, buffer_info.buffer_usage.wgpu_into()); - let resource = RenderResourceId::new(); - resource_info.insert(resource, ResourceInfo::Buffer(Some(buffer_info))); - buffers.insert(resource, buffer); - resource + let id = BufferId::new(); + buffer_infos.insert(id, buffer_info); + buffers.insert(id, buffer); + id } - fn remove_buffer(&self, resource: RenderResourceId) { + fn remove_buffer(&self, buffer: BufferId) { let mut buffers = self.resources.buffers.write().unwrap(); - let mut resource_info = self.resources.resource_info.write().unwrap(); + let mut buffer_infos = self.resources.buffer_infos.write().unwrap(); - buffers.remove(&resource); - resource_info.remove(&resource); + buffers.remove(&buffer); + buffer_infos.remove(&buffer); } - fn remove_texture(&self, resource: RenderResourceId) { + fn remove_texture(&self, texture: TextureId) { let mut textures = self.resources.textures.write().unwrap(); let mut texture_views = self.resources.texture_views.write().unwrap(); - let mut resource_info = self.resources.resource_info.write().unwrap(); + let mut texture_descriptors = self.resources.texture_descriptors.write().unwrap(); - textures.remove(&resource); - texture_views.remove(&resource); - resource_info.remove(&resource); + textures.remove(&texture); + texture_views.remove(&texture); + texture_descriptors.remove(&texture); } - fn remove_sampler(&self, resource: RenderResourceId) { + fn remove_sampler(&self, sampler: SamplerId) { let mut samplers = self.resources.samplers.write().unwrap(); - let mut resource_info = self.resources.resource_info.write().unwrap(); - - samplers.remove(&resource); - resource_info.remove(&resource); - } - - fn get_resource_info( - &self, - resource: RenderResourceId, - handle_info: &mut dyn FnMut(Option<&ResourceInfo>), - ) { - let resource_info = self.resources.resource_info.read().unwrap(); - let info = resource_info.get(&resource); - handle_info(info); + samplers.remove(&sampler); } fn create_shader_module_from_source(&self, shader_handle: Handle, shader: &Shader) { @@ -298,7 +280,7 @@ impl RenderResourceContext for WgpuRenderResourceContext { window_swap_chains.insert(window.id, swap_chain); } - fn next_swap_chain_texture(&self, window_id: bevy_window::WindowId) -> RenderResourceId { + fn next_swap_chain_texture(&self, window_id: bevy_window::WindowId) -> TextureId { let mut window_swap_chains = self.resources.window_swap_chains.write().unwrap(); let mut swap_chain_outputs = self.resources.swap_chain_frames.write().unwrap(); @@ -306,14 +288,14 @@ impl RenderResourceContext for WgpuRenderResourceContext { let next_texture = window_swap_chain.get_next_frame().unwrap(); // TODO: Add ResourceInfo - let render_resource = RenderResourceId::new(); - swap_chain_outputs.insert(render_resource, next_texture); - render_resource + let id = TextureId::new(); + swap_chain_outputs.insert(id, next_texture); + id } - fn drop_swap_chain_texture(&self, render_resource: RenderResourceId) { + fn drop_swap_chain_texture(&self, texture: TextureId) { let mut swap_chain_outputs = self.resources.swap_chain_frames.write().unwrap(); - swap_chain_outputs.remove(&render_resource); + swap_chain_outputs.remove(&texture); } fn drop_all_swap_chain_textures(&self) { @@ -331,11 +313,7 @@ impl RenderResourceContext for WgpuRenderResourceContext { asset_resources.insert((handle, index), render_resource); } - fn get_asset_resource_untyped( - &self, - handle: HandleUntyped, - index: usize, - ) -> Option { + fn get_asset_resource_untyped(&self, handle: HandleUntyped, index: usize) -> Option { let asset_resources = self.resources.asset_resources.read().unwrap(); asset_resources.get(&(handle, index)).cloned() } @@ -476,18 +454,18 @@ impl RenderResourceContext for WgpuRenderResourceContext { .map(|indexed_assignment| { let wgpu_resource = match &indexed_assignment.assignment { RenderResourceAssignment::Texture(resource) => { - let texture_view = texture_views.get(&resource).expect(&format!("{:?}", resource)); + let texture_view = texture_views + .get(&resource) + .expect(&format!("{:?}", resource)); wgpu::BindingResource::TextureView(texture_view) } RenderResourceAssignment::Sampler(resource) => { let sampler = samplers.get(&resource).unwrap(); wgpu::BindingResource::Sampler(sampler) } - RenderResourceAssignment::Buffer { - resource, range, .. - } => { - let buffer = buffers.get(&resource).unwrap(); - wgpu::BindingResource::Buffer(buffer.slice(range.clone())) + RenderResourceAssignment::Buffer { buffer, range, .. } => { + let wgpu_buffer = buffers.get(&buffer).unwrap(); + wgpu::BindingResource::Buffer(wgpu_buffer.slice(range.clone())) } }; wgpu::Binding { @@ -521,4 +499,12 @@ impl RenderResourceContext for WgpuRenderResourceContext { fn clear_bind_groups(&self) { self.resources.bind_groups.write().unwrap().clear(); } + fn get_buffer_info(&self, buffer: BufferId) -> Option { + self.resources + .buffer_infos + .read() + .unwrap() + .get(&buffer) + .cloned() + } } diff --git a/crates/bevy_wgpu/src/wgpu_render_pass.rs b/crates/bevy_wgpu/src/wgpu_render_pass.rs index 00fb161a52..7ad4c99262 100644 --- a/crates/bevy_wgpu/src/wgpu_render_pass.rs +++ b/crates/bevy_wgpu/src/wgpu_render_pass.rs @@ -2,8 +2,8 @@ use crate::{renderer::WgpuRenderContext, WgpuResourceRefs}; use bevy_asset::Handle; use bevy_render::{ pass::RenderPass, - pipeline::{PipelineDescriptor, BindGroupDescriptorId}, - render_resource::{RenderResourceId, RenderResourceSetId}, + pipeline::{BindGroupDescriptorId, PipelineDescriptor}, + render_resource::{BufferId, RenderResourceSetId}, renderer::RenderContext, }; use std::ops::Range; @@ -20,8 +20,8 @@ impl<'a> RenderPass for WgpuRenderPass<'a> { self.render_context } - fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResourceId, offset: u64) { - let buffer = self.render_resources.buffers.get(&resource).unwrap(); + fn set_vertex_buffer(&mut self, start_slot: u32, buffer_id: BufferId, offset: u64) { + let buffer = self.render_resources.buffers.get(&buffer_id).unwrap(); self.render_pass .set_vertex_buffer(start_slot, buffer.slice(offset..)); } @@ -35,8 +35,8 @@ impl<'a> RenderPass for WgpuRenderPass<'a> { self.render_pass.set_stencil_reference(reference); } - fn set_index_buffer(&mut self, resource: RenderResourceId, offset: u64) { - let buffer = self.render_resources.buffers.get(&resource).unwrap(); + fn set_index_buffer(&mut self, buffer_id: BufferId, offset: u64) { + let buffer = self.render_resources.buffers.get(&buffer_id).unwrap(); self.render_pass.set_index_buffer(buffer.slice(offset..)); } @@ -61,16 +61,14 @@ impl<'a> RenderPass for WgpuRenderPass<'a> { .bind_groups .get(&bind_group_descriptor) { - if let Some(wgpu_bind_group) = bind_group_info.bind_groups.get(&render_resource_set) - { + if let Some(wgpu_bind_group) = bind_group_info.bind_groups.get(&render_resource_set) { const EMPTY: &'static [u32] = &[]; - let dynamic_uniform_indices = if let Some(dynamic_uniform_indices) = - dynamic_uniform_indices - { - dynamic_uniform_indices - } else { - EMPTY - }; + let dynamic_uniform_indices = + if let Some(dynamic_uniform_indices) = dynamic_uniform_indices { + dynamic_uniform_indices + } else { + EMPTY + }; log::trace!( "set bind group {:?} {:?}: {:?}", @@ -78,11 +76,8 @@ impl<'a> RenderPass for WgpuRenderPass<'a> { dynamic_uniform_indices, render_resource_set ); - self.render_pass.set_bind_group( - index, - wgpu_bind_group, - dynamic_uniform_indices, - ); + self.render_pass + .set_bind_group(index, wgpu_bind_group, dynamic_uniform_indices); } } } diff --git a/crates/bevy_wgpu/src/wgpu_resources.rs b/crates/bevy_wgpu/src/wgpu_resources.rs index b9b2988121..201bb87612 100644 --- a/crates/bevy_wgpu/src/wgpu_resources.rs +++ b/crates/bevy_wgpu/src/wgpu_resources.rs @@ -1,8 +1,9 @@ use bevy_asset::{Handle, HandleUntyped}; use bevy_render::{ pipeline::{BindGroupDescriptorId, PipelineDescriptor}, - render_resource::{RenderResourceId, RenderResourceSetId, ResourceInfo}, + render_resource::{BufferId, BufferInfo, RenderResourceId, RenderResourceSetId, SamplerId, TextureId}, shader::Shader, + texture::TextureDescriptor, }; use bevy_window::WindowId; use std::{ @@ -38,9 +39,9 @@ pub struct WgpuBindGroupInfo { /// Single threaded implementations don't need to worry about these lifetimes constraints at all. RenderPasses can use a RenderContext's /// WgpuResources directly. RenderContext already has a lifetime greater than the RenderPass. pub struct WgpuResourcesReadLock<'a> { - pub buffers: RwLockReadGuard<'a, HashMap>, - pub textures: RwLockReadGuard<'a, HashMap>, - pub swap_chain_frames: RwLockReadGuard<'a, HashMap>, + pub buffers: RwLockReadGuard<'a, HashMap>, + pub textures: RwLockReadGuard<'a, HashMap>, + pub swap_chain_frames: RwLockReadGuard<'a, HashMap>, pub render_pipelines: RwLockReadGuard<'a, HashMap, wgpu::RenderPipeline>>, pub bind_groups: RwLockReadGuard<'a, HashMap>, @@ -60,23 +61,24 @@ impl<'a> WgpuResourcesReadLock<'a> { /// Stores read only references to WgpuResource collections. See WgpuResourcesReadLock docs for context on why this exists pub struct WgpuResourceRefs<'a> { - pub buffers: &'a HashMap, - pub textures: &'a HashMap, - pub swap_chain_frames: &'a HashMap, + pub buffers: &'a HashMap, + pub textures: &'a HashMap, + pub swap_chain_frames: &'a HashMap, pub render_pipelines: &'a HashMap, wgpu::RenderPipeline>, pub bind_groups: &'a HashMap, } #[derive(Default, Clone)] pub struct WgpuResources { - pub resource_info: Arc>>, + pub buffer_infos: Arc>>, + pub texture_descriptors: Arc>>, pub window_surfaces: Arc>>, pub window_swap_chains: Arc>>, - pub swap_chain_frames: Arc>>, - pub buffers: Arc>>, - pub texture_views: Arc>>, - pub textures: Arc>>, - pub samplers: Arc>>, + pub swap_chain_frames: Arc>>, + pub buffers: Arc>>, + pub texture_views: Arc>>, + pub textures: Arc>>, + pub samplers: Arc>>, pub shader_modules: Arc, wgpu::ShaderModule>>>, pub render_pipelines: Arc, wgpu::RenderPipeline>>>, pub bind_groups: Arc>>, diff --git a/examples/scene/load_scene.rs b/examples/scene/load_scene.rs index 93475322a7..7c0684856c 100644 --- a/examples/scene/load_scene.rs +++ b/examples/scene/load_scene.rs @@ -1,4 +1,4 @@ -use bevy::{input::keyboard::KeyboardInput, prelude::*, type_registry::TypeRegistry}; +use bevy::{prelude::*, type_registry::TypeRegistry}; fn main() { App::build()