Handle descriptor sets for both vertex and fragment stages

This commit is contained in:
Pierre Krieger 2016-02-20 17:42:55 +01:00
parent 89265c05cb
commit 28f7d88197
5 changed files with 49 additions and 17 deletions

View File

@ -157,7 +157,7 @@ fn write_entry_point(doc: &parse::Spirv, instruction: &parse::Instruction) -> St
format!("({}, ::std::borrow::Cow::Borrowed(\"{}\"))", loc, name) format!("({}, ::std::borrow::Cow::Borrowed(\"{}\"))", loc, name)
}).collect::<Vec<_>>().join(", "); }).collect::<Vec<_>>().join(", ");
let t = format!("::vulkano::shader::VertexShaderEntryPoint<({input}), Layout>", // FIXME: let t = format!("::vulkano::shader::VertexShaderEntryPoint<({input}), Layout>",
input = input); 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 _), vec![{}])", attributes);
(t, f) (t, f)
@ -197,7 +197,7 @@ fn write_entry_point(doc: &parse::Spirv, instruction: &parse::Instruction) -> St
if output.is_empty() { output } else { output + "," } if output.is_empty() { output } else { output + "," }
}; };
let t = format!("::vulkano::shader::FragmentShaderEntryPoint<({output})>", let t = format!("::vulkano::shader::FragmentShaderEntryPoint<({output}), Layout>",
output = output); 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 _))"))
}, },

View File

@ -106,7 +106,7 @@ fn main() {
let (pipeline_layout, set) = { let (pipeline_layout, set) = {
let layout1 = vulkano::descriptor_set::DescriptorSetLayout::new(&device, Default::default()).unwrap(); let layout1 = vulkano::descriptor_set::DescriptorSetLayout::new(&device, Default::default()).unwrap();
let pipeline_layout = vulkano::descriptor_set::PipelineLayout::new(&device, Default::default(), layout1.clone()).unwrap(); let pipeline_layout = vulkano::descriptor_set::PipelineLayout::new(&device, Default::default(), (layout1.clone(), ())).unwrap();
let set1 = vulkano::descriptor_set::DescriptorSet::new(&descriptor_pool, &layout1, uniform_buffer.clone() as std::sync::Arc<_>).unwrap(); let set1 = vulkano::descriptor_set::DescriptorSet::new(&descriptor_pool, &layout1, uniform_buffer.clone() as std::sync::Arc<_>).unwrap();
(pipeline_layout, set1) (pipeline_layout, set1)
}; };
@ -152,7 +152,7 @@ fn main() {
let command_buffers = framebuffers.iter().map(|framebuffer| { let command_buffers = framebuffers.iter().map(|framebuffer| {
vulkano::command_buffer::PrimaryCommandBufferBuilder::new(&cb_pool).unwrap() vulkano::command_buffer::PrimaryCommandBufferBuilder::new(&cb_pool).unwrap()
.draw_inline(&renderpass, &framebuffer, [0.0, 0.0, 1.0, 1.0]) .draw_inline(&renderpass, &framebuffer, [0.0, 0.0, 1.0, 1.0])
.draw(&pipeline, vertex_buffer.clone(), &vulkano::command_buffer::DynamicState::none(), set.clone()) .draw(&pipeline, vertex_buffer.clone(), &vulkano::command_buffer::DynamicState::none(), (set.clone(), ()))
.draw_end() .draw_end()
.build().unwrap() .build().unwrap()
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();

View File

@ -73,6 +73,33 @@ pub unsafe trait PipelineLayoutDesc {
fn is_compatible_with<P>(&self, _: &P) -> bool where P: PipelineLayoutDesc { true } fn is_compatible_with<P>(&self, _: &P) -> bool where P: PipelineLayoutDesc { true }
} }
// FIXME: should merge the two and check for collisions instead of making them cohabit
unsafe impl<A, B> PipelineLayoutDesc for (A, B)
where A: PipelineLayoutDesc, B: PipelineLayoutDesc
{
type DescriptorSets = (A::DescriptorSets, B::DescriptorSets);
type DescriptorSetLayouts = (A::DescriptorSetLayouts, B::DescriptorSetLayouts);
type PushConstants = (A::PushConstants, B::PushConstants);
#[inline]
fn decode_descriptor_sets(&self, s: Self::DescriptorSets) -> Vec<Arc<AbstractDescriptorSet>> {
let mut a = self.0.decode_descriptor_sets(s.0);
let b = self.1.decode_descriptor_sets(s.1);
a.extend_from_slice(&b);
a
}
#[inline]
fn decode_descriptor_set_layouts(&self, s: Self::DescriptorSetLayouts)
-> Vec<Arc<AbstractDescriptorSetLayout>>
{
let mut a = self.0.decode_descriptor_set_layouts(s.0);
let b = self.1.decode_descriptor_set_layouts(s.1);
a.extend_from_slice(&b);
a
}
}
/// Dummy implementation of `PipelineLayoutDesc` that describes an empty pipeline. /// Dummy implementation of `PipelineLayoutDesc` that describes an empty pipeline.
/// ///
/// The descriptors, descriptor sets and push constants are all `()`. You have to pass `()` when /// The descriptors, descriptor sets and push constants are all `()`. You have to pass `()` when

View File

@ -42,8 +42,8 @@ pub struct GraphicsPipeline<MultiVertex, Layout> {
marker: PhantomData<(MultiVertex,)> marker: PhantomData<(MultiVertex,)>
} }
impl<MV, L> GraphicsPipeline<MV, L> impl<MV, Vl, Fl> GraphicsPipeline<MV, (Vl, Fl)>
where MV: MultiVertex, L: PipelineLayoutDesc where MV: MultiVertex
{ {
/// Builds a new graphics pipeline object. /// Builds a new graphics pipeline object.
/// ///
@ -54,12 +54,13 @@ impl<MV, L> GraphicsPipeline<MV, L>
/// - Panicks if the `sample_shading` parameter of `multisample` is not between 0.0 and 1.0. /// - Panicks if the `sample_shading` parameter of `multisample` is not between 0.0 and 1.0.
/// ///
// TODO: check all the device's limits // TODO: check all the device's limits
pub fn new<V, F, R>(device: &Arc<Device>, vertex_shader: &VertexShaderEntryPoint<V, L>, pub fn new<Vi, Fo, R>
(device: &Arc<Device>, vertex_shader: &VertexShaderEntryPoint<Vi, Vl>,
input_assembly: &InputAssembly, viewport: &ViewportsState, input_assembly: &InputAssembly, viewport: &ViewportsState,
raster: &Rasterization, multisample: &Multisample, blend: &Blend, raster: &Rasterization, multisample: &Multisample, blend: &Blend,
fragment_shader: &FragmentShaderEntryPoint<F>, fragment_shader: &FragmentShaderEntryPoint<Fo, Fl>,
layout: &Arc<PipelineLayout<L>>, render_pass: &Subpass<R>) layout: &Arc<PipelineLayout<(Vl, Fl)>>, render_pass: &Subpass<R>)
-> Result<Arc<GraphicsPipeline<MV, L>>, OomError> -> Result<Arc<GraphicsPipeline<MV, (Vl, Fl)>>, OomError>
{ {
let vk = device.pointers(); let vk = device.pointers();
@ -296,7 +297,11 @@ impl<MV, L> GraphicsPipeline<MV, L>
marker: PhantomData, marker: PhantomData,
})) }))
} }
}
impl<MV, L> GraphicsPipeline<MV, L>
where MV: MultiVertex, L: PipelineLayoutDesc
{
/// Returns the pipeline layout used in the constructor. /// Returns the pipeline layout used in the constructor.
#[inline] #[inline]
pub fn layout(&self) -> &Arc<PipelineLayout<L>> { pub fn layout(&self) -> &Arc<PipelineLayout<L>> {

View File

@ -82,8 +82,8 @@ impl ShaderModule {
/// - Calling this function also determines the template parameters associated to the /// - Calling this function also determines the template parameters associated to the
/// `EntryPoint` struct. Therefore care must be taken that the values there are correct. /// `EntryPoint` struct. Therefore care must be taken that the values there are correct.
/// ///
pub unsafe fn fragment_shader_entry_point<'a, F>(&'a self, name: &'a CStr) pub unsafe fn fragment_shader_entry_point<'a, F, L>(&'a self, name: &'a CStr)
-> FragmentShaderEntryPoint<'a, F> -> FragmentShaderEntryPoint<'a, F, L>
{ {
FragmentShaderEntryPoint { FragmentShaderEntryPoint {
module: self, module: self,
@ -143,13 +143,13 @@ pub struct ComputeShaderEntryPoint<'a, D, S, P> {
marker: PhantomData<(D, S, P)> marker: PhantomData<(D, S, P)>
} }
pub struct FragmentShaderEntryPoint<'a, F> { pub struct FragmentShaderEntryPoint<'a, F, L> {
module: &'a ShaderModule, module: &'a ShaderModule,
name: &'a CStr, name: &'a CStr,
marker: PhantomData<F> marker: PhantomData<(F, L)>,
} }
impl<'a, F> FragmentShaderEntryPoint<'a, F> { impl<'a, F, L> FragmentShaderEntryPoint<'a, F, L> {
#[inline] #[inline]
pub fn module(&self) -> &'a ShaderModule { pub fn module(&self) -> &'a ShaderModule {
self.module self.module