collect uniform shader_defs in preparation for on-demand shader compiling

This commit is contained in:
Carter Anderson 2020-02-12 17:58:58 -08:00
parent edf57c0dd3
commit 7759fdefac
5 changed files with 53 additions and 10 deletions

View file

@ -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::<Mesh>::new());
resources.insert(AssetStorage::<Texture>::new());
resources.insert(AssetStorage::<Shader>::new());
resources.insert(ShaderAssignments::new());
self
}

View file

@ -8,6 +8,7 @@ pub use texture::*;
use std::{collections::HashMap, marker::PhantomData};
#[derive(Hash)]
pub struct Handle<T> {
pub id: usize,
marker: PhantomData<T>,

View file

@ -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<Handle<Shader>>,
pub shader_defs: HashSet<String>,
}
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<usize, Vec<Entity>>,
pub assignments: HashMap<usize, Vec<Entity>>,
}
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::<ShaderAssignments>().unwrap();
let shader_storage = world.resources.get_mut::<AssetStorage<Shader>>().unwrap();
for (entity, renderable) in <Read<Renderable>>::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 <Write<Renderable>>::query().iter_mut(world) {
renderable.shader_defs = HashSet::new();
}
}

View file

@ -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);
}

View file

@ -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<T>, Write<Renderable>)>::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(