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