Refactor render passes
This commit is contained in:
parent
837e1dc139
commit
a99b5600bc
@ -10,6 +10,7 @@ pub trait DrawTarget {
|
|||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
render_pass: &mut dyn RenderPass,
|
render_pass: &mut dyn RenderPass,
|
||||||
pipeline_handle: Handle<PipelineDescriptor>,
|
pipeline_handle: Handle<PipelineDescriptor>,
|
||||||
|
pipeline_descriptor: &PipelineDescriptor,
|
||||||
);
|
);
|
||||||
fn setup(
|
fn setup(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -19,14 +19,15 @@ impl DrawTarget for AssignedBatchesDrawTarget {
|
|||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
render_pass: &mut dyn RenderPass,
|
render_pass: &mut dyn RenderPass,
|
||||||
pipeline_handle: Handle<PipelineDescriptor>,
|
pipeline_handle: Handle<PipelineDescriptor>,
|
||||||
|
pipeline_descriptor: &PipelineDescriptor,
|
||||||
) {
|
) {
|
||||||
log::trace!("drawing batches for pipeline {:?}", pipeline_handle);
|
log::trace!("drawing batches for pipeline {:?}", pipeline_handle);
|
||||||
let asset_batches = resources.get::<AssetBatchers>().unwrap();
|
let asset_batches = resources.get::<AssetBatchers>().unwrap();
|
||||||
let global_render_resource_assignments =
|
let global_render_resource_assignments =
|
||||||
resources.get::<RenderResourceAssignments>().unwrap();
|
resources.get::<RenderResourceAssignments>().unwrap();
|
||||||
render_pass.set_render_resources(&global_render_resource_assignments);
|
render_pass.set_render_resources(pipeline_descriptor, &global_render_resource_assignments);
|
||||||
for batch in asset_batches.get_batches() {
|
for batch in asset_batches.get_batches() {
|
||||||
let indices = render_pass.set_render_resources(&batch.render_resource_assignments);
|
let indices = render_pass.set_render_resources(pipeline_descriptor, &batch.render_resource_assignments);
|
||||||
log::trace!("drawing batch {:?}", batch.render_resource_assignments.id);
|
log::trace!("drawing batch {:?}", batch.render_resource_assignments.id);
|
||||||
log::trace!("{:#?}", batch);
|
log::trace!("{:#?}", batch);
|
||||||
for batched_entity in batch.entities.iter() {
|
for batched_entity in batch.entities.iter() {
|
||||||
@ -38,7 +39,7 @@ impl DrawTarget for AssignedBatchesDrawTarget {
|
|||||||
log::trace!("start drawing batched entity: {:?}", batched_entity);
|
log::trace!("start drawing batched entity: {:?}", batched_entity);
|
||||||
log::trace!("{:#?}", renderable.render_resource_assignments);
|
log::trace!("{:#?}", renderable.render_resource_assignments);
|
||||||
let entity_indices =
|
let entity_indices =
|
||||||
render_pass.set_render_resources(&renderable.render_resource_assignments);
|
render_pass.set_render_resources(pipeline_descriptor, &renderable.render_resource_assignments);
|
||||||
let mut draw_indices = &indices;
|
let mut draw_indices = &indices;
|
||||||
if entity_indices.is_some() {
|
if entity_indices.is_some() {
|
||||||
if indices.is_some() {
|
if indices.is_some() {
|
||||||
|
@ -23,6 +23,7 @@ impl DrawTarget for AssignedMeshesDrawTarget {
|
|||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
render_pass: &mut dyn RenderPass,
|
render_pass: &mut dyn RenderPass,
|
||||||
pipeline_handle: Handle<PipelineDescriptor>,
|
pipeline_handle: Handle<PipelineDescriptor>,
|
||||||
|
pipeline_descriptor: &PipelineDescriptor,
|
||||||
) {
|
) {
|
||||||
let shader_pipeline_assignments = resources.get::<PipelineAssignments>().unwrap();
|
let shader_pipeline_assignments = resources.get::<PipelineAssignments>().unwrap();
|
||||||
let entity_render_resource_assignments =
|
let entity_render_resource_assignments =
|
||||||
@ -31,7 +32,7 @@ impl DrawTarget for AssignedMeshesDrawTarget {
|
|||||||
let mut current_mesh_index_len = 0;
|
let mut current_mesh_index_len = 0;
|
||||||
let global_render_resource_assignments =
|
let global_render_resource_assignments =
|
||||||
resources.get::<RenderResourceAssignments>().unwrap();
|
resources.get::<RenderResourceAssignments>().unwrap();
|
||||||
render_pass.set_render_resources(&global_render_resource_assignments);
|
render_pass.set_render_resources(pipeline_descriptor, &global_render_resource_assignments);
|
||||||
|
|
||||||
let assigned_render_resource_assignments = shader_pipeline_assignments
|
let assigned_render_resource_assignments = shader_pipeline_assignments
|
||||||
.assignments
|
.assignments
|
||||||
@ -74,7 +75,7 @@ impl DrawTarget for AssignedMeshesDrawTarget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: validate bind group properties against shader uniform properties at least once
|
// TODO: validate bind group properties against shader uniform properties at least once
|
||||||
render_pass.set_render_resources(&renderable.render_resource_assignments);
|
render_pass.set_render_resources(pipeline_descriptor, &renderable.render_resource_assignments);
|
||||||
render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1);
|
render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ impl DrawTarget for MeshesDrawTarget {
|
|||||||
_resources: &Resources,
|
_resources: &Resources,
|
||||||
render_pass: &mut dyn RenderPass,
|
render_pass: &mut dyn RenderPass,
|
||||||
_pipeline_handle: Handle<PipelineDescriptor>,
|
_pipeline_handle: Handle<PipelineDescriptor>,
|
||||||
|
pipeline_descriptor: &PipelineDescriptor,
|
||||||
) {
|
) {
|
||||||
let mut current_mesh_handle = None;
|
let mut current_mesh_handle = None;
|
||||||
let mut current_mesh_index_len = 0;
|
let mut current_mesh_index_len = 0;
|
||||||
@ -53,7 +54,7 @@ impl DrawTarget for MeshesDrawTarget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: validate bind group properties against shader uniform properties at least once
|
// TODO: validate bind group properties against shader uniform properties at least once
|
||||||
render_pass.set_render_resources(&renderable.render_resource_assignments);
|
render_pass.set_render_resources(pipeline_descriptor, &renderable.render_resource_assignments);
|
||||||
render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1);
|
render_pass.draw_indexed(0..current_mesh_index_len, 0, 0..1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ impl DrawTarget for UiDrawTarget {
|
|||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
render_pass: &mut dyn RenderPass,
|
render_pass: &mut dyn RenderPass,
|
||||||
_pipeline_handle: Handle<PipelineDescriptor>,
|
_pipeline_handle: Handle<PipelineDescriptor>,
|
||||||
|
pipeline_descriptor: &PipelineDescriptor,
|
||||||
) {
|
) {
|
||||||
let render_resource_assignments = resources.get::<RenderResourceAssignments>().unwrap();
|
let render_resource_assignments = resources.get::<RenderResourceAssignments>().unwrap();
|
||||||
let ui_instances_buffer = {
|
let ui_instances_buffer = {
|
||||||
@ -55,7 +56,7 @@ impl DrawTarget for UiDrawTarget {
|
|||||||
|
|
||||||
let global_render_resource_assignments =
|
let global_render_resource_assignments =
|
||||||
resources.get::<RenderResourceAssignments>().unwrap();
|
resources.get::<RenderResourceAssignments>().unwrap();
|
||||||
render_pass.set_render_resources(&global_render_resource_assignments);
|
render_pass.set_render_resources(pipeline_descriptor, &global_render_resource_assignments);
|
||||||
render_pass.set_index_buffer(self.mesh_index_buffer.unwrap(), 0);
|
render_pass.set_index_buffer(self.mesh_index_buffer.unwrap(), 0);
|
||||||
render_pass.set_vertex_buffer(0, self.mesh_vertex_buffer.unwrap(), 0);
|
render_pass.set_vertex_buffer(0, self.mesh_vertex_buffer.unwrap(), 0);
|
||||||
render_pass.set_vertex_buffer(1, ui_instances_buffer, 0);
|
render_pass.set_vertex_buffer(1, ui_instances_buffer, 0);
|
||||||
|
@ -4,15 +4,18 @@ use crate::{
|
|||||||
renderer_2::RenderContext,
|
renderer_2::RenderContext,
|
||||||
};
|
};
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
use bevy_asset::Handle;
|
||||||
|
|
||||||
pub trait RenderPass {
|
pub trait RenderPass {
|
||||||
fn get_render_context(&self) -> &dyn RenderContext;
|
fn get_render_context(&self) -> &dyn RenderContext;
|
||||||
fn get_pipeline_descriptor(&self) -> &PipelineDescriptor;
|
|
||||||
fn set_index_buffer(&mut self, resource: RenderResource, offset: u64);
|
fn set_index_buffer(&mut self, resource: RenderResource, offset: u64);
|
||||||
fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64);
|
fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64);
|
||||||
|
fn set_pipeline(&mut self, pipeline_handle: Handle<PipelineDescriptor>);
|
||||||
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
|
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
|
||||||
|
// TODO: try to somehow take into account the "set" pipeline instead of passing it in here
|
||||||
fn set_render_resources(
|
fn set_render_resources(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
pipeline_descriptor: &PipelineDescriptor,
|
||||||
render_resource_assignments: &RenderResourceAssignments,
|
render_resource_assignments: &RenderResourceAssignments,
|
||||||
) -> Option<Range<u32>>;
|
) -> Option<Range<u32>>;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use super::RenderResourceContext;
|
use super::RenderResourceContext;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
pass::{PassDescriptor, RenderPass},
|
||||||
pipeline::{BindGroupDescriptor, PipelineDescriptor},
|
pipeline::{BindGroupDescriptor, PipelineDescriptor},
|
||||||
render_resource::{RenderResource, RenderResourceAssignments, RenderResourceSetId},
|
render_resource::{RenderResource, RenderResourceAssignments, RenderResourceSetId},
|
||||||
shader::Shader,
|
shader::Shader,
|
||||||
@ -8,18 +9,6 @@ use crate::{
|
|||||||
use bevy_asset::{AssetStorage, Handle};
|
use bevy_asset::{AssetStorage, Handle};
|
||||||
|
|
||||||
pub trait RenderContext {
|
pub trait RenderContext {
|
||||||
// fn setup_render_pipeline(
|
|
||||||
// &mut self,
|
|
||||||
// pipeline_handle: Handle<PipelineDescriptor>,
|
|
||||||
// pipeline_descriptor: &mut PipelineDescriptor,
|
|
||||||
// shader_storage: &AssetStorage<Shader>,
|
|
||||||
// );
|
|
||||||
// fn setup_bind_groups(
|
|
||||||
// &mut self,
|
|
||||||
// render_resource_assignments: &mut RenderResourceAssignments,
|
|
||||||
// pipeline_descriptor: &PipelineDescriptor,
|
|
||||||
// );
|
|
||||||
|
|
||||||
fn resources(&self) -> &dyn RenderResourceContext;
|
fn resources(&self) -> &dyn RenderResourceContext;
|
||||||
fn resources_mut(&mut self) -> &mut dyn RenderResourceContext;
|
fn resources_mut(&mut self) -> &mut dyn RenderResourceContext;
|
||||||
|
|
||||||
@ -36,14 +25,6 @@ pub trait RenderContext {
|
|||||||
destination_offset: u64,
|
destination_offset: u64,
|
||||||
size: u64,
|
size: u64,
|
||||||
);
|
);
|
||||||
// fn copy_buffer_to_texture(
|
|
||||||
// &mut self,
|
|
||||||
// source_buffer: RenderResource,
|
|
||||||
// source_offset: u64,
|
|
||||||
// destination_buffer: RenderResource,
|
|
||||||
// destination_offset: u64,
|
|
||||||
// size: u64,
|
|
||||||
// );
|
|
||||||
fn create_bind_group(
|
fn create_bind_group(
|
||||||
&mut self,
|
&mut self,
|
||||||
bind_group_descriptor: &BindGroupDescriptor,
|
bind_group_descriptor: &BindGroupDescriptor,
|
||||||
@ -65,4 +46,10 @@ pub trait RenderContext {
|
|||||||
self.create_bind_group(bind_group, render_resource_assignments);
|
self.create_bind_group(bind_group, render_resource_assignments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn begin_pass(
|
||||||
|
&mut self,
|
||||||
|
pass_descriptor: &PassDescriptor,
|
||||||
|
render_resource_assignments: &RenderResourceAssignments,
|
||||||
|
run_pass: &mut dyn Fn(&mut dyn RenderPass)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ use crate::{
|
|||||||
texture::{SamplerDescriptor, Texture, TextureDescriptor},
|
texture::{SamplerDescriptor, Texture, TextureDescriptor},
|
||||||
};
|
};
|
||||||
use bevy_asset::{AssetStorage, Handle};
|
use bevy_asset::{AssetStorage, Handle};
|
||||||
|
use bevy_window::{Window, WindowId};
|
||||||
|
|
||||||
pub struct GlobalRenderResourceContext {
|
pub struct GlobalRenderResourceContext {
|
||||||
pub context: Box<dyn RenderResourceContext + Send + Sync + 'static>,
|
pub context: Box<dyn RenderResourceContext + Send + Sync + 'static>,
|
||||||
@ -12,6 +13,9 @@ pub struct GlobalRenderResourceContext {
|
|||||||
|
|
||||||
// TODO: Rename to RenderResources after cleaning up AssetResources rename
|
// TODO: Rename to RenderResources after cleaning up AssetResources rename
|
||||||
pub trait RenderResourceContext {
|
pub trait RenderResourceContext {
|
||||||
|
fn create_swap_chain(&mut self, window: &Window);
|
||||||
|
fn next_swap_chain_texture(&mut self, window_id: WindowId);
|
||||||
|
fn drop_swap_chain_texture(&mut self, window_id: WindowId);
|
||||||
fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource;
|
fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource;
|
||||||
fn create_texture(&mut self, texture_descriptor: &TextureDescriptor) -> RenderResource;
|
fn create_texture(&mut self, texture_descriptor: &TextureDescriptor) -> RenderResource;
|
||||||
fn create_buffer(&mut self, buffer_info: BufferInfo) -> RenderResource;
|
fn create_buffer(&mut self, buffer_info: BufferInfo) -> RenderResource;
|
||||||
|
@ -1,16 +1,24 @@
|
|||||||
use super::WgpuRenderResourceContextTrait;
|
use super::WgpuRenderResourceContextTrait;
|
||||||
use crate::wgpu_type_converter::{OwnedWgpuVertexBufferDescriptor, WgpuInto};
|
use crate::{
|
||||||
|
wgpu_type_converter::{OwnedWgpuVertexBufferDescriptor, WgpuInto},
|
||||||
|
WgpuRenderPass,
|
||||||
|
};
|
||||||
use bevy_asset::{AssetStorage, Handle};
|
use bevy_asset::{AssetStorage, Handle};
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
|
pass::{
|
||||||
|
PassDescriptor, RenderPass, RenderPassColorAttachmentDescriptor,
|
||||||
|
RenderPassDepthStencilAttachmentDescriptor,
|
||||||
|
},
|
||||||
pipeline::{BindGroupDescriptor, BindType, PipelineDescriptor},
|
pipeline::{BindGroupDescriptor, BindType, PipelineDescriptor},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
RenderResource, RenderResourceAssignments, RenderResourceSetId, ResourceInfo,
|
resource_name, RenderResource, RenderResourceAssignments, RenderResourceSetId, ResourceInfo,
|
||||||
},
|
},
|
||||||
renderer_2::{RenderContext, RenderResourceContext},
|
renderer_2::{RenderContext, RenderResourceContext},
|
||||||
shader::Shader,
|
shader::Shader,
|
||||||
texture::TextureDescriptor,
|
texture::TextureDescriptor,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use bevy_window::WindowId;
|
||||||
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct LazyCommandEncoder {
|
struct LazyCommandEncoder {
|
||||||
@ -22,17 +30,29 @@ impl LazyCommandEncoder {
|
|||||||
match self.command_encoder {
|
match self.command_encoder {
|
||||||
Some(ref mut command_encoder) => command_encoder,
|
Some(ref mut command_encoder) => command_encoder,
|
||||||
None => {
|
None => {
|
||||||
let command_encoder =
|
self.create(device);
|
||||||
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
|
||||||
self.command_encoder = Some(command_encoder);
|
|
||||||
self.command_encoder.as_mut().unwrap()
|
self.command_encoder.as_mut().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_some(&self) -> bool {
|
||||||
|
self.command_encoder.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create(&mut self, device: &wgpu::Device) {
|
||||||
|
let command_encoder =
|
||||||
|
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
||||||
|
self.command_encoder = Some(command_encoder);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn take(&mut self) -> Option<wgpu::CommandEncoder> {
|
pub fn take(&mut self) -> Option<wgpu::CommandEncoder> {
|
||||||
self.command_encoder.take()
|
self.command_encoder.take()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set(&mut self, command_encoder: wgpu::CommandEncoder) {
|
||||||
|
self.command_encoder = Some(command_encoder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WgpuRenderContext<T>
|
pub struct WgpuRenderContext<T>
|
||||||
@ -40,6 +60,8 @@ where
|
|||||||
T: RenderResourceContext,
|
T: RenderResourceContext,
|
||||||
{
|
{
|
||||||
pub device: Arc<wgpu::Device>,
|
pub device: Arc<wgpu::Device>,
|
||||||
|
// TODO: remove this
|
||||||
|
pub primary_window: Option<WindowId>,
|
||||||
command_encoder: LazyCommandEncoder,
|
command_encoder: LazyCommandEncoder,
|
||||||
pub render_resources: T,
|
pub render_resources: T,
|
||||||
}
|
}
|
||||||
@ -51,6 +73,7 @@ where
|
|||||||
pub fn new(device: Arc<wgpu::Device>, resources: T) -> Self {
|
pub fn new(device: Arc<wgpu::Device>, resources: T) -> Self {
|
||||||
WgpuRenderContext {
|
WgpuRenderContext {
|
||||||
device,
|
device,
|
||||||
|
primary_window: None,
|
||||||
render_resources: resources,
|
render_resources: resources,
|
||||||
command_encoder: LazyCommandEncoder::default(),
|
command_encoder: LazyCommandEncoder::default(),
|
||||||
}
|
}
|
||||||
@ -70,19 +93,6 @@ where
|
|||||||
pub fn finish_encoder(&mut self) -> Option<wgpu::CommandBuffer> {
|
pub fn finish_encoder(&mut self) -> Option<wgpu::CommandBuffer> {
|
||||||
self.command_encoder.take().map(|encoder| encoder.finish())
|
self.command_encoder.take().map(|encoder| encoder.finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn get_buffer<'b>(
|
|
||||||
// render_resource: RenderResource,
|
|
||||||
// local_resources: &'b WgpuResources,
|
|
||||||
// global_resources: &'b WgpuResources,
|
|
||||||
// ) -> Option<&'b wgpu::Buffer> {
|
|
||||||
// let buffer = local_resources.buffers.get(&render_resource);
|
|
||||||
// if buffer.is_some() {
|
|
||||||
// return buffer;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// global_resources.buffers.get(&render_resource)
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> RenderContext for WgpuRenderContext<T>
|
impl<T> RenderContext for WgpuRenderContext<T>
|
||||||
@ -365,4 +375,167 @@ where
|
|||||||
self.render_resources
|
self.render_resources
|
||||||
.set_render_pipeline(pipeline_handle, wgpu_pipeline);
|
.set_render_pipeline(pipeline_handle, wgpu_pipeline);
|
||||||
}
|
}
|
||||||
|
fn begin_pass(
|
||||||
|
&mut self,
|
||||||
|
pass_descriptor: &PassDescriptor,
|
||||||
|
render_resource_assignments: &RenderResourceAssignments,
|
||||||
|
run_pass: &mut dyn Fn(&mut dyn RenderPass),
|
||||||
|
) {
|
||||||
|
if !self.command_encoder.is_some() {
|
||||||
|
self.command_encoder.create(&self.device);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut encoder = self.command_encoder.take().unwrap();
|
||||||
|
{
|
||||||
|
let render_pass = create_render_pass(
|
||||||
|
self,
|
||||||
|
pass_descriptor,
|
||||||
|
render_resource_assignments,
|
||||||
|
&mut encoder,
|
||||||
|
);
|
||||||
|
let mut wgpu_render_pass = WgpuRenderPass {
|
||||||
|
render_context: self,
|
||||||
|
render_pass,
|
||||||
|
bound_bind_groups: HashMap::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
run_pass(&mut wgpu_render_pass);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.command_encoder.set(encoder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_render_pass<'a, 'b, T>(
|
||||||
|
render_context: &'a WgpuRenderContext<T>,
|
||||||
|
pass_descriptor: &PassDescriptor,
|
||||||
|
global_render_resource_assignments: &'b RenderResourceAssignments,
|
||||||
|
encoder: &'a mut wgpu::CommandEncoder,
|
||||||
|
) -> wgpu::RenderPass<'a>
|
||||||
|
where
|
||||||
|
T: WgpuRenderResourceContextTrait + RenderResourceContext,
|
||||||
|
{
|
||||||
|
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
color_attachments: &pass_descriptor
|
||||||
|
.color_attachments
|
||||||
|
.iter()
|
||||||
|
.map(|c| {
|
||||||
|
create_wgpu_color_attachment_descriptor(
|
||||||
|
render_context,
|
||||||
|
global_render_resource_assignments,
|
||||||
|
c,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<wgpu::RenderPassColorAttachmentDescriptor>>(),
|
||||||
|
depth_stencil_attachment: pass_descriptor.depth_stencil_attachment.as_ref().map(|d| {
|
||||||
|
create_wgpu_depth_stencil_attachment_descriptor(
|
||||||
|
render_context,
|
||||||
|
global_render_resource_assignments,
|
||||||
|
d,
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_texture_view<'a, T>(
|
||||||
|
render_context: &'a WgpuRenderContext<T>,
|
||||||
|
global_render_resource_assignments: &RenderResourceAssignments,
|
||||||
|
name: &str,
|
||||||
|
) -> &'a wgpu::TextureView
|
||||||
|
where
|
||||||
|
T: WgpuRenderResourceContextTrait + RenderResourceContext,
|
||||||
|
{
|
||||||
|
match name {
|
||||||
|
resource_name::texture::SWAP_CHAIN => {
|
||||||
|
if let Some(primary_swap_chain) = render_context
|
||||||
|
.render_resources
|
||||||
|
.get_swap_chain_output(render_context.primary_window.as_ref().unwrap())
|
||||||
|
.map(|output| &output.view)
|
||||||
|
{
|
||||||
|
primary_swap_chain
|
||||||
|
} else {
|
||||||
|
panic!("No primary swap chain found for color attachment");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => match global_render_resource_assignments.get(name) {
|
||||||
|
Some(resource) => render_context
|
||||||
|
.render_resources
|
||||||
|
.get_texture(resource)
|
||||||
|
.unwrap(),
|
||||||
|
None => {
|
||||||
|
// if let Some(swap_chain_output) = swap_chain_outputs.get(name) {
|
||||||
|
// &swap_chain_output.view
|
||||||
|
// } else {
|
||||||
|
panic!("Color attachment {} does not exist", name);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_wgpu_color_attachment_descriptor<'a, T>(
|
||||||
|
render_context: &'a WgpuRenderContext<T>,
|
||||||
|
global_render_resource_assignments: &RenderResourceAssignments,
|
||||||
|
color_attachment_descriptor: &RenderPassColorAttachmentDescriptor,
|
||||||
|
) -> wgpu::RenderPassColorAttachmentDescriptor<'a>
|
||||||
|
where
|
||||||
|
T: WgpuRenderResourceContextTrait + RenderResourceContext,
|
||||||
|
{
|
||||||
|
let attachment = get_texture_view(
|
||||||
|
render_context,
|
||||||
|
global_render_resource_assignments,
|
||||||
|
color_attachment_descriptor.attachment.as_str(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let resolve_target = color_attachment_descriptor
|
||||||
|
.resolve_target
|
||||||
|
.as_ref()
|
||||||
|
.map(|target| {
|
||||||
|
get_texture_view(
|
||||||
|
render_context,
|
||||||
|
global_render_resource_assignments,
|
||||||
|
target.as_str(),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
wgpu::RenderPassColorAttachmentDescriptor {
|
||||||
|
store_op: color_attachment_descriptor.store_op.wgpu_into(),
|
||||||
|
load_op: color_attachment_descriptor.load_op.wgpu_into(),
|
||||||
|
clear_color: color_attachment_descriptor.clear_color.wgpu_into(),
|
||||||
|
attachment,
|
||||||
|
resolve_target,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_wgpu_depth_stencil_attachment_descriptor<'a, T>(
|
||||||
|
render_context: &'a WgpuRenderContext<T>,
|
||||||
|
global_render_resource_assignments: &RenderResourceAssignments,
|
||||||
|
depth_stencil_attachment_descriptor: &RenderPassDepthStencilAttachmentDescriptor,
|
||||||
|
) -> wgpu::RenderPassDepthStencilAttachmentDescriptor<'a>
|
||||||
|
where
|
||||||
|
T: WgpuRenderResourceContextTrait + RenderResourceContext,
|
||||||
|
{
|
||||||
|
let attachment = get_texture_view(
|
||||||
|
render_context,
|
||||||
|
global_render_resource_assignments,
|
||||||
|
depth_stencil_attachment_descriptor.attachment.as_str(),
|
||||||
|
);
|
||||||
|
|
||||||
|
wgpu::RenderPassDepthStencilAttachmentDescriptor {
|
||||||
|
attachment,
|
||||||
|
clear_depth: depth_stencil_attachment_descriptor.clear_depth,
|
||||||
|
clear_stencil: depth_stencil_attachment_descriptor.clear_stencil,
|
||||||
|
depth_load_op: depth_stencil_attachment_descriptor
|
||||||
|
.depth_load_op
|
||||||
|
.wgpu_into(),
|
||||||
|
depth_store_op: depth_stencil_attachment_descriptor
|
||||||
|
.depth_store_op
|
||||||
|
.wgpu_into(),
|
||||||
|
stencil_load_op: depth_stencil_attachment_descriptor
|
||||||
|
.stencil_load_op
|
||||||
|
.wgpu_into(),
|
||||||
|
stencil_store_op: depth_stencil_attachment_descriptor
|
||||||
|
.stencil_store_op
|
||||||
|
.wgpu_into(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ use bevy_render::{
|
|||||||
texture::{SamplerDescriptor, Texture, TextureDescriptor},
|
texture::{SamplerDescriptor, Texture, TextureDescriptor},
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use bevy_window::{WindowId, Window};
|
||||||
|
|
||||||
pub struct WgpuRenderResourceContext {
|
pub struct WgpuRenderResourceContext {
|
||||||
pub device: Arc<wgpu::Device>,
|
pub device: Arc<wgpu::Device>,
|
||||||
@ -62,6 +63,7 @@ pub trait WgpuRenderResourceContextTrait {
|
|||||||
bind_group_id: BindGroupDescriptorId,
|
bind_group_id: BindGroupDescriptorId,
|
||||||
) -> Option<&wgpu::BindGroupLayout>;
|
) -> Option<&wgpu::BindGroupLayout>;
|
||||||
fn get_buffer(&self, render_resource: RenderResource) -> Option<&wgpu::Buffer>;
|
fn get_buffer(&self, render_resource: RenderResource) -> Option<&wgpu::Buffer>;
|
||||||
|
fn get_swap_chain_output(&self, window_id: &WindowId) -> Option<&wgpu::SwapChainOutput>;
|
||||||
fn get_texture(&self, render_resource: RenderResource) -> Option<&wgpu::TextureView>;
|
fn get_texture(&self, render_resource: RenderResource) -> Option<&wgpu::TextureView>;
|
||||||
fn get_sampler(&self, render_resource: RenderResource) -> Option<&wgpu::Sampler>;
|
fn get_sampler(&self, render_resource: RenderResource) -> Option<&wgpu::Sampler>;
|
||||||
fn get_pipeline(&self, pipeline: Handle<PipelineDescriptor>) -> Option<&wgpu::RenderPipeline>;
|
fn get_pipeline(&self, pipeline: Handle<PipelineDescriptor>) -> Option<&wgpu::RenderPipeline>;
|
||||||
@ -154,6 +156,9 @@ impl WgpuRenderResourceContextTrait for WgpuRenderResourceContext {
|
|||||||
self.wgpu_resources
|
self.wgpu_resources
|
||||||
.set_render_pipeline(pipeline_handle, pipeline);
|
.set_render_pipeline(pipeline_handle, pipeline);
|
||||||
}
|
}
|
||||||
|
fn get_swap_chain_output(&self, window_id: &WindowId) -> Option<&wgpu::SwapChainOutput> {
|
||||||
|
self.wgpu_resources.swap_chain_outputs.get(window_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuRenderResourceContext {
|
impl WgpuRenderResourceContext {
|
||||||
@ -254,4 +259,13 @@ impl RenderResourceContext for WgpuRenderResourceContext {
|
|||||||
self.wgpu_resources
|
self.wgpu_resources
|
||||||
.create_shader_module(&self.device, shader_handle, shader);
|
.create_shader_module(&self.device, shader_handle, shader);
|
||||||
}
|
}
|
||||||
|
fn create_swap_chain(&mut self, window: &Window) {
|
||||||
|
self.wgpu_resources.create_window_swap_chain(&self.device, window)
|
||||||
|
}
|
||||||
|
fn next_swap_chain_texture(&mut self, window_id: bevy_window::WindowId) {
|
||||||
|
self.wgpu_resources.next_swap_chain_texture(window_id);
|
||||||
|
}
|
||||||
|
fn drop_swap_chain_texture(&mut self, window_id: WindowId) {
|
||||||
|
self.wgpu_resources.remove_swap_chain_texture(window_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ use bevy_render::{
|
|||||||
shader::Shader,
|
shader::Shader,
|
||||||
texture::{SamplerDescriptor, Texture, TextureDescriptor},
|
texture::{SamplerDescriptor, Texture, TextureDescriptor},
|
||||||
};
|
};
|
||||||
|
use bevy_window::{WindowId, Window};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct WgpuTransactionalRenderResourceContext<'a> {
|
pub struct WgpuTransactionalRenderResourceContext<'a> {
|
||||||
@ -139,6 +140,16 @@ impl<'a> WgpuRenderResourceContextTrait for WgpuTransactionalRenderResourceConte
|
|||||||
self.local_resources
|
self.local_resources
|
||||||
.set_render_pipeline(pipeline_handle, pipeline);
|
.set_render_pipeline(pipeline_handle, pipeline);
|
||||||
}
|
}
|
||||||
|
fn get_swap_chain_output(
|
||||||
|
&self,
|
||||||
|
window_id: &bevy_window::WindowId,
|
||||||
|
) -> Option<&wgpu::SwapChainOutput> {
|
||||||
|
let local = self.local_resources.swap_chain_outputs.get(window_id);
|
||||||
|
if local.is_some() {
|
||||||
|
return local;
|
||||||
|
}
|
||||||
|
self.parent_resources.swap_chain_outputs.get(window_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> WgpuTransactionalRenderResourceContext<'a> {
|
impl<'a> WgpuTransactionalRenderResourceContext<'a> {
|
||||||
@ -283,4 +294,14 @@ impl<'a> RenderResourceContext for WgpuTransactionalRenderResourceContext<'a> {
|
|||||||
self.local_resources
|
self.local_resources
|
||||||
.create_shader_module(&self.device, shader_handle, shader);
|
.create_shader_module(&self.device, shader_handle, shader);
|
||||||
}
|
}
|
||||||
|
fn create_swap_chain(&mut self, window: &Window) {
|
||||||
|
self.local_resources
|
||||||
|
.create_window_swap_chain(&self.device, window)
|
||||||
|
}
|
||||||
|
fn next_swap_chain_texture(&mut self, window_id: bevy_window::WindowId) {
|
||||||
|
self.local_resources.next_swap_chain_texture(window_id);
|
||||||
|
}
|
||||||
|
fn drop_swap_chain_texture(&mut self, window_id: WindowId) {
|
||||||
|
self.local_resources.remove_swap_chain_texture(window_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,17 +9,16 @@ use bevy_render::{
|
|||||||
};
|
};
|
||||||
use std::{collections::HashMap, ops::Range};
|
use std::{collections::HashMap, ops::Range};
|
||||||
|
|
||||||
pub struct WgpuRenderPass<'a, 'b, 'c, T>
|
pub struct WgpuRenderPass<'a, T>
|
||||||
where
|
where
|
||||||
T: RenderResourceContext + WgpuRenderResourceContextTrait,
|
T: RenderResourceContext + WgpuRenderResourceContextTrait,
|
||||||
{
|
{
|
||||||
pub render_pass: &'b mut wgpu::RenderPass<'a>,
|
pub render_pass: wgpu::RenderPass<'a>,
|
||||||
pub pipeline_descriptor: &'c PipelineDescriptor,
|
|
||||||
pub render_context: &'a WgpuRenderContext<T>,
|
pub render_context: &'a WgpuRenderContext<T>,
|
||||||
pub bound_bind_groups: HashMap<u32, RenderResourceSetId>,
|
pub bound_bind_groups: HashMap<u32, RenderResourceSetId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, 'c, T> RenderPass for WgpuRenderPass<'a, 'b, 'c, T>
|
impl<'a, T> RenderPass for WgpuRenderPass<'a, T>
|
||||||
where
|
where
|
||||||
T: RenderResourceContext + WgpuRenderResourceContextTrait,
|
T: RenderResourceContext + WgpuRenderResourceContextTrait,
|
||||||
{
|
{
|
||||||
@ -27,10 +26,6 @@ where
|
|||||||
self.render_context
|
self.render_context
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_pipeline_descriptor(&self) -> &PipelineDescriptor {
|
|
||||||
self.pipeline_descriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64) {
|
fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64) {
|
||||||
let buffer = self
|
let buffer = self
|
||||||
.render_context
|
.render_context
|
||||||
@ -57,9 +52,11 @@ where
|
|||||||
|
|
||||||
fn set_render_resources(
|
fn set_render_resources(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
pipeline_descriptor: &PipelineDescriptor,
|
||||||
render_resource_assignments: &RenderResourceAssignments,
|
render_resource_assignments: &RenderResourceAssignments,
|
||||||
) -> Option<Range<u32>> {
|
) -> Option<Range<u32>> {
|
||||||
let pipeline_layout = self.pipeline_descriptor.get_layout().unwrap();
|
let pipeline_layout = pipeline_descriptor.get_layout()
|
||||||
|
.unwrap();
|
||||||
// PERF: vertex buffer lookup comes at a cost when vertex buffers aren't in render_resource_assignments. iterating over render_resource_assignment vertex buffers
|
// PERF: vertex buffer lookup comes at a cost when vertex buffers aren't in render_resource_assignments. iterating over render_resource_assignment vertex buffers
|
||||||
// would likely be faster
|
// would likely be faster
|
||||||
let mut indices = None;
|
let mut indices = None;
|
||||||
@ -151,4 +148,8 @@ where
|
|||||||
|
|
||||||
indices
|
indices
|
||||||
}
|
}
|
||||||
|
fn set_pipeline(&mut self, pipeline_handle: bevy_asset::Handle<PipelineDescriptor>) {
|
||||||
|
let pipeline = self.render_context.render_resources.get_pipeline(pipeline_handle).expect("Attempted to use a pipeline that does not exist in this RenderPass's RenderContext");
|
||||||
|
self.render_pass.set_pipeline(pipeline);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,23 @@
|
|||||||
use super::{wgpu_type_converter::WgpuInto, WgpuRenderPass, WgpuResources};
|
use super::WgpuResources;
|
||||||
use crate::renderer_2::{
|
use crate::renderer_2::{
|
||||||
render_resource_sets_system, WgpuRenderContext, WgpuRenderResourceContext,
|
render_resource_sets_system, WgpuRenderContext, WgpuRenderResourceContext,
|
||||||
WgpuRenderResourceContextTrait, WgpuTransactionalRenderResourceContext,
|
WgpuTransactionalRenderResourceContext,
|
||||||
};
|
};
|
||||||
use bevy_app::{EventReader, Events};
|
use bevy_app::{EventReader, Events};
|
||||||
use bevy_asset::AssetStorage;
|
use bevy_asset::AssetStorage;
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
pass::{
|
|
||||||
PassDescriptor, RenderPassColorAttachmentDescriptor,
|
|
||||||
RenderPassDepthStencilAttachmentDescriptor,
|
|
||||||
},
|
|
||||||
pipeline::{update_shader_assignments, PipelineCompiler, PipelineDescriptor},
|
pipeline::{update_shader_assignments, PipelineCompiler, PipelineDescriptor},
|
||||||
render_graph::RenderGraph,
|
render_graph::RenderGraph,
|
||||||
render_resource::{resource_name, RenderResourceAssignments},
|
render_resource::RenderResourceAssignments,
|
||||||
renderer_2::RenderContext,
|
renderer_2::{RenderContext, RenderResourceContext},
|
||||||
};
|
};
|
||||||
use bevy_window::{WindowCreated, WindowResized, Windows};
|
use bevy_window::{WindowCreated, WindowResized, Windows};
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
use std::{
|
use std::{collections::HashSet, ops::Deref, sync::Arc};
|
||||||
collections::{HashMap, HashSet},
|
|
||||||
ops::Deref,
|
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct WgpuRenderer {
|
pub struct WgpuRenderer {
|
||||||
pub global_context: WgpuRenderContext<WgpuRenderResourceContext>,
|
pub global_context: WgpuRenderContext<WgpuRenderResourceContext>,
|
||||||
pub queue: wgpu::Queue,
|
pub queue: wgpu::Queue,
|
||||||
pub encoder: Option<wgpu::CommandEncoder>,
|
|
||||||
pub window_resized_event_reader: EventReader<WindowResized>,
|
pub window_resized_event_reader: EventReader<WindowResized>,
|
||||||
pub window_created_event_reader: EventReader<WindowCreated>,
|
pub window_created_event_reader: EventReader<WindowCreated>,
|
||||||
pub intialized: bool,
|
pub intialized: bool,
|
||||||
@ -62,149 +53,12 @@ impl WgpuRenderer {
|
|||||||
WgpuRenderResourceContext::new(device),
|
WgpuRenderResourceContext::new(device),
|
||||||
),
|
),
|
||||||
queue,
|
queue,
|
||||||
encoder: None,
|
|
||||||
window_resized_event_reader,
|
window_resized_event_reader,
|
||||||
window_created_event_reader,
|
window_created_event_reader,
|
||||||
intialized: false,
|
intialized: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_render_pass<'a, 'b>(
|
|
||||||
wgpu_resources: &'a WgpuResources,
|
|
||||||
pass_descriptor: &PassDescriptor,
|
|
||||||
global_render_resource_assignments: &'b RenderResourceAssignments,
|
|
||||||
encoder: &'a mut wgpu::CommandEncoder,
|
|
||||||
primary_swap_chain: &Option<String>,
|
|
||||||
swap_chain_outputs: &'a HashMap<String, wgpu::SwapChainOutput>,
|
|
||||||
) -> wgpu::RenderPass<'a> {
|
|
||||||
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
|
||||||
color_attachments: &pass_descriptor
|
|
||||||
.color_attachments
|
|
||||||
.iter()
|
|
||||||
.map(|c| {
|
|
||||||
Self::create_wgpu_color_attachment_descriptor(
|
|
||||||
wgpu_resources,
|
|
||||||
global_render_resource_assignments,
|
|
||||||
c,
|
|
||||||
primary_swap_chain,
|
|
||||||
swap_chain_outputs,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.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,
|
|
||||||
global_render_resource_assignments,
|
|
||||||
d,
|
|
||||||
primary_swap_chain,
|
|
||||||
swap_chain_outputs,
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_texture_view<'a>(
|
|
||||||
wgpu_resources: &'a WgpuResources,
|
|
||||||
global_render_resource_assignments: &RenderResourceAssignments,
|
|
||||||
primary_swap_chain: &Option<String>,
|
|
||||||
swap_chain_outputs: &'a HashMap<String, wgpu::SwapChainOutput>,
|
|
||||||
name: &str,
|
|
||||||
) -> &'a wgpu::TextureView {
|
|
||||||
match name {
|
|
||||||
resource_name::texture::SWAP_CHAIN => {
|
|
||||||
if let Some(primary_swap_chain) = primary_swap_chain {
|
|
||||||
swap_chain_outputs
|
|
||||||
.get(primary_swap_chain)
|
|
||||||
.map(|output| &output.view)
|
|
||||||
.unwrap()
|
|
||||||
} else {
|
|
||||||
panic!("No primary swap chain found for color attachment");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => match global_render_resource_assignments.get(name) {
|
|
||||||
Some(resource) => wgpu_resources.textures.get(&resource).unwrap(),
|
|
||||||
None => {
|
|
||||||
if let Some(swap_chain_output) = swap_chain_outputs.get(name) {
|
|
||||||
&swap_chain_output.view
|
|
||||||
} else {
|
|
||||||
panic!("Color attachment {} does not exist", name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_wgpu_color_attachment_descriptor<'a>(
|
|
||||||
wgpu_resources: &'a WgpuResources,
|
|
||||||
global_render_resource_assignments: &RenderResourceAssignments,
|
|
||||||
color_attachment_descriptor: &RenderPassColorAttachmentDescriptor,
|
|
||||||
primary_swap_chain: &Option<String>,
|
|
||||||
swap_chain_outputs: &'a HashMap<String, wgpu::SwapChainOutput>,
|
|
||||||
) -> wgpu::RenderPassColorAttachmentDescriptor<'a> {
|
|
||||||
let attachment = Self::get_texture_view(
|
|
||||||
wgpu_resources,
|
|
||||||
global_render_resource_assignments,
|
|
||||||
primary_swap_chain,
|
|
||||||
swap_chain_outputs,
|
|
||||||
color_attachment_descriptor.attachment.as_str(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let resolve_target = color_attachment_descriptor
|
|
||||||
.resolve_target
|
|
||||||
.as_ref()
|
|
||||||
.map(|target| {
|
|
||||||
Self::get_texture_view(
|
|
||||||
wgpu_resources,
|
|
||||||
global_render_resource_assignments,
|
|
||||||
primary_swap_chain,
|
|
||||||
swap_chain_outputs,
|
|
||||||
target.as_str(),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
wgpu::RenderPassColorAttachmentDescriptor {
|
|
||||||
store_op: color_attachment_descriptor.store_op.wgpu_into(),
|
|
||||||
load_op: color_attachment_descriptor.load_op.wgpu_into(),
|
|
||||||
clear_color: color_attachment_descriptor.clear_color.wgpu_into(),
|
|
||||||
attachment,
|
|
||||||
resolve_target,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_wgpu_depth_stencil_attachment_descriptor<'a>(
|
|
||||||
wgpu_resources: &'a WgpuResources,
|
|
||||||
global_render_resource_assignments: &RenderResourceAssignments,
|
|
||||||
depth_stencil_attachment_descriptor: &RenderPassDepthStencilAttachmentDescriptor,
|
|
||||||
primary_swap_chain: &Option<String>,
|
|
||||||
swap_chain_outputs: &'a HashMap<String, wgpu::SwapChainOutput>,
|
|
||||||
) -> wgpu::RenderPassDepthStencilAttachmentDescriptor<'a> {
|
|
||||||
let attachment = Self::get_texture_view(
|
|
||||||
wgpu_resources,
|
|
||||||
global_render_resource_assignments,
|
|
||||||
primary_swap_chain,
|
|
||||||
swap_chain_outputs,
|
|
||||||
depth_stencil_attachment_descriptor.attachment.as_str(),
|
|
||||||
);
|
|
||||||
|
|
||||||
wgpu::RenderPassDepthStencilAttachmentDescriptor {
|
|
||||||
attachment,
|
|
||||||
clear_depth: depth_stencil_attachment_descriptor.clear_depth,
|
|
||||||
clear_stencil: depth_stencil_attachment_descriptor.clear_stencil,
|
|
||||||
depth_load_op: depth_stencil_attachment_descriptor
|
|
||||||
.depth_load_op
|
|
||||||
.wgpu_into(),
|
|
||||||
depth_store_op: depth_stencil_attachment_descriptor
|
|
||||||
.depth_store_op
|
|
||||||
.wgpu_into(),
|
|
||||||
stencil_load_op: depth_stencil_attachment_descriptor
|
|
||||||
.stencil_load_op
|
|
||||||
.wgpu_into(),
|
|
||||||
stencil_store_op: depth_stencil_attachment_descriptor
|
|
||||||
.stencil_store_op
|
|
||||||
.wgpu_into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn initialize_resource_providers(
|
pub fn initialize_resource_providers(
|
||||||
world: &mut World,
|
world: &mut World,
|
||||||
resources: &mut Resources,
|
resources: &mut Resources,
|
||||||
@ -398,35 +252,6 @@ impl WgpuRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_swap_chain_outputs(
|
|
||||||
&mut self,
|
|
||||||
resources: &Resources,
|
|
||||||
) -> (Option<String>, HashMap<String, wgpu::SwapChainOutput>) {
|
|
||||||
let primary_window_id = resources
|
|
||||||
.get::<Windows>()
|
|
||||||
.unwrap()
|
|
||||||
.get_primary()
|
|
||||||
.map(|window| window.id);
|
|
||||||
let primary_swap_chain =
|
|
||||||
primary_window_id.map(|primary_window_id| primary_window_id.to_string());
|
|
||||||
let swap_chain_outputs = self
|
|
||||||
.global_context
|
|
||||||
.render_resources
|
|
||||||
.wgpu_resources
|
|
||||||
.window_swap_chains
|
|
||||||
.iter_mut()
|
|
||||||
// TODO: include non-primary swap chains
|
|
||||||
.filter(|(window_id, _swap_chain)| **window_id == primary_window_id.unwrap())
|
|
||||||
.map(|(window_id, swap_chain)| {
|
|
||||||
let swap_chain_texture = swap_chain
|
|
||||||
.get_next_texture()
|
|
||||||
.expect("Timeout when acquiring next swap chain texture");
|
|
||||||
(window_id.to_string(), swap_chain_texture)
|
|
||||||
})
|
|
||||||
.collect::<HashMap<String, wgpu::SwapChainOutput>>();
|
|
||||||
(primary_swap_chain, swap_chain_outputs)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update(&mut self, world: &mut World, resources: &mut Resources) {
|
pub fn update(&mut self, world: &mut World, resources: &mut Resources) {
|
||||||
Self::handle_window_created_events(
|
Self::handle_window_created_events(
|
||||||
resources,
|
resources,
|
||||||
@ -457,78 +282,80 @@ impl WgpuRenderer {
|
|||||||
&mut self.global_context.render_resources.wgpu_resources,
|
&mut self.global_context.render_resources.wgpu_resources,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.encoder = Some(
|
|
||||||
self.global_context
|
|
||||||
.device
|
|
||||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }),
|
|
||||||
);
|
|
||||||
update_shader_assignments(world, resources, &self.global_context);
|
update_shader_assignments(world, resources, &self.global_context);
|
||||||
self.create_queued_textures(resources);
|
self.create_queued_textures(resources);
|
||||||
let mut encoder = self.encoder.take().unwrap();
|
|
||||||
|
|
||||||
render_resource_sets_system().run(world, resources);
|
render_resource_sets_system().run(world, resources);
|
||||||
// setup draw targets
|
// setup draw targets
|
||||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
||||||
render_graph.setup_pipeline_draw_targets(world, resources, &mut self.global_context);
|
render_graph.setup_pipeline_draw_targets(world, resources, &mut self.global_context);
|
||||||
|
|
||||||
let (primary_swap_chain, swap_chain_outputs) = self.get_swap_chain_outputs(resources);
|
// get next swap chain texture on primary window
|
||||||
|
let primary_window_id = resources
|
||||||
|
.get::<Windows>()
|
||||||
|
.unwrap()
|
||||||
|
.get_primary()
|
||||||
|
.map(|window| window.id);
|
||||||
|
if let Some(primary_window_id) = primary_window_id {
|
||||||
|
self.global_context
|
||||||
|
.render_resources
|
||||||
|
.next_swap_chain_texture(primary_window_id);
|
||||||
|
self.global_context.primary_window = Some(primary_window_id);
|
||||||
|
}
|
||||||
|
|
||||||
// begin render passes
|
// begin render passes
|
||||||
let pipeline_storage = resources.get::<AssetStorage<PipelineDescriptor>>().unwrap();
|
let pipeline_storage = resources.get::<AssetStorage<PipelineDescriptor>>().unwrap();
|
||||||
let pipeline_compiler = resources.get::<PipelineCompiler>().unwrap();
|
let pipeline_compiler = resources.get::<PipelineCompiler>().unwrap();
|
||||||
|
|
||||||
for (pass_name, pass_descriptor) in render_graph.pass_descriptors.iter() {
|
for (pass_name, pass_descriptor) in render_graph.pass_descriptors.iter() {
|
||||||
let mut render_pass = {
|
let global_render_resource_assignments =
|
||||||
let global_render_resource_assignments =
|
resources.get::<RenderResourceAssignments>().unwrap();
|
||||||
resources.get::<RenderResourceAssignments>().unwrap();
|
self.global_context.begin_pass(
|
||||||
Self::create_render_pass(
|
pass_descriptor,
|
||||||
&self.global_context.render_resources.wgpu_resources,
|
&global_render_resource_assignments,
|
||||||
pass_descriptor,
|
&mut |render_pass| {
|
||||||
&global_render_resource_assignments,
|
if let Some(pass_pipelines) = render_graph.pass_pipelines.get(pass_name) {
|
||||||
&mut encoder,
|
for pass_pipeline in pass_pipelines.iter() {
|
||||||
&primary_swap_chain,
|
if let Some(compiled_pipelines_iter) =
|
||||||
&swap_chain_outputs,
|
pipeline_compiler.iter_compiled_pipelines(*pass_pipeline)
|
||||||
)
|
{
|
||||||
};
|
for compiled_pipeline_handle in compiled_pipelines_iter {
|
||||||
if let Some(pass_pipelines) = render_graph.pass_pipelines.get(pass_name) {
|
let pipeline_descriptor =
|
||||||
for pass_pipeline in pass_pipelines.iter() {
|
pipeline_storage.get(compiled_pipeline_handle).unwrap();
|
||||||
if let Some(compiled_pipelines_iter) =
|
render_pass.set_pipeline(*compiled_pipeline_handle);
|
||||||
pipeline_compiler.iter_compiled_pipelines(*pass_pipeline)
|
|
||||||
{
|
|
||||||
for compiled_pipeline_handle in compiled_pipelines_iter {
|
|
||||||
let pipeline_descriptor =
|
|
||||||
pipeline_storage.get(compiled_pipeline_handle).unwrap();
|
|
||||||
let render_pipeline = self
|
|
||||||
.global_context
|
|
||||||
.render_resources
|
|
||||||
.get_pipeline(*compiled_pipeline_handle)
|
|
||||||
.unwrap();
|
|
||||||
render_pass.set_pipeline(render_pipeline);
|
|
||||||
|
|
||||||
let mut wgpu_render_pass = WgpuRenderPass {
|
for draw_target_name in pipeline_descriptor.draw_targets.iter()
|
||||||
render_pass: &mut render_pass,
|
{
|
||||||
pipeline_descriptor,
|
let draw_target = render_graph
|
||||||
render_context: &self.global_context,
|
.draw_targets
|
||||||
bound_bind_groups: HashMap::default(),
|
.get(draw_target_name)
|
||||||
};
|
.unwrap();
|
||||||
|
draw_target.draw(
|
||||||
for draw_target_name in pipeline_descriptor.draw_targets.iter() {
|
world,
|
||||||
let draw_target =
|
resources,
|
||||||
render_graph.draw_targets.get(draw_target_name).unwrap();
|
render_pass,
|
||||||
draw_target.draw(
|
*compiled_pipeline_handle,
|
||||||
world,
|
pipeline_descriptor,
|
||||||
resources,
|
);
|
||||||
&mut wgpu_render_pass,
|
}
|
||||||
*compiled_pipeline_handle,
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let command_buffer = encoder.finish();
|
let command_buffer = self.global_context.finish_encoder();
|
||||||
self.queue.submit(&[command_buffer]);
|
if let Some(command_buffer) = command_buffer {
|
||||||
|
self.queue.submit(&[command_buffer]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear primary swap chain texture
|
||||||
|
if let Some(primary_window_id) = primary_window_id {
|
||||||
|
self.global_context
|
||||||
|
.render_resources
|
||||||
|
.drop_swap_chain_texture(primary_window_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ pub struct WgpuResources {
|
|||||||
pub asset_resources: AssetResources,
|
pub asset_resources: AssetResources,
|
||||||
pub window_surfaces: HashMap<WindowId, wgpu::Surface>,
|
pub window_surfaces: HashMap<WindowId, wgpu::Surface>,
|
||||||
pub window_swap_chains: HashMap<WindowId, wgpu::SwapChain>,
|
pub window_swap_chains: HashMap<WindowId, wgpu::SwapChain>,
|
||||||
|
pub swap_chain_outputs: HashMap<WindowId, wgpu::SwapChainOutput>,
|
||||||
pub buffers: HashMap<RenderResource, wgpu::Buffer>,
|
pub buffers: HashMap<RenderResource, wgpu::Buffer>,
|
||||||
pub textures: HashMap<RenderResource, wgpu::TextureView>,
|
pub textures: HashMap<RenderResource, wgpu::TextureView>,
|
||||||
pub samplers: HashMap<RenderResource, wgpu::Sampler>,
|
pub samplers: HashMap<RenderResource, wgpu::Sampler>,
|
||||||
@ -43,11 +44,14 @@ impl WgpuResources {
|
|||||||
self.window_surfaces.extend(wgpu_resources.window_surfaces);
|
self.window_surfaces.extend(wgpu_resources.window_surfaces);
|
||||||
self.window_swap_chains
|
self.window_swap_chains
|
||||||
.extend(wgpu_resources.window_swap_chains);
|
.extend(wgpu_resources.window_swap_chains);
|
||||||
|
self.swap_chain_outputs
|
||||||
|
.extend(wgpu_resources.swap_chain_outputs);
|
||||||
self.buffers.extend(wgpu_resources.buffers);
|
self.buffers.extend(wgpu_resources.buffers);
|
||||||
self.textures.extend(wgpu_resources.textures);
|
self.textures.extend(wgpu_resources.textures);
|
||||||
self.samplers.extend(wgpu_resources.samplers);
|
self.samplers.extend(wgpu_resources.samplers);
|
||||||
self.resource_info.extend(wgpu_resources.resource_info);
|
self.resource_info.extend(wgpu_resources.resource_info);
|
||||||
self.shader_modules.extend(wgpu_resources.shader_modules);
|
self.shader_modules.extend(wgpu_resources.shader_modules);
|
||||||
|
self.render_pipelines.extend(wgpu_resources.render_pipelines);
|
||||||
self.bind_groups.extend(wgpu_resources.bind_groups);
|
self.bind_groups.extend(wgpu_resources.bind_groups);
|
||||||
self.bind_group_layouts
|
self.bind_group_layouts
|
||||||
.extend(wgpu_resources.bind_group_layouts);
|
.extend(wgpu_resources.bind_group_layouts);
|
||||||
@ -61,6 +65,21 @@ impl WgpuResources {
|
|||||||
self.window_surfaces.get(&window_id)
|
self.window_surfaces.get(&window_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn next_swap_chain_texture(&mut self, window_id: WindowId) -> Option<&wgpu::SwapChainOutput> {
|
||||||
|
let swap_chain_output = self.window_swap_chains.get_mut(&window_id).unwrap();
|
||||||
|
let next_texture = swap_chain_output.get_next_texture().unwrap();
|
||||||
|
self.swap_chain_outputs.insert(window_id, next_texture);
|
||||||
|
self.swap_chain_outputs.get(&window_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_swap_chain_texture(&mut self, window_id: WindowId) {
|
||||||
|
self.swap_chain_outputs.remove(&window_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_all_swap_chain_textures(&mut self) {
|
||||||
|
self.swap_chain_outputs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_window_swap_chain(&mut self, device: &wgpu::Device, window: &Window) {
|
pub fn create_window_swap_chain(&mut self, device: &wgpu::Device, window: &Window) {
|
||||||
let swap_chain_descriptor: wgpu::SwapChainDescriptor = window.wgpu_into();
|
let swap_chain_descriptor: wgpu::SwapChainDescriptor = window.wgpu_into();
|
||||||
let surface = self
|
let surface = self
|
||||||
|
Loading…
Reference in New Issue
Block a user