mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 23:05:43 +00:00
Split pipeline_layout/mod.rs in multiple submodules
This commit is contained in:
parent
c502522aa1
commit
5b3c2a0929
@ -819,7 +819,7 @@ impl InnerCommandBufferBuilder {
|
||||
|
||||
// TODO: shouldn't rebind everything every time
|
||||
if !descriptor_sets.as_ref().unwrap().is_empty() {
|
||||
let pipeline = pipeline.layout().inner_pipeline_layout().internal_object();
|
||||
let pipeline = PipelineLayout::inner_pipeline_layout(&**pipeline.layout()).internal_object();
|
||||
self.staging_commands.push(Box::new(move |vk, cmd| {
|
||||
let descriptor_sets = descriptor_sets.take().unwrap();
|
||||
vk.CmdBindDescriptorSets(cmd, vk::PIPELINE_BIND_POINT_COMPUTE,
|
||||
@ -910,7 +910,7 @@ impl InnerCommandBufferBuilder {
|
||||
|
||||
// TODO: shouldn't rebind everything every time
|
||||
if !descriptor_sets.as_ref().unwrap().is_empty() {
|
||||
let pipeline = pipeline.layout().inner_pipeline_layout().internal_object();
|
||||
let pipeline = PipelineLayout::inner_pipeline_layout(&**pipeline.layout()).internal_object();
|
||||
self.render_pass_staging_commands.push(Box::new(move |vk, cmd| {
|
||||
let descriptor_sets = descriptor_sets.take().unwrap();
|
||||
vk.CmdBindDescriptorSets(cmd, vk::PIPELINE_BIND_POINT_GRAPHICS, pipeline,
|
||||
|
@ -7,197 +7,14 @@
|
||||
// notice may not be copied, modified, or distributed except
|
||||
// according to those terms.
|
||||
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use std::sync::Arc;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use check_errors;
|
||||
use OomError;
|
||||
use VulkanObject;
|
||||
use VulkanPointers;
|
||||
use vk;
|
||||
|
||||
use descriptor::descriptor::DescriptorDesc;
|
||||
use descriptor::descriptor_set::DescriptorSetsCollection;
|
||||
use descriptor::descriptor_set::UnsafeDescriptorSetLayout;
|
||||
use device::Device;
|
||||
pub use self::sys::UnsafePipelineLayout;
|
||||
pub use self::traits::PipelineLayout;
|
||||
pub use self::traits::PipelineLayoutDesc;
|
||||
pub use self::traits::PipelineLayoutSuperset;
|
||||
pub use self::traits::PipelineLayoutSetsCompatible;
|
||||
pub use self::traits::PipelineLayoutPushConstantsCompatible;
|
||||
|
||||
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 {
|
||||
/// Returns the inner `UnsafePipelineLayout`.
|
||||
// TODO: should be named "inner()" after https://github.com/rust-lang/rust/issues/12808 is fixed
|
||||
fn inner_pipeline_layout(&self) -> &UnsafePipelineLayout;
|
||||
}
|
||||
|
||||
/// Trait for objects that describe the layout of the descriptors and push constants of a pipeline.
|
||||
pub unsafe trait PipelineLayoutDesc {
|
||||
/// Iterator that describes descriptor sets.
|
||||
type SetsIter: Iterator<Item = Self::DescIter>;
|
||||
/// Iterator that describes individual descriptors.
|
||||
type DescIter: Iterator<Item = DescriptorDesc>;
|
||||
|
||||
/// Describes the layout of the descriptors of the pipeline.
|
||||
fn descriptors_desc(&self) -> Self::SetsIter;
|
||||
|
||||
// TODO: describe push constants
|
||||
}
|
||||
|
||||
/// Traits that allow determining whether a pipeline layout is a superset of another one.
|
||||
///
|
||||
/// This trait is automatically implemented on all types that implement `PipelineLayout`.
|
||||
/// TODO: once specialization lands, we can add implementations that don't perform deep comparisons
|
||||
pub unsafe trait PipelineLayoutSuperset<Other>: PipelineLayoutDesc
|
||||
where Other: PipelineLayoutDesc
|
||||
{
|
||||
/// Returns true if `self` is a superset of `Other`.
|
||||
fn is_superset_of(&self, &Other) -> bool;
|
||||
}
|
||||
|
||||
unsafe impl<T, U> PipelineLayoutSuperset<U> for T
|
||||
where T: PipelineLayoutDesc, U: PipelineLayoutDesc
|
||||
{
|
||||
fn is_superset_of(&self, other: &U) -> bool {
|
||||
let mut other_descriptor_sets = other.descriptors_desc();
|
||||
|
||||
for my_set in self.descriptors_desc() {
|
||||
let mut other_set = match other_descriptor_sets.next() {
|
||||
None => return false,
|
||||
Some(s) => s,
|
||||
};
|
||||
|
||||
for my_desc in my_set {
|
||||
let other_desc = match other_set.next() {
|
||||
None => return false,
|
||||
Some(d) => d,
|
||||
};
|
||||
|
||||
if !my_desc.is_superset_of(&other_desc) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// Traits that allow determining whether
|
||||
pub unsafe trait PipelineLayoutSetsCompatible<Other>: PipelineLayout
|
||||
where Other: DescriptorSetsCollection
|
||||
{
|
||||
/// Returns true if `Other` can be used with a pipeline that uses `self` as layout.
|
||||
fn is_compatible(&self, &Other) -> bool;
|
||||
}
|
||||
|
||||
unsafe impl<T, U> PipelineLayoutSetsCompatible<U> for T
|
||||
where T: PipelineLayout, U: DescriptorSetsCollection
|
||||
{
|
||||
fn is_compatible(&self, _: &U) -> bool {
|
||||
// FIXME:
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// Traits that allow determining whether
|
||||
// TODO: require a trait on Pc
|
||||
pub unsafe trait PipelineLayoutPushConstantsCompatible<Pc>: PipelineLayout {
|
||||
/// Returns true if `Pc` can be used with a pipeline that uses `self` as layout.
|
||||
fn is_compatible(&self, &Pc) -> bool;
|
||||
}
|
||||
|
||||
unsafe impl<T, U> PipelineLayoutPushConstantsCompatible<U> for T where T: PipelineLayout {
|
||||
fn is_compatible(&self, _: &U) -> bool {
|
||||
// FIXME:
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// Implemented on types whose exact layout is known at compile-time.
|
||||
pub unsafe trait CompiletimePipelineLayout: PipelineLayout {
|
||||
type RawContent;
|
||||
}
|
||||
|
||||
/// Low-level struct that represents the layout of the resources available to your shaders.
|
||||
// TODO: push constants.
|
||||
pub struct UnsafePipelineLayout {
|
||||
device: Arc<Device>,
|
||||
layout: vk::PipelineLayout,
|
||||
layouts: SmallVec<[Arc<UnsafeDescriptorSetLayout>; 16]>,
|
||||
}
|
||||
|
||||
impl UnsafePipelineLayout {
|
||||
/// Creates a new `UnsafePipelineLayout`.
|
||||
// TODO: is this function unsafe?
|
||||
#[inline]
|
||||
pub unsafe fn new<'a, I>(device: &Arc<Device>, layouts: I)
|
||||
-> Result<UnsafePipelineLayout, OomError>
|
||||
where I: IntoIterator<Item = &'a Arc<UnsafeDescriptorSetLayout>>
|
||||
{
|
||||
UnsafePipelineLayout::new_inner(device, layouts.into_iter().map(|e| e.clone()).collect())
|
||||
}
|
||||
|
||||
// TODO: is this function unsafe?
|
||||
unsafe fn new_inner(device: &Arc<Device>,
|
||||
layouts: SmallVec<[Arc<UnsafeDescriptorSetLayout>; 16]>)
|
||||
-> Result<UnsafePipelineLayout, OomError>
|
||||
{
|
||||
let vk = device.pointers();
|
||||
|
||||
// FIXME: check that they belong to the right device
|
||||
let layouts_ids = layouts.iter().map(|l| l.internal_object())
|
||||
.collect::<SmallVec<[_; 16]>>();
|
||||
|
||||
let layout = {
|
||||
let infos = vk::PipelineLayoutCreateInfo {
|
||||
sType: vk::STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||
pNext: ptr::null(),
|
||||
flags: 0, // reserved
|
||||
setLayoutCount: layouts_ids.len() as u32,
|
||||
pSetLayouts: layouts_ids.as_ptr(),
|
||||
pushConstantRangeCount: 0, // TODO: unimplemented
|
||||
pPushConstantRanges: ptr::null(), // TODO: unimplemented
|
||||
};
|
||||
|
||||
let mut output = mem::uninitialized();
|
||||
try!(check_errors(vk.CreatePipelineLayout(device.internal_object(), &infos,
|
||||
ptr::null(), &mut output)));
|
||||
output
|
||||
};
|
||||
|
||||
Ok(UnsafePipelineLayout {
|
||||
device: device.clone(),
|
||||
layout: layout,
|
||||
layouts: layouts,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the `UnsafeDescriptorSetLayout` object of the specified set index.
|
||||
///
|
||||
/// Returns `None` if out of range.
|
||||
#[inline]
|
||||
pub fn descriptor_set_layout(&self, index: usize) -> Option<&Arc<UnsafeDescriptorSetLayout>> {
|
||||
self.layouts.get(index)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl VulkanObject for UnsafePipelineLayout {
|
||||
type Object = vk::PipelineLayout;
|
||||
|
||||
#[inline]
|
||||
fn internal_object(&self) -> vk::PipelineLayout {
|
||||
self.layout
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for UnsafePipelineLayout {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
let vk = self.device.pointers();
|
||||
vk.DestroyPipelineLayout(self.device.internal_object(), self.layout, ptr::null());
|
||||
}
|
||||
}
|
||||
}
|
||||
mod sys;
|
||||
mod traits;
|
||||
|
104
vulkano/src/descriptor/pipeline_layout/sys.rs
Normal file
104
vulkano/src/descriptor/pipeline_layout/sys.rs
Normal file
@ -0,0 +1,104 @@
|
||||
// Copyright (c) 2016 The vulkano developers
|
||||
// Licensed under the Apache License, Version 2.0
|
||||
// <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
|
||||
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||
// at your option. All files in the project carrying such
|
||||
// notice may not be copied, modified, or distributed except
|
||||
// according to those terms.
|
||||
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use std::sync::Arc;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use check_errors;
|
||||
use OomError;
|
||||
use VulkanObject;
|
||||
use VulkanPointers;
|
||||
use vk;
|
||||
|
||||
use descriptor::descriptor_set::UnsafeDescriptorSetLayout;
|
||||
use device::Device;
|
||||
|
||||
/// Low-level struct that represents the layout of the resources available to your shaders.
|
||||
// TODO: push constants.
|
||||
pub struct UnsafePipelineLayout {
|
||||
device: Arc<Device>,
|
||||
layout: vk::PipelineLayout,
|
||||
layouts: SmallVec<[Arc<UnsafeDescriptorSetLayout>; 16]>,
|
||||
}
|
||||
|
||||
impl UnsafePipelineLayout {
|
||||
/// Creates a new `UnsafePipelineLayout`.
|
||||
// TODO: is this function unsafe?
|
||||
#[inline]
|
||||
pub unsafe fn new<'a, I>(device: &Arc<Device>, layouts: I)
|
||||
-> Result<UnsafePipelineLayout, OomError>
|
||||
where I: IntoIterator<Item = &'a Arc<UnsafeDescriptorSetLayout>>
|
||||
{
|
||||
UnsafePipelineLayout::new_inner(device, layouts.into_iter().map(|e| e.clone()).collect())
|
||||
}
|
||||
|
||||
// TODO: is this function unsafe?
|
||||
unsafe fn new_inner(device: &Arc<Device>,
|
||||
layouts: SmallVec<[Arc<UnsafeDescriptorSetLayout>; 16]>)
|
||||
-> Result<UnsafePipelineLayout, OomError>
|
||||
{
|
||||
let vk = device.pointers();
|
||||
|
||||
// FIXME: check that they belong to the right device
|
||||
let layouts_ids = layouts.iter().map(|l| l.internal_object())
|
||||
.collect::<SmallVec<[_; 16]>>();
|
||||
|
||||
let layout = {
|
||||
let infos = vk::PipelineLayoutCreateInfo {
|
||||
sType: vk::STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||
pNext: ptr::null(),
|
||||
flags: 0, // reserved
|
||||
setLayoutCount: layouts_ids.len() as u32,
|
||||
pSetLayouts: layouts_ids.as_ptr(),
|
||||
pushConstantRangeCount: 0, // TODO: unimplemented
|
||||
pPushConstantRanges: ptr::null(), // TODO: unimplemented
|
||||
};
|
||||
|
||||
let mut output = mem::uninitialized();
|
||||
try!(check_errors(vk.CreatePipelineLayout(device.internal_object(), &infos,
|
||||
ptr::null(), &mut output)));
|
||||
output
|
||||
};
|
||||
|
||||
Ok(UnsafePipelineLayout {
|
||||
device: device.clone(),
|
||||
layout: layout,
|
||||
layouts: layouts,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the `UnsafeDescriptorSetLayout` object of the specified set index.
|
||||
///
|
||||
/// Returns `None` if out of range.
|
||||
#[inline]
|
||||
pub fn descriptor_set_layout(&self, index: usize) -> Option<&Arc<UnsafeDescriptorSetLayout>> {
|
||||
self.layouts.get(index)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl VulkanObject for UnsafePipelineLayout {
|
||||
type Object = vk::PipelineLayout;
|
||||
|
||||
#[inline]
|
||||
fn internal_object(&self) -> vk::PipelineLayout {
|
||||
self.layout
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for UnsafePipelineLayout {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
let vk = self.device.pointers();
|
||||
vk.DestroyPipelineLayout(self.device.internal_object(), self.layout, ptr::null());
|
||||
}
|
||||
}
|
||||
}
|
102
vulkano/src/descriptor/pipeline_layout/traits.rs
Normal file
102
vulkano/src/descriptor/pipeline_layout/traits.rs
Normal file
@ -0,0 +1,102 @@
|
||||
// Copyright (c) 2016 The vulkano developers
|
||||
// Licensed under the Apache License, Version 2.0
|
||||
// <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
|
||||
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||
// at your option. All files in the project carrying such
|
||||
// notice may not be copied, modified, or distributed except
|
||||
// according to those terms.
|
||||
|
||||
use descriptor::descriptor::DescriptorDesc;
|
||||
use descriptor::descriptor_set::DescriptorSetsCollection;
|
||||
use descriptor::pipeline_layout::UnsafePipelineLayout;
|
||||
|
||||
/// Trait for objects that describe the layout of the descriptors and push constants of a pipeline.
|
||||
pub unsafe trait PipelineLayout: PipelineLayoutDesc + 'static + Send + Sync {
|
||||
/// Returns the inner `UnsafePipelineLayout`.
|
||||
// TODO: should be named "inner()" after https://github.com/rust-lang/rust/issues/12808 is fixed
|
||||
fn inner_pipeline_layout(&self) -> &UnsafePipelineLayout;
|
||||
}
|
||||
|
||||
/// Trait for objects that describe the layout of the descriptors and push constants of a pipeline.
|
||||
pub unsafe trait PipelineLayoutDesc {
|
||||
/// Iterator that describes descriptor sets.
|
||||
type SetsIter: Iterator<Item = Self::DescIter>;
|
||||
/// Iterator that describes individual descriptors.
|
||||
type DescIter: Iterator<Item = DescriptorDesc>;
|
||||
|
||||
/// Describes the layout of the descriptors of the pipeline.
|
||||
fn descriptors_desc(&self) -> Self::SetsIter;
|
||||
|
||||
// TODO: describe push constants
|
||||
}
|
||||
|
||||
/// Traits that allow determining whether a pipeline layout is a superset of another one.
|
||||
///
|
||||
/// This trait is automatically implemented on all types that implement `PipelineLayout`.
|
||||
/// TODO: once specialization lands, we can add implementations that don't perform deep comparisons
|
||||
pub unsafe trait PipelineLayoutSuperset<Other>: PipelineLayoutDesc
|
||||
where Other: PipelineLayoutDesc
|
||||
{
|
||||
/// Returns true if `self` is a superset of `Other`.
|
||||
fn is_superset_of(&self, &Other) -> bool;
|
||||
}
|
||||
|
||||
unsafe impl<T, U> PipelineLayoutSuperset<U> for T
|
||||
where T: PipelineLayoutDesc, U: PipelineLayoutDesc
|
||||
{
|
||||
fn is_superset_of(&self, other: &U) -> bool {
|
||||
let mut other_descriptor_sets = other.descriptors_desc();
|
||||
|
||||
for my_set in self.descriptors_desc() {
|
||||
let mut other_set = match other_descriptor_sets.next() {
|
||||
None => return false,
|
||||
Some(s) => s,
|
||||
};
|
||||
|
||||
for my_desc in my_set {
|
||||
let other_desc = match other_set.next() {
|
||||
None => return false,
|
||||
Some(d) => d,
|
||||
};
|
||||
|
||||
if !my_desc.is_superset_of(&other_desc) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// Traits that allow determining whether
|
||||
pub unsafe trait PipelineLayoutSetsCompatible<Other>: PipelineLayout
|
||||
where Other: DescriptorSetsCollection
|
||||
{
|
||||
/// Returns true if `Other` can be used with a pipeline that uses `self` as layout.
|
||||
fn is_compatible(&self, &Other) -> bool;
|
||||
}
|
||||
|
||||
unsafe impl<T, U> PipelineLayoutSetsCompatible<U> for T
|
||||
where T: PipelineLayout, U: DescriptorSetsCollection
|
||||
{
|
||||
fn is_compatible(&self, _: &U) -> bool {
|
||||
// FIXME:
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// Traits that allow determining whether
|
||||
// TODO: require a trait on Pc
|
||||
pub unsafe trait PipelineLayoutPushConstantsCompatible<Pc>: PipelineLayout {
|
||||
/// Returns true if `Pc` can be used with a pipeline that uses `self` as layout.
|
||||
fn is_compatible(&self, &Pc) -> bool;
|
||||
}
|
||||
|
||||
unsafe impl<T, U> PipelineLayoutPushConstantsCompatible<U> for T where T: PipelineLayout {
|
||||
fn is_compatible(&self, _: &U) -> bool {
|
||||
// FIXME:
|
||||
true
|
||||
}
|
||||
}
|
@ -76,7 +76,7 @@ impl<Pl> ComputePipeline<Pl> {
|
||||
pNext: ptr::null(),
|
||||
flags: 0,
|
||||
stage: stage,
|
||||
layout: pipeline_layout.inner_pipeline_layout().internal_object(),
|
||||
layout: PipelineLayout::inner_pipeline_layout(&**pipeline_layout).internal_object(),
|
||||
basePipelineHandle: 0,
|
||||
basePipelineIndex: 0,
|
||||
};
|
||||
|
@ -315,7 +315,7 @@ impl<Mv, L, Rp> GraphicsPipeline<Mv, L, Rp>
|
||||
pDepthStencilState: &depth_stencil,
|
||||
pColorBlendState: &blend,
|
||||
pDynamicState: &dynamic_states,
|
||||
layout: layout.inner_pipeline_layout().internal_object(),
|
||||
layout: PipelineLayout::inner_pipeline_layout(&**layout).internal_object(),
|
||||
renderPass: render_pass.render_pass().render_pass().internal_object(),
|
||||
subpass: render_pass.index(),
|
||||
basePipelineHandle: 0, // TODO:
|
||||
|
Loading…
Reference in New Issue
Block a user