mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-25 00:04:15 +00:00
Make teapot example compile (but not work)
This commit is contained in:
parent
105f2ba421
commit
f01d1fde37
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<_>>();
|
||||
|
@ -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 {
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
{
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user