mirror of
https://github.com/bevyengine/bevy
synced 2024-11-21 20:23:28 +00:00
create entities as a separate step before starting a render pass
This commit is contained in:
parent
cadea8deb0
commit
e0a1a83bc9
25 changed files with 503 additions and 266 deletions
|
@ -12,7 +12,9 @@ fn setup(world: &mut World) {
|
|||
|
||||
let texture_handle = {
|
||||
let mut texture_storage = world.resources.get_mut::<AssetStorage<Texture>>().unwrap();
|
||||
let texture = Texture::load(TextureType::Png(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/temp_bevy_logo.png").to_string()));
|
||||
let texture = Texture::load(TextureType::Png(
|
||||
concat!(env!("CARGO_MANIFEST_DIR"), "/assets/temp_bevy_logo.png").to_string(),
|
||||
));
|
||||
texture_storage.add(texture)
|
||||
};
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ use crate::{
|
|||
render::{
|
||||
render_graph::{
|
||||
draw_targets::*, passes::*, pipelines::*, renderers::wgpu_renderer::WgpuRenderer,
|
||||
resource_name, resource_providers::*, CompiledShaderMap, PipelineDescriptor,
|
||||
RenderGraphBuilder, Renderer, ShaderPipelineAssignments, StandardMaterial,
|
||||
resource_providers::*, CompiledShaderMap, PipelineDescriptor, RenderGraphBuilder,
|
||||
Renderer, ShaderPipelineAssignments, StandardMaterial,
|
||||
},
|
||||
*,
|
||||
},
|
||||
|
@ -140,12 +140,9 @@ impl AppBuilder {
|
|||
pub fn add_render_graph_defaults(self) -> Self {
|
||||
self.setup_render_graph(|builder, pipeline_storage, shader_storage| {
|
||||
builder
|
||||
.add_draw_target(resource_name::draw_target::MESHES, meshes_draw_target)
|
||||
.add_draw_target(
|
||||
resource_name::draw_target::ASSIGNED_MESHES,
|
||||
assigned_meshes_draw_target,
|
||||
)
|
||||
.add_draw_target(resource_name::draw_target::UI, ui_draw_target)
|
||||
.add_draw_target(MeshesDrawTarget::default())
|
||||
.add_draw_target(AssignedMeshesDrawTarget::default())
|
||||
.add_draw_target(UiDrawTarget::default())
|
||||
.add_resource_provider(Box::new(CameraResourceProvider::default()))
|
||||
.add_resource_provider(Box::new(Camera2dResourceProvider::default()))
|
||||
.add_resource_provider(Box::new(LightResourceProvider::new(10)))
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
use crate::{render::render_graph::{TextureDimension, TextureDescriptor}, asset::Asset};
|
||||
use crate::{
|
||||
asset::Asset,
|
||||
render::render_graph::{TextureDescriptor, TextureDimension},
|
||||
};
|
||||
use std::fs::File;
|
||||
|
||||
pub enum TextureType {
|
||||
Data(Vec<u8>, usize, usize),
|
||||
Png(String) // TODO: please rethink this
|
||||
Png(String), // TODO: please rethink this
|
||||
}
|
||||
|
||||
pub struct Texture {
|
||||
|
@ -25,13 +28,17 @@ impl Asset<TextureType> for Texture {
|
|||
}
|
||||
};
|
||||
|
||||
Texture { data, width, height }
|
||||
Texture {
|
||||
data,
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Texture> for TextureDescriptor {
|
||||
fn from(texture: &Texture) -> Self {
|
||||
TextureDescriptor {
|
||||
TextureDescriptor {
|
||||
size: wgpu::Extent3d {
|
||||
height: texture.height as u32,
|
||||
width: texture.width as u32,
|
||||
|
@ -43,9 +50,8 @@ impl From<&Texture> for TextureDescriptor {
|
|||
dimension: TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn create_texels(size: usize) -> Vec<u8> {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use super::Renderer;
|
||||
use crate::{
|
||||
asset::Handle,
|
||||
render::render_graph::{pipeline::PipelineDescriptor, RenderPass},
|
||||
|
@ -12,3 +13,19 @@ pub type DrawTarget = fn(
|
|||
render_pass: &mut dyn RenderPass,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
);
|
||||
|
||||
pub trait NewDrawTarget {
|
||||
fn draw(
|
||||
&self,
|
||||
world: &World,
|
||||
render_pass: &mut dyn RenderPass,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
);
|
||||
fn setup(
|
||||
&mut self,
|
||||
world: &World,
|
||||
renderer: &mut dyn Renderer,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
);
|
||||
fn get_name(&self) -> String;
|
||||
}
|
||||
|
|
|
@ -1,53 +1,98 @@
|
|||
use crate::{
|
||||
asset::{Handle, Mesh},
|
||||
asset::{AssetStorage, Handle, Mesh},
|
||||
legion::prelude::*,
|
||||
render::render_graph::{PipelineDescriptor, RenderPass, Renderable, ShaderPipelineAssignments, ResourceInfo},
|
||||
render::render_graph::{
|
||||
resource_name, NewDrawTarget, PipelineDescriptor, RenderPass, Renderable, ResourceInfo,
|
||||
ShaderPipelineAssignments,
|
||||
},
|
||||
};
|
||||
|
||||
pub fn assigned_meshes_draw_target(
|
||||
world: &World,
|
||||
render_pass: &mut dyn RenderPass,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
) {
|
||||
let shader_pipeline_assignments = world
|
||||
.resources
|
||||
.get_mut::<ShaderPipelineAssignments>()
|
||||
.unwrap();
|
||||
let mut current_mesh_handle = None;
|
||||
let mut current_mesh_index_len = 0;
|
||||
#[derive(Default)]
|
||||
pub struct AssignedMeshesDrawTarget;
|
||||
|
||||
let assigned_entities = shader_pipeline_assignments
|
||||
.assignments
|
||||
.get(&pipeline_handle);
|
||||
impl NewDrawTarget for AssignedMeshesDrawTarget {
|
||||
fn draw(
|
||||
&self,
|
||||
world: &World,
|
||||
render_pass: &mut dyn RenderPass,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
) {
|
||||
let shader_pipeline_assignments =
|
||||
world.resources.get::<ShaderPipelineAssignments>().unwrap();
|
||||
let mut current_mesh_handle = None;
|
||||
let mut current_mesh_index_len = 0;
|
||||
|
||||
if let Some(assigned_entities) = assigned_entities {
|
||||
for entity in assigned_entities.iter() {
|
||||
// TODO: hopefully legion has better random access apis that are more like queries?
|
||||
let renderable = world.get_component::<Renderable>(*entity).unwrap();
|
||||
let mesh = *world.get_component::<Handle<Mesh>>(*entity).unwrap();
|
||||
if !renderable.is_visible {
|
||||
continue;
|
||||
}
|
||||
let assigned_entities = shader_pipeline_assignments
|
||||
.assignments
|
||||
.get(&pipeline_handle);
|
||||
|
||||
let renderer = render_pass.get_renderer();
|
||||
let render_resources = renderer.get_render_resources();
|
||||
if current_mesh_handle != Some(mesh) {
|
||||
if let Some(vertex_buffer_resource) = render_resources.get_mesh_vertices_resource(mesh) {
|
||||
let index_buffer_resource = render_resources.get_mesh_indices_resource(mesh).unwrap();
|
||||
match renderer.get_resource_info(index_buffer_resource).unwrap() {
|
||||
ResourceInfo::Buffer { size, ..} => current_mesh_index_len = (size / 2) as u32,
|
||||
_ => panic!("expected a buffer type"),
|
||||
}
|
||||
render_pass.set_index_buffer(index_buffer_resource, 0);
|
||||
render_pass.set_vertex_buffer(0, vertex_buffer_resource, 0);
|
||||
if let Some(assigned_entities) = assigned_entities {
|
||||
for entity in assigned_entities.iter() {
|
||||
// TODO: hopefully legion has better random access apis that are more like queries?
|
||||
let renderable = world.get_component::<Renderable>(*entity).unwrap();
|
||||
let mesh = *world.get_component::<Handle<Mesh>>(*entity).unwrap();
|
||||
if !renderable.is_visible {
|
||||
continue;
|
||||
}
|
||||
// TODO: Verify buffer format matches render pass
|
||||
current_mesh_handle = Some(mesh);
|
||||
}
|
||||
|
||||
// TODO: validate bind group properties against shader uniform properties at least once
|
||||
render_pass.setup_bind_groups(Some(&entity));
|
||||
render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1);
|
||||
let renderer = render_pass.get_renderer();
|
||||
let render_resources = renderer.get_render_resources();
|
||||
if current_mesh_handle != Some(mesh) {
|
||||
if let Some(vertex_buffer_resource) =
|
||||
render_resources.get_mesh_vertices_resource(mesh)
|
||||
{
|
||||
let index_buffer_resource =
|
||||
render_resources.get_mesh_indices_resource(mesh).unwrap();
|
||||
match renderer.get_resource_info(index_buffer_resource).unwrap() {
|
||||
ResourceInfo::Buffer { size, .. } => {
|
||||
current_mesh_index_len = (size / 2) as u32
|
||||
}
|
||||
_ => panic!("expected a buffer type"),
|
||||
}
|
||||
render_pass.set_index_buffer(index_buffer_resource, 0);
|
||||
render_pass.set_vertex_buffer(0, vertex_buffer_resource, 0);
|
||||
}
|
||||
// TODO: Verify buffer format matches render pass
|
||||
current_mesh_handle = Some(mesh);
|
||||
}
|
||||
|
||||
// TODO: validate bind group properties against shader uniform properties at least once
|
||||
render_pass.set_bind_groups(Some(&entity));
|
||||
render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn setup(
|
||||
&mut self,
|
||||
world: &World,
|
||||
renderer: &mut dyn crate::render::render_graph::Renderer,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
) {
|
||||
let shader_pipeline_assignments =
|
||||
world.resources.get::<ShaderPipelineAssignments>().unwrap();
|
||||
let assigned_entities = shader_pipeline_assignments
|
||||
.assignments
|
||||
.get(&pipeline_handle);
|
||||
let pipeline_storage = world
|
||||
.resources
|
||||
.get::<AssetStorage<PipelineDescriptor>>()
|
||||
.unwrap();
|
||||
let pipeline_descriptor = pipeline_storage.get(&pipeline_handle).unwrap();
|
||||
if let Some(assigned_entities) = assigned_entities {
|
||||
for entity in assigned_entities.iter() {
|
||||
// TODO: hopefully legion has better random access apis that are more like queries?
|
||||
let renderable = world.get_component::<Renderable>(*entity).unwrap();
|
||||
if !renderable.is_visible {
|
||||
continue;
|
||||
}
|
||||
|
||||
renderer.setup_entity_bind_groups(*entity, pipeline_descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_name(&self) -> String {
|
||||
resource_name::draw_target::ASSIGNED_MESHES.to_string()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,46 +2,69 @@ use crate::{
|
|||
asset::{Handle, Mesh},
|
||||
legion::prelude::*,
|
||||
render::{
|
||||
render_graph::{PipelineDescriptor, RenderPass, Renderable, ResourceInfo},
|
||||
render_graph::{
|
||||
resource_name, NewDrawTarget, PipelineDescriptor, RenderPass, Renderable, ResourceInfo,
|
||||
},
|
||||
Instanced,
|
||||
},
|
||||
};
|
||||
|
||||
pub fn meshes_draw_target(
|
||||
world: &World,
|
||||
render_pass: &mut dyn RenderPass,
|
||||
_pipeline_handle: Handle<PipelineDescriptor>,
|
||||
) {
|
||||
let mut current_mesh_handle = None;
|
||||
let mut current_mesh_index_len = 0;
|
||||
let mesh_query =
|
||||
<(Read<Handle<Mesh>>, Read<Renderable>)>::query().filter(!component::<Instanced>());
|
||||
#[derive(Default)]
|
||||
pub struct MeshesDrawTarget;
|
||||
|
||||
for (entity, (mesh, renderable)) in mesh_query.iter_entities(world) {
|
||||
if !renderable.is_visible {
|
||||
continue;
|
||||
}
|
||||
impl NewDrawTarget for MeshesDrawTarget {
|
||||
fn draw(
|
||||
&self,
|
||||
world: &World,
|
||||
render_pass: &mut dyn RenderPass,
|
||||
_pipeline_handle: Handle<PipelineDescriptor>,
|
||||
) {
|
||||
let mut current_mesh_handle = None;
|
||||
let mut current_mesh_index_len = 0;
|
||||
let mesh_query =
|
||||
<(Read<Handle<Mesh>>, Read<Renderable>)>::query().filter(!component::<Instanced>());
|
||||
|
||||
let renderer = render_pass.get_renderer();
|
||||
let render_resources = renderer.get_render_resources();
|
||||
if current_mesh_handle != Some(*mesh) {
|
||||
if let Some(vertex_buffer_resource) = render_resources.get_mesh_vertices_resource(*mesh)
|
||||
{
|
||||
let index_buffer_resource =
|
||||
render_resources.get_mesh_indices_resource(*mesh).unwrap();
|
||||
match renderer.get_resource_info(index_buffer_resource).unwrap() {
|
||||
ResourceInfo::Buffer { size, .. } => current_mesh_index_len = (size / 2) as u32,
|
||||
_ => panic!("expected a buffer type"),
|
||||
}
|
||||
render_pass.set_index_buffer(index_buffer_resource, 0);
|
||||
render_pass.set_vertex_buffer(0, vertex_buffer_resource, 0);
|
||||
for (entity, (mesh, renderable)) in mesh_query.iter_entities(world) {
|
||||
if !renderable.is_visible {
|
||||
continue;
|
||||
}
|
||||
// TODO: Verify buffer format matches render pass
|
||||
current_mesh_handle = Some(*mesh);
|
||||
}
|
||||
|
||||
// TODO: validate bind group properties against shader uniform properties at least once
|
||||
render_pass.setup_bind_groups(Some(&entity));
|
||||
render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1);
|
||||
let renderer = render_pass.get_renderer();
|
||||
let render_resources = renderer.get_render_resources();
|
||||
if current_mesh_handle != Some(*mesh) {
|
||||
if let Some(vertex_buffer_resource) =
|
||||
render_resources.get_mesh_vertices_resource(*mesh)
|
||||
{
|
||||
let index_buffer_resource =
|
||||
render_resources.get_mesh_indices_resource(*mesh).unwrap();
|
||||
match renderer.get_resource_info(index_buffer_resource).unwrap() {
|
||||
ResourceInfo::Buffer { size, .. } => {
|
||||
current_mesh_index_len = (size / 2) as u32
|
||||
}
|
||||
_ => panic!("expected a buffer type"),
|
||||
}
|
||||
render_pass.set_index_buffer(index_buffer_resource, 0);
|
||||
render_pass.set_vertex_buffer(0, vertex_buffer_resource, 0);
|
||||
}
|
||||
// TODO: Verify buffer format matches render pass
|
||||
current_mesh_handle = Some(*mesh);
|
||||
}
|
||||
|
||||
// TODO: validate bind group properties against shader uniform properties at least once
|
||||
render_pass.set_bind_groups(Some(&entity));
|
||||
render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1);
|
||||
}
|
||||
}
|
||||
|
||||
fn setup(
|
||||
&mut self,
|
||||
_world: &World,
|
||||
_renderer: &mut dyn crate::render::render_graph::Renderer,
|
||||
_pipeline_handle: Handle<PipelineDescriptor>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn get_name(&self) -> String {
|
||||
resource_name::draw_target::MESHES.to_string()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,77 +1,95 @@
|
|||
use crate::{
|
||||
asset::{AssetStorage, Handle, Mesh},
|
||||
legion::prelude::*,
|
||||
render::render_graph::{resource_name, PipelineDescriptor, RenderPass, ResourceInfo},
|
||||
render::render_graph::{
|
||||
resource_name, NewDrawTarget, PipelineDescriptor, RenderPass, ResourceInfo,
|
||||
},
|
||||
};
|
||||
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
pub fn ui_draw_target(
|
||||
world: &World,
|
||||
render_pass: &mut dyn RenderPass,
|
||||
_pipeline_handle: Handle<PipelineDescriptor>,
|
||||
) {
|
||||
// TODO: re-add support for this
|
||||
// let mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||
// let mut current_mesh_vertex_buffer = None;
|
||||
// let mut current_mesh_index_buffer = None;
|
||||
// let ui_instances_buffer = {
|
||||
// let renderer = render_pass.get_renderer();
|
||||
// match renderer.get_render_resources().get_named_resource(resource_name::buffer::UI_INSTANCES) {
|
||||
// Some(buffer) => buffer,
|
||||
// None => return,
|
||||
// }
|
||||
// };
|
||||
// // NOTE: this is ugly and borrowing is stupid
|
||||
// let result = {
|
||||
// let renderer = render_pass.get_renderer();
|
||||
// let result = if let Some(ResourceInfo::InstanceBuffer { count, mesh_id, .. }) =
|
||||
// renderer.get_resource_info(ui_instances_buffer)
|
||||
// {
|
||||
// Some((*count, *mesh_id))
|
||||
// } else {
|
||||
// None
|
||||
// };
|
||||
#[derive(Default)]
|
||||
pub struct UiDrawTarget;
|
||||
|
||||
// if let Some((instance_count, mesh_id)) = result {
|
||||
// if let Some(mesh_asset) = mesh_storage.get_id(mesh_id) {
|
||||
// if let Some(buffer) = current_mesh_vertex_buffer {
|
||||
// renderer.remove_buffer(buffer);
|
||||
// }
|
||||
impl NewDrawTarget for UiDrawTarget {
|
||||
fn draw(
|
||||
&self,
|
||||
_world: &World,
|
||||
_render_pass: &mut dyn RenderPass,
|
||||
_pipeline_handle: Handle<PipelineDescriptor>,
|
||||
) {
|
||||
// TODO: re-add support for this
|
||||
// let mesh_storage = world.resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||
// let mut current_mesh_vertex_buffer = None;
|
||||
// let mut current_mesh_index_buffer = None;
|
||||
// let ui_instances_buffer = {
|
||||
// let renderer = render_pass.get_renderer();
|
||||
// match renderer.get_render_resources().get_named_resource(resource_name::buffer::UI_INSTANCES) {
|
||||
// Some(buffer) => buffer,
|
||||
// None => return,
|
||||
// }
|
||||
// };
|
||||
// // NOTE: this is ugly and borrowing is stupid
|
||||
// let result = {
|
||||
// let renderer = render_pass.get_renderer();
|
||||
// let result = if let Some(ResourceInfo::InstanceBuffer { count, mesh_id, .. }) =
|
||||
// renderer.get_resource_info(ui_instances_buffer)
|
||||
// {
|
||||
// Some((*count, *mesh_id))
|
||||
// } else {
|
||||
// None
|
||||
// };
|
||||
|
||||
// if let Some(buffer) = current_mesh_index_buffer {
|
||||
// renderer.remove_buffer(buffer);
|
||||
// }
|
||||
// current_mesh_vertex_buffer = Some(renderer.create_buffer_with_data(
|
||||
// mesh_asset.vertices.as_bytes(),
|
||||
// wgpu::BufferUsage::VERTEX,
|
||||
// ));
|
||||
// current_mesh_index_buffer = Some(renderer.create_buffer_with_data(
|
||||
// mesh_asset.indices.as_bytes(),
|
||||
// wgpu::BufferUsage::INDEX,
|
||||
// ));
|
||||
// Some((instance_count, mesh_asset.indices.len()))
|
||||
// } else {
|
||||
// None
|
||||
// }
|
||||
// } else {
|
||||
// None
|
||||
// }
|
||||
// };
|
||||
// if let Some((instance_count, indices_length)) = result {
|
||||
// render_pass.setup_bind_groups(None);
|
||||
// render_pass.set_index_buffer(current_mesh_index_buffer.unwrap(), 0);
|
||||
// render_pass.set_vertex_buffer(0, current_mesh_vertex_buffer.unwrap(), 0);
|
||||
// render_pass.set_vertex_buffer(1, ui_instances_buffer, 0);
|
||||
// render_pass.draw_indexed(0..indices_length as u32, 0, 0..(instance_count as u32));
|
||||
// }
|
||||
// if let Some((instance_count, mesh_id)) = result {
|
||||
// if let Some(mesh_asset) = mesh_storage.get_id(mesh_id) {
|
||||
// if let Some(buffer) = current_mesh_vertex_buffer {
|
||||
// renderer.remove_buffer(buffer);
|
||||
// }
|
||||
|
||||
// let renderer = render_pass.get_renderer();
|
||||
// if let Some(buffer) = current_mesh_vertex_buffer {
|
||||
// renderer.remove_buffer(buffer);
|
||||
// }
|
||||
// if let Some(buffer) = current_mesh_index_buffer {
|
||||
// renderer.remove_buffer(buffer);
|
||||
// }
|
||||
// current_mesh_vertex_buffer = Some(renderer.create_buffer_with_data(
|
||||
// mesh_asset.vertices.as_bytes(),
|
||||
// wgpu::BufferUsage::VERTEX,
|
||||
// ));
|
||||
// current_mesh_index_buffer = Some(renderer.create_buffer_with_data(
|
||||
// mesh_asset.indices.as_bytes(),
|
||||
// wgpu::BufferUsage::INDEX,
|
||||
// ));
|
||||
// Some((instance_count, mesh_asset.indices.len()))
|
||||
// } else {
|
||||
// None
|
||||
// }
|
||||
// } else {
|
||||
// None
|
||||
// }
|
||||
// };
|
||||
// if let Some((instance_count, indices_length)) = result {
|
||||
// render_pass.setup_bind_groups(None);
|
||||
// render_pass.set_index_buffer(current_mesh_index_buffer.unwrap(), 0);
|
||||
// render_pass.set_vertex_buffer(0, current_mesh_vertex_buffer.unwrap(), 0);
|
||||
// render_pass.set_vertex_buffer(1, ui_instances_buffer, 0);
|
||||
// render_pass.draw_indexed(0..indices_length as u32, 0, 0..(instance_count as u32));
|
||||
// }
|
||||
|
||||
// if let Some(buffer) = current_mesh_index_buffer {
|
||||
// renderer.remove_buffer(buffer);
|
||||
// }
|
||||
// let renderer = render_pass.get_renderer();
|
||||
// if let Some(buffer) = current_mesh_vertex_buffer {
|
||||
// renderer.remove_buffer(buffer);
|
||||
// }
|
||||
|
||||
// if let Some(buffer) = current_mesh_index_buffer {
|
||||
// renderer.remove_buffer(buffer);
|
||||
// }
|
||||
}
|
||||
fn setup(
|
||||
&mut self,
|
||||
_world: &World,
|
||||
_renderer: &mut dyn crate::render::render_graph::Renderer,
|
||||
_pipeline_handle: Handle<PipelineDescriptor>,
|
||||
) {
|
||||
}
|
||||
fn get_name(&self) -> String {
|
||||
resource_name::draw_target::UI.to_string()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,8 +99,7 @@ impl Hash for BindGroup {
|
|||
|
||||
impl PartialEq for BindGroup {
|
||||
fn eq(&self, other: &BindGroup) -> bool {
|
||||
self.index == other.index &&
|
||||
self.bindings == other.bindings
|
||||
self.index == other.index && self.bindings == other.bindings
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,6 +291,6 @@ impl From<&Texture> for SamplerDescriptor {
|
|||
lod_min_clamp: -100.0,
|
||||
lod_max_clamp: 100.0,
|
||||
compare_function: wgpu::CompareFunction::Always,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
use crate::{
|
||||
asset::{AssetStorage, Handle},
|
||||
render::render_graph::{
|
||||
DrawTarget, PassDescriptor, PipelineDescriptor, ResourceProvider, TextureDescriptor,
|
||||
},
|
||||
use super::{
|
||||
NewDrawTarget, PassDescriptor, PipelineDescriptor, ResourceProvider, TextureDescriptor,
|
||||
};
|
||||
use crate::asset::{AssetStorage, Handle};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
pub struct RenderGraph {
|
||||
|
@ -13,7 +11,7 @@ pub struct RenderGraph {
|
|||
pub pass_pipelines: HashMap<String, Vec<Handle<PipelineDescriptor>>>,
|
||||
pub resource_providers: Vec<Box<dyn ResourceProvider>>,
|
||||
pub queued_textures: Vec<(String, TextureDescriptor)>,
|
||||
pub draw_targets: HashMap<String, DrawTarget>,
|
||||
pub draw_targets: HashMap<String, Box<dyn NewDrawTarget>>,
|
||||
}
|
||||
|
||||
impl Default for RenderGraph {
|
||||
|
@ -102,10 +100,13 @@ impl RenderGraphBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn add_draw_target(mut self, name: &str, draw_target: DrawTarget) -> Self {
|
||||
pub fn add_draw_target<T>(mut self, draw_target: T) -> Self
|
||||
where
|
||||
T: NewDrawTarget + 'static,
|
||||
{
|
||||
self.render_graph
|
||||
.draw_targets
|
||||
.insert(name.to_string(), draw_target);
|
||||
.insert(draw_target.get_name(), Box::new(draw_target));
|
||||
self
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::asset::{Handle, Texture, Mesh};
|
||||
use crate::asset::{Handle, Mesh, Texture};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Copy, Clone, Hash, Debug, Eq, PartialEq)]
|
||||
|
@ -49,7 +49,11 @@ impl RenderResources {
|
|||
self.mesh_to_indices_resource.get(&mesh).cloned()
|
||||
}
|
||||
|
||||
pub fn set_texture_sampler_resource(&mut self, texture: Handle<Texture>, resource: RenderResource) {
|
||||
pub fn set_texture_sampler_resource(
|
||||
&mut self,
|
||||
texture: Handle<Texture>,
|
||||
resource: RenderResource,
|
||||
) {
|
||||
self.texture_to_sampler_resource.insert(texture, resource);
|
||||
}
|
||||
|
||||
|
|
|
@ -170,10 +170,8 @@ pub fn update_shader_assignments(world: &mut World, render_graph: &mut RenderGra
|
|||
let macroed_pipeline_handle =
|
||||
pipeline_descriptor_storage.add(macroed_pipeline);
|
||||
// TODO: get correct pass name
|
||||
render_graph.add_pipeline(
|
||||
resource_name::pass::MAIN,
|
||||
macroed_pipeline_handle,
|
||||
);
|
||||
render_graph
|
||||
.add_pipeline(resource_name::pass::MAIN, macroed_pipeline_handle);
|
||||
macroed_pipeline_handle
|
||||
} else {
|
||||
*pipeline_handle
|
||||
|
@ -184,10 +182,7 @@ pub fn update_shader_assignments(world: &mut World, render_graph: &mut RenderGra
|
|||
.pipeline_to_macro_pipelines
|
||||
.get_mut(pipeline_handle)
|
||||
.unwrap();
|
||||
macro_pipelines.push((
|
||||
renderable.shader_defs.clone(),
|
||||
macroed_pipeline_handle,
|
||||
));
|
||||
macro_pipelines.push((renderable.shader_defs.clone(), macroed_pipeline_handle));
|
||||
macroed_pipeline_handle
|
||||
};
|
||||
|
||||
|
|
|
@ -80,8 +80,22 @@ pub trait Renderer {
|
|||
);
|
||||
fn get_render_resources(&self) -> &RenderResources;
|
||||
fn get_render_resources_mut(&mut self) -> &mut RenderResources;
|
||||
fn set_entity_uniform_resource(&mut self, entity: Entity, uniform_name: &str, resource: RenderResource);
|
||||
fn get_entity_uniform_resource(&self, entity: Entity, uniform_name: &str) -> Option<RenderResource>;
|
||||
fn set_entity_uniform_resource(
|
||||
&mut self,
|
||||
entity: Entity,
|
||||
uniform_name: &str,
|
||||
resource: RenderResource,
|
||||
);
|
||||
fn get_entity_uniform_resource(
|
||||
&self,
|
||||
entity: Entity,
|
||||
uniform_name: &str,
|
||||
) -> Option<RenderResource>;
|
||||
fn setup_entity_bind_groups(
|
||||
&mut self,
|
||||
entity: Entity,
|
||||
pipeline_descriptor: &PipelineDescriptor,
|
||||
);
|
||||
}
|
||||
|
||||
pub trait RenderPass {
|
||||
|
@ -91,5 +105,5 @@ pub trait RenderPass {
|
|||
fn set_index_buffer(&mut self, resource: RenderResource, offset: u64);
|
||||
fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64);
|
||||
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
|
||||
fn setup_bind_groups(&mut self, entity: Option<&Entity>);
|
||||
fn set_bind_groups(&mut self, entity: Option<&Entity>);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
mod wgpu_render_pass;
|
||||
mod wgpu_renderer;
|
||||
mod wgpu_resources;
|
||||
mod wgpu_render_pass;
|
||||
|
||||
pub use wgpu_render_pass::*;
|
||||
pub use wgpu_renderer::*;
|
||||
pub use wgpu_resources::*;
|
||||
pub use wgpu_render_pass::*;
|
|
@ -1,5 +1,7 @@
|
|||
use super::{WgpuRenderer, WgpuResources};
|
||||
use crate::render::render_graph::{RenderPass, PipelineDescriptor, Renderer, RenderResource, BindType};
|
||||
use crate::render::render_graph::{
|
||||
BindType, PipelineDescriptor, RenderPass, RenderResource, Renderer,
|
||||
};
|
||||
use legion::prelude::Entity;
|
||||
|
||||
pub struct WgpuRenderPass<'a, 'b, 'c, 'd> {
|
||||
|
@ -39,7 +41,7 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
|
|||
.draw_indexed(indices, base_vertex, instances);
|
||||
}
|
||||
|
||||
fn setup_bind_groups(&mut self, entity: Option<&Entity>) {
|
||||
fn set_bind_groups(&mut self, entity: Option<&Entity>) {
|
||||
let pipeline_layout = self.pipeline_descriptor.get_layout().unwrap();
|
||||
for bind_group in pipeline_layout.bind_groups.iter() {
|
||||
let bind_group_id = bind_group.get_hash().unwrap();
|
||||
|
@ -49,14 +51,6 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
|
|||
// otherwise try to get an entity-specific bind group
|
||||
None => {
|
||||
if let Some(entity) = entity {
|
||||
if let None = self
|
||||
.wgpu_resources
|
||||
.get_entity_bind_group(*entity, bind_group_id)
|
||||
{
|
||||
// TODO: Uncomment this
|
||||
// self.wgpu_resources.create_entity_bind_group(&self.renderer.device, bind_group, *entity);
|
||||
}
|
||||
|
||||
self.wgpu_resources
|
||||
.get_entity_bind_group(*entity, bind_group_id)
|
||||
.unwrap()
|
||||
|
@ -103,4 +97,4 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
use super::WgpuRenderPass;
|
||||
use crate::{
|
||||
asset::{AssetStorage, Handle},
|
||||
legion::prelude::*,
|
||||
render::{
|
||||
render_graph::{
|
||||
resource_name, update_shader_assignments, BindType,
|
||||
DynamicUniformBufferInfo, PassDescriptor, PipelineDescriptor, PipelineLayout,
|
||||
renderers::wgpu_renderer::WgpuResources, resource_name, update_shader_assignments,
|
||||
BindType, DynamicUniformBufferInfo, PassDescriptor, PipelineDescriptor, PipelineLayout,
|
||||
PipelineLayoutType, RenderGraph, RenderPassColorAttachmentDescriptor,
|
||||
RenderPassDepthStencilAttachmentDescriptor, RenderResource, RenderResources, Renderer,
|
||||
ResourceInfo, SamplerDescriptor, TextureDescriptor,
|
||||
renderers::wgpu_renderer::WgpuResources,
|
||||
},
|
||||
Shader,
|
||||
},
|
||||
};
|
||||
use std::{collections::HashMap, ops::Deref};
|
||||
use super::WgpuRenderPass;
|
||||
|
||||
|
||||
pub struct WgpuRenderer {
|
||||
pub device: wgpu::Device,
|
||||
|
@ -201,10 +199,9 @@ impl WgpuRenderer {
|
|||
.iter()
|
||||
.map(|c| Self::create_wgpu_color_attachment_descriptor(wgpu_resources, c, frame))
|
||||
.collect::<Vec<wgpu::RenderPassColorAttachmentDescriptor>>(),
|
||||
depth_stencil_attachment: pass_descriptor
|
||||
.depth_stencil_attachment
|
||||
.as_ref()
|
||||
.map(|d| Self::create_wgpu_depth_stencil_attachment_descriptor(wgpu_resources, d, frame)),
|
||||
depth_stencil_attachment: pass_descriptor.depth_stencil_attachment.as_ref().map(|d| {
|
||||
Self::create_wgpu_depth_stencil_attachment_descriptor(wgpu_resources, d, frame)
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -232,7 +229,10 @@ impl WgpuRenderer {
|
|||
let resolve_target = match color_attachment_descriptor.resolve_target {
|
||||
Some(ref target) => match target.as_str() {
|
||||
resource_name::texture::SWAP_CHAIN => Some(&frame.view),
|
||||
_ => match wgpu_resources.render_resources.get_named_resource(target.as_str()) {
|
||||
_ => match wgpu_resources
|
||||
.render_resources
|
||||
.get_named_resource(target.as_str())
|
||||
{
|
||||
Some(resource) => Some(wgpu_resources.textures.get(&resource).unwrap()),
|
||||
None => panic!(
|
||||
"Color attachment {} does not exist",
|
||||
|
@ -284,7 +284,6 @@ impl WgpuRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn create_shader_module(
|
||||
device: &wgpu::Device,
|
||||
shader: &Shader,
|
||||
|
@ -310,7 +309,6 @@ impl WgpuRenderer {
|
|||
let command_buffer = self.encoder.take().unwrap().finish();
|
||||
self.queue.submit(&[command_buffer]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Renderer for WgpuRenderer {
|
||||
|
@ -373,7 +371,9 @@ impl Renderer for WgpuRenderer {
|
|||
|
||||
for (name, texture_descriptor) in render_graph.queued_textures.drain(..) {
|
||||
let resource = self.create_texture(&texture_descriptor, None);
|
||||
self.wgpu_resources.render_resources.set_named_resource(&name, resource);
|
||||
self.wgpu_resources
|
||||
.render_resources
|
||||
.set_named_resource(&name, resource);
|
||||
}
|
||||
|
||||
let mut encoder = self.encoder.take().unwrap();
|
||||
|
@ -425,13 +425,33 @@ impl Renderer for WgpuRenderer {
|
|||
// create bind groups
|
||||
let pipeline_layout = pipeline_descriptor.get_layout().unwrap();
|
||||
for bind_group in pipeline_layout.bind_groups.iter() {
|
||||
self.wgpu_resources.setup_bind_group(&self.device, bind_group);
|
||||
self.wgpu_resources
|
||||
.setup_bind_group(&self.device, bind_group);
|
||||
}
|
||||
}
|
||||
|
||||
// setup draw targets
|
||||
for (pass_name, _pass_descriptor) in render_graph.pass_descriptors.iter() {
|
||||
if let Some(pass_pipelines) = render_graph.pass_pipelines.get(pass_name) {
|
||||
for pass_pipeline in pass_pipelines.iter() {
|
||||
let pipeline_descriptor = pipeline_storage.get(pass_pipeline).unwrap();
|
||||
for draw_target_name in pipeline_descriptor.draw_targets.iter() {
|
||||
let draw_target =
|
||||
render_graph.draw_targets.get_mut(draw_target_name).unwrap();
|
||||
draw_target.setup(world, self, *pass_pipeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// begin render passes
|
||||
for (pass_name, pass_descriptor) in render_graph.pass_descriptors.iter() {
|
||||
// run passes
|
||||
let mut render_pass = Self::create_render_pass(&self.wgpu_resources, pass_descriptor, &mut encoder, &frame);
|
||||
let mut render_pass = Self::create_render_pass(
|
||||
&self.wgpu_resources,
|
||||
pass_descriptor,
|
||||
&mut encoder,
|
||||
&frame,
|
||||
);
|
||||
if let Some(pass_pipelines) = render_graph.pass_pipelines.get(pass_name) {
|
||||
for pass_pipeline in pass_pipelines.iter() {
|
||||
let pipeline_descriptor = pipeline_storage.get(pass_pipeline).unwrap();
|
||||
|
@ -442,12 +462,12 @@ impl Renderer for WgpuRenderer {
|
|||
render_pass: &mut render_pass,
|
||||
pipeline_descriptor,
|
||||
wgpu_resources: &self.wgpu_resources,
|
||||
renderer: &self
|
||||
renderer: &self,
|
||||
};
|
||||
|
||||
for draw_target_name in pipeline_descriptor.draw_targets.iter() {
|
||||
let draw_target = render_graph.draw_targets.get(draw_target_name).unwrap();
|
||||
draw_target(world, &mut wgpu_render_pass, *pass_pipeline);
|
||||
draw_target.draw(world, &mut wgpu_render_pass, *pass_pipeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -462,11 +482,13 @@ impl Renderer for WgpuRenderer {
|
|||
data: &[u8],
|
||||
buffer_usage: wgpu::BufferUsage,
|
||||
) -> RenderResource {
|
||||
self.wgpu_resources.create_buffer_with_data(&self.device, data, buffer_usage)
|
||||
self.wgpu_resources
|
||||
.create_buffer_with_data(&self.device, data, buffer_usage)
|
||||
}
|
||||
|
||||
fn create_buffer(&mut self, size: u64, buffer_usage: wgpu::BufferUsage) -> RenderResource {
|
||||
self.wgpu_resources.create_buffer(&self.device, size, buffer_usage)
|
||||
self.wgpu_resources
|
||||
.create_buffer(&self.device, size, buffer_usage)
|
||||
}
|
||||
|
||||
fn create_instance_buffer(
|
||||
|
@ -476,7 +498,8 @@ impl Renderer for WgpuRenderer {
|
|||
count: usize,
|
||||
buffer_usage: wgpu::BufferUsage,
|
||||
) -> RenderResource {
|
||||
self.wgpu_resources.create_instance_buffer(&self.device, mesh_id, size, count, buffer_usage)
|
||||
self.wgpu_resources
|
||||
.create_instance_buffer(&self.device, mesh_id, size, count, buffer_usage)
|
||||
}
|
||||
|
||||
fn create_instance_buffer_with_data(
|
||||
|
@ -487,7 +510,14 @@ impl Renderer for WgpuRenderer {
|
|||
count: usize,
|
||||
buffer_usage: wgpu::BufferUsage,
|
||||
) -> RenderResource {
|
||||
self.wgpu_resources.create_instance_buffer_with_data(&self.device, mesh_id, data, size, count, buffer_usage)
|
||||
self.wgpu_resources.create_instance_buffer_with_data(
|
||||
&self.device,
|
||||
mesh_id,
|
||||
data,
|
||||
size,
|
||||
count,
|
||||
buffer_usage,
|
||||
)
|
||||
}
|
||||
|
||||
fn get_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo> {
|
||||
|
@ -504,7 +534,8 @@ impl Renderer for WgpuRenderer {
|
|||
buffer_usage: wgpu::BufferUsage,
|
||||
setup_data: &mut dyn FnMut(&mut [u8]),
|
||||
) -> RenderResource {
|
||||
self.wgpu_resources.create_buffer_mapped(&self.device, size, buffer_usage, setup_data)
|
||||
self.wgpu_resources
|
||||
.create_buffer_mapped(&self.device, size, buffer_usage, setup_data)
|
||||
}
|
||||
|
||||
fn copy_buffer_to_buffer(
|
||||
|
@ -515,21 +546,30 @@ impl Renderer for WgpuRenderer {
|
|||
destination_offset: u64,
|
||||
size: u64,
|
||||
) {
|
||||
self.wgpu_resources.copy_buffer_to_buffer(self.encoder.as_mut().unwrap(), source_buffer, source_offset, destination_buffer, destination_offset, size);
|
||||
self.wgpu_resources.copy_buffer_to_buffer(
|
||||
self.encoder.as_mut().unwrap(),
|
||||
source_buffer,
|
||||
source_offset,
|
||||
destination_buffer,
|
||||
destination_offset,
|
||||
size,
|
||||
);
|
||||
}
|
||||
|
||||
fn get_dynamic_uniform_buffer_info(
|
||||
&self,
|
||||
resource: RenderResource,
|
||||
) -> Option<&DynamicUniformBufferInfo> {
|
||||
self.wgpu_resources.get_dynamic_uniform_buffer_info(resource)
|
||||
self.wgpu_resources
|
||||
.get_dynamic_uniform_buffer_info(resource)
|
||||
}
|
||||
|
||||
fn get_dynamic_uniform_buffer_info_mut(
|
||||
&mut self,
|
||||
resource: RenderResource,
|
||||
) -> Option<&mut DynamicUniformBufferInfo> {
|
||||
self.wgpu_resources.get_dynamic_uniform_buffer_info_mut(resource)
|
||||
self.wgpu_resources
|
||||
.get_dynamic_uniform_buffer_info_mut(resource)
|
||||
}
|
||||
|
||||
fn add_dynamic_uniform_buffer_info(
|
||||
|
@ -537,11 +577,13 @@ impl Renderer for WgpuRenderer {
|
|||
resource: RenderResource,
|
||||
info: DynamicUniformBufferInfo,
|
||||
) {
|
||||
self.wgpu_resources.add_dynamic_uniform_buffer_info(resource, info);
|
||||
self.wgpu_resources
|
||||
.add_dynamic_uniform_buffer_info(resource, info);
|
||||
}
|
||||
|
||||
fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource {
|
||||
self.wgpu_resources.create_sampler(&self.device, sampler_descriptor)
|
||||
self.wgpu_resources
|
||||
.create_sampler(&self.device, sampler_descriptor)
|
||||
}
|
||||
|
||||
fn create_texture(
|
||||
|
@ -549,7 +591,12 @@ impl Renderer for WgpuRenderer {
|
|||
texture_descriptor: &TextureDescriptor,
|
||||
bytes: Option<&[u8]>,
|
||||
) -> RenderResource {
|
||||
self.wgpu_resources.create_texture(&self.device, self.encoder.as_mut().unwrap(), texture_descriptor, bytes)
|
||||
self.wgpu_resources.create_texture(
|
||||
&self.device,
|
||||
self.encoder.as_mut().unwrap(),
|
||||
texture_descriptor,
|
||||
bytes,
|
||||
)
|
||||
}
|
||||
|
||||
fn remove_texture(&mut self, resource: RenderResource) {
|
||||
|
@ -574,14 +621,37 @@ impl Renderer for WgpuRenderer {
|
|||
uniform_name: &str,
|
||||
resource: RenderResource,
|
||||
) {
|
||||
self.wgpu_resources.set_entity_uniform_resource(entity, uniform_name, resource)
|
||||
self.wgpu_resources
|
||||
.set_entity_uniform_resource(entity, uniform_name, resource)
|
||||
}
|
||||
fn get_entity_uniform_resource(
|
||||
&self,
|
||||
entity: Entity,
|
||||
uniform_name: &str,
|
||||
) -> Option<RenderResource> {
|
||||
self.wgpu_resources.get_entity_uniform_resource(entity, uniform_name)
|
||||
self.wgpu_resources
|
||||
.get_entity_uniform_resource(entity, uniform_name)
|
||||
}
|
||||
|
||||
fn setup_entity_bind_groups(
|
||||
&mut self,
|
||||
entity: Entity,
|
||||
pipeline_descriptor: &PipelineDescriptor,
|
||||
) {
|
||||
let pipeline_layout = pipeline_descriptor.get_layout().unwrap();
|
||||
for bind_group in pipeline_layout.bind_groups.iter() {
|
||||
let bind_group_id = bind_group.get_hash().unwrap();
|
||||
// only setup entity bind groups if there isn't already a "global" bind group created
|
||||
if let None = self.wgpu_resources.bind_groups.get(&bind_group_id) {
|
||||
if let None = self
|
||||
.wgpu_resources
|
||||
.get_entity_bind_group(entity, bind_group_id)
|
||||
{
|
||||
self.wgpu_resources
|
||||
.create_entity_bind_group(&self.device, bind_group, entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -609,4 +679,4 @@ impl From<&BindType> for wgpu::BindingType {
|
|||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
use crate::{
|
||||
legion::prelude::*,
|
||||
render::{
|
||||
render_graph::{
|
||||
BindGroup, BindType,
|
||||
DynamicUniformBufferInfo, RenderResource, RenderResources,
|
||||
ResourceInfo, SamplerDescriptor, TextureDescriptor,
|
||||
},
|
||||
render::render_graph::{
|
||||
BindGroup, BindType, DynamicUniformBufferInfo, RenderResource, RenderResources,
|
||||
ResourceInfo, SamplerDescriptor, TextureDescriptor,
|
||||
},
|
||||
};
|
||||
use std::{borrow::Cow, collections::HashMap};
|
||||
|
@ -152,7 +149,12 @@ impl WgpuResources {
|
|||
self.entity_bind_groups.get(&(entity, bind_group_id))
|
||||
}
|
||||
|
||||
pub fn create_entity_bind_group(&mut self, device: &wgpu::Device, bind_group: &BindGroup, entity: Entity) {
|
||||
pub fn create_entity_bind_group(
|
||||
&mut self,
|
||||
device: &wgpu::Device,
|
||||
bind_group: &BindGroup,
|
||||
entity: Entity,
|
||||
) {
|
||||
// TODO: don't make this per-entity. bind groups should be re-used across the same resource when possible
|
||||
let bind_group_id = bind_group.get_hash().unwrap();
|
||||
let bindings = bind_group
|
||||
|
@ -208,7 +210,12 @@ impl WgpuResources {
|
|||
);
|
||||
}
|
||||
|
||||
pub fn create_buffer(&mut self, device: &wgpu::Device, size: u64, buffer_usage: wgpu::BufferUsage) -> RenderResource {
|
||||
pub fn create_buffer(
|
||||
&mut self,
|
||||
device: &wgpu::Device,
|
||||
size: u64,
|
||||
buffer_usage: wgpu::BufferUsage,
|
||||
) -> RenderResource {
|
||||
let buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
size,
|
||||
usage: buffer_usage,
|
||||
|
@ -364,7 +371,11 @@ impl WgpuResources {
|
|||
self.dynamic_uniform_buffer_info.insert(resource, info);
|
||||
}
|
||||
|
||||
pub fn create_sampler(&mut self, device: &wgpu::Device, sampler_descriptor: &SamplerDescriptor) -> RenderResource {
|
||||
pub fn create_sampler(
|
||||
&mut self,
|
||||
device: &wgpu::Device,
|
||||
sampler_descriptor: &SamplerDescriptor,
|
||||
) -> RenderResource {
|
||||
let descriptor: wgpu::SamplerDescriptor = (*sampler_descriptor).into();
|
||||
let sampler = device.create_sampler(&descriptor);
|
||||
let resource = self.render_resources.get_next_resource();
|
||||
|
@ -384,8 +395,7 @@ impl WgpuResources {
|
|||
let texture = device.create_texture(&descriptor);
|
||||
let texture_view = texture.create_default_view();
|
||||
if let Some(bytes) = bytes {
|
||||
let temp_buf = device
|
||||
.create_buffer_with_data(bytes, wgpu::BufferUsage::COPY_SRC);
|
||||
let temp_buf = device.create_buffer_with_data(bytes, wgpu::BufferUsage::COPY_SRC);
|
||||
encoder.copy_buffer_to_texture(
|
||||
wgpu::BufferCopyView {
|
||||
buffer: &temp_buf,
|
||||
|
@ -447,4 +457,4 @@ impl WgpuResources {
|
|||
.get(&(Cow::Owned(entity), Cow::Borrowed(uniform_name)))
|
||||
.cloned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,9 @@ impl ResourceProvider for Camera2dResourceProvider {
|
|||
wgpu::BufferUsage::COPY_DST | wgpu::BufferUsage::UNIFORM,
|
||||
);
|
||||
|
||||
renderer.get_render_resources_mut().set_named_resource(resource_name::uniform::CAMERA2D, buffer);
|
||||
renderer
|
||||
.get_render_resources_mut()
|
||||
.set_named_resource(resource_name::uniform::CAMERA2D, buffer);
|
||||
self.camera_buffer = Some(buffer);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,9 @@ impl ResourceProvider for CameraResourceProvider {
|
|||
wgpu::BufferUsage::COPY_DST | wgpu::BufferUsage::UNIFORM,
|
||||
);
|
||||
|
||||
renderer.get_render_resources_mut().set_named_resource(resource_name::uniform::CAMERA, buffer);
|
||||
renderer
|
||||
.get_render_resources_mut()
|
||||
.set_named_resource(resource_name::uniform::CAMERA, buffer);
|
||||
self.camera_buffer = Some(buffer);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,12 +22,17 @@ impl FrameTextureResourceProvider {
|
|||
self.descriptor.size.width = window_size.width;
|
||||
self.descriptor.size.height = window_size.height;
|
||||
|
||||
if let Some(old_resource) = renderer.get_render_resources().get_named_resource(&self.name) {
|
||||
if let Some(old_resource) = renderer
|
||||
.get_render_resources()
|
||||
.get_named_resource(&self.name)
|
||||
{
|
||||
renderer.remove_texture(old_resource);
|
||||
}
|
||||
|
||||
let texture_resource = renderer.create_texture(&self.descriptor, None);
|
||||
renderer.get_render_resources_mut().set_named_resource(&self.name, texture_resource);
|
||||
renderer
|
||||
.get_render_resources_mut()
|
||||
.set_named_resource(&self.name, texture_resource);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,9 @@ impl ResourceProvider for LightResourceProvider {
|
|||
light_uniform_size,
|
||||
wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_SRC | wgpu::BufferUsage::COPY_DST,
|
||||
);
|
||||
renderer.get_render_resources_mut().set_named_resource(resource_name::uniform::LIGHTS, buffer);
|
||||
renderer
|
||||
.get_render_resources_mut()
|
||||
.set_named_resource(resource_name::uniform::LIGHTS, buffer);
|
||||
self.light_buffer = Some(buffer);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,14 +2,14 @@ mod camera2d_resource_provider;
|
|||
mod camera_resource_provider;
|
||||
mod frame_texture_resource_provider;
|
||||
mod light_resource_provider;
|
||||
mod mesh_resource_provider;
|
||||
mod ui_resource_provider;
|
||||
mod uniform_resource_provider;
|
||||
mod mesh_resource_provider;
|
||||
|
||||
pub use camera2d_resource_provider::*;
|
||||
pub use camera_resource_provider::*;
|
||||
pub use frame_texture_resource_provider::*;
|
||||
pub use light_resource_provider::*;
|
||||
pub use mesh_resource_provider::*;
|
||||
pub use ui_resource_provider::*;
|
||||
pub use uniform_resource_provider::*;
|
||||
pub use mesh_resource_provider::*;
|
||||
|
|
|
@ -82,7 +82,9 @@ impl UiResourceProvider {
|
|||
wgpu::BufferUsage::COPY_SRC | wgpu::BufferUsage::VERTEX,
|
||||
);
|
||||
|
||||
renderer.get_render_resources_mut().set_named_resource(resource_name::buffer::UI_INSTANCES, buffer);
|
||||
renderer
|
||||
.get_render_resources_mut()
|
||||
.set_named_resource(resource_name::buffer::UI_INSTANCES, buffer);
|
||||
self.instance_buffer = Some(buffer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,16 @@ use crate::{
|
|||
asset::{AssetStorage, Texture},
|
||||
render::render_graph::{
|
||||
render_resource::RenderResource, AsUniforms, BindType, DynamicUniformBufferInfo,
|
||||
Renderable, Renderer, ResourceProvider, TextureDescriptor, UniformInfoIter, SamplerDescriptor,
|
||||
Renderable, Renderer, ResourceProvider, SamplerDescriptor, TextureDescriptor,
|
||||
UniformInfoIter,
|
||||
},
|
||||
};
|
||||
use legion::prelude::*;
|
||||
use std::{marker::PhantomData, ops::Deref, collections::{HashSet, HashMap}};
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
marker::PhantomData,
|
||||
ops::Deref,
|
||||
};
|
||||
|
||||
pub struct UniformResourceProvider<T>
|
||||
where
|
||||
|
@ -14,7 +19,8 @@ where
|
|||
{
|
||||
_marker: PhantomData<T>,
|
||||
// PERF: somehow remove this HashSet
|
||||
uniform_buffer_info_resources: HashMap<String, (Option<RenderResource>, usize, HashSet<Entity>)>,
|
||||
uniform_buffer_info_resources:
|
||||
HashMap<String, (Option<RenderResource>, usize, HashSet<Entity>)>,
|
||||
}
|
||||
|
||||
impl<T> UniformResourceProvider<T>
|
||||
|
@ -63,7 +69,10 @@ where
|
|||
.insert(uniform_info.name.to_string(), (None, 0, HashSet::new()));
|
||||
}
|
||||
|
||||
let (_resource, counts, entities) = self.uniform_buffer_info_resources.get_mut(uniform_info.name).unwrap();
|
||||
let (_resource, counts, entities) = self
|
||||
.uniform_buffer_info_resources
|
||||
.get_mut(uniform_info.name)
|
||||
.unwrap();
|
||||
entities.insert(entity);
|
||||
*counts += 1;
|
||||
}
|
||||
|
@ -72,13 +81,18 @@ where
|
|||
uniforms.get_uniform_texture(&uniform_info.name).unwrap();
|
||||
let storage = world.resources.get::<AssetStorage<Texture>>().unwrap();
|
||||
let texture = storage.get(&texture_handle).unwrap();
|
||||
let resource = match renderer.get_render_resources().get_texture_resource(texture_handle) {
|
||||
let resource = match renderer
|
||||
.get_render_resources()
|
||||
.get_texture_resource(texture_handle)
|
||||
{
|
||||
Some(resource) => resource,
|
||||
None => {
|
||||
let descriptor: TextureDescriptor = texture.into();
|
||||
let resource =
|
||||
renderer.create_texture(&descriptor, Some(&texture.data));
|
||||
renderer.get_render_resources_mut().set_texture_resource(texture_handle, resource);
|
||||
renderer
|
||||
.get_render_resources_mut()
|
||||
.set_texture_resource(texture_handle, resource);
|
||||
resource
|
||||
}
|
||||
};
|
||||
|
@ -90,13 +104,17 @@ where
|
|||
uniforms.get_uniform_texture(&uniform_info.name).unwrap();
|
||||
let storage = world.resources.get::<AssetStorage<Texture>>().unwrap();
|
||||
let texture = storage.get(&texture_handle).unwrap();
|
||||
let resource = match renderer.get_render_resources().get_texture_sampler_resource(texture_handle) {
|
||||
let resource = match renderer
|
||||
.get_render_resources()
|
||||
.get_texture_sampler_resource(texture_handle)
|
||||
{
|
||||
Some(resource) => resource,
|
||||
None => {
|
||||
let descriptor: SamplerDescriptor = texture.into();
|
||||
let resource =
|
||||
renderer.create_sampler(&descriptor);
|
||||
renderer.get_render_resources_mut().set_texture_sampler_resource(texture_handle, resource);
|
||||
let resource = renderer.create_sampler(&descriptor);
|
||||
renderer
|
||||
.get_render_resources_mut()
|
||||
.set_texture_sampler_resource(texture_handle, resource);
|
||||
resource
|
||||
}
|
||||
};
|
||||
|
@ -135,7 +153,9 @@ where
|
|||
info.capacity = capacity;
|
||||
renderer.add_dynamic_uniform_buffer_info(created_resource, info);
|
||||
*resource = Some(created_resource);
|
||||
renderer.get_render_resources_mut().set_named_resource(name, created_resource);
|
||||
renderer
|
||||
.get_render_resources_mut()
|
||||
.set_named_resource(name, created_resource);
|
||||
}
|
||||
|
||||
// copy entity uniform data to buffers
|
||||
|
@ -153,7 +173,7 @@ where
|
|||
.unwrap();
|
||||
for (entity, _) in query.iter_entities(world) {
|
||||
if !entities.contains(&entity) {
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
// TODO: check if index has changed. if it has, then entity should be updated
|
||||
// TODO: only mem-map entities if their data has changed
|
||||
|
@ -171,7 +191,7 @@ where
|
|||
let mut offset = 0usize;
|
||||
for (entity, (uniforms, _renderable)) in query.iter_entities(world) {
|
||||
if !entities.contains(&entity) {
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
// TODO: check if index has changed. if it has, then entity should be updated
|
||||
// TODO: only mem-map entities if their data has changed
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
use crate::{asset::{Handle, Texture}, render::render_graph::{uniform::AsUniforms, FieldBindType, FieldUniformName}};
|
||||
use crate::{
|
||||
asset::{Handle, Texture},
|
||||
render::render_graph::{uniform::AsUniforms, FieldBindType, FieldUniformName},
|
||||
};
|
||||
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
|
|
|
@ -71,14 +71,20 @@ fn reflect_dimension(type_description: &ReflectTypeDescription) -> TextureViewDi
|
|||
fn reflect_binding(binding: &ReflectDescriptorBinding) -> Binding {
|
||||
let type_description = binding.type_description.as_ref().unwrap();
|
||||
let (name, bind_type) = match binding.descriptor_type {
|
||||
ReflectDescriptorType::UniformBuffer => (&type_description.type_name, BindType::Uniform {
|
||||
dynamic: false,
|
||||
properties: vec![reflect_uniform(type_description)],
|
||||
}),
|
||||
ReflectDescriptorType::SampledImage => (&binding.name, BindType::SampledTexture {
|
||||
dimension: reflect_dimension(type_description),
|
||||
multisampled: false,
|
||||
}),
|
||||
ReflectDescriptorType::UniformBuffer => (
|
||||
&type_description.type_name,
|
||||
BindType::Uniform {
|
||||
dynamic: false,
|
||||
properties: vec![reflect_uniform(type_description)],
|
||||
},
|
||||
),
|
||||
ReflectDescriptorType::SampledImage => (
|
||||
&binding.name,
|
||||
BindType::SampledTexture {
|
||||
dimension: reflect_dimension(type_description),
|
||||
multisampled: false,
|
||||
},
|
||||
),
|
||||
ReflectDescriptorType::Sampler => (&binding.name, BindType::Sampler),
|
||||
_ => panic!("unsupported bind type {:?}", binding.descriptor_type),
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue