diff --git a/src/render/render_graph_2/passes/forward.rs b/src/render/render_graph_2/passes/forward.rs index f9b8c1fe34..75a34af845 100644 --- a/src/render/render_graph_2/passes/forward.rs +++ b/src/render/render_graph_2/passes/forward.rs @@ -1,9 +1,7 @@ -use crate::render::{ - render_graph_2::{ - resource_name, PassDescriptor, - RenderGraphBuilder, RenderPassColorAttachmentDescriptor, - }, - }; +use crate::render::render_graph_2::{ + resource_name, PassDescriptor, RenderGraphBuilder, RenderPassColorAttachmentDescriptor, + RenderPassDepthStencilAttachmentDescriptor, TextureDescriptor, TextureDimension, +}; pub trait ForwardPassBuilder { fn add_forward_pass(self) -> Self; @@ -11,7 +9,23 @@ pub trait ForwardPassBuilder { impl ForwardPassBuilder for RenderGraphBuilder { fn add_forward_pass(self) -> Self { - self.add_pass( + self.add_texture( + resource_name::texture::DEPTH, + TextureDescriptor { + size: wgpu::Extent3d { + depth: 1, + width: 2560, + height: 1440, + }, + array_layer_count: 1, + mip_level_count: 1, + sample_count: 1, + dimension: TextureDimension::D2, + format: wgpu::TextureFormat::Depth32Float, + usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, + }, + ) + .add_pass( "main", PassDescriptor { color_attachments: vec![RenderPassColorAttachmentDescriptor { @@ -26,18 +40,17 @@ impl ForwardPassBuilder for RenderGraphBuilder { a: 1.0, }, }], - depth_stencil_attachment: None, - // depth_stencil_attachment: Some(RenderPassDepthStencilAttachmentDescriptor { - // attachment: "forward_depth".to_string(), - // depth_load_op: wgpu::LoadOp::Clear, - // depth_store_op: wgpu::StoreOp::Store, - // stencil_load_op: wgpu::LoadOp::Clear, - // stencil_store_op: wgpu::StoreOp::Store, - // clear_depth: 1.0, - // clear_stencil: 0, - // }), + depth_stencil_attachment: Some(RenderPassDepthStencilAttachmentDescriptor { + attachment: resource_name::texture::DEPTH.to_string(), + depth_load_op: wgpu::LoadOp::Clear, + depth_store_op: wgpu::StoreOp::Store, + stencil_load_op: wgpu::LoadOp::Clear, + stencil_store_op: wgpu::StoreOp::Store, + clear_depth: 1.0, + clear_stencil: 0, + }), sample_count: 1, }, ) } -} \ No newline at end of file +} diff --git a/src/render/render_graph_2/pipeline_layout.rs b/src/render/render_graph_2/pipeline_layout.rs index 54fd3b6eb1..beb5eeb2e7 100644 --- a/src/render/render_graph_2/pipeline_layout.rs +++ b/src/render/render_graph_2/pipeline_layout.rs @@ -59,10 +59,10 @@ pub enum BindType { Sampler, SampledTexture { multisampled: bool, - dimension: TextureDimension, + dimension: TextureViewDimension, }, StorageTexture { - dimension: TextureDimension, + dimension: TextureViewDimension, }, } @@ -117,7 +117,7 @@ impl UniformPropertyType { } #[derive(Copy, Clone, Hash)] -pub enum TextureDimension { +pub enum TextureViewDimension { D1, D2, D2Array, @@ -125,3 +125,57 @@ pub enum TextureDimension { CubeArray, D3, } + +impl From for wgpu::TextureViewDimension { + fn from(dimension: TextureViewDimension) -> Self { + match dimension { + TextureViewDimension::D1 => wgpu::TextureViewDimension::D1, + TextureViewDimension::D2 => wgpu::TextureViewDimension::D2, + TextureViewDimension::D2Array => wgpu::TextureViewDimension::D2Array, + TextureViewDimension::Cube => wgpu::TextureViewDimension::Cube, + TextureViewDimension::CubeArray => wgpu::TextureViewDimension::CubeArray, + TextureViewDimension::D3 => wgpu::TextureViewDimension::D3, + } + } +} + +#[derive(Copy, Clone, Hash)] +pub enum TextureDimension { + D1, + D2, + D3, +} + +impl From for wgpu::TextureDimension { + fn from(dimension: TextureDimension) -> Self { + match dimension { + TextureDimension::D1 => wgpu::TextureDimension::D1, + TextureDimension::D2 => wgpu::TextureDimension::D2, + TextureDimension::D3 => wgpu::TextureDimension::D3, + } + } +} + +pub struct TextureDescriptor { + pub size: wgpu::Extent3d, + pub array_layer_count: u32, + pub mip_level_count: u32, + pub sample_count: u32, + pub dimension: TextureDimension, + pub format: wgpu::TextureFormat, + pub usage: wgpu::TextureUsage, +} + +impl From for wgpu::TextureDescriptor { + fn from(texture_descriptor: TextureDescriptor) -> Self { + wgpu::TextureDescriptor { + size: texture_descriptor.size, + array_layer_count: texture_descriptor.array_layer_count, + mip_level_count: texture_descriptor.mip_level_count, + sample_count: texture_descriptor.sample_count, + dimension: texture_descriptor.dimension.into(), + format: texture_descriptor.format, + usage: texture_descriptor.usage, + } + } +} \ No newline at end of file diff --git a/src/render/render_graph_2/pipelines/forward/mod.rs b/src/render/render_graph_2/pipelines/forward/mod.rs index b15eb8008d..6d4809b290 100644 --- a/src/render/render_graph_2/pipelines/forward/mod.rs +++ b/src/render/render_graph_2/pipelines/forward/mod.rs @@ -98,15 +98,15 @@ impl ForwardPipelineBuilder for RenderGraphBuilder { depth_bias_slope_scale: 0.0, depth_bias_clamp: 0.0, }) - // .with_depth_stencil_state(wgpu::DepthStencilStateDescriptor { - // format: wgpu::TextureFormat::Depth32Float, - // depth_write_enabled: true, - // depth_compare: wgpu::CompareFunction::Less, - // stencil_front: wgpu::StencilStateFaceDescriptor::IGNORE, - // stencil_back: wgpu::StencilStateFaceDescriptor::IGNORE, - // stencil_read_mask: 0, - // stencil_write_mask: 0, - // }) + .with_depth_stencil_state(wgpu::DepthStencilStateDescriptor { + format: wgpu::TextureFormat::Depth32Float, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::Less, + stencil_front: wgpu::StencilStateFaceDescriptor::IGNORE, + stencil_back: wgpu::StencilStateFaceDescriptor::IGNORE, + stencil_read_mask: 0, + stencil_write_mask: 0, + }) .add_color_state(wgpu::ColorStateDescriptor { format: wgpu::TextureFormat::Bgra8UnormSrgb, color_blend: wgpu::BlendDescriptor::REPLACE, diff --git a/src/render/render_graph_2/render_graph.rs b/src/render/render_graph_2/render_graph.rs index bd72ee0906..9dd4ca2cb5 100644 --- a/src/render/render_graph_2/render_graph.rs +++ b/src/render/render_graph_2/render_graph.rs @@ -1,4 +1,4 @@ -use crate::render::render_graph_2::{PassDescriptor, PipelineDescriptor, ResourceProvider}; +use crate::render::render_graph_2::{PassDescriptor, PipelineDescriptor, ResourceProvider, TextureDescriptor}; use std::collections::HashMap; pub struct RenderGraph { @@ -7,6 +7,7 @@ pub struct RenderGraph { pub pass_descriptors: HashMap, pub pass_pipelines: HashMap>, pub resource_providers: Vec>, + pub queued_textures: Vec<(String, TextureDescriptor)>, } impl Default for RenderGraph { @@ -16,6 +17,7 @@ impl Default for RenderGraph { pass_descriptors: HashMap::new(), pass_pipelines: HashMap::new(), resource_providers: Vec::new(), + queued_textures: Vec::new(), } } } @@ -63,6 +65,11 @@ impl RenderGraphBuilder { self } + pub fn add_texture(mut self, name: &str, texture_descriptor: TextureDescriptor) -> Self { + self.render_graph.queued_textures.push((name.to_string(), texture_descriptor)); + self + } + pub fn build(self) -> RenderGraph { self.render_graph } diff --git a/src/render/render_graph_2/renderer.rs b/src/render/render_graph_2/renderer.rs index c28dc9b81f..d099c5b4a7 100644 --- a/src/render/render_graph_2/renderer.rs +++ b/src/render/render_graph_2/renderer.rs @@ -1,20 +1,49 @@ -use crate::{legion::prelude::*, render::render_graph_2::{RenderGraph, ResourceInfo, PipelineDescriptor, wgpu_renderer::DynamicUniformBufferInfo}}; +use crate::{ + legion::prelude::*, + render::render_graph_2::{ + wgpu_renderer::DynamicUniformBufferInfo, PipelineDescriptor, RenderGraph, ResourceInfo, + TextureDescriptor, + }, +}; use std::ops::Range; pub trait Renderer { fn initialize(&mut self, world: &mut World, render_graph: &mut RenderGraph); - fn resize(&mut self, world: &mut World, render_graph: &mut RenderGraph, width: u32, height: u32); + fn resize( + &mut self, + world: &mut World, + render_graph: &mut RenderGraph, + width: u32, + height: u32, + ); fn process_render_graph(&mut self, render_graph: &mut RenderGraph, world: &mut World); // TODO: swap out wgpu::BufferUsage for non-wgpu type fn create_buffer_with_data(&mut self, name: &str, data: &[u8], buffer_usage: wgpu::BufferUsage); + fn create_texture(&mut self, name: &str, texture_descriptor: TextureDescriptor); fn get_dynamic_uniform_buffer_info(&self, name: &str) -> Option<&DynamicUniformBufferInfo>; - fn get_dynamic_uniform_buffer_info_mut(&mut self, name: &str) -> Option<&mut DynamicUniformBufferInfo>; + fn get_dynamic_uniform_buffer_info_mut( + &mut self, + name: &str, + ) -> Option<&mut DynamicUniformBufferInfo>; fn add_dynamic_uniform_buffer_info(&mut self, name: &str, info: DynamicUniformBufferInfo); fn create_buffer(&mut self, name: &str, size: u64, buffer_usage: wgpu::BufferUsage); - fn create_buffer_mapped(&mut self, name: &str, size: usize, buffer_usage: wgpu::BufferUsage, func: &mut dyn FnMut(&mut [u8])); + fn create_buffer_mapped( + &mut self, + name: &str, + size: usize, + buffer_usage: wgpu::BufferUsage, + func: &mut dyn FnMut(&mut [u8]), + ); fn remove_buffer(&mut self, name: &str); fn get_resource_info(&self, name: &str) -> Option<&ResourceInfo>; - fn copy_buffer_to_buffer(&mut self, source_buffer: &str, source_offset: u64, destination_buffer: &str, destination_offset: u64, size: u64); + fn copy_buffer_to_buffer( + &mut self, + source_buffer: &str, + source_offset: u64, + destination_buffer: &str, + destination_offset: u64, + size: u64, + ); } pub trait RenderPass { @@ -25,4 +54,4 @@ pub trait RenderPass { fn set_vertex_buffer(&mut self, start_slot: u32, name: &str, offset: u64); fn draw_indexed(&mut self, indices: Range, base_vertex: i32, instances: Range); fn setup_bind_groups(&mut self, entity: Option<&Entity>); -} \ No newline at end of file +} diff --git a/src/render/render_graph_2/resource_name.rs b/src/render/render_graph_2/resource_name.rs index a419eadd2a..b8abfc042d 100644 --- a/src/render/render_graph_2/resource_name.rs +++ b/src/render/render_graph_2/resource_name.rs @@ -1,5 +1,6 @@ pub mod texture { pub const SWAP_CHAIN: &str = "SwapChain"; + pub const DEPTH: &str = "Depth"; } pub mod uniform { diff --git a/src/render/render_graph_2/wgpu_renderer.rs b/src/render/render_graph_2/wgpu_renderer.rs index a492b1123e..297ea215f8 100644 --- a/src/render/render_graph_2/wgpu_renderer.rs +++ b/src/render/render_graph_2/wgpu_renderer.rs @@ -4,7 +4,7 @@ use crate::{ resource_name, BindGroup, BindType, PassDescriptor, PipelineDescriptor, RenderGraph, RenderPass, RenderPassColorAttachmentDescriptor, RenderPassDepthStencilAttachmentDescriptor, Renderer, ResourceInfo, ShaderUniforms, - TextureDimension, + TextureDescriptor, }, }; use std::{collections::HashMap, ops::Deref}; @@ -470,7 +470,7 @@ impl Renderer for WgpuRenderer { for resource_provider in render_graph.resource_providers.iter_mut() { resource_provider.resize(self, world, width, height); } - + // consume current encoder let command_buffer = self.encoder.take().unwrap().finish(); self.queue.submit(&[command_buffer]); @@ -488,6 +488,10 @@ impl Renderer for WgpuRenderer { resource_provider.update(self, world); } + for (name, texture_descriptor) in render_graph.queued_textures.drain(..) { + self.create_texture(&name, texture_descriptor); + } + let mut encoder = self.encoder.take().unwrap(); let mut swap_chain = world.resources.get_mut::().unwrap(); @@ -638,6 +642,12 @@ impl Renderer for WgpuRenderer { self.dynamic_uniform_buffer_info .insert(name.to_string(), info); } + + fn create_texture(&mut self, name: &str, texture_descriptor: TextureDescriptor) { + let texture = self.device.create_texture(&texture_descriptor.into()); + self.textures + .insert(name.to_string(), texture.create_default_view()); + } } pub struct WgpuRenderPass<'a, 'b, 'c, 'd> { @@ -717,19 +727,6 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> { } } -impl From for wgpu::TextureViewDimension { - fn from(dimension: TextureDimension) -> Self { - match dimension { - TextureDimension::D1 => wgpu::TextureViewDimension::D1, - TextureDimension::D2 => wgpu::TextureViewDimension::D2, - TextureDimension::D2Array => wgpu::TextureViewDimension::D2Array, - TextureDimension::Cube => wgpu::TextureViewDimension::Cube, - TextureDimension::CubeArray => wgpu::TextureViewDimension::CubeArray, - TextureDimension::D3 => wgpu::TextureViewDimension::D3, - } - } -} - impl From<&BindType> for wgpu::BindingType { fn from(bind_type: &BindType) -> Self { match bind_type {