From 4ce21d4db02f00cafb64bfeb26c6976d5c28b5e6 Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Sat, 16 Mar 2024 19:12:32 -0400 Subject: [PATCH] render: dont send the same material to the gpu multiple times, speeding up gpu texture loading --- lyra-game/src/render/light_cull_compute.rs | 4 ++-- lyra-game/src/render/renderer.rs | 25 ++++++++++++++++------ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/lyra-game/src/render/light_cull_compute.rs b/lyra-game/src/render/light_cull_compute.rs index dca54c1..4cca981 100644 --- a/lyra-game/src/render/light_cull_compute.rs +++ b/lyra-game/src/render/light_cull_compute.rs @@ -1,10 +1,10 @@ -use std::{borrow::Cow, mem, num::NonZeroU32, ptr::NonNull, rc::Rc}; +use std::{borrow::Cow, mem, ptr::NonNull, rc::Rc}; use glam::UVec2; use wgpu::{util::DeviceExt, ComputePipeline}; use winit::dpi::PhysicalSize; -use super::{light::LightUniformBuffers, render_buffer::BufferWrapper, renderer::RenderPass, texture::RenderTexture}; +use super::{light::LightUniformBuffers, render_buffer::BufferWrapper, texture::RenderTexture}; struct LightIndicesGridBuffer { indices_buffer: wgpu::Buffer, diff --git a/lyra-game/src/render/renderer.rs b/lyra-game/src/render/renderer.rs index 47eda68..74db284 100755 --- a/lyra-game/src/render/renderer.rs +++ b/lyra-game/src/render/renderer.rs @@ -1,4 +1,5 @@ use std::collections::{HashMap, VecDeque, HashSet}; +use std::ops::Deref; use std::rc::Rc; use std::sync::Arc; use std::borrow::Cow; @@ -10,6 +11,7 @@ use lyra_ecs::query::filter::{Has, Or}; use lyra_ecs::{Entity, Tick}; use lyra_ecs::query::{Entities, TickOf}; use lyra_ecs::World; +use lyra_reflect::resource; use lyra_resource::gltf::GltfScene; use tracing::{debug, warn}; use uuid::Uuid; @@ -20,6 +22,7 @@ use winit::window::Window; use crate::math::Transform; use crate::render::material::MaterialUniform; use crate::render::render_buffer::BufferWrapperBuilder; +use crate::resources; use crate::scene::CameraComponent; use super::camera::{RenderCamera, CameraUniform}; @@ -59,7 +62,7 @@ struct MeshBufferStorage { //#[allow(dead_code)] //render_texture: Option, - material: Option, + material: Option>, // The index of the transform for this entity. // The tuple is structured like this: (transform index, index of transform inside the buffer) @@ -88,6 +91,7 @@ pub struct BasicRenderer { pub render_jobs: VecDeque, mesh_buffers: HashMap, // TODO: clean up left over buffers from deleted entities/components + material_buffers: HashMap>, entity_meshes: HashMap, entity_last_transforms: HashMap, @@ -223,6 +227,7 @@ impl BasicRenderer { render_pipelines: HashMap::new(), render_jobs: VecDeque::new(), mesh_buffers: HashMap::new(), + material_buffers: HashMap::new(), entity_meshes: HashMap::new(), render_limits, @@ -347,18 +352,24 @@ impl BasicRenderer { let (vertex_buffer, buffer_indices) = self.create_vertex_index_buffers(mesh); let material = mesh.material.as_ref() - .expect("Material resource not loaded yet") - .data_ref() + .expect("Material resource not loaded yet"); + let material_ref = material.data_ref() .unwrap(); - let material = Material::from_resource(&self.device, &self.queue, self.bgl_texture.clone(), &material); - let uni = MaterialUniform::from(&material); + + let material = self.material_buffers.entry(material.uuid()) + .or_insert_with(|| { + debug!(uuid=material.uuid().to_string(), "Sending material to gpu"); + Rc::new(Material::from_resource(&self.device, &self.queue, self.bgl_texture.clone(), &material_ref)) + }); + + // TODO: support material uniforms from multiple uniforms + let uni = MaterialUniform::from(&**material); self.queue.write_buffer(&self.material_buffer.inner_buf, 0, bytemuck::bytes_of(&uni)); - debug!("Wrote material to buffer"); MeshBufferStorage { buffer_vertex: vertex_buffer, buffer_indices, - material: Some(material), + material: Some(material.clone()), } }