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

View File

@ -106,7 +106,7 @@ fn main() {
let (pipeline_layout, set) = {
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();
(pipeline_layout, set1)
};
@ -152,7 +152,7 @@ fn main() {
let command_buffers = framebuffers.iter().map(|framebuffer| {
vulkano::command_buffer::PrimaryCommandBufferBuilder::new(&cb_pool).unwrap()
.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()
.build().unwrap()
}).collect::<Vec<_>>();

View File

@ -73,6 +73,33 @@ pub unsafe trait PipelineLayoutDesc {
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.
///
/// 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,)>
}
impl<MV, L> GraphicsPipeline<MV, L>
where MV: MultiVertex, L: PipelineLayoutDesc
impl<MV, Vl, Fl> GraphicsPipeline<MV, (Vl, Fl)>
where MV: MultiVertex
{
/// 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.
///
// TODO: check all the device's limits
pub fn new<V, F, R>(device: &Arc<Device>, vertex_shader: &VertexShaderEntryPoint<V, L>,
input_assembly: &InputAssembly, viewport: &ViewportsState,
raster: &Rasterization, multisample: &Multisample, blend: &Blend,
fragment_shader: &FragmentShaderEntryPoint<F>,
layout: &Arc<PipelineLayout<L>>, render_pass: &Subpass<R>)
-> Result<Arc<GraphicsPipeline<MV, L>>, OomError>
pub fn new<Vi, Fo, R>
(device: &Arc<Device>, vertex_shader: &VertexShaderEntryPoint<Vi, Vl>,
input_assembly: &InputAssembly, viewport: &ViewportsState,
raster: &Rasterization, multisample: &Multisample, blend: &Blend,
fragment_shader: &FragmentShaderEntryPoint<Fo, Fl>,
layout: &Arc<PipelineLayout<(Vl, Fl)>>, render_pass: &Subpass<R>)
-> Result<Arc<GraphicsPipeline<MV, (Vl, Fl)>>, OomError>
{
let vk = device.pointers();
@ -296,7 +297,11 @@ impl<MV, L> GraphicsPipeline<MV, L>
marker: PhantomData,
}))
}
}
impl<MV, L> GraphicsPipeline<MV, L>
where MV: MultiVertex, L: PipelineLayoutDesc
{
/// Returns the pipeline layout used in the constructor.
#[inline]
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
/// `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)
-> FragmentShaderEntryPoint<'a, F>
pub unsafe fn fragment_shader_entry_point<'a, F, L>(&'a self, name: &'a CStr)
-> FragmentShaderEntryPoint<'a, F, L>
{
FragmentShaderEntryPoint {
module: self,
@ -143,13 +143,13 @@ pub struct ComputeShaderEntryPoint<'a, D, S, P> {
marker: PhantomData<(D, S, P)>
}
pub struct FragmentShaderEntryPoint<'a, F> {
pub struct FragmentShaderEntryPoint<'a, F, L> {
module: &'a ShaderModule,
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]
pub fn module(&self) -> &'a ShaderModule {
self.module