Make teapot example compile (but not work)

This commit is contained in:
Pierre Krieger 2016-04-03 20:31:24 +02:00
parent 105f2ba421
commit f01d1fde37
11 changed files with 199 additions and 248 deletions

View File

@ -13,26 +13,18 @@ use enums;
use parse;
pub fn write_descriptor_sets(doc: &parse::Spirv) -> String {
// TODO: not implemented
// TODO: not implemented correctly
// finding all the descriptors
// Finding all the descriptors.
let mut descriptors = Vec::new();
struct Descriptor {
name: String,
desc_ty: String,
bind_ty: String,
bind_template_params: Vec<String>,
bind_where_clauses: String,
bind: String,
set: u32,
binding: u32,
desc_ty: String,
}
// template parameter names that are available for the purpose of the code below
// TODO: better system
let mut template_params = vec!["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M"].into_iter();
// looping to find all the elements that have the `DescriptorSet` decoration
// Looping to find all the elements that have the `DescriptorSet` decoration.
for instruction in doc.instructions.iter() {
let (variable_id, descriptor_set) = match instruction {
&parse::Instruction::Decorate { target_id, decoration: enums::Decoration::DecorationDescriptorSet, ref params } => {
@ -41,12 +33,12 @@ pub fn write_descriptor_sets(doc: &parse::Spirv) -> String {
_ => continue
};
// find which type is pointed to by this variable
// Find which type is pointed to by this variable.
let pointed_ty = pointer_variable_ty(doc, variable_id);
// name of the variable
// Name of the variable.
let name = ::name_from_id(doc, variable_id);
// find the binding point of this descriptor
// Find the binding point of this descriptor.
let binding = doc.instructions.iter().filter_map(|i| {
match i {
&parse::Instruction::Decorate { target_id, decoration: enums::Decoration::DecorationBinding, ref params } if target_id == variable_id => {
@ -56,12 +48,10 @@ pub fn write_descriptor_sets(doc: &parse::Spirv) -> String {
}
}).next().expect(&format!("Uniform `{}` is missing a binding", name));
// find informations about the kind of binding for this descriptor
let (desc_ty, bind_template_params, bind_where_clauses, bind_ty, bind) = doc.instructions.iter().filter_map(|i| {
// Find informations about the kind of binding for this descriptor.
let desc_ty = doc.instructions.iter().filter_map(|i| {
match i {
&parse::Instruction::TypeStruct { result_id, .. } if result_id == pointed_ty => {
let tp_buffer = template_params.next().unwrap();
// Determine whether there's a Block or BufferBlock decoration.
let is_ssbo = doc.instructions.iter().filter_map(|i| {
match i {
@ -75,62 +65,28 @@ pub fn write_descriptor_sets(doc: &parse::Spirv) -> String {
}
}).next().expect("Found a buffer uniform with neither the Block nor BufferBlock decorations");
Some((
if !is_ssbo {
"::vulkano::descriptor_set::DescriptorType::UniformBuffer"
} else {
"::vulkano::descriptor_set::DescriptorType::StorageBuffer"
},
vec![tp_buffer.to_owned()],
format!("{}: 'static + ::vulkano::buffer::TypedBuffer", tp_buffer),
format!("&'a ::std::sync::Arc<{}>", tp_buffer),
if !is_ssbo {
"::vulkano::descriptor_set::DescriptorBind::uniform_buffer(data)"
} else {
"::vulkano::descriptor_set::DescriptorBind::storage_buffer(data)"
}
))
Some(if !is_ssbo {
"DescriptorType::UniformBuffer"
} else {
"DescriptorType::StorageBuffer"
})
},
&parse::Instruction::TypeImage { result_id, sampled_type_id, ref dim, arrayed, ms,
sampled, ref format, ref access, .. }
if result_id == pointed_ty && sampled == Some(true) =>
{
let img = template_params.next().unwrap();
Some((
"::vulkano::descriptor_set::DescriptorType::SampledImage",
vec![img.to_owned()],
format!("{}: 'static + ::vulkano::image::ImageView", img),
format!("&'a ::std::sync::Arc<{}>", img),
"::vulkano::descriptor_set::DescriptorBind::sampled_image(data)"
))
Some("DescriptorType::SampledImage")
},
&parse::Instruction::TypeImage { result_id, sampled_type_id, ref dim, arrayed, ms,
sampled, ref format, ref access, .. }
if result_id == pointed_ty && sampled == Some(false) =>
{
let img = template_params.next().unwrap();
Some((
"::vulkano::descriptor_set::DescriptorType::InputAttachment", // FIXME: can be `StorageImage`
vec![img.to_owned()],
format!("{}: 'static + ::vulkano::image::ImageView", img),
format!("&'a ::std::sync::Arc<{}>", img),
"::vulkano::descriptor_set::DescriptorBind::input_attachment(data)"
))
Some("DescriptorType::InputAttachment") // FIXME: can be `StorageImage`
},
&parse::Instruction::TypeSampledImage { result_id, image_type_id }
if result_id == pointed_ty =>
{
let img = template_params.next().unwrap();
Some((
"::vulkano::descriptor_set::DescriptorType::CombinedImageSampler",
vec![img.to_owned()],
format!("{}: 'static + ::vulkano::image::ImageView", img),
format!("(&'a ::std::sync::Arc<::vulkano::sampler::Sampler>, &'a ::std::sync::Arc<{}>)", img),
"::vulkano::descriptor_set::DescriptorBind::combined_image_sampler(data.0, data.1)"
))
Some("DescriptorType::CombinedImageSampler")
},
_ => None, // TODO: other types
}
@ -139,177 +95,60 @@ pub fn write_descriptor_sets(doc: &parse::Spirv) -> String {
descriptors.push(Descriptor {
name: name,
desc_ty: desc_ty.to_owned(),
bind_ty: bind_ty,
bind_template_params: bind_template_params,
bind_where_clauses: bind_where_clauses,
bind: bind.to_owned(),
set: descriptor_set,
binding: binding,
});
}
// Sorting descriptors by binding in order to make sure we're in the right order.
descriptors.sort_by(|a, b| a.binding.cmp(&b.binding));
// Computing the list of sets that are needed.
let sets_list = descriptors.iter().map(|d| d.set).collect::<HashSet<u32>>();
let mut output = String::new();
// iterate once per set that is defined somewhere
for set in sets_list.iter() {
let write_ty = descriptors.iter().filter(|d| d.set == *set)
.map(|d| d.bind_ty.clone())
.collect::<Vec<_>>();
let write_tp = {
let v = descriptors.iter().filter(|d| d.set == *set)
.map(|d| d.bind_template_params.join(", "))
.collect::<Vec<_>>().join(", ");
if v.is_empty() { v } else { ", ".to_owned() + &v }
};
let write_where = {
let v = descriptors.iter().filter(|d| d.set == *set)
.map(|d| d.bind_where_clauses.clone())
.collect::<Vec<_>>().join(", ");
if v.is_empty() { v } else { "where ".to_owned() + &v }
};
let writes = descriptors.iter().enumerate().filter(|&(_, d)| d.set == *set)
.map(|(entry, d)| {
let entry = if write_ty.len() == 1 {
"".to_owned()
} else {
format!(".{}", entry)
};
format!("{{ let data = data{entry};
::vulkano::descriptor_set::DescriptorWrite {{
binding: {binding},
array_element: 0,
content: {bind},
}} }}", binding = d.binding, bind = d.bind,
entry = entry)
})
.collect::<Vec<_>>();
let write_ty = if write_ty.len() == 1 {
write_ty.into_iter().next().unwrap()
} else {
format!("({})", write_ty.join(", "))
};
let descr = descriptors.iter().enumerate().filter(|&(_, d)| d.set == *set)
// Iterate once per set.
for &set in sets_list.iter() {
let descr = descriptors.iter().enumerate().filter(|&(_, d)| d.set == set)
.map(|(entry, d)| {
format!("::vulkano::descriptor_set::DescriptorDesc {{
format!("DescriptorDesc {{
binding: {binding},
ty: {desc_ty},
array_count: 1,
stages: ::vulkano::descriptor_set::ShaderStages::all(), // TODO:
stages: ShaderStages::all(), // TODO:
}}", binding = d.binding, desc_ty = d.desc_ty)
})
.collect::<Vec<_>>();
output.push_str(&format!(r#"
#[derive(Default)]
pub struct Set{set};
unsafe impl ::vulkano::descriptor_set::SetLayout for Set{set} {{
fn descriptors(&self) -> Vec<::vulkano::descriptor_set::DescriptorDesc> {{
vec![
{descr}
]
}}
}}
unsafe impl<'a {write_tp}> ::vulkano::descriptor_set::SetLayoutWrite<{write_ty}> for Set{set}
{write_where}
{{
fn decode(&self, data: {write_ty}) -> Vec<::vulkano::descriptor_set::DescriptorWrite> {{
vec![
{writes}
]
}}
}}
unsafe impl<'a {write_tp}> ::vulkano::descriptor_set::SetLayoutInit<{write_ty}> for Set{set}
{write_where}
{{
fn decode(&self, data: {write_ty}) -> Vec<::vulkano::descriptor_set::DescriptorWrite> {{
::vulkano::descriptor_set::SetLayoutWrite::decode(self, data)
}}
}}
"#, set = set, write_ty = write_ty, writes = writes.join(","), write_tp = write_tp,
write_where = write_where, descr = descr.join(",")));
fn set{set}_layout() -> VecIntoIter<DescriptorDesc> {{
vec![
{descr}
].into_iter()
}}
"#, set = set, descr = descr.join(",")));
}
let max_set = sets_list.iter().cloned().max().map(|v| v + 1).unwrap_or(0);
let sets_defs = (0 .. max_set).map(|num| {
if sets_list.contains(&num) {
format!("::std::sync::Arc<::vulkano::descriptor_set::DescriptorSet<Set{}>>", num)
} else {
"()".to_owned()
}
}).collect::<Vec<_>>();
let sets = (0 .. max_set).map(|num| {
if sets_list.contains(&num) {
if sets_defs.len() == 1 {
format!("sets")
} else {
format!("sets.{}", num)
}
} else {
"()".to_owned() // FIXME: wrong
}
}).collect::<Vec<_>>();
let layouts_defs = (0 .. max_set).map(|num| {
if sets_list.contains(&num) {
format!("::std::sync::Arc<::vulkano::descriptor_set::DescriptorSetLayout<Set{}>>", num)
} else {
"()".to_owned()
}
}).collect::<Vec<_>>();
let layouts = (0 .. max_set).map(|num| {
if sets_list.contains(&num) {
if layouts_defs.len() == 1 {
format!("layouts")
} else {
format!("layouts.{}", num)
}
} else {
"()".to_owned() // FIXME: wrong
}
}).collect::<Vec<_>>();
output.push_str(&format!(r#"
#[derive(Default)]
pub struct Layout;
#[derive(Default)]
pub struct Layout;
unsafe impl ::vulkano::descriptor_set::Layout for Layout {{
type DescriptorSets = ({sets_defs});
type DescriptorSetLayouts = ({layouts_defs});
type PushConstants = ();
#[allow(unsafe_code)]
unsafe impl PipelineLayoutDesc for Layout {{
type SetsIter = VecIntoIter<Self::DescIter>;
type DescIter = VecIntoIter<DescriptorDesc>;
fn decode_descriptor_set_layouts(&self, layouts: Self::DescriptorSetLayouts)
-> Vec<::std::sync::Arc<::vulkano::descriptor_set::AbstractDescriptorSetLayout>>
{{
vec![
{layouts}
]
}}
fn descriptors_desc(&self) -> Self::SetsIter {{
vec![
{layouts}
].into_iter()
}}
}}
fn decode_descriptor_sets(&self, sets: Self::DescriptorSets)
-> Vec<::std::sync::Arc<::vulkano::descriptor_set::AbstractDescriptorSet>>
{{
vec![
{sets}
]
}}
}}
"#, sets_defs = sets_defs.join(","), layouts_defs = layouts_defs.join(","),
layouts = layouts.join(","), sets = sets.join(",")));
"#, layouts = (0 .. max_set).map(|n| format!("set{}_layout()", n)).collect::<Vec<_>>().join(",")));
output
}

View File

@ -65,6 +65,21 @@ pub fn reflect<R>(name: &str, mut spirv: R) -> Result<String, Error>
println!("{:#?}", doc);
let mut output = String::new();
output.push_str(r#"
use std::sync::Arc;
use std::vec::IntoIter as VecIntoIter;
use vulkano::device::Device;
use vulkano::descriptor_set::descriptor::DescriptorDesc;
use vulkano::descriptor_set::descriptor::DescriptorType;
use vulkano::descriptor_set::descriptor::ShaderStages;
use vulkano::descriptor_set::descriptor_set::DescriptorSet;
use vulkano::descriptor_set::descriptor_set::UnsafeDescriptorSet;
use vulkano::descriptor_set::descriptor_set::UnsafeDescriptorSetLayout;
use vulkano::descriptor_set::pipeline_layout::PipelineLayout;
use vulkano::descriptor_set::pipeline_layout::PipelineLayoutDesc;
use vulkano::descriptor_set::pipeline_layout::UnsafePipelineLayout;
"#);
{
// contains the data that was passed as input to this function

View File

@ -160,14 +160,20 @@ fn main() {
let renderpass = renderpass::CustomRenderPass::new(&device).unwrap();
let descriptor_pool = vulkano::descriptor_set::DescriptorPool::new(&device).unwrap();
let descriptor_set_layout = vulkano::descriptor_set::DescriptorSetLayout::new(&device, vs::Set0).unwrap();
let descriptor_pool = vulkano::descriptor_set::descriptor_set::DescriptorPool::new(&device).unwrap();
mod pipeline_layout { pipeline_from_sets!(::vs::Set0); }
let pipeline_layout = vulkano::descriptor_set::PipelineLayout::new(&device, pipeline_layout::Layout, (descriptor_set_layout.clone(),)).unwrap();
let set = vulkano::descriptor_set::DescriptorSet::new(&descriptor_pool, &descriptor_set_layout,
&uniform_buffer).unwrap();
mod pipeline_layout {
pipeline_layout!{
set0: {
uniforms: UniformBuffer<::vs::ty::Data>
}
}
}
let pipeline_layout = pipeline_layout::CustomPipeline::new(&device).unwrap();
let set = pipeline_layout::set0::Set::new(&descriptor_pool, &pipeline_layout, &pipeline_layout::set0::Descriptors {
uniforms: &uniform_buffer
}).unwrap();
let pipeline = {
let ia = vulkano::pipeline::input_assembly::InputAssembly::triangle_list();
@ -211,7 +217,8 @@ fn main() {
color: [0.0, 0.0, 1.0, 1.0],
depth: 1.0,
})
.draw_indexed(&pipeline, (&vertex_buffer, &normals_buffer), &index_buffer, &vulkano::command_buffer::DynamicState::none(), set.clone())
.draw_indexed(&pipeline, (&vertex_buffer, &normals_buffer), &index_buffer,
&vulkano::command_buffer::DynamicState::none(), &set)
.draw_end()
.build().unwrap()
}).collect::<Vec<_>>();

View File

@ -689,7 +689,7 @@ impl InnerCommandBufferBuilder {
pub unsafe fn draw<V, Pv, Pl, L, Rp>(mut self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
vertices: V, dynamic: &DynamicState,
sets: L) -> InnerCommandBufferBuilder
where Pv: 'static + VertexDefinition + VertexSource<V>, L: 'static + DescriptorSetsCollection + Send + Sync,
where Pv: 'static + VertexDefinition + VertexSource<V>, L: DescriptorSetsCollection + Send + Sync,
Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync
{
// FIXME: add buffers to the resources
@ -730,7 +730,7 @@ impl InnerCommandBufferBuilder {
pub unsafe fn draw_indexed<'a, V, Pv, Pl, Rp, L, I, Ib, Ibb>(mut self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
vertices: V, indices: Ib, dynamic: &DynamicState,
sets: L) -> InnerCommandBufferBuilder
where L: 'static + DescriptorSetsCollection + Send + Sync,
where L: DescriptorSetsCollection + Send + Sync,
Pv: 'static + VertexDefinition + VertexSource<V>,
Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync,
Ib: Into<BufferSlice<'a, [I], Ibb>>, I: 'static + Index, Ibb: Buffer + 'static
@ -783,7 +783,7 @@ impl InnerCommandBufferBuilder {
}
fn bind_compute_pipeline_state<Pl, L>(&mut self, pipeline: &Arc<ComputePipeline<Pl>>, sets: L)
where L: 'static + DescriptorSetsCollection,
where L: DescriptorSetsCollection,
Pl: 'static + PipelineLayout + Send + Sync
{
unsafe {
@ -832,7 +832,7 @@ impl InnerCommandBufferBuilder {
fn bind_gfx_pipeline_state<V, Pl, L, Rp>(&mut self, pipeline: &Arc<GraphicsPipeline<V, Pl, Rp>>,
dynamic: &DynamicState, sets: L)
where V: 'static + VertexDefinition + Send + Sync, L: 'static + DescriptorSetsCollection + Send + Sync,
where V: 'static + VertexDefinition + Send + Sync, L: DescriptorSetsCollection + Send + Sync,
Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync
{
unsafe {

View File

@ -285,7 +285,7 @@ impl PrimaryCommandBufferBuilderInlineDraw {
vertices: V, dynamic: &DynamicState, sets: L)
-> PrimaryCommandBufferBuilderInlineDraw
where Pv: VertexDefinition + VertexSource<V> + 'static, Pl: PipelineLayout + 'static + Send + Sync, Rp: 'static + Send + Sync,
L: DescriptorSetsCollection + 'static + Send + Sync
L: DescriptorSetsCollection + Send + Sync
{
// FIXME: check subpass
@ -304,7 +304,7 @@ impl PrimaryCommandBufferBuilderInlineDraw {
sets: L) -> PrimaryCommandBufferBuilderInlineDraw
where Pv: 'static + VertexDefinition + VertexSource<V> + Send + Sync, Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync,
Ib: Into<BufferSlice<'a, [I], Ibb>>, I: 'static + Index, Ibb: Buffer + 'static + Send + Sync,
L: DescriptorSetsCollection + 'static + Send + Sync
L: DescriptorSetsCollection + Send + Sync
{
// FIXME: check subpass
@ -532,7 +532,7 @@ impl<R> SecondaryGraphicsCommandBufferBuilder<R>
vertices: V, dynamic: &DynamicState, sets: L)
-> SecondaryGraphicsCommandBufferBuilder<R>
where Pv: VertexDefinition + VertexSource<V> + 'static, Pl: PipelineLayout + 'static + Send + Sync,
Rp: RenderPass + 'static + Send + Sync, L: DescriptorSetsCollection + 'static + Send + Sync,
Rp: RenderPass + 'static + Send + Sync, L: DescriptorSetsCollection + Send + Sync,
R: RenderPassCompatible<Rp>
{
assert!(self.render_pass.is_compatible_with(pipeline.subpass().render_pass()));
@ -555,7 +555,7 @@ impl<R> SecondaryGraphicsCommandBufferBuilder<R>
where Pv: 'static + VertexDefinition + VertexSource<V>, Pl: 'static + PipelineLayout + Send + Sync,
Rp: RenderPass + 'static + Send + Sync,
Ib: Into<BufferSlice<'a, [I], Ibb>>, I: 'static + Index, Ibb: Buffer + 'static,
L: DescriptorSetsCollection + 'static + Send + Sync
L: DescriptorSetsCollection + Send + Sync
{
assert!(self.render_pass.is_compatible_with(pipeline.subpass().render_pass()));
assert_eq!(self.render_pass_subpass, pipeline.subpass().index());

View File

@ -33,6 +33,17 @@ unsafe impl DescriptorSetsCollection for () {
}
}
unsafe impl<'a, T> DescriptorSetsCollection for Arc<T>
where T: DescriptorSet
{
type Iter = OptionIntoIter<Arc<DescriptorSet>>;
#[inline]
fn list(&self) -> Self::Iter {
Some(self.clone() as Arc<_>).into_iter()
}
}
unsafe impl<'a, T> DescriptorSetsCollection for &'a Arc<T>
where T: DescriptorSet
{

View File

@ -58,7 +58,7 @@ impl UnsafeDescriptorSet {
// FIXME: this has to check whether there's still enough room in the pool
pub unsafe fn uninitialized(pool: &Arc<DescriptorPool>,
layout: &Arc<UnsafeDescriptorSetLayout>)
-> Result<Arc<UnsafeDescriptorSet>, OomError>
-> Result<UnsafeDescriptorSet, OomError>
{
assert_eq!(&**pool.device() as *const Device, &**layout.device() as *const Device);
@ -81,7 +81,7 @@ impl UnsafeDescriptorSet {
output
};
Ok(Arc::new(UnsafeDescriptorSet {
Ok(UnsafeDescriptorSet {
set: set,
pool: pool.clone(),
layout: layout.clone(),
@ -90,7 +90,7 @@ impl UnsafeDescriptorSet {
resources_images: Vec::new(),
resources_image_views: Vec::new(),
resources_buffers: Vec::new(),
}))
})
}
/// Modifies a descriptor set without checking that the writes are correct.

View File

@ -7,17 +7,21 @@
// notice may not be copied, modified, or distributed except
// according to those terms.
use std::marker::PhantomData;
use std::sync::Arc;
use buffer::TypedBuffer;
#[macro_export]
macro_rules! pipeline_layout {
($($name:ident: { $($field:ident $ty:ty),* }),*) => (
#![allow(unsafe_code)]
($($name:ident: { $($field:ident: $ty:ty),* }),*) => {
use std::sync::Arc;
use std::vec::IntoIter as VecIntoIter;
use $crate::OomError;
use $crate::descriptor_set::descriptor_set::DescriptorSet;
use $crate::descriptor_set::descriptor_set::UnsafeDescriptorSet;
use $crate::descriptor_set::descriptor_set::UnsafeDescriptorSetLayout;
use $crate::device::Device;
use $crate::descriptor_set::descriptor::DescriptorDesc;
use $crate::descriptor_set::pipeline_layout::PipelineLayout;
use $crate::descriptor_set::pipeline_layout::PipelineLayoutDesc;
use $crate::descriptor_set::pipeline_layout::UnsafePipelineLayout;
pub struct CustomPipeline {
@ -25,21 +29,25 @@ macro_rules! pipeline_layout {
}
impl CustomPipeline {
#[allow(unsafe_code)]
pub fn new(device: &Arc<Device>) -> Result<Arc<CustomPipeline>, OomError> {
let layouts = vec![
$(
try!($name::layout(device))
try!($name::build_set_layout(device))
),*
];
let inner = try!(UnsafePipelineLayout::new(device, layouts.iter()));
let inner = unsafe {
try!(UnsafePipelineLayout::new(device, layouts.iter()))
};
Ok(CustomPipeline {
Ok(Arc::new(CustomPipeline {
inner: inner
})
}))
}
}
#[allow(unsafe_code)]
unsafe impl PipelineLayout for CustomPipeline {
#[inline]
fn inner_pipeline_layout(&self) -> &UnsafePipelineLayout {
@ -47,26 +55,95 @@ macro_rules! pipeline_layout {
}
}
$(
pub struct $name {
inner: UnsafeDescriptorSet
#[allow(unsafe_code)]
unsafe impl PipelineLayoutDesc for CustomPipeline {
type SetsIter = VecIntoIter<Self::DescIter>;
type DescIter = VecIntoIter<DescriptorDesc>;
fn descriptors_desc(&self) -> Self::SetsIter {
// FIXME:
vec![].into_iter()
}
}
pipeline_layout!{__inner__ (0) $($name: {$($field: $ty),*}),*}
};
(__inner__ ($num:expr) $name:ident: { $($field:ident: $ty:ty),* } $($rest:tt)*) => {
pub mod $name {
use std::sync::Arc;
use super::CustomPipeline;
use $crate::OomError;
use $crate::device::Device;
use $crate::descriptor_set::descriptor::DescriptorWrite;
use $crate::descriptor_set::descriptor_set::DescriptorPool;
use $crate::descriptor_set::descriptor_set::DescriptorSet;
use $crate::descriptor_set::descriptor_set::UnsafeDescriptorSet;
use $crate::descriptor_set::descriptor_set::UnsafeDescriptorSetLayout;
use $crate::descriptor_set::pipeline_layout::PipelineLayout;
use $crate::descriptor_set::pipeline_layout::custom_pipeline_macro::ValidParameter;
use $crate::descriptor_set::pipeline_layout::custom_pipeline_macro::UniformBuffer;
pub const SET_NUM: u32 = $num;
pub struct Descriptors<$($field),*> {
$(
pub $field: $field
),*
}
impl $name {
fn layout(device: &Arc<Device>)
-> Result<Arc<UnsafeDescriptorSetLayout>, OomError>
{
unimplemented!()
impl<$($field: ValidParameter<$ty>),*> Descriptors<$($field),*> {
pub fn writes(&self) -> Vec<DescriptorWrite> {
vec![]
}
}
unsafe impl DescriptorSet for $name {
pub struct Set {
inner: UnsafeDescriptorSet
}
impl Set {
#[inline]
pub fn new<$($field: ValidParameter<$ty>),*>
(pool: &Arc<DescriptorPool>, layout: &Arc<CustomPipeline>,
descriptors: &Descriptors<$($field)*>)
-> Result<Arc<Set>, OomError>
{
#![allow(unsafe_code)]
unsafe {
let layout = layout.inner_pipeline_layout().descriptor_set_layout($num).unwrap();
let mut set = try!(UnsafeDescriptorSet::uninitialized(pool, layout));
set.write(descriptors.writes());
Ok(Arc::new(Set { inner: set }))
}
}
}
#[allow(unsafe_code)]
unsafe impl DescriptorSet for Set {
#[inline]
fn inner_descriptor_set(&self) -> &UnsafeDescriptorSet {
&self.inner
}
}
)*
);
pub fn build_set_layout(device: &Arc<Device>)
-> Result<Arc<UnsafeDescriptorSetLayout>, OomError>
{
unimplemented!()
}
}
pipeline_layout!{__inner__ ($num+1) $($rest)*}
};
(__inner__ ($num:expr)) => {};
}
pub unsafe trait ValidParameter<Target> {}
pub struct UniformBuffer<T: ?Sized>(PhantomData<T>);
unsafe impl<'a, B, T: ?Sized + 'static> ValidParameter<UniformBuffer<T>> for &'a Arc<B>
where B: TypedBuffer<Content = T>
{
}

View File

@ -23,7 +23,7 @@ use descriptor_set::descriptor_set::DescriptorSetsCollection;
use descriptor_set::descriptor_set::UnsafeDescriptorSetLayout;
use device::Device;
mod custom_pipeline_macro;
pub mod custom_pipeline_macro;
/// Trait for objects that describe the layout of the descriptors and push constants of a pipeline.
pub unsafe trait PipelineLayout: PipelineLayoutDesc + 'static + Send + Sync {

View File

@ -12,6 +12,7 @@ use std::ptr;
use std::sync::Arc;
use descriptor_set::PipelineLayout;
//use descriptor_set::pipeline_layout::PipelineLayoutDesc;
//use descriptor_set::pipeline_layout::PipelineLayoutSuperset;
use pipeline::shader::ComputeShaderEntryPoint;
@ -40,7 +41,7 @@ impl<Pl> ComputePipeline<Pl> {
pub fn new<Csl>(device: &Arc<Device>, pipeline_layout: &Arc<Pl>,
shader: &ComputeShaderEntryPoint<Csl>)
-> Result<Arc<ComputePipeline<Pl>>, OomError>
where Pl: PipelineLayout// + PipelineLayoutSuperset<Csl>, Csl: PipelineLayout
where Pl: PipelineLayout// + PipelineLayoutSuperset<Csl>, Csl: PipelineLayoutDesc
{
let vk = device.pointers();

View File

@ -14,6 +14,7 @@ use smallvec::SmallVec;
use device::Device;
use descriptor_set::PipelineLayout;
use descriptor_set::pipeline_layout::PipelineLayoutDesc;
use descriptor_set::pipeline_layout::PipelineLayoutSuperset;
use framebuffer::RenderPass;
use framebuffer::Subpass;
@ -77,7 +78,7 @@ impl<Mv, L, Rp> GraphicsPipeline<Mv, L, Rp>
layout: &Arc<L>, render_pass: Subpass<Rp>)
-> Result<Arc<GraphicsPipeline<Mv, L, Rp>>, OomError>
where L: PipelineLayout + PipelineLayoutSuperset<Vl> + PipelineLayoutSuperset<Fl>,
Vl: PipelineLayout, Fl: PipelineLayout
Vl: PipelineLayoutDesc, Fl: PipelineLayoutDesc
{
let vk = device.pointers();