diff --git a/src/app/app_builder.rs b/src/app/app_builder.rs index c9b38c43d0..5276602113 100644 --- a/src/app/app_builder.rs +++ b/src/app/app_builder.rs @@ -8,7 +8,7 @@ use crate::{ passes::*, render_graph_2::{ passes::*, pipelines::*, renderers::wgpu_renderer::WgpuRenderer, resource_providers::*, - StandardMaterial, + ShaderAssignments, StandardMaterial, }, *, }, @@ -164,6 +164,8 @@ impl AppBuilder { resources.insert(Time::new()); resources.insert(AssetStorage::::new()); resources.insert(AssetStorage::::new()); + resources.insert(AssetStorage::::new()); + resources.insert(ShaderAssignments::new()); self } diff --git a/src/asset/mod.rs b/src/asset/mod.rs index caf44f6884..a2ad7d4126 100644 --- a/src/asset/mod.rs +++ b/src/asset/mod.rs @@ -8,6 +8,7 @@ pub use texture::*; use std::{collections::HashMap, marker::PhantomData}; +#[derive(Hash)] pub struct Handle { pub id: usize, marker: PhantomData, diff --git a/src/render/render_graph_2/renderable.rs b/src/render/render_graph_2/renderable.rs index 2656bcde63..93999abe94 100644 --- a/src/render/render_graph_2/renderable.rs +++ b/src/render/render_graph_2/renderable.rs @@ -1,10 +1,11 @@ -use crate::{asset::Handle, render::Shader}; -use legion::prelude::Entity; -use std::collections::HashSet; +use crate::{asset::{AssetStorage, Handle}, render::Shader, render::render_graph_2::RenderGraph}; +use legion::prelude::*; +use std::collections::{HashMap, HashSet}; pub struct Renderable { pub is_visible: bool, pub shaders: Vec>, + pub shader_defs: HashSet, } impl Default for Renderable { @@ -12,10 +13,38 @@ impl Default for Renderable { Renderable { is_visible: true, shaders: Vec::new(), + shader_defs: HashSet::new(), } } } pub struct ShaderAssignments { - pub assignments: HashSet>, + pub assignments: HashMap>, } + +impl ShaderAssignments { + pub fn new() -> Self { + ShaderAssignments { + assignments: HashMap::new(), + } + } +} + +pub fn update_shader_assignments(world: &mut World, render_graph: &mut RenderGraph) { + // PERF: this seems like a lot of work for things that don't change that often. + // lots of string + hashset allocations. sees uniform_resource_provider for more context + { + let shader_assignments = world.resources.get_mut::().unwrap(); + let shader_storage = world.resources.get_mut::>().unwrap(); + for (entity, renderable) in >::query().iter_entities(world) { + for shader in renderable.shaders.iter() { + + } + } + } + + // cleanup entity shader_defs so next frame they can be refreshed + for mut renderable in >::query().iter_mut(world) { + renderable.shader_defs = HashSet::new(); + } +} \ No newline at end of file diff --git a/src/render/render_graph_2/renderers/wgpu_renderer.rs b/src/render/render_graph_2/renderers/wgpu_renderer.rs index 230163745e..f4479a8368 100644 --- a/src/render/render_graph_2/renderers/wgpu_renderer.rs +++ b/src/render/render_graph_2/renderers/wgpu_renderer.rs @@ -1,10 +1,10 @@ use crate::{ legion::prelude::*, render::render_graph_2::{ - resource_name, BindGroup, BindType, DynamicUniformBufferInfo, PassDescriptor, - PipelineDescriptor, RenderGraph, RenderPass, RenderPassColorAttachmentDescriptor, - RenderPassDepthStencilAttachmentDescriptor, Renderer, ResourceInfo, ShaderUniforms, - TextureDescriptor, + resource_name, update_shader_assignments, BindGroup, BindType, DynamicUniformBufferInfo, + PassDescriptor, PipelineDescriptor, RenderGraph, RenderPass, + RenderPassColorAttachmentDescriptor, RenderPassDepthStencilAttachmentDescriptor, Renderer, + ResourceInfo, ShaderUniforms, TextureDescriptor, }, }; use std::{collections::HashMap, ops::Deref}; @@ -470,6 +470,8 @@ impl Renderer for WgpuRenderer { resource_provider.update(self, world); } + update_shader_assignments(world, render_graph); + for (name, texture_descriptor) in render_graph.queued_textures.drain(..) { self.create_texture(&name, &texture_descriptor); } diff --git a/src/render/render_graph_2/resource_providers/uniform_resource_provider.rs b/src/render/render_graph_2/resource_providers/uniform_resource_provider.rs index 162ff7b7ed..d842b73739 100644 --- a/src/render/render_graph_2/resource_providers/uniform_resource_provider.rs +++ b/src/render/render_graph_2/resource_providers/uniform_resource_provider.rs @@ -136,7 +136,7 @@ where for (uniforms, _renderable) in query.iter(world) { // TODO: check if index has changed. if it has, then entity should be updated // TODO: only mem-map entities if their data has changed - // TODO: try getting ref first + // TODO: try getting bytes ref first if let Some(uniform_bytes) = uniforms.get_uniform_bytes(name) { mapped[offset..(offset + uniform_bytes.len())] .copy_from_slice(uniform_bytes.as_slice()); @@ -148,6 +148,15 @@ where renderer.copy_buffer_to_buffer("tmp_uniform_mapped", 0, name, 0, size); } + + // update shader assignments based on current macro defs + for (uniforms, mut renderable) in <(Read, Write)>::query().iter_mut(world) { + if let Some(shader_defs) = uniforms.get_shader_defs() { + for shader_def in shader_defs { + renderable.shader_defs.insert(shader_def); + } + } + } } fn resize(