more shader assignment work

This commit is contained in:
Carter Anderson 2020-02-15 13:58:40 -08:00
parent e38d3be0e3
commit 478d475219
11 changed files with 57 additions and 15 deletions

View file

@ -16,6 +16,7 @@ use crate::{
}; };
use bevy_transform::{prelude::LocalToWorld, transform_system_bundle}; use bevy_transform::{prelude::LocalToWorld, transform_system_bundle};
use render_graph_2::CompiledShaderMap;
use std::collections::HashMap; use std::collections::HashMap;
pub struct AppBuilder { pub struct AppBuilder {
@ -166,6 +167,7 @@ impl AppBuilder {
resources.insert(AssetStorage::<Texture>::new()); resources.insert(AssetStorage::<Texture>::new());
resources.insert(AssetStorage::<Shader>::new()); resources.insert(AssetStorage::<Shader>::new());
resources.insert(ShaderAssignments::new()); resources.insert(ShaderAssignments::new());
resources.insert(CompiledShaderMap::new());
self self
} }

View file

@ -8,7 +8,7 @@ pub use texture::*;
use std::{collections::HashMap, marker::PhantomData}; use std::{collections::HashMap, marker::PhantomData};
#[derive(Hash)] #[derive(Hash, Eq, PartialEq)]
pub struct Handle<T> { pub struct Handle<T> {
pub id: usize, pub id: usize,
marker: PhantomData<T>, marker: PhantomData<T>,
@ -75,7 +75,11 @@ impl<T> AssetStorage<T> {
handle handle
} }
pub fn get(&mut self, id: usize) -> Option<&mut T> { pub fn get_id(&mut self, id: usize) -> Option<&mut T> {
self.assets.get_mut(&id) self.assets.get_mut(&id)
} }
pub fn get(&mut self, handle: &Handle<T>) -> Option<&mut T> {
self.assets.get_mut(&handle.id)
}
} }

View file

@ -157,14 +157,14 @@ impl Pipeline for ForwardPipeline {
} }
if should_load_mesh { if should_load_mesh {
if let Some(mesh_asset) = mesh_storage.get(mesh.id) { if let Some(mesh_asset) = mesh_storage.get_id(mesh.id) {
mesh_asset.setup_buffers(&render_graph.device); mesh_asset.setup_buffers(&render_graph.device);
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0); pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);
pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]); pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]);
}; };
} }
if let Some(ref mesh_asset) = mesh_storage.get(mesh.id) { if let Some(ref mesh_asset) = mesh_storage.get_id(mesh.id) {
pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]); pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]);
pass.draw_indexed(0..mesh_asset.indices.len() as u32, 0, 0..1); pass.draw_indexed(0..mesh_asset.indices.len() as u32, 0, 0..1);
}; };

View file

@ -285,7 +285,7 @@ impl Pipeline for ForwardInstancedPipeline {
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap(); let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
for instance_buffer_info in self.instance_buffer_infos.as_ref().unwrap().iter() { for instance_buffer_info in self.instance_buffer_infos.as_ref().unwrap().iter() {
if let Some(mesh_asset) = mesh_storage.get(instance_buffer_info.mesh_id) { if let Some(mesh_asset) = mesh_storage.get_id(instance_buffer_info.mesh_id) {
mesh_asset.setup_buffers(&render_graph.device); mesh_asset.setup_buffers(&render_graph.device);
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0); pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);
pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]); pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]);

View file

@ -176,7 +176,7 @@ impl Pipeline for ForwardShadowPassNew {
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap(); let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
for (material, mesh) in mesh_query.iter(world) { for (material, mesh) in mesh_query.iter(world) {
if let Some(mesh_asset) = mesh_storage.get(mesh.id) { if let Some(mesh_asset) = mesh_storage.get_id(mesh.id) {
mesh_asset.setup_buffers(&render_graph.device); mesh_asset.setup_buffers(&render_graph.device);
pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]); pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]);
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0); pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);

View file

@ -166,7 +166,7 @@ impl Pipeline for ShadowPipeline {
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap(); let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
for (material, mesh) in mesh_query.iter(world) { for (material, mesh) in mesh_query.iter(world) {
if let Some(mesh_asset) = mesh_storage.get(mesh.id) { if let Some(mesh_asset) = mesh_storage.get_id(mesh.id) {
mesh_asset.setup_buffers(&render_graph.device); mesh_asset.setup_buffers(&render_graph.device);
pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]); pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]);

View file

@ -242,7 +242,7 @@ impl Pipeline for UiPipeline {
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap(); let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
for instance_buffer_info in instance_buffer_infos.as_ref().unwrap().iter() { for instance_buffer_info in instance_buffer_infos.as_ref().unwrap().iter() {
if let Some(mesh_asset) = mesh_storage.get(instance_buffer_info.mesh_id) { if let Some(mesh_asset) = mesh_storage.get_id(instance_buffer_info.mesh_id) {
mesh_asset.setup_buffers(&render_graph.device); mesh_asset.setup_buffers(&render_graph.device);
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0); pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);
pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]); pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]);

View file

@ -26,7 +26,7 @@ pub fn mesh_draw_target(world: &World, render_pass: &mut dyn RenderPass) {
} }
if should_load_mesh { if should_load_mesh {
if let Some(mesh_asset) = mesh_storage.get(mesh.id) { if let Some(mesh_asset) = mesh_storage.get_id(mesh.id) {
let renderer = render_pass.get_renderer(); let renderer = render_pass.get_renderer();
renderer.create_buffer_with_data( renderer.create_buffer_with_data(
resource_name::buffer::TEMP_MESH_VERTEX_BUFFER_NAME, resource_name::buffer::TEMP_MESH_VERTEX_BUFFER_NAME,

View file

@ -20,7 +20,7 @@ pub fn ui_draw_target(world: &World, render_pass: &mut dyn RenderPass) {
}; };
if let Some((instance_count, mesh_id)) = result { if let Some((instance_count, mesh_id)) = result {
if let Some(mesh_asset) = mesh_storage.get(mesh_id) { if let Some(mesh_asset) = mesh_storage.get_id(mesh_id) {
renderer.create_buffer_with_data( renderer.create_buffer_with_data(
resource_name::buffer::TEMP_MESH_VERTEX_BUFFER_NAME, resource_name::buffer::TEMP_MESH_VERTEX_BUFFER_NAME,
mesh_asset.vertices.as_bytes(), mesh_asset.vertices.as_bytes(),

View file

@ -1,4 +1,7 @@
use crate::{asset::{AssetStorage, Handle}, render::Shader, render::render_graph_2::RenderGraph}; use crate::{
asset::{AssetStorage, Handle},
render::{render_graph_2::RenderGraph, Shader},
};
use legion::prelude::*; use legion::prelude::*;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
@ -18,6 +21,19 @@ impl Default for Renderable {
} }
} }
pub struct CompiledShaderMap {
// TODO: need macro hash lookup
pub source_to_compiled: HashMap<Handle<Shader>, Vec<(HashSet<String>, Handle<Shader>)>>,
}
impl CompiledShaderMap {
pub fn new() -> Self {
CompiledShaderMap {
source_to_compiled: HashMap::new(),
}
}
}
pub struct ShaderAssignments { pub struct ShaderAssignments {
pub assignments: HashMap<usize, Vec<Entity>>, pub assignments: HashMap<usize, Vec<Entity>>,
} }
@ -35,10 +51,27 @@ pub fn update_shader_assignments(world: &mut World, render_graph: &mut RenderGra
// lots of string + hashset allocations. sees uniform_resource_provider for more context // lots of string + hashset allocations. sees uniform_resource_provider for more context
{ {
let shader_assignments = world.resources.get_mut::<ShaderAssignments>().unwrap(); let shader_assignments = world.resources.get_mut::<ShaderAssignments>().unwrap();
let shader_storage = world.resources.get_mut::<AssetStorage<Shader>>().unwrap(); let mut compiled_shader_map = world.resources.get_mut::<CompiledShaderMap>().unwrap();
let mut shader_storage = world.resources.get_mut::<AssetStorage<Shader>>().unwrap();
for (entity, renderable) in <Read<Renderable>>::query().iter_entities(world) { for (entity, renderable) in <Read<Renderable>>::query().iter_entities(world) {
for shader in renderable.shaders.iter() { for shader in renderable.shaders.iter() {
if let None = compiled_shader_map.source_to_compiled.get(shader) {
compiled_shader_map
.source_to_compiled
.insert(shader.clone(), Vec::new());
}
let compiled_shaders = compiled_shader_map.source_to_compiled.get_mut(shader).unwrap();
if let None = compiled_shaders.iter().find(|(shader_defs, _shader)| *shader_defs == renderable.shader_defs) {
let shader_resource = shader_storage.get(shader).unwrap();
let shader_def_vec = renderable.shader_defs.iter().cloned().collect::<Vec<String>>();
let compiled_shader = shader_resource.get_spirv_shader(Some(&shader_def_vec));
compiled_shaders.push((renderable.shader_defs.clone(), shader.clone()));
let compiled_shader_handle = shader_storage.add(compiled_shader);
// TODO: collecting assigments in a map means they won't be removed when the macro changes
// TODO: need to somehow grab base shader's pipeline, then copy it
// shader_assignments.assignments.insert()
}
} }
} }
} }

View file

@ -1,6 +1,6 @@
use std::marker::Copy; use std::marker::Copy;
#[derive(Copy, Clone)] #[derive(Hash, Eq, PartialEq, Copy, Clone)]
pub enum ShaderStage { pub enum ShaderStage {
Vertex, Vertex,
Fragment, Fragment,
@ -43,15 +43,18 @@ pub fn glsl_to_spirv(
binary_result.as_binary().into() binary_result.as_binary().into()
} }
#[derive(Hash, Eq, PartialEq)]
pub enum ShaderSource { pub enum ShaderSource {
Spirv(Vec<u32>), Spirv(Vec<u32>),
Glsl(String), Glsl(String),
} }
#[derive(Hash, Eq, PartialEq)]
pub struct Shader { pub struct Shader {
pub source: ShaderSource, pub source: ShaderSource,
pub stage: ShaderStage, pub stage: ShaderStage,
pub entry_point: String, pub entry_point: String,
// TODO: add "precompile" flag?
} }
impl Shader { impl Shader {