refactor renderer to avoid resource access collisions. this fixes the legion errors in debug builds.
NOTE: these "random resource access" issues are a pretty compelling reason to remove Resources from the render api
This commit is contained in:
parent
6d53100ff3
commit
7bb889bada
@ -22,6 +22,7 @@ pub trait DrawTarget {
|
|||||||
_resources: &Resources,
|
_resources: &Resources,
|
||||||
_renderer: &mut dyn Renderer,
|
_renderer: &mut dyn Renderer,
|
||||||
_pipeline_handle: Handle<PipelineDescriptor>,
|
_pipeline_handle: Handle<PipelineDescriptor>,
|
||||||
|
_pipeline_descriptor: &PipelineDescriptor,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
fn get_name(&self) -> String;
|
fn get_name(&self) -> String;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
asset::{AssetStorage, Handle},
|
asset::Handle,
|
||||||
legion::prelude::*,
|
legion::prelude::*,
|
||||||
prelude::Renderable,
|
prelude::Renderable,
|
||||||
render::{
|
render::{
|
||||||
@ -68,17 +68,17 @@ impl DrawTarget for AssignedBatchesDrawTarget {
|
|||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
renderer: &mut dyn Renderer,
|
renderer: &mut dyn Renderer,
|
||||||
pipeline_handle: Handle<PipelineDescriptor>,
|
pipeline_handle: Handle<PipelineDescriptor>,
|
||||||
|
pipeline_descriptor: &PipelineDescriptor,
|
||||||
) {
|
) {
|
||||||
let mut asset_batches = resources.get_mut::<AssetBatchers>().unwrap();
|
let mut asset_batches = resources.get_mut::<AssetBatchers>().unwrap();
|
||||||
let pipeline_storage = resources.get::<AssetStorage<PipelineDescriptor>>().unwrap();
|
|
||||||
let pipeline_descriptor = pipeline_storage.get(&pipeline_handle).unwrap();
|
|
||||||
|
|
||||||
let mut global_render_resource_assignments =
|
let mut global_render_resource_assignments =
|
||||||
resources.get_mut::<RenderResourceAssignments>().unwrap();
|
resources.get_mut::<RenderResourceAssignments>().unwrap();
|
||||||
|
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"setting up batch bind groups for pipeline: {:?}",
|
"setting up batch bind groups for pipeline: {:?} {:?}",
|
||||||
pipeline_handle
|
pipeline_handle,
|
||||||
|
pipeline_descriptor.name,
|
||||||
);
|
);
|
||||||
log::trace!("setting up global bind groups");
|
log::trace!("setting up global bind groups");
|
||||||
renderer.setup_bind_groups(&mut global_render_resource_assignments, pipeline_descriptor);
|
renderer.setup_bind_groups(&mut global_render_resource_assignments, pipeline_descriptor);
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
asset::{AssetStorage, Handle},
|
asset::Handle,
|
||||||
legion::prelude::*,
|
legion::prelude::*,
|
||||||
render::{
|
render::{
|
||||||
draw_target::DrawTarget,
|
draw_target::DrawTarget,
|
||||||
@ -83,6 +83,7 @@ impl DrawTarget for AssignedMeshesDrawTarget {
|
|||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
renderer: &mut dyn Renderer,
|
renderer: &mut dyn Renderer,
|
||||||
pipeline_handle: Handle<PipelineDescriptor>,
|
pipeline_handle: Handle<PipelineDescriptor>,
|
||||||
|
pipeline_descriptor: &PipelineDescriptor,
|
||||||
) {
|
) {
|
||||||
let shader_pipeline_assignments = resources.get::<ShaderPipelineAssignments>().unwrap();
|
let shader_pipeline_assignments = resources.get::<ShaderPipelineAssignments>().unwrap();
|
||||||
let entity_render_resource_assignments =
|
let entity_render_resource_assignments =
|
||||||
@ -90,14 +91,11 @@ impl DrawTarget for AssignedMeshesDrawTarget {
|
|||||||
let assigned_render_resource_assignments = shader_pipeline_assignments
|
let assigned_render_resource_assignments = shader_pipeline_assignments
|
||||||
.assignments
|
.assignments
|
||||||
.get(&pipeline_handle);
|
.get(&pipeline_handle);
|
||||||
let pipeline_storage = resources.get::<AssetStorage<PipelineDescriptor>>().unwrap();
|
|
||||||
let pipeline_descriptor = pipeline_storage.get(&pipeline_handle).unwrap();
|
|
||||||
let mut global_render_resource_assignments =
|
let mut global_render_resource_assignments =
|
||||||
resources.get_mut::<RenderResourceAssignments>().unwrap();
|
resources.get_mut::<RenderResourceAssignments>().unwrap();
|
||||||
renderer.setup_bind_groups(&mut global_render_resource_assignments, pipeline_descriptor);
|
renderer.setup_bind_groups(&mut global_render_resource_assignments, pipeline_descriptor);
|
||||||
if let Some(assigned_render_resource_assignments) = assigned_render_resource_assignments {
|
if let Some(assigned_render_resource_assignments) = assigned_render_resource_assignments {
|
||||||
for assignment_id in assigned_render_resource_assignments.iter() {
|
for assignment_id in assigned_render_resource_assignments.iter() {
|
||||||
// TODO: hopefully legion has better random access apis that are more like queries?
|
|
||||||
let entity = entity_render_resource_assignments
|
let entity = entity_render_resource_assignments
|
||||||
.get(*assignment_id)
|
.get(*assignment_id)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
asset::{Asset, AssetStorage, Handle},
|
asset::{Asset, Handle},
|
||||||
legion::prelude::*,
|
legion::prelude::*,
|
||||||
math,
|
math,
|
||||||
prelude::MeshType,
|
prelude::MeshType,
|
||||||
@ -72,7 +72,8 @@ impl DrawTarget for UiDrawTarget {
|
|||||||
_world: &mut World,
|
_world: &mut World,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
renderer: &mut dyn Renderer,
|
renderer: &mut dyn Renderer,
|
||||||
pipeline_handle: Handle<PipelineDescriptor>,
|
_pipeline_handle: Handle<PipelineDescriptor>,
|
||||||
|
pipeline_descriptor: &PipelineDescriptor,
|
||||||
) {
|
) {
|
||||||
// don't create meshes if they have already been created
|
// don't create meshes if they have already been created
|
||||||
if let Some(_) = self.mesh_vertex_buffer {
|
if let Some(_) = self.mesh_vertex_buffer {
|
||||||
@ -100,8 +101,6 @@ impl DrawTarget for UiDrawTarget {
|
|||||||
|
|
||||||
let mut global_render_resource_assignments =
|
let mut global_render_resource_assignments =
|
||||||
resources.get_mut::<RenderResourceAssignments>().unwrap();
|
resources.get_mut::<RenderResourceAssignments>().unwrap();
|
||||||
let pipeline_storage = resources.get::<AssetStorage<PipelineDescriptor>>().unwrap();
|
|
||||||
let pipeline_descriptor = pipeline_storage.get(&pipeline_handle).unwrap();
|
|
||||||
renderer.setup_bind_groups(&mut global_render_resource_assignments, pipeline_descriptor);
|
renderer.setup_bind_groups(&mut global_render_resource_assignments, pipeline_descriptor);
|
||||||
}
|
}
|
||||||
fn get_name(&self) -> String {
|
fn get_name(&self) -> String {
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
use super::{BindType, PipelineDescriptor, PipelineLayout, PipelineLayoutType};
|
use super::{BindType, PipelineDescriptor, PipelineLayout, PipelineLayoutType, VertexBufferDescriptors};
|
||||||
use crate::{
|
use crate::{
|
||||||
asset::{AssetStorage, Handle},
|
asset::{AssetStorage, Handle},
|
||||||
prelude::{Renderable, Resources, Shader, World},
|
prelude::{Renderable, Resources, Shader, World},
|
||||||
render::{
|
render::{
|
||||||
render_graph::RenderGraph,
|
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BufferInfo, RenderResourceAssignments, RenderResourceAssignmentsId, ResourceInfo,
|
BufferInfo, RenderResourceAssignments, RenderResourceAssignmentsId, ResourceInfo,
|
||||||
},
|
},
|
||||||
@ -32,7 +31,7 @@ impl PipelineCompiler {
|
|||||||
|
|
||||||
fn reflect_layout(
|
fn reflect_layout(
|
||||||
shader_storage: &AssetStorage<Shader>,
|
shader_storage: &AssetStorage<Shader>,
|
||||||
render_graph: &RenderGraph,
|
vertex_buffer_descriptors: &VertexBufferDescriptors,
|
||||||
pipeline_descriptor: &mut PipelineDescriptor,
|
pipeline_descriptor: &mut PipelineDescriptor,
|
||||||
renderer: &dyn Renderer,
|
renderer: &dyn Renderer,
|
||||||
render_resource_assignments: &RenderResourceAssignments,
|
render_resource_assignments: &RenderResourceAssignments,
|
||||||
@ -52,7 +51,7 @@ impl PipelineCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut layout = PipelineLayout::from_shader_layouts(&mut layouts);
|
let mut layout = PipelineLayout::from_shader_layouts(&mut layouts);
|
||||||
layout.sync_vertex_buffer_descriptors_with_render_graph(render_graph);
|
layout.sync_vertex_buffer_descriptors(vertex_buffer_descriptors);
|
||||||
|
|
||||||
// set binding uniforms to dynamic if render resource assignments use dynamic
|
// set binding uniforms to dynamic if render resource assignments use dynamic
|
||||||
// TODO: this breaks down if different assignments have different "dynamic" status or if the dynamic status changes.
|
// TODO: this breaks down if different assignments have different "dynamic" status or if the dynamic status changes.
|
||||||
@ -113,7 +112,7 @@ impl PipelineCompiler {
|
|||||||
|
|
||||||
fn compile_pipeline(
|
fn compile_pipeline(
|
||||||
&mut self,
|
&mut self,
|
||||||
render_graph: &RenderGraph,
|
vertex_buffer_descriptors: &VertexBufferDescriptors,
|
||||||
shader_storage: &mut AssetStorage<Shader>,
|
shader_storage: &mut AssetStorage<Shader>,
|
||||||
renderer: &dyn Renderer,
|
renderer: &dyn Renderer,
|
||||||
pipeline_descriptor: &PipelineDescriptor,
|
pipeline_descriptor: &PipelineDescriptor,
|
||||||
@ -140,7 +139,7 @@ impl PipelineCompiler {
|
|||||||
|
|
||||||
Self::reflect_layout(
|
Self::reflect_layout(
|
||||||
shader_storage,
|
shader_storage,
|
||||||
render_graph,
|
vertex_buffer_descriptors,
|
||||||
&mut compiled_pipeline_descriptor,
|
&mut compiled_pipeline_descriptor,
|
||||||
renderer,
|
renderer,
|
||||||
render_resource_assignments,
|
render_resource_assignments,
|
||||||
@ -151,7 +150,7 @@ impl PipelineCompiler {
|
|||||||
|
|
||||||
fn update_shader_assignments(
|
fn update_shader_assignments(
|
||||||
&mut self,
|
&mut self,
|
||||||
render_graph: &RenderGraph,
|
vertex_buffer_descriptors: &VertexBufferDescriptors,
|
||||||
shader_pipeline_assignments: &mut ShaderPipelineAssignments,
|
shader_pipeline_assignments: &mut ShaderPipelineAssignments,
|
||||||
renderer: &dyn Renderer,
|
renderer: &dyn Renderer,
|
||||||
pipeline_storage: &mut AssetStorage<PipelineDescriptor>,
|
pipeline_storage: &mut AssetStorage<PipelineDescriptor>,
|
||||||
@ -177,7 +176,7 @@ impl PipelineCompiler {
|
|||||||
} else {
|
} else {
|
||||||
let pipeline_descriptor = pipeline_storage.get(pipeline_handle).unwrap();
|
let pipeline_descriptor = pipeline_storage.get(pipeline_handle).unwrap();
|
||||||
let compiled_pipeline = self.compile_pipeline(
|
let compiled_pipeline = self.compile_pipeline(
|
||||||
render_graph,
|
vertex_buffer_descriptors,
|
||||||
shader_storage,
|
shader_storage,
|
||||||
renderer,
|
renderer,
|
||||||
pipeline_descriptor,
|
pipeline_descriptor,
|
||||||
@ -248,7 +247,7 @@ pub fn update_shader_assignments(
|
|||||||
resources.get_mut::<ShaderPipelineAssignments>().unwrap();
|
resources.get_mut::<ShaderPipelineAssignments>().unwrap();
|
||||||
let mut pipeline_compiler = resources.get_mut::<PipelineCompiler>().unwrap();
|
let mut pipeline_compiler = resources.get_mut::<PipelineCompiler>().unwrap();
|
||||||
let mut shader_storage = resources.get_mut::<AssetStorage<Shader>>().unwrap();
|
let mut shader_storage = resources.get_mut::<AssetStorage<Shader>>().unwrap();
|
||||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
let vertex_buffer_descriptors = resources.get::<VertexBufferDescriptors>().unwrap();
|
||||||
let mut pipeline_descriptor_storage = resources
|
let mut pipeline_descriptor_storage = resources
|
||||||
.get_mut::<AssetStorage<PipelineDescriptor>>()
|
.get_mut::<AssetStorage<PipelineDescriptor>>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -264,7 +263,7 @@ pub fn update_shader_assignments(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pipeline_compiler.update_shader_assignments(
|
pipeline_compiler.update_shader_assignments(
|
||||||
&mut render_graph,
|
&vertex_buffer_descriptors,
|
||||||
&mut shader_pipeline_assignments,
|
&mut shader_pipeline_assignments,
|
||||||
renderer,
|
renderer,
|
||||||
&mut pipeline_descriptor_storage,
|
&mut pipeline_descriptor_storage,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use super::{BindGroupDescriptor, VertexBufferDescriptor};
|
use super::{BindGroupDescriptor, VertexBufferDescriptor, VertexBufferDescriptors};
|
||||||
use crate::render::{render_graph::RenderGraph, shader::ShaderLayout};
|
use crate::render::shader::ShaderLayout;
|
||||||
use std::{collections::HashMap, hash::Hash};
|
use std::{collections::HashMap, hash::Hash};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
@ -56,10 +56,13 @@ impl PipelineLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sync_vertex_buffer_descriptors_with_render_graph(&mut self, render_graph: &RenderGraph) {
|
pub fn sync_vertex_buffer_descriptors(
|
||||||
|
&mut self,
|
||||||
|
vertex_buffer_descriptors: &VertexBufferDescriptors,
|
||||||
|
) {
|
||||||
for vertex_buffer_descriptor in self.vertex_buffer_descriptors.iter_mut() {
|
for vertex_buffer_descriptor in self.vertex_buffer_descriptors.iter_mut() {
|
||||||
if let Some(graph_descriptor) =
|
if let Some(graph_descriptor) =
|
||||||
render_graph.get_vertex_buffer_descriptor(&vertex_buffer_descriptor.name)
|
vertex_buffer_descriptors.get(&vertex_buffer_descriptor.name)
|
||||||
{
|
{
|
||||||
vertex_buffer_descriptor.sync_with_descriptor(graph_descriptor);
|
vertex_buffer_descriptor.sync_with_descriptor(graph_descriptor);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
use super::VertexFormat;
|
use super::VertexFormat;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct VertexBufferDescriptor {
|
pub struct VertexBufferDescriptor {
|
||||||
@ -41,3 +42,21 @@ pub struct VertexAttributeDescriptor {
|
|||||||
pub format: VertexFormat,
|
pub format: VertexFormat,
|
||||||
pub shader_location: u32,
|
pub shader_location: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct VertexBufferDescriptors {
|
||||||
|
pub descriptors: HashMap<String, VertexBufferDescriptor>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VertexBufferDescriptors {
|
||||||
|
pub fn set(&mut self, vertex_buffer_descriptor: VertexBufferDescriptor) {
|
||||||
|
self.descriptors.insert(
|
||||||
|
vertex_buffer_descriptor.name.to_string(),
|
||||||
|
vertex_buffer_descriptor,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, name: &str) -> Option<&VertexBufferDescriptor> {
|
||||||
|
self.descriptors.get(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
use super::RenderGraphBuilder;
|
use super::RenderGraphBuilder;
|
||||||
use crate::{
|
use crate::{
|
||||||
asset::{AssetStorage, Handle},
|
asset::{AssetStorage, Handle},
|
||||||
prelude::Shader,
|
prelude::{Resources, Shader, World},
|
||||||
render::{
|
render::{
|
||||||
draw_target::DrawTarget,
|
draw_target::DrawTarget,
|
||||||
pass::PassDescriptor,
|
pass::PassDescriptor,
|
||||||
pipeline::{PipelineDescriptor, VertexBufferDescriptor},
|
pipeline::{PipelineCompiler, PipelineDescriptor},
|
||||||
render_resource::ResourceProvider,
|
render_resource::ResourceProvider,
|
||||||
|
renderer::Renderer,
|
||||||
texture::TextureDescriptor,
|
texture::TextureDescriptor,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -21,7 +22,6 @@ pub struct RenderGraph {
|
|||||||
pub resource_providers: Vec<Box<dyn ResourceProvider + Send + Sync>>,
|
pub resource_providers: Vec<Box<dyn ResourceProvider + Send + Sync>>,
|
||||||
pub queued_textures: Vec<(String, TextureDescriptor)>,
|
pub queued_textures: Vec<(String, TextureDescriptor)>,
|
||||||
pub draw_targets: HashMap<String, Box<dyn DrawTarget + Send + Sync>>,
|
pub draw_targets: HashMap<String, Box<dyn DrawTarget + Send + Sync>>,
|
||||||
pub vertex_buffer_descriptors: HashMap<String, VertexBufferDescriptor>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderGraph {
|
impl RenderGraph {
|
||||||
@ -49,17 +49,52 @@ impl RenderGraph {
|
|||||||
pass_pipelines.push(pipeline);
|
pass_pipelines.push(pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_vertex_buffer_descriptor(
|
pub fn setup_pipeline_draw_targets(
|
||||||
&mut self,
|
&mut self,
|
||||||
vertex_buffer_descriptor: VertexBufferDescriptor,
|
world: &mut World,
|
||||||
|
resources: &Resources,
|
||||||
|
renderer: &mut dyn Renderer,
|
||||||
) {
|
) {
|
||||||
self.vertex_buffer_descriptors.insert(
|
let shader_storage = resources.get::<AssetStorage<Shader>>().unwrap();
|
||||||
vertex_buffer_descriptor.name.to_string(),
|
let pipeline_compiler = resources.get::<PipelineCompiler>().unwrap();
|
||||||
vertex_buffer_descriptor,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_vertex_buffer_descriptor(&self, name: &str) -> Option<&VertexBufferDescriptor> {
|
for (pass_name, _pass_descriptor) in self.pass_descriptors.iter() {
|
||||||
self.vertex_buffer_descriptors.get(name)
|
if let Some(pass_pipelines) = self.pass_pipelines.get(pass_name) {
|
||||||
|
for pass_pipeline in pass_pipelines.iter() {
|
||||||
|
if let Some(compiled_pipelines_iter) =
|
||||||
|
pipeline_compiler.iter_compiled_pipelines(*pass_pipeline)
|
||||||
|
{
|
||||||
|
for compiled_pipeline_handle in compiled_pipelines_iter {
|
||||||
|
let mut pipeline_storage = resources
|
||||||
|
.get_mut::<AssetStorage<PipelineDescriptor>>()
|
||||||
|
.unwrap();
|
||||||
|
let compiled_pipeline_descriptor =
|
||||||
|
pipeline_storage.get_mut(compiled_pipeline_handle).unwrap();
|
||||||
|
|
||||||
|
// create wgpu pipeline if it doesn't exist
|
||||||
|
renderer.setup_render_pipeline(
|
||||||
|
*compiled_pipeline_handle,
|
||||||
|
compiled_pipeline_descriptor,
|
||||||
|
&shader_storage,
|
||||||
|
);
|
||||||
|
|
||||||
|
// setup pipeline draw targets
|
||||||
|
for draw_target_name in compiled_pipeline_descriptor.draw_targets.iter()
|
||||||
|
{
|
||||||
|
let draw_target =
|
||||||
|
self.draw_targets.get_mut(draw_target_name).unwrap();
|
||||||
|
draw_target.setup(
|
||||||
|
world,
|
||||||
|
resources,
|
||||||
|
renderer,
|
||||||
|
*compiled_pipeline_handle,
|
||||||
|
compiled_pipeline_descriptor,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use super::{
|
|||||||
AssignedBatchesDrawTarget, AssignedMeshesDrawTarget, MeshesDrawTarget, UiDrawTarget,
|
AssignedBatchesDrawTarget, AssignedMeshesDrawTarget, MeshesDrawTarget, UiDrawTarget,
|
||||||
},
|
},
|
||||||
pass::passes::ForwardPassBuilder,
|
pass::passes::ForwardPassBuilder,
|
||||||
pipeline::{pipelines::ForwardPipelineBuilder, PipelineCompiler, ShaderPipelineAssignments},
|
pipeline::{pipelines::ForwardPipelineBuilder, PipelineCompiler, ShaderPipelineAssignments, VertexBufferDescriptors},
|
||||||
render_graph::RenderGraph,
|
render_graph::RenderGraph,
|
||||||
render_resource::{
|
render_resource::{
|
||||||
build_entity_render_resource_assignments_system,
|
build_entity_render_resource_assignments_system,
|
||||||
@ -62,6 +62,7 @@ impl AppPlugin for RenderPlugin {
|
|||||||
.add_resource(AssetStorage::<StandardMaterial>::new())
|
.add_resource(AssetStorage::<StandardMaterial>::new())
|
||||||
.add_resource(AssetStorage::<PipelineDescriptor>::new())
|
.add_resource(AssetStorage::<PipelineDescriptor>::new())
|
||||||
.add_resource(ShaderPipelineAssignments::new())
|
.add_resource(ShaderPipelineAssignments::new())
|
||||||
|
.add_resource(VertexBufferDescriptors::default())
|
||||||
.add_resource(PipelineCompiler::new())
|
.add_resource(PipelineCompiler::new())
|
||||||
.add_resource(RenderResourceAssignments::default())
|
.add_resource(RenderResourceAssignments::default())
|
||||||
.add_resource(EntityRenderResourceAssignments::default())
|
.add_resource(EntityRenderResourceAssignments::default())
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use crate::{
|
|||||||
prelude::Renderable,
|
prelude::Renderable,
|
||||||
render::{
|
render::{
|
||||||
mesh::Mesh,
|
mesh::Mesh,
|
||||||
render_graph::RenderGraph,
|
pipeline::VertexBufferDescriptors,
|
||||||
render_resource::{
|
render_resource::{
|
||||||
AssetBatchers, BufferInfo, BufferUsage, RenderResourceAssignments, ResourceProvider,
|
AssetBatchers, BufferInfo, BufferUsage, RenderResourceAssignments, ResourceProvider,
|
||||||
},
|
},
|
||||||
@ -92,9 +92,8 @@ impl ResourceProvider for MeshResourceProvider {
|
|||||||
_world: &mut World,
|
_world: &mut World,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
) {
|
) {
|
||||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
let mut vertex_buffer_descriptors = resources.get_mut::<VertexBufferDescriptors>().unwrap();
|
||||||
render_graph
|
vertex_buffer_descriptors.set(Vertex::get_vertex_buffer_descriptor().cloned().unwrap());
|
||||||
.set_vertex_buffer_descriptor(Vertex::get_vertex_buffer_descriptor().cloned().unwrap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, _renderer: &mut dyn Renderer, world: &mut World, resources: &Resources) {
|
fn update(&mut self, _renderer: &mut dyn Renderer, world: &mut World, resources: &Resources) {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use crate::{
|
|||||||
ecs,
|
ecs,
|
||||||
prelude::Node,
|
prelude::Node,
|
||||||
render::{
|
render::{
|
||||||
render_graph::RenderGraph,
|
pipeline::VertexBufferDescriptors,
|
||||||
render_resource::{
|
render_resource::{
|
||||||
resource_name, BufferArrayInfo, BufferInfo, BufferUsage, RenderResource,
|
resource_name, BufferArrayInfo, BufferInfo, BufferUsage, RenderResource,
|
||||||
RenderResourceAssignments, ResourceProvider,
|
RenderResourceAssignments, ResourceProvider,
|
||||||
@ -113,9 +113,8 @@ impl ResourceProvider for UiResourceProvider {
|
|||||||
_world: &mut World,
|
_world: &mut World,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
) {
|
) {
|
||||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
let mut vertex_buffer_descriptors = resources.get_mut::<VertexBufferDescriptors>().unwrap();
|
||||||
render_graph
|
vertex_buffer_descriptors.set(Rect::get_vertex_buffer_descriptor().cloned().unwrap());
|
||||||
.set_vertex_buffer_descriptor(Rect::get_vertex_buffer_descriptor().cloned().unwrap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, renderer: &mut dyn Renderer, world: &mut World, resources: &Resources) {
|
fn update(&mut self, renderer: &mut dyn Renderer, world: &mut World, resources: &Resources) {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
asset::{AssetStorage, Handle},
|
asset::{AssetStorage, Handle},
|
||||||
render::{
|
render::{
|
||||||
render_graph::RenderGraph,
|
pipeline::VertexBufferDescriptors,
|
||||||
render_resource::{
|
render_resource::{
|
||||||
AssetBatchers, BufferArrayInfo, BufferInfo, BufferUsage, RenderResource,
|
AssetBatchers, BufferArrayInfo, BufferInfo, BufferUsage, RenderResource,
|
||||||
RenderResourceAssignments, ResourceInfo, ResourceProvider,
|
RenderResourceAssignments, ResourceInfo, ResourceProvider,
|
||||||
@ -543,12 +543,14 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize_vertex_buffer_descriptor(&self, render_graph: &mut RenderGraph) {
|
fn initialize_vertex_buffer_descriptor(
|
||||||
|
&self,
|
||||||
|
vertex_buffer_descriptors: &mut VertexBufferDescriptors,
|
||||||
|
) {
|
||||||
let vertex_buffer_descriptor = T::get_vertex_buffer_descriptor();
|
let vertex_buffer_descriptor = T::get_vertex_buffer_descriptor();
|
||||||
if let Some(vertex_buffer_descriptor) = vertex_buffer_descriptor {
|
if let Some(vertex_buffer_descriptor) = vertex_buffer_descriptor {
|
||||||
if let None = render_graph.get_vertex_buffer_descriptor(&vertex_buffer_descriptor.name)
|
if let None = vertex_buffer_descriptors.get(&vertex_buffer_descriptor.name) {
|
||||||
{
|
vertex_buffer_descriptors.set(vertex_buffer_descriptor.clone());
|
||||||
render_graph.set_vertex_buffer_descriptor(vertex_buffer_descriptor.clone());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -601,8 +603,8 @@ where
|
|||||||
world: &mut World,
|
world: &mut World,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
) {
|
) {
|
||||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
let mut vertex_buffer_descriptors = resources.get_mut::<VertexBufferDescriptors>().unwrap();
|
||||||
self.initialize_vertex_buffer_descriptor(&mut render_graph);
|
self.initialize_vertex_buffer_descriptor(&mut vertex_buffer_descriptors);
|
||||||
self.update(renderer, world, resources);
|
self.update(renderer, world, resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
|
asset::{AssetStorage, Handle},
|
||||||
legion::prelude::*,
|
legion::prelude::*,
|
||||||
render::{
|
render::{
|
||||||
pipeline::PipelineDescriptor,
|
pipeline::PipelineDescriptor,
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BufferInfo, RenderResource, RenderResourceAssignments, RenderResources, ResourceInfo,
|
BufferInfo, RenderResource, RenderResourceAssignments, RenderResources, ResourceInfo,
|
||||||
},
|
},
|
||||||
|
shader::Shader,
|
||||||
texture::{SamplerDescriptor, TextureDescriptor},
|
texture::{SamplerDescriptor, TextureDescriptor},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -40,6 +42,12 @@ pub trait Renderer {
|
|||||||
);
|
);
|
||||||
fn get_render_resources(&self) -> &RenderResources;
|
fn get_render_resources(&self) -> &RenderResources;
|
||||||
fn get_render_resources_mut(&mut self) -> &mut RenderResources;
|
fn get_render_resources_mut(&mut self) -> &mut RenderResources;
|
||||||
|
fn setup_render_pipeline(
|
||||||
|
&mut self,
|
||||||
|
pipeline_handle: Handle<PipelineDescriptor>,
|
||||||
|
pipeline_descriptor: &mut PipelineDescriptor,
|
||||||
|
shader_storage: &AssetStorage<Shader>,
|
||||||
|
);
|
||||||
fn setup_bind_groups(
|
fn setup_bind_groups(
|
||||||
&mut self,
|
&mut self,
|
||||||
render_resource_assignments: &mut RenderResourceAssignments,
|
render_resource_assignments: &mut RenderResourceAssignments,
|
||||||
|
|||||||
@ -82,143 +82,10 @@ impl WgpuRenderer {
|
|||||||
self.intialized = true;
|
self.intialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_render_pipeline(
|
pub fn create_render_pass<'a, 'b>(
|
||||||
&mut self,
|
|
||||||
pipeline_handle: Handle<PipelineDescriptor>,
|
|
||||||
pipeline_descriptor: &mut PipelineDescriptor,
|
|
||||||
shader_storage: &AssetStorage<Shader>,
|
|
||||||
) {
|
|
||||||
let device = self.device.borrow();
|
|
||||||
let layout = pipeline_descriptor.get_layout().unwrap();
|
|
||||||
for bind_group in layout.bind_groups.iter() {
|
|
||||||
if let None = self.wgpu_resources.bind_group_layouts.get(&bind_group.id) {
|
|
||||||
let bind_group_layout_binding = bind_group
|
|
||||||
.bindings
|
|
||||||
.iter()
|
|
||||||
.map(|binding| wgpu::BindGroupLayoutEntry {
|
|
||||||
binding: binding.index,
|
|
||||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
|
||||||
ty: (&binding.bind_type).into(),
|
|
||||||
})
|
|
||||||
.collect::<Vec<wgpu::BindGroupLayoutEntry>>();
|
|
||||||
let wgpu_bind_group_layout =
|
|
||||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
|
||||||
bindings: bind_group_layout_binding.as_slice(),
|
|
||||||
});
|
|
||||||
|
|
||||||
self.wgpu_resources
|
|
||||||
.bind_group_layouts
|
|
||||||
.insert(bind_group.id, wgpu_bind_group_layout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup and collect bind group layouts
|
|
||||||
let bind_group_layouts = layout
|
|
||||||
.bind_groups
|
|
||||||
.iter()
|
|
||||||
.map(|bind_group| {
|
|
||||||
self.wgpu_resources
|
|
||||||
.bind_group_layouts
|
|
||||||
.get(&bind_group.id)
|
|
||||||
.unwrap()
|
|
||||||
})
|
|
||||||
.collect::<Vec<&wgpu::BindGroupLayout>>();
|
|
||||||
|
|
||||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
|
||||||
bind_group_layouts: bind_group_layouts.as_slice(),
|
|
||||||
});
|
|
||||||
|
|
||||||
let owned_vertex_buffer_descriptors = layout
|
|
||||||
.vertex_buffer_descriptors
|
|
||||||
.iter()
|
|
||||||
.map(|v| v.into())
|
|
||||||
.collect::<Vec<OwnedWgpuVertexBufferDescriptor>>();
|
|
||||||
|
|
||||||
let color_states = pipeline_descriptor
|
|
||||||
.color_states
|
|
||||||
.iter()
|
|
||||||
.map(|c| c.into())
|
|
||||||
.collect::<Vec<wgpu::ColorStateDescriptor>>();
|
|
||||||
|
|
||||||
if let None = self
|
|
||||||
.wgpu_resources
|
|
||||||
.shader_modules
|
|
||||||
.get(&pipeline_descriptor.shader_stages.vertex)
|
|
||||||
{
|
|
||||||
self.wgpu_resources.create_shader_module(
|
|
||||||
&device,
|
|
||||||
pipeline_descriptor.shader_stages.vertex,
|
|
||||||
shader_storage,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(fragment_handle) = pipeline_descriptor.shader_stages.fragment {
|
|
||||||
if let None = self.wgpu_resources.shader_modules.get(&fragment_handle) {
|
|
||||||
self.wgpu_resources
|
|
||||||
.create_shader_module(&device, fragment_handle, shader_storage);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let vertex_shader_module = self
|
|
||||||
.wgpu_resources
|
|
||||||
.shader_modules
|
|
||||||
.get(&pipeline_descriptor.shader_stages.vertex)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let fragment_shader_module = match pipeline_descriptor.shader_stages.fragment {
|
|
||||||
Some(fragment_handle) => Some(
|
|
||||||
self.wgpu_resources
|
|
||||||
.shader_modules
|
|
||||||
.get(&fragment_handle)
|
|
||||||
.unwrap(),
|
|
||||||
),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut render_pipeline_descriptor = wgpu::RenderPipelineDescriptor {
|
|
||||||
layout: &pipeline_layout,
|
|
||||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
|
||||||
module: &vertex_shader_module,
|
|
||||||
entry_point: "main",
|
|
||||||
},
|
|
||||||
fragment_stage: match pipeline_descriptor.shader_stages.fragment {
|
|
||||||
Some(_) => Some(wgpu::ProgrammableStageDescriptor {
|
|
||||||
entry_point: "main",
|
|
||||||
module: fragment_shader_module.as_ref().unwrap(),
|
|
||||||
}),
|
|
||||||
None => None,
|
|
||||||
},
|
|
||||||
rasterization_state: pipeline_descriptor
|
|
||||||
.rasterization_state
|
|
||||||
.as_ref()
|
|
||||||
.map(|r| r.into()),
|
|
||||||
primitive_topology: pipeline_descriptor.primitive_topology.into(),
|
|
||||||
color_states: &color_states,
|
|
||||||
depth_stencil_state: pipeline_descriptor
|
|
||||||
.depth_stencil_state
|
|
||||||
.as_ref()
|
|
||||||
.map(|d| d.into()),
|
|
||||||
vertex_state: wgpu::VertexStateDescriptor {
|
|
||||||
index_format: pipeline_descriptor.index_format.into(),
|
|
||||||
vertex_buffers: &owned_vertex_buffer_descriptors
|
|
||||||
.iter()
|
|
||||||
.map(|v| v.into())
|
|
||||||
.collect::<Vec<wgpu::VertexBufferDescriptor>>(),
|
|
||||||
},
|
|
||||||
sample_count: pipeline_descriptor.sample_count,
|
|
||||||
sample_mask: pipeline_descriptor.sample_mask,
|
|
||||||
alpha_to_coverage_enabled: pipeline_descriptor.alpha_to_coverage_enabled,
|
|
||||||
};
|
|
||||||
|
|
||||||
let render_pipeline = device.create_render_pipeline(&mut render_pipeline_descriptor);
|
|
||||||
self.render_pipelines
|
|
||||||
.insert(pipeline_handle, render_pipeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_render_pass<'a>(
|
|
||||||
wgpu_resources: &'a WgpuResources,
|
wgpu_resources: &'a WgpuResources,
|
||||||
pass_descriptor: &PassDescriptor,
|
pass_descriptor: &PassDescriptor,
|
||||||
global_render_resource_assignments: &RenderResourceAssignments,
|
global_render_resource_assignments: &'b RenderResourceAssignments,
|
||||||
encoder: &'a mut wgpu::CommandEncoder,
|
encoder: &'a mut wgpu::CommandEncoder,
|
||||||
primary_swap_chain: &Option<String>,
|
primary_swap_chain: &Option<String>,
|
||||||
swap_chain_outputs: &'a HashMap<String, wgpu::SwapChainOutput>,
|
swap_chain_outputs: &'a HashMap<String, wgpu::SwapChainOutput>,
|
||||||
@ -344,12 +211,13 @@ impl WgpuRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn initialize_resource_providers(&mut self, world: &mut World, resources: &mut Resources) {
|
pub fn initialize_resource_providers(&mut self, world: &mut World, resources: &mut Resources) {
|
||||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
|
||||||
self.encoder = Some(
|
self.encoder = Some(
|
||||||
self.device
|
self.device
|
||||||
.borrow()
|
.borrow()
|
||||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }),
|
.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
||||||
for resource_provider in render_graph.resource_providers.iter_mut() {
|
for resource_provider in render_graph.resource_providers.iter_mut() {
|
||||||
resource_provider.initialize(self, world, resources);
|
resource_provider.initialize(self, world, resources);
|
||||||
}
|
}
|
||||||
@ -491,68 +359,29 @@ impl Renderer for WgpuRenderer {
|
|||||||
|
|
||||||
let mut encoder = self.encoder.take().unwrap();
|
let mut encoder = self.encoder.take().unwrap();
|
||||||
|
|
||||||
let mut pipeline_storage = resources
|
|
||||||
.get_mut::<AssetStorage<PipelineDescriptor>>()
|
|
||||||
.unwrap();
|
|
||||||
let shader_storage = resources.get::<AssetStorage<Shader>>().unwrap();
|
|
||||||
let render_graph = resources.get::<RenderGraph>().unwrap();
|
|
||||||
let mut render_graph_mut = resources.get_mut::<RenderGraph>().unwrap();
|
|
||||||
let global_render_resource_assignments =
|
|
||||||
resources.get::<RenderResourceAssignments>().unwrap();
|
|
||||||
let pipeline_compiler = resources.get::<PipelineCompiler>().unwrap();
|
|
||||||
|
|
||||||
// setup draw targets
|
// setup draw targets
|
||||||
for (pass_name, _pass_descriptor) in render_graph.pass_descriptors.iter() {
|
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
||||||
if let Some(pass_pipelines) = render_graph.pass_pipelines.get(pass_name) {
|
render_graph.setup_pipeline_draw_targets(world, resources, self);
|
||||||
for pass_pipeline in pass_pipelines.iter() {
|
|
||||||
if let Some(compiled_pipelines_iter) =
|
|
||||||
pipeline_compiler.iter_compiled_pipelines(*pass_pipeline)
|
|
||||||
{
|
|
||||||
for compiled_pipeline_handle in compiled_pipelines_iter {
|
|
||||||
let compiled_pipeline_descriptor =
|
|
||||||
pipeline_storage.get_mut(compiled_pipeline_handle).unwrap();
|
|
||||||
|
|
||||||
// create wgpu pipeline if it doesn't exist
|
|
||||||
if !self.render_pipelines.contains_key(compiled_pipeline_handle) {
|
|
||||||
self.create_render_pipeline(
|
|
||||||
*compiled_pipeline_handle,
|
|
||||||
compiled_pipeline_descriptor,
|
|
||||||
&shader_storage,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup pipeline draw targets
|
|
||||||
for draw_target_name in compiled_pipeline_descriptor.draw_targets.iter()
|
|
||||||
{
|
|
||||||
let draw_target = render_graph_mut
|
|
||||||
.draw_targets
|
|
||||||
.get_mut(draw_target_name)
|
|
||||||
.unwrap();
|
|
||||||
draw_target.setup(
|
|
||||||
world,
|
|
||||||
resources,
|
|
||||||
self,
|
|
||||||
*compiled_pipeline_handle,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let (primary_swap_chain, swap_chain_outputs) = self.get_swap_chain_outputs(resources);
|
let (primary_swap_chain, swap_chain_outputs) = self.get_swap_chain_outputs(resources);
|
||||||
|
|
||||||
// begin render passes
|
// begin render passes
|
||||||
|
let pipeline_storage = resources.get::<AssetStorage<PipelineDescriptor>>().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 = Self::create_render_pass(
|
let mut render_pass = {
|
||||||
&self.wgpu_resources,
|
let global_render_resource_assignments =
|
||||||
pass_descriptor,
|
resources.get::<RenderResourceAssignments>().unwrap();
|
||||||
&global_render_resource_assignments,
|
Self::create_render_pass(
|
||||||
&mut encoder,
|
&self.wgpu_resources,
|
||||||
&primary_swap_chain,
|
pass_descriptor,
|
||||||
&swap_chain_outputs,
|
&global_render_resource_assignments,
|
||||||
);
|
&mut encoder,
|
||||||
|
&primary_swap_chain,
|
||||||
|
&swap_chain_outputs,
|
||||||
|
)
|
||||||
|
};
|
||||||
if let Some(pass_pipelines) = render_graph.pass_pipelines.get(pass_name) {
|
if let Some(pass_pipelines) = render_graph.pass_pipelines.get(pass_name) {
|
||||||
for pass_pipeline in pass_pipelines.iter() {
|
for pass_pipeline in pass_pipelines.iter() {
|
||||||
if let Some(compiled_pipelines_iter) =
|
if let Some(compiled_pipelines_iter) =
|
||||||
@ -705,4 +534,141 @@ impl Renderer for WgpuRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn setup_render_pipeline(
|
||||||
|
&mut self,
|
||||||
|
pipeline_handle: Handle<PipelineDescriptor>,
|
||||||
|
pipeline_descriptor: &mut PipelineDescriptor,
|
||||||
|
shader_storage: &AssetStorage<Shader>,
|
||||||
|
) {
|
||||||
|
if self.render_pipelines.contains_key(&pipeline_handle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let device = self.device.borrow();
|
||||||
|
let layout = pipeline_descriptor.get_layout().unwrap();
|
||||||
|
for bind_group in layout.bind_groups.iter() {
|
||||||
|
if let None = self.wgpu_resources.bind_group_layouts.get(&bind_group.id) {
|
||||||
|
let bind_group_layout_binding = bind_group
|
||||||
|
.bindings
|
||||||
|
.iter()
|
||||||
|
.map(|binding| wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: binding.index,
|
||||||
|
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||||
|
ty: (&binding.bind_type).into(),
|
||||||
|
})
|
||||||
|
.collect::<Vec<wgpu::BindGroupLayoutEntry>>();
|
||||||
|
let wgpu_bind_group_layout =
|
||||||
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
bindings: bind_group_layout_binding.as_slice(),
|
||||||
|
});
|
||||||
|
|
||||||
|
self.wgpu_resources
|
||||||
|
.bind_group_layouts
|
||||||
|
.insert(bind_group.id, wgpu_bind_group_layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup and collect bind group layouts
|
||||||
|
let bind_group_layouts = layout
|
||||||
|
.bind_groups
|
||||||
|
.iter()
|
||||||
|
.map(|bind_group| {
|
||||||
|
self.wgpu_resources
|
||||||
|
.bind_group_layouts
|
||||||
|
.get(&bind_group.id)
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
|
.collect::<Vec<&wgpu::BindGroupLayout>>();
|
||||||
|
|
||||||
|
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
|
bind_group_layouts: bind_group_layouts.as_slice(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let owned_vertex_buffer_descriptors = layout
|
||||||
|
.vertex_buffer_descriptors
|
||||||
|
.iter()
|
||||||
|
.map(|v| v.into())
|
||||||
|
.collect::<Vec<OwnedWgpuVertexBufferDescriptor>>();
|
||||||
|
|
||||||
|
let color_states = pipeline_descriptor
|
||||||
|
.color_states
|
||||||
|
.iter()
|
||||||
|
.map(|c| c.into())
|
||||||
|
.collect::<Vec<wgpu::ColorStateDescriptor>>();
|
||||||
|
|
||||||
|
if let None = self
|
||||||
|
.wgpu_resources
|
||||||
|
.shader_modules
|
||||||
|
.get(&pipeline_descriptor.shader_stages.vertex)
|
||||||
|
{
|
||||||
|
self.wgpu_resources.create_shader_module(
|
||||||
|
&device,
|
||||||
|
pipeline_descriptor.shader_stages.vertex,
|
||||||
|
shader_storage,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(fragment_handle) = pipeline_descriptor.shader_stages.fragment {
|
||||||
|
if let None = self.wgpu_resources.shader_modules.get(&fragment_handle) {
|
||||||
|
self.wgpu_resources
|
||||||
|
.create_shader_module(&device, fragment_handle, shader_storage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let vertex_shader_module = self
|
||||||
|
.wgpu_resources
|
||||||
|
.shader_modules
|
||||||
|
.get(&pipeline_descriptor.shader_stages.vertex)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let fragment_shader_module = match pipeline_descriptor.shader_stages.fragment {
|
||||||
|
Some(fragment_handle) => Some(
|
||||||
|
self.wgpu_resources
|
||||||
|
.shader_modules
|
||||||
|
.get(&fragment_handle)
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut render_pipeline_descriptor = wgpu::RenderPipelineDescriptor {
|
||||||
|
layout: &pipeline_layout,
|
||||||
|
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||||
|
module: &vertex_shader_module,
|
||||||
|
entry_point: "main",
|
||||||
|
},
|
||||||
|
fragment_stage: match pipeline_descriptor.shader_stages.fragment {
|
||||||
|
Some(_) => Some(wgpu::ProgrammableStageDescriptor {
|
||||||
|
entry_point: "main",
|
||||||
|
module: fragment_shader_module.as_ref().unwrap(),
|
||||||
|
}),
|
||||||
|
None => None,
|
||||||
|
},
|
||||||
|
rasterization_state: pipeline_descriptor
|
||||||
|
.rasterization_state
|
||||||
|
.as_ref()
|
||||||
|
.map(|r| r.into()),
|
||||||
|
primitive_topology: pipeline_descriptor.primitive_topology.into(),
|
||||||
|
color_states: &color_states,
|
||||||
|
depth_stencil_state: pipeline_descriptor
|
||||||
|
.depth_stencil_state
|
||||||
|
.as_ref()
|
||||||
|
.map(|d| d.into()),
|
||||||
|
vertex_state: wgpu::VertexStateDescriptor {
|
||||||
|
index_format: pipeline_descriptor.index_format.into(),
|
||||||
|
vertex_buffers: &owned_vertex_buffer_descriptors
|
||||||
|
.iter()
|
||||||
|
.map(|v| v.into())
|
||||||
|
.collect::<Vec<wgpu::VertexBufferDescriptor>>(),
|
||||||
|
},
|
||||||
|
sample_count: pipeline_descriptor.sample_count,
|
||||||
|
sample_mask: pipeline_descriptor.sample_mask,
|
||||||
|
alpha_to_coverage_enabled: pipeline_descriptor.alpha_to_coverage_enabled,
|
||||||
|
};
|
||||||
|
|
||||||
|
let render_pipeline = device.create_render_pipeline(&mut render_pipeline_descriptor);
|
||||||
|
self.render_pipelines
|
||||||
|
.insert(pipeline_handle, render_pipeline);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user