mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 14:56:42 +00:00
Add unsafe support for push constants
This commit is contained in:
parent
e9d82d8c18
commit
f6733628e8
@ -29,3 +29,5 @@
|
|||||||
- This repository contains the `vulkano-shaders` library, which generates Rust code that uses the `vulkano` library. If the API of `vulkano` gets
|
- This repository contains the `vulkano-shaders` library, which generates Rust code that uses the `vulkano` library. If the API of `vulkano` gets
|
||||||
a breaking change, there is no way to enforce or to check the fact that the user uses a correct combination of versions for `vulkano-shaders`
|
a breaking change, there is no way to enforce or to check the fact that the user uses a correct combination of versions for `vulkano-shaders`
|
||||||
and `vulkano`.
|
and `vulkano`.
|
||||||
|
|
||||||
|
- No way to set the alignment of a struct member, or to force the size of a struct to be a multiple of a certain size.
|
||||||
|
@ -220,7 +220,7 @@ fn main() {
|
|||||||
.draw_inline(&renderpass, &framebuffer, renderpass::ClearValues {
|
.draw_inline(&renderpass, &framebuffer, renderpass::ClearValues {
|
||||||
color: [0.0, 0.0, 1.0, 1.0]
|
color: [0.0, 0.0, 1.0, 1.0]
|
||||||
})
|
})
|
||||||
.draw(&pipeline, &vertex_buffer, &vulkano::command_buffer::DynamicState::none(), set.clone())
|
.draw(&pipeline, &vertex_buffer, &vulkano::command_buffer::DynamicState::none(), set.clone(), &())
|
||||||
.draw_end()
|
.draw_end()
|
||||||
.build().unwrap()
|
.build().unwrap()
|
||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
|
@ -216,7 +216,7 @@ fn main() {
|
|||||||
depth: 1.0,
|
depth: 1.0,
|
||||||
})
|
})
|
||||||
.draw_indexed(&pipeline, (&vertex_buffer, &normals_buffer), &index_buffer,
|
.draw_indexed(&pipeline, (&vertex_buffer, &normals_buffer), &index_buffer,
|
||||||
&vulkano::command_buffer::DynamicState::none(), &set)
|
&vulkano::command_buffer::DynamicState::none(), &set, &())
|
||||||
.draw_end()
|
.draw_end()
|
||||||
.build().unwrap()
|
.build().unwrap()
|
||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
|
@ -237,7 +237,7 @@ fn main() {
|
|||||||
let command_buffers = framebuffers.iter().map(|framebuffer| {
|
let command_buffers = framebuffers.iter().map(|framebuffer| {
|
||||||
vulkano::command_buffer::PrimaryCommandBufferBuilder::new(&cb_pool).unwrap()
|
vulkano::command_buffer::PrimaryCommandBufferBuilder::new(&cb_pool).unwrap()
|
||||||
.draw_inline(&renderpass, &framebuffer, ([0.0, 0.0, 1.0, 1.0],))
|
.draw_inline(&renderpass, &framebuffer, ([0.0, 0.0, 1.0, 1.0],))
|
||||||
.draw(&pipeline, vertex_buffer.clone(), &vulkano::command_buffer::DynamicState::none(), ())
|
.draw(&pipeline, vertex_buffer.clone(), &vulkano::command_buffer::DynamicState::none(), (), &())
|
||||||
.draw_end()
|
.draw_end()
|
||||||
.build().unwrap()
|
.build().unwrap()
|
||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
|
@ -686,15 +686,15 @@ impl InnerCommandBufferBuilder {
|
|||||||
|
|
||||||
/// Calls `vkCmdDraw`.
|
/// Calls `vkCmdDraw`.
|
||||||
// FIXME: push constants
|
// FIXME: push constants
|
||||||
pub unsafe fn draw<V, Pv, Pl, L, Rp>(mut self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
pub unsafe fn draw<V, Pv, Pl, L, Rp, Pc>(mut self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
||||||
vertices: V, dynamic: &DynamicState,
|
vertices: V, dynamic: &DynamicState,
|
||||||
sets: L) -> InnerCommandBufferBuilder
|
sets: L, push_constants: &Pc) -> InnerCommandBufferBuilder
|
||||||
where Pv: 'static + VertexDefinition + VertexSource<V>, L: DescriptorSetsCollection + Send + Sync,
|
where Pv: 'static + VertexDefinition + VertexSource<V>, L: DescriptorSetsCollection + Send + Sync,
|
||||||
Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync
|
Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync, Pc: 'static + Clone
|
||||||
{
|
{
|
||||||
// FIXME: add buffers to the resources
|
// FIXME: add buffers to the resources
|
||||||
|
|
||||||
self.bind_gfx_pipeline_state(pipeline, dynamic, sets);
|
self.bind_gfx_pipeline_state(pipeline, dynamic, sets, push_constants);
|
||||||
|
|
||||||
let vertices = pipeline.vertex_definition().decode(vertices);
|
let vertices = pipeline.vertex_definition().decode(vertices);
|
||||||
|
|
||||||
@ -727,17 +727,18 @@ impl InnerCommandBufferBuilder {
|
|||||||
|
|
||||||
/// Calls `vkCmdDrawIndexed`.
|
/// Calls `vkCmdDrawIndexed`.
|
||||||
// FIXME: push constants
|
// FIXME: push constants
|
||||||
pub unsafe fn draw_indexed<'a, V, Pv, Pl, Rp, L, I, Ib, Ibb>(mut self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
pub unsafe fn draw_indexed<'a, V, Pv, Pl, Rp, L, I, Ib, Ibb, Pc>(mut self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
||||||
vertices: V, indices: Ib, dynamic: &DynamicState,
|
vertices: V, indices: Ib, dynamic: &DynamicState,
|
||||||
sets: L) -> InnerCommandBufferBuilder
|
sets: L, push_constants: &Pc) -> InnerCommandBufferBuilder
|
||||||
where L: DescriptorSetsCollection + Send + Sync,
|
where L: DescriptorSetsCollection + Send + Sync,
|
||||||
Pv: 'static + VertexDefinition + VertexSource<V>,
|
Pv: 'static + VertexDefinition + VertexSource<V>,
|
||||||
Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync,
|
Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync,
|
||||||
Ib: Into<BufferSlice<'a, [I], Ibb>>, I: 'static + Index, Ibb: Buffer + 'static
|
Ib: Into<BufferSlice<'a, [I], Ibb>>, I: 'static + Index, Ibb: Buffer + 'static,
|
||||||
|
Pc: 'static + Clone
|
||||||
{
|
{
|
||||||
// FIXME: add buffers to the resources
|
// FIXME: add buffers to the resources
|
||||||
|
|
||||||
self.bind_gfx_pipeline_state(pipeline, dynamic, sets);
|
self.bind_gfx_pipeline_state(pipeline, dynamic, sets, push_constants);
|
||||||
|
|
||||||
|
|
||||||
let indices = indices.into();
|
let indices = indices.into();
|
||||||
@ -830,10 +831,10 @@ impl InnerCommandBufferBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind_gfx_pipeline_state<V, Pl, L, Rp>(&mut self, pipeline: &Arc<GraphicsPipeline<V, Pl, Rp>>,
|
fn bind_gfx_pipeline_state<V, Pl, L, Rp, Pc>(&mut self, pipeline: &Arc<GraphicsPipeline<V, Pl, Rp>>,
|
||||||
dynamic: &DynamicState, sets: L)
|
dynamic: &DynamicState, sets: L, push_constants: &Pc)
|
||||||
where V: 'static + VertexDefinition + Send + Sync, L: DescriptorSetsCollection + Send + Sync,
|
where V: 'static + VertexDefinition + Send + Sync, L: DescriptorSetsCollection + Send + Sync,
|
||||||
Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync
|
Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync, Pc: 'static + Clone
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
//assert!(sets.is_compatible_with(pipeline.layout()));
|
//assert!(sets.is_compatible_with(pipeline.layout()));
|
||||||
@ -905,6 +906,18 @@ impl InnerCommandBufferBuilder {
|
|||||||
for d in descriptor_sets.iter() { self.keep_alive.push(mem::transmute(d.clone()) /* FIXME: */); }
|
for d in descriptor_sets.iter() { self.keep_alive.push(mem::transmute(d.clone()) /* FIXME: */); }
|
||||||
let mut descriptor_sets = Some(descriptor_sets.into_iter().map(|set| set.inner_descriptor_set().internal_object()).collect::<SmallVec<[_; 32]>>());
|
let mut descriptor_sets = Some(descriptor_sets.into_iter().map(|set| set.inner_descriptor_set().internal_object()).collect::<SmallVec<[_; 32]>>());
|
||||||
|
|
||||||
|
if mem::size_of_val(push_constants) >= 1 {
|
||||||
|
let pipeline = PipelineLayout::inner_pipeline_layout(&**pipeline.layout()).internal_object();
|
||||||
|
let size = mem::size_of_val(push_constants);
|
||||||
|
let push_constants = push_constants.clone();
|
||||||
|
assert!((size % 4) == 0);
|
||||||
|
|
||||||
|
self.render_pass_staging_commands.push(Box::new(move |vk, cmd| {
|
||||||
|
vk.CmdPushConstants(cmd, pipeline, 0x7fffffff, 0, size as u32,
|
||||||
|
&push_constants as *const Pc as *const _);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: input attachments of descriptor sets have to be checked against input
|
// FIXME: input attachments of descriptor sets have to be checked against input
|
||||||
// attachments of the render pass
|
// attachments of the render pass
|
||||||
|
|
||||||
|
@ -281,17 +281,17 @@ pub struct PrimaryCommandBufferBuilderInlineDraw {
|
|||||||
impl PrimaryCommandBufferBuilderInlineDraw {
|
impl PrimaryCommandBufferBuilderInlineDraw {
|
||||||
/// Calls `vkCmdDraw`.
|
/// Calls `vkCmdDraw`.
|
||||||
// FIXME: push constants
|
// FIXME: push constants
|
||||||
pub fn draw<V, L, Pv, Pl, Rp>(self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
pub fn draw<V, L, Pv, Pl, Rp, Pc>(self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
||||||
vertices: V, dynamic: &DynamicState, sets: L)
|
vertices: V, dynamic: &DynamicState, sets: L, push_constants: &Pc)
|
||||||
-> PrimaryCommandBufferBuilderInlineDraw
|
-> PrimaryCommandBufferBuilderInlineDraw
|
||||||
where Pv: VertexDefinition + VertexSource<V> + 'static, Pl: PipelineLayout + 'static + Send + Sync, Rp: 'static + Send + Sync,
|
where Pv: VertexDefinition + VertexSource<V> + 'static, Pl: PipelineLayout + 'static + Send + Sync, Rp: 'static + Send + Sync,
|
||||||
L: DescriptorSetsCollection + Send + Sync
|
L: DescriptorSetsCollection + Send + Sync, Pc: 'static + Clone
|
||||||
{
|
{
|
||||||
// FIXME: check subpass
|
// FIXME: check subpass
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
PrimaryCommandBufferBuilderInlineDraw {
|
PrimaryCommandBufferBuilderInlineDraw {
|
||||||
inner: self.inner.draw(pipeline, vertices, dynamic, sets),
|
inner: self.inner.draw(pipeline, vertices, dynamic, sets, push_constants),
|
||||||
num_subpasses: self.num_subpasses,
|
num_subpasses: self.num_subpasses,
|
||||||
current_subpass: self.current_subpass,
|
current_subpass: self.current_subpass,
|
||||||
}
|
}
|
||||||
@ -299,18 +299,18 @@ impl PrimaryCommandBufferBuilderInlineDraw {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Calls `vkCmdDrawIndexed`.
|
/// Calls `vkCmdDrawIndexed`.
|
||||||
pub fn draw_indexed<'a, V, L, Pv, Pl, Rp, I, Ib, Ibb>(self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
pub fn draw_indexed<'a, V, L, Pv, Pl, Rp, I, Ib, Ibb, Pc>(self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
||||||
vertices: V, indices: Ib, dynamic: &DynamicState,
|
vertices: V, indices: Ib, dynamic: &DynamicState,
|
||||||
sets: L) -> PrimaryCommandBufferBuilderInlineDraw
|
sets: L, push_constants: &Pc) -> PrimaryCommandBufferBuilderInlineDraw
|
||||||
where Pv: 'static + VertexDefinition + VertexSource<V> + Send + Sync, Pl: 'static + PipelineLayout + Send + Sync, Rp: 'static + Send + Sync,
|
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,
|
Ib: Into<BufferSlice<'a, [I], Ibb>>, I: 'static + Index, Ibb: Buffer + 'static + Send + Sync,
|
||||||
L: DescriptorSetsCollection + Send + Sync
|
L: DescriptorSetsCollection + Send + Sync, Pc: 'static + Clone
|
||||||
{
|
{
|
||||||
// FIXME: check subpass
|
// FIXME: check subpass
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
PrimaryCommandBufferBuilderInlineDraw {
|
PrimaryCommandBufferBuilderInlineDraw {
|
||||||
inner: self.inner.draw_indexed(pipeline, vertices, indices, dynamic, sets),
|
inner: self.inner.draw_indexed(pipeline, vertices, indices, dynamic, sets, push_constants),
|
||||||
num_subpasses: self.num_subpasses,
|
num_subpasses: self.num_subpasses,
|
||||||
current_subpass: self.current_subpass,
|
current_subpass: self.current_subpass,
|
||||||
}
|
}
|
||||||
@ -528,19 +528,19 @@ impl<R> SecondaryGraphicsCommandBufferBuilder<R>
|
|||||||
|
|
||||||
/// Calls `vkCmdDraw`.
|
/// Calls `vkCmdDraw`.
|
||||||
// FIXME: push constants
|
// FIXME: push constants
|
||||||
pub fn draw<V, L, Pv, Pl, Rp>(self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
pub fn draw<V, L, Pv, Pl, Rp, Pc>(self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
||||||
vertices: V, dynamic: &DynamicState, sets: L)
|
vertices: V, dynamic: &DynamicState, sets: L, push_constants: &Pc)
|
||||||
-> SecondaryGraphicsCommandBufferBuilder<R>
|
-> SecondaryGraphicsCommandBufferBuilder<R>
|
||||||
where Pv: VertexDefinition + VertexSource<V> + 'static, Pl: PipelineLayout + 'static + Send + Sync,
|
where Pv: VertexDefinition + VertexSource<V> + 'static, Pl: PipelineLayout + 'static + Send + Sync,
|
||||||
Rp: RenderPass + 'static + Send + Sync, L: DescriptorSetsCollection + Send + Sync,
|
Rp: RenderPass + 'static + Send + Sync, L: DescriptorSetsCollection + Send + Sync,
|
||||||
R: RenderPassCompatible<Rp>
|
R: RenderPassCompatible<Rp>, Pc: 'static + Clone
|
||||||
{
|
{
|
||||||
assert!(self.render_pass.is_compatible_with(pipeline.subpass().render_pass()));
|
assert!(self.render_pass.is_compatible_with(pipeline.subpass().render_pass()));
|
||||||
assert_eq!(self.render_pass_subpass, pipeline.subpass().index());
|
assert_eq!(self.render_pass_subpass, pipeline.subpass().index());
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
SecondaryGraphicsCommandBufferBuilder {
|
SecondaryGraphicsCommandBufferBuilder {
|
||||||
inner: self.inner.draw(pipeline, vertices, dynamic, sets),
|
inner: self.inner.draw(pipeline, vertices, dynamic, sets, push_constants),
|
||||||
render_pass: self.render_pass,
|
render_pass: self.render_pass,
|
||||||
render_pass_subpass: self.render_pass_subpass,
|
render_pass_subpass: self.render_pass_subpass,
|
||||||
framebuffer: self.framebuffer,
|
framebuffer: self.framebuffer,
|
||||||
@ -549,20 +549,20 @@ impl<R> SecondaryGraphicsCommandBufferBuilder<R>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Calls `vkCmdDrawIndexed`.
|
/// Calls `vkCmdDrawIndexed`.
|
||||||
pub fn draw_indexed<'a, V, L, Pv, Pl, Rp, I, Ib, Ibb>(self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
pub fn draw_indexed<'a, V, L, Pv, Pl, Rp, I, Ib, Ibb, Pc>(self, pipeline: &Arc<GraphicsPipeline<Pv, Pl, Rp>>,
|
||||||
vertices: V, indices: Ib, dynamic: &DynamicState,
|
vertices: V, indices: Ib, dynamic: &DynamicState,
|
||||||
sets: L) -> SecondaryGraphicsCommandBufferBuilder<R>
|
sets: L, push_constants: &Pc) -> SecondaryGraphicsCommandBufferBuilder<R>
|
||||||
where Pv: 'static + VertexDefinition + VertexSource<V>, Pl: 'static + PipelineLayout + Send + Sync,
|
where Pv: 'static + VertexDefinition + VertexSource<V>, Pl: 'static + PipelineLayout + Send + Sync,
|
||||||
Rp: RenderPass + 'static + Send + Sync,
|
Rp: RenderPass + 'static + Send + Sync,
|
||||||
Ib: Into<BufferSlice<'a, [I], Ibb>>, I: 'static + Index, Ibb: Buffer + 'static,
|
Ib: Into<BufferSlice<'a, [I], Ibb>>, I: 'static + Index, Ibb: Buffer + 'static,
|
||||||
L: DescriptorSetsCollection + Send + Sync
|
L: DescriptorSetsCollection + Send + Sync, Pc: 'static + Clone
|
||||||
{
|
{
|
||||||
assert!(self.render_pass.is_compatible_with(pipeline.subpass().render_pass()));
|
assert!(self.render_pass.is_compatible_with(pipeline.subpass().render_pass()));
|
||||||
assert_eq!(self.render_pass_subpass, pipeline.subpass().index());
|
assert_eq!(self.render_pass_subpass, pipeline.subpass().index());
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
SecondaryGraphicsCommandBufferBuilder {
|
SecondaryGraphicsCommandBufferBuilder {
|
||||||
inner: self.inner.draw_indexed(pipeline, vertices, indices, dynamic, sets),
|
inner: self.inner.draw_indexed(pipeline, vertices, indices, dynamic, sets, push_constants),
|
||||||
render_pass: self.render_pass,
|
render_pass: self.render_pass,
|
||||||
render_pass_subpass: self.render_pass_subpass,
|
render_pass_subpass: self.render_pass_subpass,
|
||||||
framebuffer: self.framebuffer,
|
framebuffer: self.framebuffer,
|
||||||
|
@ -314,7 +314,7 @@ impl DescriptorType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Describes which shader stages have access to a descriptor.
|
/// Describes which shader stages have access to a descriptor.
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct ShaderStages {
|
pub struct ShaderStages {
|
||||||
/// `True` means that the descriptor will be used by the vertex shader.
|
/// `True` means that the descriptor will be used by the vertex shader.
|
||||||
pub vertex: bool,
|
pub vertex: bool,
|
||||||
@ -344,6 +344,19 @@ impl ShaderStages {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a `ShaderStages` struct will all stages set to `false`.
|
||||||
|
#[inline]
|
||||||
|
pub fn none() -> ShaderStages {
|
||||||
|
ShaderStages {
|
||||||
|
vertex: false,
|
||||||
|
tessellation_control: false,
|
||||||
|
tessellation_evaluation: false,
|
||||||
|
geometry: false,
|
||||||
|
fragment: false,
|
||||||
|
compute: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a `ShaderStages` struct will all graphics stages set to `true`.
|
/// Creates a `ShaderStages` struct will all graphics stages set to `true`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn all_graphics() -> ShaderStages {
|
pub fn all_graphics() -> ShaderStages {
|
||||||
|
@ -21,16 +21,23 @@ use sampler::Sampler;
|
|||||||
// TODO: more docs
|
// TODO: more docs
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! pipeline_layout {
|
macro_rules! pipeline_layout {
|
||||||
($($name:ident: { $($field:ident: $ty:ty),* }),*) => {
|
(push_constants: { $($pc_f:ident: $pc_t:ty),* } $(, $name:ident: { $($field:ident: $ty:ty),* })*) => {
|
||||||
|
use std::mem;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::vec::IntoIter as VecIntoIter;
|
use std::vec::IntoIter as VecIntoIter;
|
||||||
use $crate::OomError;
|
use $crate::OomError;
|
||||||
use $crate::device::Device;
|
use $crate::device::Device;
|
||||||
use $crate::descriptor::descriptor::DescriptorDesc;
|
use $crate::descriptor::descriptor::DescriptorDesc;
|
||||||
|
use $crate::descriptor::descriptor::ShaderStages;
|
||||||
use $crate::descriptor::pipeline_layout::PipelineLayout;
|
use $crate::descriptor::pipeline_layout::PipelineLayout;
|
||||||
use $crate::descriptor::pipeline_layout::PipelineLayoutDesc;
|
use $crate::descriptor::pipeline_layout::PipelineLayoutDesc;
|
||||||
use $crate::descriptor::pipeline_layout::UnsafePipelineLayout;
|
use $crate::descriptor::pipeline_layout::UnsafePipelineLayout;
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct PushConstants {
|
||||||
|
$(pub $pc_f: $pc_t,)*
|
||||||
|
}
|
||||||
|
|
||||||
pub struct CustomPipeline {
|
pub struct CustomPipeline {
|
||||||
inner: UnsafePipelineLayout
|
inner: UnsafePipelineLayout
|
||||||
}
|
}
|
||||||
@ -44,8 +51,14 @@ macro_rules! pipeline_layout {
|
|||||||
),*
|
),*
|
||||||
];
|
];
|
||||||
|
|
||||||
|
let push_constants = if mem::size_of::<PushConstants>() >= 1 {
|
||||||
|
Some((0, mem::size_of::<PushConstants>(), ShaderStages::all()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
let inner = unsafe {
|
let inner = unsafe {
|
||||||
try!(UnsafePipelineLayout::new(device, layouts.iter()))
|
try!(UnsafePipelineLayout::new(device, layouts.iter(), push_constants))
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Arc::new(CustomPipeline {
|
Ok(Arc::new(CustomPipeline {
|
||||||
@ -85,6 +98,10 @@ macro_rules! pipeline_layout {
|
|||||||
pipeline_layout!{__inner__ (0) $($name: {$($field: $ty),*})*}
|
pipeline_layout!{__inner__ (0) $($name: {$($field: $ty),*})*}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
($($name:ident: { $($field:ident: $ty:ty),* }),*) => {
|
||||||
|
pipeline_layout!{ push_constants: {} $(, $name: {$($field: $ty),*})* }
|
||||||
|
};
|
||||||
|
|
||||||
(__inner__ ($num:expr) $name:ident: { $($field:ident: $ty:ty),* } $($rest:tt)*) => {
|
(__inner__ ($num:expr) $name:ident: { $($field:ident: $ty:ty),* } $($rest:tt)*) => {
|
||||||
pub mod $name {
|
pub mod $name {
|
||||||
#![allow(unused_imports)]
|
#![allow(unused_imports)]
|
||||||
|
@ -18,6 +18,7 @@ use VulkanObject;
|
|||||||
use VulkanPointers;
|
use VulkanPointers;
|
||||||
use vk;
|
use vk;
|
||||||
|
|
||||||
|
use descriptor::descriptor::ShaderStages;
|
||||||
use descriptor::descriptor_set::UnsafeDescriptorSetLayout;
|
use descriptor::descriptor_set::UnsafeDescriptorSetLayout;
|
||||||
use device::Device;
|
use device::Device;
|
||||||
|
|
||||||
@ -33,16 +34,19 @@ impl UnsafePipelineLayout {
|
|||||||
/// Creates a new `UnsafePipelineLayout`.
|
/// Creates a new `UnsafePipelineLayout`.
|
||||||
// TODO: is this function unsafe?
|
// TODO: is this function unsafe?
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn new<'a, I>(device: &Arc<Device>, layouts: I)
|
pub unsafe fn new<'a, I, P>(device: &Arc<Device>, layouts: I, push_constants: P)
|
||||||
-> Result<UnsafePipelineLayout, OomError>
|
-> Result<UnsafePipelineLayout, OomError>
|
||||||
where I: IntoIterator<Item = &'a Arc<UnsafeDescriptorSetLayout>>
|
where I: IntoIterator<Item = &'a Arc<UnsafeDescriptorSetLayout>>,
|
||||||
|
P: IntoIterator<Item = (usize, usize, ShaderStages)>,
|
||||||
{
|
{
|
||||||
UnsafePipelineLayout::new_inner(device, layouts.into_iter().map(|e| e.clone()).collect())
|
UnsafePipelineLayout::new_inner(device, layouts.into_iter().map(|e| e.clone()).collect(),
|
||||||
|
push_constants.into_iter().collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: is this function unsafe?
|
// TODO: is this function unsafe?
|
||||||
unsafe fn new_inner(device: &Arc<Device>,
|
unsafe fn new_inner(device: &Arc<Device>,
|
||||||
layouts: SmallVec<[Arc<UnsafeDescriptorSetLayout>; 16]>)
|
layouts: SmallVec<[Arc<UnsafeDescriptorSetLayout>; 16]>,
|
||||||
|
push_constants: SmallVec<[(usize, usize, ShaderStages); 8]>)
|
||||||
-> Result<UnsafePipelineLayout, OomError>
|
-> Result<UnsafePipelineLayout, OomError>
|
||||||
{
|
{
|
||||||
let vk = device.pointers();
|
let vk = device.pointers();
|
||||||
@ -51,6 +55,21 @@ impl UnsafePipelineLayout {
|
|||||||
let layouts_ids = layouts.iter().map(|l| l.internal_object())
|
let layouts_ids = layouts.iter().map(|l| l.internal_object())
|
||||||
.collect::<SmallVec<[_; 16]>>();
|
.collect::<SmallVec<[_; 16]>>();
|
||||||
|
|
||||||
|
let push_constants = push_constants.iter().map(|pc| {
|
||||||
|
// TODO: error
|
||||||
|
assert!(pc.2 != ShaderStages::none());
|
||||||
|
assert!(pc.1 > 0);
|
||||||
|
assert!((pc.1 % 4) == 0);
|
||||||
|
assert!(pc.0 + pc.1 <=
|
||||||
|
device.physical_device().limits().max_push_constants_size() as usize);
|
||||||
|
|
||||||
|
vk::PushConstantRange {
|
||||||
|
stageFlags: pc.2.into(),
|
||||||
|
offset: pc.0 as u32,
|
||||||
|
size: pc.1 as u32,
|
||||||
|
}
|
||||||
|
}).collect::<SmallVec<[_; 8]>>();
|
||||||
|
|
||||||
let layout = {
|
let layout = {
|
||||||
let infos = vk::PipelineLayoutCreateInfo {
|
let infos = vk::PipelineLayoutCreateInfo {
|
||||||
sType: vk::STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
sType: vk::STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||||
@ -58,8 +77,8 @@ impl UnsafePipelineLayout {
|
|||||||
flags: 0, // reserved
|
flags: 0, // reserved
|
||||||
setLayoutCount: layouts_ids.len() as u32,
|
setLayoutCount: layouts_ids.len() as u32,
|
||||||
pSetLayouts: layouts_ids.as_ptr(),
|
pSetLayouts: layouts_ids.as_ptr(),
|
||||||
pushConstantRangeCount: 0, // TODO: unimplemented
|
pushConstantRangeCount: push_constants.len() as u32,
|
||||||
pPushConstantRanges: ptr::null(), // TODO: unimplemented
|
pPushConstantRanges: push_constants.as_ptr(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut output = mem::uninitialized();
|
let mut output = mem::uninitialized();
|
||||||
|
Loading…
Reference in New Issue
Block a user