render: dont send the same material to the gpu multiple times, speeding up gpu texture loading

This commit is contained in:
SeanOMik 2024-03-16 19:12:32 -04:00
parent 1818a0b48b
commit 4ce21d4db0
Signed by: SeanOMik
GPG Key ID: FEC9E2FC15235964
2 changed files with 20 additions and 9 deletions

View File

@ -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 glam::UVec2;
use wgpu::{util::DeviceExt, ComputePipeline}; use wgpu::{util::DeviceExt, ComputePipeline};
use winit::dpi::PhysicalSize; 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 { struct LightIndicesGridBuffer {
indices_buffer: wgpu::Buffer, indices_buffer: wgpu::Buffer,

View File

@ -1,4 +1,5 @@
use std::collections::{HashMap, VecDeque, HashSet}; use std::collections::{HashMap, VecDeque, HashSet};
use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use std::borrow::Cow; use std::borrow::Cow;
@ -10,6 +11,7 @@ use lyra_ecs::query::filter::{Has, Or};
use lyra_ecs::{Entity, Tick}; use lyra_ecs::{Entity, Tick};
use lyra_ecs::query::{Entities, TickOf}; use lyra_ecs::query::{Entities, TickOf};
use lyra_ecs::World; use lyra_ecs::World;
use lyra_reflect::resource;
use lyra_resource::gltf::GltfScene; use lyra_resource::gltf::GltfScene;
use tracing::{debug, warn}; use tracing::{debug, warn};
use uuid::Uuid; use uuid::Uuid;
@ -20,6 +22,7 @@ use winit::window::Window;
use crate::math::Transform; use crate::math::Transform;
use crate::render::material::MaterialUniform; use crate::render::material::MaterialUniform;
use crate::render::render_buffer::BufferWrapperBuilder; use crate::render::render_buffer::BufferWrapperBuilder;
use crate::resources;
use crate::scene::CameraComponent; use crate::scene::CameraComponent;
use super::camera::{RenderCamera, CameraUniform}; use super::camera::{RenderCamera, CameraUniform};
@ -59,7 +62,7 @@ struct MeshBufferStorage {
//#[allow(dead_code)] //#[allow(dead_code)]
//render_texture: Option<RenderTexture>, //render_texture: Option<RenderTexture>,
material: Option<Material>, material: Option<Rc<Material>>,
// The index of the transform for this entity. // The index of the transform for this entity.
// The tuple is structured like this: (transform index, index of transform inside the buffer) // 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<RenderJob>, pub render_jobs: VecDeque<RenderJob>,
mesh_buffers: HashMap<uuid::Uuid, MeshBufferStorage>, // TODO: clean up left over buffers from deleted entities/components mesh_buffers: HashMap<uuid::Uuid, MeshBufferStorage>, // TODO: clean up left over buffers from deleted entities/components
material_buffers: HashMap<uuid::Uuid, Rc<Material>>,
entity_meshes: HashMap<Entity, uuid::Uuid>, entity_meshes: HashMap<Entity, uuid::Uuid>,
entity_last_transforms: HashMap<Entity, CachedTransform>, entity_last_transforms: HashMap<Entity, CachedTransform>,
@ -223,6 +227,7 @@ impl BasicRenderer {
render_pipelines: HashMap::new(), render_pipelines: HashMap::new(),
render_jobs: VecDeque::new(), render_jobs: VecDeque::new(),
mesh_buffers: HashMap::new(), mesh_buffers: HashMap::new(),
material_buffers: HashMap::new(),
entity_meshes: HashMap::new(), entity_meshes: HashMap::new(),
render_limits, render_limits,
@ -347,18 +352,24 @@ impl BasicRenderer {
let (vertex_buffer, buffer_indices) = self.create_vertex_index_buffers(mesh); let (vertex_buffer, buffer_indices) = self.create_vertex_index_buffers(mesh);
let material = mesh.material.as_ref() let material = mesh.material.as_ref()
.expect("Material resource not loaded yet") .expect("Material resource not loaded yet");
.data_ref() let material_ref = material.data_ref()
.unwrap(); .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)); self.queue.write_buffer(&self.material_buffer.inner_buf, 0, bytemuck::bytes_of(&uni));
debug!("Wrote material to buffer");
MeshBufferStorage { MeshBufferStorage {
buffer_vertex: vertex_buffer, buffer_vertex: vertex_buffer,
buffer_indices, buffer_indices,
material: Some(material), material: Some(material.clone()),
} }
} }