mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 12:43:34 +00:00
more shader assignment work
This commit is contained in:
parent
e38d3be0e3
commit
478d475219
11 changed files with 57 additions and 15 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)]);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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(), &[]);
|
||||||
|
|
|
@ -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)]);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue