diff --git a/vulkano-shaders/src/lib.rs b/vulkano-shaders/src/lib.rs index 3cf6ca20..2b66b3a4 100644 --- a/vulkano-shaders/src/lib.rs +++ b/vulkano-shaders/src/lib.rs @@ -198,7 +198,7 @@ fn write_entry_point(doc: &parse::Spirv, instruction: &parse::Instruction) -> St let t = format!("::vulkano::shader::VertexShaderEntryPoint<({input}), Layout>", input = input); - let f = format!("vertex_shader_entry_point(::std::ffi::CStr::from_ptr(NAME.as_ptr() as *const _), vec![{}])", attributes); + let f = format!("vertex_shader_entry_point(::std::ffi::CStr::from_ptr(NAME.as_ptr() as *const _), Layout, vec![{}])", attributes); (t, f) }, @@ -238,7 +238,7 @@ fn write_entry_point(doc: &parse::Spirv, instruction: &parse::Instruction) -> St let t = format!("::vulkano::shader::FragmentShaderEntryPoint<({output}), Layout>", output = output); - (t, format!("fragment_shader_entry_point(::std::ffi::CStr::from_ptr(NAME.as_ptr() as *const _))")) + (t, format!("fragment_shader_entry_point(::std::ffi::CStr::from_ptr(NAME.as_ptr() as *const _), Layout)")) }, enums::ExecutionModel::ExecutionModelGLCompute => { diff --git a/vulkano/src/descriptor_set/layout_def.rs b/vulkano/src/descriptor_set/layout_def.rs index b5ad3b00..adb3269e 100644 --- a/vulkano/src/descriptor_set/layout_def.rs +++ b/vulkano/src/descriptor_set/layout_def.rs @@ -33,6 +33,19 @@ pub unsafe trait Layout { fn is_compatible_with

(&self, _: &P) -> bool where P: Layout { true } } +/// Extension for `Layout`. +pub unsafe trait LayoutPossibleSuperset: Layout where Other: Layout { + /// Returns true if `self` is a superset of `Other`. That is, all the descriptors in `Other` + /// are also in `self` and have an identical definition. + fn is_superset_of(&self, &Other) -> bool; +} + +// CRITICAL FIXME: temporary hack +unsafe impl LayoutPossibleSuperset for T where T: Layout, U: Layout { + #[inline] + fn is_superset_of(&self, _: &U) -> bool { true } +} + /// Types that describe a single descriptor set. pub unsafe trait SetLayout { /// Returns the list of descriptors contained in this set. @@ -53,7 +66,8 @@ pub unsafe trait SetLayoutInit: SetLayout { /// Extension for `SetLayout`. pub unsafe trait SetLayoutPossibleSuperset: SetLayout where Other: SetLayout { - /// Returns true if `self` is a superset of `Other`. + /// Returns true if `self` is a superset of `Other`. That is, all the descriptors in `Other` + /// are also in `self` and have an identical definition. fn is_superset_of(&self, &Other) -> bool; } diff --git a/vulkano/src/descriptor_set/mod.rs b/vulkano/src/descriptor_set/mod.rs index efad8d33..ca612a78 100644 --- a/vulkano/src/descriptor_set/mod.rs +++ b/vulkano/src/descriptor_set/mod.rs @@ -36,9 +36,11 @@ use std::option::IntoIter as OptionIntoIter; use std::sync::Arc; pub use self::layout_def::Layout; +pub use self::layout_def::LayoutPossibleSuperset; pub use self::layout_def::SetLayout; pub use self::layout_def::SetLayoutWrite; pub use self::layout_def::SetLayoutInit; +pub use self::layout_def::SetLayoutPossibleSuperset; pub use self::layout_def::DescriptorWrite; pub use self::layout_def::DescriptorBind; pub use self::layout_def::DescriptorDesc; diff --git a/vulkano/src/descriptor_set/vk_objects.rs b/vulkano/src/descriptor_set/vk_objects.rs index 05fb66a3..ab9fc3d9 100644 --- a/vulkano/src/descriptor_set/vk_objects.rs +++ b/vulkano/src/descriptor_set/vk_objects.rs @@ -46,7 +46,7 @@ impl DescriptorSet where S: SetLayout { { unsafe { let mut set = try!(DescriptorSet::uninitialized(pool, layout)); - Arc::get_mut(&mut set).unwrap().unchecked_write(layout.description().decode(init)); + Arc::get_mut(&mut set).unwrap().unchecked_write(layout.layout().decode(init)); Ok(set) } } @@ -101,7 +101,7 @@ impl DescriptorSet where S: SetLayout { pub fn write(&mut self, write: W) where S: SetLayoutWrite { - let write = self.layout.description().decode(write); + let write = self.layout.layout().decode(write); unsafe { self.unchecked_write(write); } } @@ -318,7 +318,7 @@ impl DescriptorSetLayout where S: SetLayout { } #[inline] - pub fn description(&self) -> &S { + pub fn layout(&self) -> &S { &self.description } } @@ -395,7 +395,7 @@ impl

PipelineLayout

where P: Layout { } #[inline] - pub fn description(&self) -> &P { + pub fn layout(&self) -> &P { &self.description } } diff --git a/vulkano/src/pipeline/graphics_pipeline.rs b/vulkano/src/pipeline/graphics_pipeline.rs index 920afc12..dba8bdfe 100644 --- a/vulkano/src/pipeline/graphics_pipeline.rs +++ b/vulkano/src/pipeline/graphics_pipeline.rs @@ -6,6 +6,7 @@ use std::sync::Arc; use device::Device; use descriptor_set::PipelineLayout; use descriptor_set::Layout as PipelineLayoutDesc; +use descriptor_set::LayoutPossibleSuperset as PipelineLayoutPossibleSuperset; use framebuffer::Subpass; use shader::FragmentShaderEntryPoint; use shader::VertexShaderEntryPoint; @@ -64,10 +65,13 @@ impl GraphicsPipeline fragment_shader: &FragmentShaderEntryPoint, layout: &Arc>, render_pass: &Subpass) -> Result>, OomError> + where L: PipelineLayoutDesc + PipelineLayoutPossibleSuperset + PipelineLayoutPossibleSuperset, + Vl: PipelineLayoutDesc, Fl: PipelineLayoutDesc { let vk = device.pointers(); - // FIXME: check layout compatibility + assert!(PipelineLayoutPossibleSuperset::is_superset_of(layout.layout(), vertex_shader.layout())); + assert!(PipelineLayoutPossibleSuperset::is_superset_of(layout.layout(), fragment_shader.layout())); let pipeline = unsafe { // TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618) diff --git a/vulkano/src/shader.rs b/vulkano/src/shader.rs index 11cb4878..b9d39379 100644 --- a/vulkano/src/shader.rs +++ b/vulkano/src/shader.rs @@ -58,13 +58,14 @@ impl ShaderModule { })) } - pub unsafe fn vertex_shader_entry_point<'a, V, L>(&'a self, name: &'a CStr, + pub unsafe fn vertex_shader_entry_point<'a, V, L>(&'a self, name: &'a CStr, layout: L, attributes: Vec<(u32, Cow<'static, str>)>) -> VertexShaderEntryPoint<'a, V, L> { VertexShaderEntryPoint { module: self, name: name, + layout: layout, marker: PhantomData, attributes: attributes, } @@ -82,12 +83,13 @@ impl ShaderModule { /// - Calling this function also determines the template parameters associated to the /// `EntryPoint` struct. Therefore care must be taken that the values there are correct. /// - pub unsafe fn fragment_shader_entry_point<'a, F, L>(&'a self, name: &'a CStr) + pub unsafe fn fragment_shader_entry_point<'a, F, L>(&'a self, name: &'a CStr, layout: L) -> FragmentShaderEntryPoint<'a, F, L> { FragmentShaderEntryPoint { module: self, name: name, + layout: layout, marker: PhantomData, } } @@ -115,8 +117,9 @@ impl Drop for ShaderModule { pub struct VertexShaderEntryPoint<'a, V, L> { module: &'a ShaderModule, name: &'a CStr, - marker: PhantomData<(V, L)>, + marker: PhantomData, attributes: Vec<(u32, Cow<'static, str>)>, + layout: L, } impl<'a, V, L> VertexShaderEntryPoint<'a, V, L> { @@ -130,6 +133,11 @@ impl<'a, V, L> VertexShaderEntryPoint<'a, V, L> { self.name } + #[inline] + pub fn layout(&self) -> &L { + &self.layout + } + // TODO: change API #[inline] pub fn attributes(&self) -> &[(u32, Cow<'static, str>)] { @@ -146,7 +154,8 @@ pub struct ComputeShaderEntryPoint<'a, D, S, P> { pub struct FragmentShaderEntryPoint<'a, F, L> { module: &'a ShaderModule, name: &'a CStr, - marker: PhantomData<(F, L)>, + marker: PhantomData, + layout: L, } impl<'a, F, L> FragmentShaderEntryPoint<'a, F, L> { @@ -159,6 +168,11 @@ impl<'a, F, L> FragmentShaderEntryPoint<'a, F, L> { pub fn name(&self) -> &'a CStr { self.name } + + #[inline] + pub fn layout(&self) -> &L { + &self.layout + } } pub unsafe trait ShaderInterfaceDef {