mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 06:45:23 +00:00
Better descriptor sets design
This commit is contained in:
parent
b155b5bae4
commit
5106b6aa0f
@ -140,14 +140,26 @@ fn main() {
|
||||
|
||||
|
||||
let descriptor_pool = vulkano::descriptor_set::DescriptorPool::new(&device).unwrap();
|
||||
let descriptor_set_layout = {
|
||||
let desc = vulkano::descriptor_set::RuntimeDescriptorSetDesc {
|
||||
descriptors: vec![
|
||||
vulkano::descriptor_set::DescriptorDesc {
|
||||
binding: 0,
|
||||
ty: vulkano::descriptor_set::DescriptorType::UniformBuffer,
|
||||
array_count: 1,
|
||||
stages: vulkano::descriptor_set::ShaderStages::all_graphics(),
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
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 set1 = vulkano::descriptor_set::DescriptorSet::new(&descriptor_pool, &layout1, uniform_buffer.clone() as std::sync::Arc<_>).unwrap();
|
||||
(pipeline_layout, set1)
|
||||
vulkano::descriptor_set::DescriptorSetLayout::new(&device, desc).unwrap()
|
||||
};
|
||||
|
||||
let pipeline_layout = vulkano::descriptor_set::PipelineLayout::new(&device, vulkano::descriptor_set::RuntimeDesc, vec![descriptor_set_layout.clone()]).unwrap();
|
||||
let set = vulkano::descriptor_set::DescriptorSet::new(&descriptor_pool, &descriptor_set_layout,
|
||||
vec![(0, vulkano::descriptor_set::DescriptorBind::UniformBuffer(uniform_buffer.clone()))]).unwrap();
|
||||
|
||||
|
||||
let pipeline = {
|
||||
let ia = vulkano::pipeline::input_assembly::InputAssembly {
|
||||
topology: vulkano::pipeline::input_assembly::PrimitiveTopology::TriangleList,
|
||||
@ -189,7 +201,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], 1.0))
|
||||
.draw_indexed(&pipeline, (vertex_buffer.clone(), normals_buffer.clone()), &index_buffer, &vulkano::command_buffer::DynamicState::none(), (set.clone(), ()))
|
||||
.draw_indexed(&pipeline, (vertex_buffer.clone(), normals_buffer.clone()), &index_buffer, &vulkano::command_buffer::DynamicState::none(), set.clone())
|
||||
.draw_end()
|
||||
.build().unwrap()
|
||||
}).collect::<Vec<_>>();
|
||||
|
@ -8,6 +8,7 @@ use buffer::BufferResource;
|
||||
use command_buffer::CommandBufferPool;
|
||||
use command_buffer::DynamicState;
|
||||
use descriptor_set::PipelineLayoutDesc;
|
||||
use descriptor_set::DescriptorSetsCollection;
|
||||
use device::Queue;
|
||||
use framebuffer::ClearValue;
|
||||
use framebuffer::Framebuffer;
|
||||
@ -265,10 +266,11 @@ impl InnerCommandBufferBuilder {
|
||||
|
||||
/// Calls `vkCmdDraw`.
|
||||
// FIXME: push constants
|
||||
pub unsafe fn draw<V, L>(mut self, pipeline: &Arc<GraphicsPipeline<V, L>>,
|
||||
pub unsafe fn draw<V, Pl, L>(mut self, pipeline: &Arc<GraphicsPipeline<V, Pl>>,
|
||||
vertices: V, dynamic: &DynamicState,
|
||||
sets: L::DescriptorSets) -> InnerCommandBufferBuilder
|
||||
where V: 'static + MultiVertex, L: 'static + PipelineLayoutDesc
|
||||
sets: L) -> InnerCommandBufferBuilder
|
||||
where V: 'static + MultiVertex, L: 'static + DescriptorSetsCollection,
|
||||
Pl: 'static + PipelineLayoutDesc
|
||||
{
|
||||
|
||||
// FIXME: add buffers to the resources
|
||||
@ -292,10 +294,11 @@ impl InnerCommandBufferBuilder {
|
||||
|
||||
/// Calls `vkCmdDrawIndexed`.
|
||||
// FIXME: push constants
|
||||
pub unsafe fn draw_indexed<'a, V, L, I, Ib, IbM>(mut self, pipeline: &Arc<GraphicsPipeline<V, L>>,
|
||||
pub unsafe fn draw_indexed<'a, V, Pl, L, I, Ib, IbM>(mut self, pipeline: &Arc<GraphicsPipeline<V, Pl>>,
|
||||
vertices: V, indices: Ib, dynamic: &DynamicState,
|
||||
sets: L::DescriptorSets) -> InnerCommandBufferBuilder
|
||||
where V: 'static + MultiVertex, L: 'static + PipelineLayoutDesc,
|
||||
sets: L) -> InnerCommandBufferBuilder
|
||||
where V: 'static + MultiVertex, L: 'static + DescriptorSetsCollection,
|
||||
Pl: 'static + PipelineLayoutDesc,
|
||||
Ib: Into<BufferSlice<'a, [I], IbM>>, I: 'static + Index, IbM: 'static
|
||||
{
|
||||
|
||||
@ -323,13 +326,16 @@ impl InnerCommandBufferBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
fn bind_gfx_pipeline_state<V: 'static, L: 'static>(&mut self, pipeline: &Arc<GraphicsPipeline<V, L>>,
|
||||
dynamic: &DynamicState, sets: L::DescriptorSets)
|
||||
where V: MultiVertex, L: PipelineLayoutDesc
|
||||
fn bind_gfx_pipeline_state<V, Pl, L>(&mut self, pipeline: &Arc<GraphicsPipeline<V, Pl>>,
|
||||
dynamic: &DynamicState, sets: L)
|
||||
where V: 'static + MultiVertex, L: 'static + DescriptorSetsCollection,
|
||||
Pl: 'static + PipelineLayoutDesc
|
||||
{
|
||||
unsafe {
|
||||
let vk = self.device.pointers();
|
||||
|
||||
assert!(sets.is_compatible_with(pipeline.layout()));
|
||||
|
||||
if self.graphics_pipeline != Some(pipeline.internal_object()) {
|
||||
vk.CmdBindPipeline(self.cmd.unwrap(), vk::PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pipeline.internal_object());
|
||||
@ -349,7 +355,8 @@ impl InnerCommandBufferBuilder {
|
||||
}
|
||||
|
||||
// FIXME: keep these alive
|
||||
let descriptor_sets = pipeline.layout().description().decode_descriptor_sets(sets);
|
||||
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
|
||||
let descriptor_sets = sets.list().collect::<Vec<_>>();
|
||||
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
|
||||
let descriptor_sets = descriptor_sets.into_iter().map(|set| set.internal_object()).collect::<Vec<_>>();
|
||||
|
||||
|
@ -6,6 +6,7 @@ use command_buffer::CommandBufferPool;
|
||||
use command_buffer::inner::InnerCommandBufferBuilder;
|
||||
use command_buffer::inner::InnerCommandBuffer;
|
||||
use descriptor_set::PipelineLayoutDesc;
|
||||
use descriptor_set::DescriptorSetsCollection;
|
||||
use device::Queue;
|
||||
use framebuffer::Framebuffer;
|
||||
use framebuffer::RenderPass;
|
||||
@ -203,10 +204,11 @@ pub struct PrimaryCommandBufferBuilderInlineDraw {
|
||||
impl PrimaryCommandBufferBuilderInlineDraw {
|
||||
/// Calls `vkCmdDraw`.
|
||||
// FIXME: push constants
|
||||
pub fn draw<V, L>(self, pipeline: &Arc<GraphicsPipeline<V, L>>,
|
||||
vertices: V, dynamic: &DynamicState, sets: L::DescriptorSets)
|
||||
-> PrimaryCommandBufferBuilderInlineDraw
|
||||
where V: MultiVertex + 'static, L: PipelineLayoutDesc + 'static
|
||||
pub fn draw<V, L, Pl>(self, pipeline: &Arc<GraphicsPipeline<V, Pl>>,
|
||||
vertices: V, dynamic: &DynamicState, sets: L)
|
||||
-> PrimaryCommandBufferBuilderInlineDraw
|
||||
where V: MultiVertex + 'static, Pl: PipelineLayoutDesc + 'static,
|
||||
L: DescriptorSetsCollection + 'static
|
||||
{
|
||||
unsafe {
|
||||
PrimaryCommandBufferBuilderInlineDraw {
|
||||
@ -218,11 +220,12 @@ impl PrimaryCommandBufferBuilderInlineDraw {
|
||||
}
|
||||
|
||||
/// Calls `vkCmdDrawIndexed`.
|
||||
pub fn draw_indexed<'a, V, L, I, Ib, IbM>(mut self, pipeline: &Arc<GraphicsPipeline<V, L>>,
|
||||
pub fn draw_indexed<'a, V, L, Pl, I, Ib, IbM>(mut self, pipeline: &Arc<GraphicsPipeline<V, Pl>>,
|
||||
vertices: V, indices: Ib, dynamic: &DynamicState,
|
||||
sets: L::DescriptorSets) -> PrimaryCommandBufferBuilderInlineDraw
|
||||
where V: 'static + MultiVertex, L: 'static + PipelineLayoutDesc,
|
||||
Ib: Into<BufferSlice<'a, [I], IbM>>, I: 'static + Index, IbM: 'static
|
||||
sets: L) -> PrimaryCommandBufferBuilderInlineDraw
|
||||
where V: 'static + MultiVertex, Pl: 'static + PipelineLayoutDesc,
|
||||
Ib: Into<BufferSlice<'a, [I], IbM>>, I: 'static + Index, IbM: 'static,
|
||||
L: DescriptorSetsCollection + 'static
|
||||
{
|
||||
unsafe {
|
||||
PrimaryCommandBufferBuilderInlineDraw {
|
||||
|
@ -19,7 +19,7 @@
|
||||
//! # Binding resources
|
||||
//!
|
||||
//! In parallel of the pipeline initialization, you have to create a `DescriptorSet<T>`. This
|
||||
//! struct contains the list of actual resources that will be binded when the pipeline is executed.
|
||||
//! struct contains the list of actual resources that will be bound when the pipeline is executed.
|
||||
//! To build a `DescriptorSet<T>`, you need to pass a `DescriptorSetLayout<T>`. The `T` parameter
|
||||
//! must implement `DescriptorSetDesc` as if the same for both the descriptor set and its layout.
|
||||
//!
|
||||
@ -37,6 +37,7 @@
|
||||
|
||||
|
||||
use std::mem;
|
||||
use std::option::IntoIter as OptionIntoIter;
|
||||
use std::ptr;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -63,43 +64,135 @@ pub unsafe trait PipelineLayoutDesc {
|
||||
type PushConstants;
|
||||
|
||||
/// Turns the `DescriptorSets` associated type into something vulkano can understand.
|
||||
fn decode_descriptor_sets(&self, Self::DescriptorSets) -> Vec<Arc<AbstractDescriptorSet>>;
|
||||
fn decode_descriptor_sets(&self, Self::DescriptorSets) -> Vec<Arc<AbstractDescriptorSet>>; // TODO: vec is slow
|
||||
|
||||
/// Turns the `DescriptorSetLayouts` associated type into something vulkano can understand.
|
||||
fn decode_descriptor_set_layouts(&self, Self::DescriptorSetLayouts)
|
||||
-> Vec<Arc<AbstractDescriptorSetLayout>>;
|
||||
-> Vec<Arc<AbstractDescriptorSetLayout>>; // TODO: vec is slow
|
||||
|
||||
// FIXME: implement this correctly
|
||||
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);
|
||||
/// FIXME: it should be unsafe to create this struct
|
||||
pub struct RuntimeDesc;
|
||||
|
||||
unsafe impl PipelineLayoutDesc for RuntimeDesc {
|
||||
type DescriptorSets = Vec<Arc<AbstractDescriptorSet>>;
|
||||
type DescriptorSetLayouts = Vec<Arc<AbstractDescriptorSetLayout>>;
|
||||
type 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
|
||||
fn decode_descriptor_sets(&self, sets: Self::DescriptorSets) -> Vec<Arc<AbstractDescriptorSet>> {
|
||||
sets
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn decode_descriptor_set_layouts(&self, s: Self::DescriptorSetLayouts)
|
||||
fn decode_descriptor_set_layouts(&self, layouts: 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
|
||||
layouts
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#[macro_export]
|
||||
macro_rules! pipeline_layout {
|
||||
(sets: {$($set_name:ident: { $($name:ident : ),* }),*}) => {
|
||||
mod layout {
|
||||
use std::sync::Arc;
|
||||
use $crate::descriptor_set::DescriptorType;
|
||||
use $crate::descriptor_set::DescriptorDesc;
|
||||
use $crate::descriptor_set::DescriptorSetDesc;
|
||||
use $crate::descriptor_set::DescriptorWrite;
|
||||
use $crate::descriptor_set::DescriptorBind;
|
||||
use $crate::descriptor_set::PipelineLayout;
|
||||
use $crate::descriptor_set::PipelineLayoutDesc;
|
||||
use $crate::descriptor_set::ShaderStages;
|
||||
use $crate::buffer::BufferResource;
|
||||
|
||||
$(
|
||||
pub struct $set_name;
|
||||
unsafe impl DescriptorSetDesc for $set_name {
|
||||
type Write = ( // FIXME: variable number of elems
|
||||
Arc<BufferResource> // FIXME: strong typing
|
||||
);
|
||||
|
||||
type Init = Self::Write;
|
||||
|
||||
#[inline]
|
||||
fn descriptors(&self) -> Vec<DescriptorDesc> {
|
||||
let mut binding = 0;
|
||||
let mut result = Vec::new(); // TODO: with_capacity
|
||||
|
||||
//$(
|
||||
result.push(DescriptorDesc {
|
||||
binding: binding,
|
||||
ty: DescriptorType::UniformBuffer, // FIXME:
|
||||
array_count: 1, // FIXME:
|
||||
stages: ShaderStages::all_graphics(), // FIXME:
|
||||
});
|
||||
|
||||
binding += 1;
|
||||
//)* // FIXME: variable number of elems
|
||||
|
||||
let _ = binding; // removes a warning
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn decode_write(&self, data: Self::Write) -> Vec<DescriptorWrite> {
|
||||
let mut binding = 0;
|
||||
let mut result = Vec::new(); // TODO: with_capacity
|
||||
|
||||
let $($name),* = data;
|
||||
|
||||
$(
|
||||
result.push(DescriptorWrite {
|
||||
binding: binding,
|
||||
array_element: 0, // FIXME:
|
||||
content: DescriptorBind::UniformBuffer($name),
|
||||
});
|
||||
|
||||
binding += 1;
|
||||
)*
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn decode_init(&self, data: Self::Init) -> Vec<DescriptorWrite> {
|
||||
self.decode_write(data)
|
||||
}
|
||||
}
|
||||
)*
|
||||
|
||||
pub struct Layout;
|
||||
unsafe impl PipelineLayoutDesc for Layout {
|
||||
type DescriptorSets = ($(Arc<DescriptorSet<$set_name>>),*);
|
||||
type DescriptorSetLayouts = ($(Arc<DescriptorSetLayout<$set_name>>),*);
|
||||
type PushConstants = ();
|
||||
|
||||
#[inline]
|
||||
fn decode_descriptor_sets(&self, sets: Self::DescriptorSets)
|
||||
-> Vec<Arc<AbstractDescriptorSet>>
|
||||
{
|
||||
let $($set_name),* = sets;
|
||||
vec![$($set_name as Arc<_>),*]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn decode_descriptor_set_layouts(&self, layouts: Self::DescriptorSetLayouts)
|
||||
-> Vec<Arc<AbstractDescriptorSetLayout>>
|
||||
{
|
||||
let $($set_name),* = layouts;
|
||||
vec![$($set_name as Arc<_>),*]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
/// Dummy implementation of `PipelineLayoutDesc` that describes an empty pipeline.
|
||||
///
|
||||
/// The descriptors, descriptor sets and push constants are all `()`. You have to pass `()` when
|
||||
@ -119,6 +212,26 @@ unsafe impl PipelineLayoutDesc for EmptyPipelineDesc {
|
||||
-> Vec<Arc<AbstractDescriptorSet>> { vec![] }
|
||||
}
|
||||
|
||||
unsafe impl<A, B> PipelineLayoutDesc for (Arc<DescriptorSet<A>>, Arc<DescriptorSet<B>>)
|
||||
where A: 'static + DescriptorSetDesc, B: 'static + DescriptorSetDesc
|
||||
{
|
||||
type DescriptorSets = (Arc<DescriptorSet<A>>, Arc<DescriptorSet<B>>);
|
||||
type DescriptorSetLayouts = (Arc<DescriptorSetLayout<A>>, Arc<DescriptorSetLayout<B>>);
|
||||
type PushConstants = ();
|
||||
|
||||
#[inline]
|
||||
fn decode_descriptor_sets(&self, sets: Self::DescriptorSets) -> Vec<Arc<AbstractDescriptorSet>> {
|
||||
vec![sets.0, sets.1]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn decode_descriptor_set_layouts(&self, layouts: Self::DescriptorSetLayouts)
|
||||
-> Vec<Arc<AbstractDescriptorSetLayout>>
|
||||
{
|
||||
vec![layouts.0, layouts.1]
|
||||
}
|
||||
}
|
||||
|
||||
/// Types that describe a single descriptor set.
|
||||
pub unsafe trait DescriptorSetDesc {
|
||||
/// Represents a modification of a descriptor set. A parameter of this type must be passed
|
||||
@ -129,13 +242,13 @@ pub unsafe trait DescriptorSetDesc {
|
||||
type Init;
|
||||
|
||||
/// Returns the list of descriptors contained in this set.
|
||||
fn descriptors(&self) -> Vec<DescriptorDesc>; // TODO: Cow for better perfs
|
||||
fn descriptors(&self) -> Vec<DescriptorDesc>; // TODO: better perfs
|
||||
|
||||
/// Turns the `Write` associated type into something vulkano can understand.
|
||||
fn decode_write(&self, Self::Write) -> Vec<DescriptorWrite>;
|
||||
fn decode_write(&self, Self::Write) -> Vec<DescriptorWrite>; // TODO: better perfs
|
||||
|
||||
/// Turns the `Init` associated type into something vulkano can understand.
|
||||
fn decode_init(&self, Self::Init) -> Vec<DescriptorWrite>;
|
||||
fn decode_init(&self, Self::Init) -> Vec<DescriptorWrite>; // TODO: better perfs
|
||||
|
||||
// FIXME: implement this correctly
|
||||
fn is_compatible_with<S>(&self, _: &S) -> bool where S: DescriptorSetDesc { true }
|
||||
@ -155,6 +268,7 @@ pub enum DescriptorBind {
|
||||
}
|
||||
|
||||
/// Describes a single descriptor.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct DescriptorDesc {
|
||||
/// Offset of the binding within the descriptor.
|
||||
pub binding: u32,
|
||||
@ -169,7 +283,7 @@ pub struct DescriptorDesc {
|
||||
pub stages: ShaderStages,
|
||||
}
|
||||
|
||||
/// Describes what kind of resource may later be bind to a descriptor.
|
||||
/// Describes what kind of resource may later be bound to a descriptor.
|
||||
// FIXME: add immutable sampler when relevant
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(u32)]
|
||||
@ -197,6 +311,7 @@ impl DescriptorType {
|
||||
}
|
||||
|
||||
/// Describes which shader stages have access to a descriptor.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct ShaderStages {
|
||||
pub vertex: bool,
|
||||
pub tessellation_control: bool,
|
||||
@ -249,55 +364,37 @@ impl Into<vk::ShaderStageFlags> for ShaderStages {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
pub unsafe trait CompatiblePipeline<T> { type Out: PipelineLayoutDesc; }
|
||||
pub unsafe trait CompatibleSet<T> { type Out: DescriptorSetDesc; }
|
||||
|
||||
macro_rules! impl_tuple {
|
||||
(($in_first:ident $out_first:ident) $(, ($in_rest:ident $out_rest:ident))*) => {
|
||||
unsafe impl<$in_first, $out_first $(, $in_rest, $out_rest)*>
|
||||
CompatibleSet<($out_first, $($out_rest,)*)> for ($in_first, $($in_rest,)*)
|
||||
where $in_first: CompatibleDescriptor<$out_first> $(, $in_rest: CompatibleDescriptor<$out_rest>)*
|
||||
{
|
||||
type Out = (
|
||||
<$in_first as CompatibleDescriptor<$out_first>>::Out,
|
||||
$(
|
||||
<$in_rest as CompatibleDescriptor<$out_rest>>::Out,
|
||||
)*
|
||||
);
|
||||
}
|
||||
|
||||
unsafe impl<$in_first, $out_first $(, $in_rest, $out_rest)*>
|
||||
CompatiblePipeline<($out_first, $($out_rest,)*)> for ($in_first, $($in_rest,)*)
|
||||
where $in_first: CompatibleSet<$out_first> $(, $in_rest: CompatibleSet<$out_rest>)*
|
||||
{
|
||||
type Out = (
|
||||
<$in_first as CompatibleSet<$out_first>>::Out,
|
||||
$(
|
||||
<$in_rest as CompatibleSet<$out_rest>>::Out,
|
||||
)*
|
||||
);
|
||||
}
|
||||
|
||||
impl_tuple!{$(($in_rest $out_rest)),*}
|
||||
};
|
||||
|
||||
() => ();
|
||||
/// FIXME: should be unsafe to create this struct
|
||||
pub struct RuntimeDescriptorSetDesc {
|
||||
pub descriptors: Vec<DescriptorDesc>,
|
||||
}
|
||||
|
||||
impl_tuple!( (A N), (B O), (C P), (D Q), (E R), (F S), (G T),
|
||||
(H U), (I V), (J W), (K X), (L Y), (M Z) );
|
||||
unsafe impl DescriptorSetDesc for RuntimeDescriptorSetDesc {
|
||||
type Write = Vec<(u32, DescriptorBind)>;
|
||||
|
||||
/// If a type `A` can be interpreted as a `T`, then `A` will implement `CompatibleDescriptor<T>`.
|
||||
trait CompatibleDescriptor<T> { type Out; }
|
||||
type Init = Vec<(u32, DescriptorBind)>;
|
||||
|
||||
impl CompatibleDescriptor<()> for () { type Out = (); }
|
||||
impl<T> CompatibleDescriptor<()> for T where T: Descriptor { type Out = T; }
|
||||
impl<T> CompatibleDescriptor<T> for () where T: Descriptor { type Out = T; }
|
||||
impl<T> CompatibleDescriptor<T> for T where T: Descriptor { type Out = T; }
|
||||
fn descriptors(&self) -> Vec<DescriptorDesc> {
|
||||
self.descriptors.clone()
|
||||
}
|
||||
|
||||
fn decode_write(&self, data: Self::Write) -> Vec<DescriptorWrite> {
|
||||
data.into_iter().map(|(binding, bind)| {
|
||||
// TODO: check correctness?
|
||||
|
||||
DescriptorWrite {
|
||||
binding: binding,
|
||||
array_element: 0, // FIXME:
|
||||
content: bind,
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
||||
fn decode_init(&self, data: Self::Init) -> Vec<DescriptorWrite> {
|
||||
self.decode_write(data)
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe trait Descriptor {}*/
|
||||
|
||||
/// An actual descriptor set with the resources that are binded to it.
|
||||
pub struct DescriptorSet<S> {
|
||||
@ -595,3 +692,28 @@ impl DescriptorPool {
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe trait DescriptorSetsCollection {
|
||||
type Iter: ExactSizeIterator<Item = Arc<AbstractDescriptorSet>>;
|
||||
|
||||
fn list(&self) -> Self::Iter;
|
||||
|
||||
fn is_compatible_with<P>(&self, pipeline_layout: &Arc<PipelineLayout<P>>) -> bool;
|
||||
}
|
||||
|
||||
unsafe impl<T> DescriptorSetsCollection for Arc<DescriptorSet<T>>
|
||||
where T: 'static + DescriptorSetDesc
|
||||
{
|
||||
type Iter = OptionIntoIter<Arc<AbstractDescriptorSet>>;
|
||||
|
||||
#[inline]
|
||||
fn list(&self) -> Self::Iter {
|
||||
Some(self.clone() as Arc<_>).into_iter()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_compatible_with<P>(&self, pipeline_layout: &Arc<PipelineLayout<P>>) -> bool {
|
||||
// FIXME:
|
||||
true
|
||||
}
|
||||
}
|
||||
|
@ -42,8 +42,8 @@ pub struct GraphicsPipeline<MultiVertex, Layout> {
|
||||
marker: PhantomData<(MultiVertex,)>
|
||||
}
|
||||
|
||||
impl<MV, Vl, Fl> GraphicsPipeline<MV, (Vl, Fl)>
|
||||
where MV: MultiVertex
|
||||
impl<MV, L> GraphicsPipeline<MV, L>
|
||||
where MV: MultiVertex, L: PipelineLayoutDesc
|
||||
{
|
||||
/// Builds a new graphics pipeline object.
|
||||
///
|
||||
@ -54,16 +54,18 @@ impl<MV, Vl, Fl> GraphicsPipeline<MV, (Vl, Fl)>
|
||||
/// - 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<Vi, Fo, R>
|
||||
pub fn new<Vi, Fo, R, Vl, Fl>
|
||||
(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>
|
||||
layout: &Arc<PipelineLayout<L>>, render_pass: &Subpass<R>)
|
||||
-> Result<Arc<GraphicsPipeline<MV, L>>, OomError>
|
||||
{
|
||||
let vk = device.pointers();
|
||||
|
||||
// FIXME: check layout compatibility
|
||||
|
||||
let pipeline = unsafe {
|
||||
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
|
||||
let mut dynamic_states: Vec<vk::DynamicState> = Vec::new();
|
||||
|
Loading…
Reference in New Issue
Block a user