mirror of
https://github.com/bevyengine/bevy
synced 2024-11-21 20:23:28 +00:00
collect uniform shader_defs in preparation for on-demand shader compiling
This commit is contained in:
parent
edf57c0dd3
commit
7759fdefac
5 changed files with 53 additions and 10 deletions
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue