mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
move pipeline layout reflection to pipeline descriptor
This commit is contained in:
parent
20cc41a639
commit
3d65a0d236
3 changed files with 79 additions and 72 deletions
|
@ -4,9 +4,14 @@ use super::{
|
|||
CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, IndexFormat,
|
||||
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>
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -127,4 +132,66 @@ impl PipelineDescriptor {
|
|||
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::{
|
||||
state_descriptors::PrimitiveTopology, BindType, PipelineDescriptor, PipelineLayout,
|
||||
PipelineLayoutType, VertexBufferDescriptors,
|
||||
};
|
||||
use super::{state_descriptors::PrimitiveTopology, PipelineDescriptor, VertexBufferDescriptors};
|
||||
use crate::{
|
||||
render_resource::{
|
||||
BufferInfo, RenderResourceAssignments, RenderResourceAssignmentsId, ResourceInfo,
|
||||
},
|
||||
render_resource::{RenderResourceAssignments, RenderResourceAssignmentsId},
|
||||
renderer::{RenderResourceContext, RenderResources},
|
||||
shader::{Shader, ShaderSource},
|
||||
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(
|
||||
&mut self,
|
||||
shader_storage: &mut AssetStorage<Shader>,
|
||||
|
@ -141,7 +83,7 @@ impl PipelineCompiler {
|
|||
fn compile_pipeline(
|
||||
&mut self,
|
||||
vertex_buffer_descriptors: &VertexBufferDescriptors,
|
||||
shader_storage: &mut AssetStorage<Shader>,
|
||||
shaders: &mut AssetStorage<Shader>,
|
||||
render_resource_context: &dyn RenderResourceContext,
|
||||
pipeline_descriptor: &PipelineDescriptor,
|
||||
render_resource_assignments: &RenderResourceAssignments,
|
||||
|
@ -149,7 +91,7 @@ impl PipelineCompiler {
|
|||
let mut compiled_pipeline_descriptor = pipeline_descriptor.clone();
|
||||
|
||||
compiled_pipeline_descriptor.shader_stages.vertex = self.compile_shader(
|
||||
shader_storage,
|
||||
shaders,
|
||||
&pipeline_descriptor.shader_stages.vertex,
|
||||
&render_resource_assignments
|
||||
.pipeline_specialization
|
||||
|
@ -161,7 +103,7 @@ impl PipelineCompiler {
|
|||
.as_ref()
|
||||
.map(|fragment| {
|
||||
self.compile_shader(
|
||||
shader_storage,
|
||||
shaders,
|
||||
fragment,
|
||||
&render_resource_assignments
|
||||
.pipeline_specialization
|
||||
|
@ -169,12 +111,10 @@ impl PipelineCompiler {
|
|||
)
|
||||
});
|
||||
|
||||
Self::reflect_layout(
|
||||
shader_storage,
|
||||
vertex_buffer_descriptors,
|
||||
&mut compiled_pipeline_descriptor,
|
||||
render_resource_context,
|
||||
render_resource_assignments,
|
||||
compiled_pipeline_descriptor.reflect_layout(
|
||||
shaders,
|
||||
Some(vertex_buffer_descriptors),
|
||||
Some((render_resource_assignments, render_resource_context)),
|
||||
);
|
||||
|
||||
compiled_pipeline_descriptor.primitive_topology = render_resource_assignments
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use super::{Extent3d, Texture, TextureDimension, TextureFormat, TextureUsage};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct TextureDescriptor {
|
||||
pub size: Extent3d,
|
||||
pub mip_level_count: u32,
|
||||
|
|
Loading…
Reference in a new issue