move pipeline layout reflection to pipeline descriptor
This commit is contained in:
		
							parent
							
								
									20cc41a639
								
							
						
					
					
						commit
						3d65a0d236
					
				| @ -4,9 +4,14 @@ use super::{ | |||||||
|         CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, IndexFormat, |         CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, IndexFormat, | ||||||
|         PrimitiveTopology, RasterizationStateDescriptor, StencilStateFaceDescriptor, |         PrimitiveTopology, RasterizationStateDescriptor, StencilStateFaceDescriptor, | ||||||
|     }, |     }, | ||||||
|     PipelineLayout, |     PipelineLayout, VertexBufferDescriptors, BindType, | ||||||
| }; | }; | ||||||
| use crate::{shader::ShaderStages, texture::TextureFormat}; | use crate::{ | ||||||
|  |     render_resource::{ResourceInfo, RenderResourceAssignments, BufferInfo}, | ||||||
|  |     shader::{Shader, ShaderStages}, | ||||||
|  |     texture::TextureFormat, renderer::RenderResourceContext, | ||||||
|  | }; | ||||||
|  | use bevy_asset::AssetStorage; | ||||||
| 
 | 
 | ||||||
| // TODO: consider removing this in favor of Option<Layout>
 | // TODO: consider removing this in favor of Option<Layout>
 | ||||||
| #[derive(Clone, Debug)] | #[derive(Clone, Debug)] | ||||||
| @ -127,4 +132,66 @@ impl PipelineDescriptor { | |||||||
|             PipelineLayoutType::Manual(ref mut layout) => Some(layout), |             PipelineLayoutType::Manual(ref mut layout) => Some(layout), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     /// Reflects the pipeline layout from its shaders.
 | ||||||
|  |     /// 
 | ||||||
|  |     /// If `vertex_buffer_descriptors` is set, the pipeline's vertex buffers
 | ||||||
|  |     /// will inherit their layouts from global descriptors, otherwise the layout will be assumed to be complete / local.
 | ||||||
|  |     ///
 | ||||||
|  |     /// If `dynamic_uniform_lookup` is set, shader uniforms will be set to "dynamic" if there is a matching "dynamic uniform"
 | ||||||
|  |     /// render resource.
 | ||||||
|  |     pub fn reflect_layout( | ||||||
|  |         &mut self, | ||||||
|  |         shaders: &AssetStorage<Shader>, | ||||||
|  |         vertex_buffer_descriptors: Option<&VertexBufferDescriptors>, | ||||||
|  |         dynamic_uniform_lookup: Option<(&RenderResourceAssignments, &dyn RenderResourceContext)>, | ||||||
|  |     ) { | ||||||
|  |         let vertex_spirv = shaders.get(&self.shader_stages.vertex).unwrap(); | ||||||
|  |         let fragment_spirv = self | ||||||
|  |             .shader_stages | ||||||
|  |             .fragment | ||||||
|  |             .as_ref() | ||||||
|  |             .map(|handle| shaders.get(&handle).unwrap()); | ||||||
|  | 
 | ||||||
|  |         let mut layouts = vec![vertex_spirv.reflect_layout().unwrap()]; | ||||||
|  |         if let Some(ref fragment_spirv) = fragment_spirv { | ||||||
|  |             layouts.push(fragment_spirv.reflect_layout().unwrap()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         let mut layout = PipelineLayout::from_shader_layouts(&mut layouts); | ||||||
|  |         if let Some(vertex_buffer_descriptors) = vertex_buffer_descriptors { | ||||||
|  |             layout.sync_vertex_buffer_descriptors(vertex_buffer_descriptors); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if let Some((render_resource_assignments, render_resource_context)) = dynamic_uniform_lookup { | ||||||
|  |             // 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.
 | ||||||
|  |             // the fix would be to add "dynamic bindings" to the existing shader_def sets. this would ensure new pipelines are generated
 | ||||||
|  |             // for all permutations of dynamic/non-dynamic
 | ||||||
|  |             for bind_group in layout.bind_groups.iter_mut() { | ||||||
|  |                 for binding in bind_group.bindings.iter_mut() { | ||||||
|  |                     if let Some(render_resource) = render_resource_assignments.get(&binding.name) { | ||||||
|  |                         render_resource_context.get_resource_info( | ||||||
|  |                             render_resource, | ||||||
|  |                             &mut |resource_info| { | ||||||
|  |                                 if let Some(ResourceInfo::Buffer(BufferInfo { | ||||||
|  |                                     is_dynamic, .. | ||||||
|  |                                 })) = resource_info | ||||||
|  |                                 { | ||||||
|  |                                     if let BindType::Uniform { | ||||||
|  |                                         ref mut dynamic, .. | ||||||
|  |                                     } = binding.bind_type | ||||||
|  |                                     { | ||||||
|  |                                         *dynamic = *is_dynamic | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             }, | ||||||
|  |                         ); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         self.layout = PipelineLayoutType::Reflected(Some(layout)); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,11 +1,6 @@ | |||||||
| use super::{ | use super::{state_descriptors::PrimitiveTopology, PipelineDescriptor, VertexBufferDescriptors}; | ||||||
|     state_descriptors::PrimitiveTopology, BindType, PipelineDescriptor, PipelineLayout, |  | ||||||
|     PipelineLayoutType, VertexBufferDescriptors, |  | ||||||
| }; |  | ||||||
| use crate::{ | use crate::{ | ||||||
|     render_resource::{ |     render_resource::{RenderResourceAssignments, RenderResourceAssignmentsId}, | ||||||
|         BufferInfo, RenderResourceAssignments, RenderResourceAssignmentsId, ResourceInfo, |  | ||||||
|     }, |  | ||||||
|     renderer::{RenderResourceContext, RenderResources}, |     renderer::{RenderResourceContext, RenderResources}, | ||||||
|     shader::{Shader, ShaderSource}, |     shader::{Shader, ShaderSource}, | ||||||
|     Renderable, |     Renderable, | ||||||
| @ -44,59 +39,6 @@ impl PipelineCompiler { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn reflect_layout( |  | ||||||
|         shader_storage: &AssetStorage<Shader>, |  | ||||||
|         vertex_buffer_descriptors: &VertexBufferDescriptors, |  | ||||||
|         pipeline_descriptor: &mut PipelineDescriptor, |  | ||||||
|         render_resource_context: &dyn RenderResourceContext, |  | ||||||
|         render_resource_assignments: &RenderResourceAssignments, |  | ||||||
|     ) { |  | ||||||
|         let vertex_spirv = shader_storage |  | ||||||
|             .get(&pipeline_descriptor.shader_stages.vertex) |  | ||||||
|             .unwrap(); |  | ||||||
|         let fragment_spirv = pipeline_descriptor |  | ||||||
|             .shader_stages |  | ||||||
|             .fragment |  | ||||||
|             .as_ref() |  | ||||||
|             .map(|handle| &*shader_storage.get(&handle).unwrap()); |  | ||||||
| 
 |  | ||||||
|         let mut layouts = vec![vertex_spirv.reflect_layout().unwrap()]; |  | ||||||
|         if let Some(ref fragment_spirv) = fragment_spirv { |  | ||||||
|             layouts.push(fragment_spirv.reflect_layout().unwrap()); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         let mut layout = PipelineLayout::from_shader_layouts(&mut layouts); |  | ||||||
|         layout.sync_vertex_buffer_descriptors(vertex_buffer_descriptors); |  | ||||||
| 
 |  | ||||||
|         // 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.
 |  | ||||||
|         // the fix would be to add "dynamic bindings" to the existing shader_def sets. this would ensure new pipelines are generated
 |  | ||||||
|         // for all permutations of dynamic/non-dynamic
 |  | ||||||
|         for bind_group in layout.bind_groups.iter_mut() { |  | ||||||
|             for binding in bind_group.bindings.iter_mut() { |  | ||||||
|                 if let Some(render_resource) = render_resource_assignments.get(&binding.name) { |  | ||||||
|                     render_resource_context.get_resource_info( |  | ||||||
|                         render_resource, |  | ||||||
|                         &mut |resource_info| { |  | ||||||
|                             if let Some(ResourceInfo::Buffer(BufferInfo { is_dynamic, .. })) = |  | ||||||
|                                 resource_info |  | ||||||
|                             { |  | ||||||
|                                 if let BindType::Uniform { |  | ||||||
|                                     ref mut dynamic, .. |  | ||||||
|                                 } = binding.bind_type |  | ||||||
|                                 { |  | ||||||
|                                     *dynamic = *is_dynamic |  | ||||||
|                                 } |  | ||||||
|                             } |  | ||||||
|                         }, |  | ||||||
|                     ); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         pipeline_descriptor.layout = PipelineLayoutType::Reflected(Some(layout)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn compile_shader( |     fn compile_shader( | ||||||
|         &mut self, |         &mut self, | ||||||
|         shader_storage: &mut AssetStorage<Shader>, |         shader_storage: &mut AssetStorage<Shader>, | ||||||
| @ -141,7 +83,7 @@ impl PipelineCompiler { | |||||||
|     fn compile_pipeline( |     fn compile_pipeline( | ||||||
|         &mut self, |         &mut self, | ||||||
|         vertex_buffer_descriptors: &VertexBufferDescriptors, |         vertex_buffer_descriptors: &VertexBufferDescriptors, | ||||||
|         shader_storage: &mut AssetStorage<Shader>, |         shaders: &mut AssetStorage<Shader>, | ||||||
|         render_resource_context: &dyn RenderResourceContext, |         render_resource_context: &dyn RenderResourceContext, | ||||||
|         pipeline_descriptor: &PipelineDescriptor, |         pipeline_descriptor: &PipelineDescriptor, | ||||||
|         render_resource_assignments: &RenderResourceAssignments, |         render_resource_assignments: &RenderResourceAssignments, | ||||||
| @ -149,7 +91,7 @@ impl PipelineCompiler { | |||||||
|         let mut compiled_pipeline_descriptor = pipeline_descriptor.clone(); |         let mut compiled_pipeline_descriptor = pipeline_descriptor.clone(); | ||||||
| 
 | 
 | ||||||
|         compiled_pipeline_descriptor.shader_stages.vertex = self.compile_shader( |         compiled_pipeline_descriptor.shader_stages.vertex = self.compile_shader( | ||||||
|             shader_storage, |             shaders, | ||||||
|             &pipeline_descriptor.shader_stages.vertex, |             &pipeline_descriptor.shader_stages.vertex, | ||||||
|             &render_resource_assignments |             &render_resource_assignments | ||||||
|                 .pipeline_specialization |                 .pipeline_specialization | ||||||
| @ -161,7 +103,7 @@ impl PipelineCompiler { | |||||||
|             .as_ref() |             .as_ref() | ||||||
|             .map(|fragment| { |             .map(|fragment| { | ||||||
|                 self.compile_shader( |                 self.compile_shader( | ||||||
|                     shader_storage, |                     shaders, | ||||||
|                     fragment, |                     fragment, | ||||||
|                     &render_resource_assignments |                     &render_resource_assignments | ||||||
|                         .pipeline_specialization |                         .pipeline_specialization | ||||||
| @ -169,12 +111,10 @@ impl PipelineCompiler { | |||||||
|                 ) |                 ) | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|         Self::reflect_layout( |         compiled_pipeline_descriptor.reflect_layout( | ||||||
|             shader_storage, |             shaders, | ||||||
|             vertex_buffer_descriptors, |             Some(vertex_buffer_descriptors), | ||||||
|             &mut compiled_pipeline_descriptor, |             Some((render_resource_assignments, render_resource_context)), | ||||||
|             render_resource_context, |  | ||||||
|             render_resource_assignments, |  | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
|         compiled_pipeline_descriptor.primitive_topology = render_resource_assignments |         compiled_pipeline_descriptor.primitive_topology = render_resource_assignments | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| use super::{Extent3d, Texture, TextureDimension, TextureFormat, TextureUsage}; | use super::{Extent3d, Texture, TextureDimension, TextureFormat, TextureUsage}; | ||||||
| 
 | 
 | ||||||
| #[derive(Copy, Clone)] | #[derive(Debug, Copy, Clone)] | ||||||
| pub struct TextureDescriptor { | pub struct TextureDescriptor { | ||||||
|     pub size: Extent3d, |     pub size: Extent3d, | ||||||
|     pub mip_level_count: u32, |     pub mip_level_count: u32, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Carter Anderson
						Carter Anderson