Check pipeline layout of shaders

This commit is contained in:
Pierre Krieger 2016-03-01 14:50:30 +01:00
parent a5b21125ed
commit f341552825
6 changed files with 46 additions and 12 deletions

View File

@ -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 => {

View File

@ -33,6 +33,19 @@ pub unsafe trait Layout {
fn is_compatible_with<P>(&self, _: &P) -> bool where P: Layout { true }
}
/// Extension for `Layout`.
pub unsafe trait LayoutPossibleSuperset<Other>: 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<T, U> LayoutPossibleSuperset<U> 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<Data>: SetLayout {
/// Extension for `SetLayout`.
pub unsafe trait SetLayoutPossibleSuperset<Other>: 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;
}

View File

@ -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;

View File

@ -46,7 +46,7 @@ impl<S> DescriptorSet<S> 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<S> DescriptorSet<S> where S: SetLayout {
pub fn write<W>(&mut self, write: W)
where S: SetLayoutWrite<W>
{
let write = self.layout.description().decode(write);
let write = self.layout.layout().decode(write);
unsafe { self.unchecked_write(write); }
}
@ -318,7 +318,7 @@ impl<S> DescriptorSetLayout<S> where S: SetLayout {
}
#[inline]
pub fn description(&self) -> &S {
pub fn layout(&self) -> &S {
&self.description
}
}
@ -395,7 +395,7 @@ impl<P> PipelineLayout<P> where P: Layout {
}
#[inline]
pub fn description(&self) -> &P {
pub fn layout(&self) -> &P {
&self.description
}
}

View File

@ -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<MV, L> GraphicsPipeline<MV, L>
fragment_shader: &FragmentShaderEntryPoint<Fo, Fl>,
layout: &Arc<PipelineLayout<L>>, render_pass: &Subpass<R>)
-> Result<Arc<GraphicsPipeline<MV, L>>, OomError>
where L: PipelineLayoutDesc + PipelineLayoutPossibleSuperset<Vl> + PipelineLayoutPossibleSuperset<Fl>,
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)

View File

@ -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<V>,
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<F>,
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 {