mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-23 15:24:25 +00:00
Merge pull request #428 from tomaka/draw-indirect
Add back draw_indirect command
This commit is contained in:
commit
ffee50e21d
@ -14,6 +14,7 @@ use std::sync::Arc;
|
||||
use buffer::Buffer;
|
||||
use buffer::TypedBuffer;
|
||||
use device::DeviceOwned;
|
||||
use command_buffer::DrawIndirectCommand;
|
||||
use command_buffer::DynamicState;
|
||||
use command_buffer::cb::AddCommand;
|
||||
use command_buffer::cb::CommandBufferBuild;
|
||||
@ -199,6 +200,24 @@ pub unsafe trait CommandBufferBuilder: DeviceOwned {
|
||||
self.add(cmd)
|
||||
}
|
||||
|
||||
/// Adds an indirect draw command.
|
||||
///
|
||||
/// Can only be used from inside a render pass.
|
||||
#[inline]
|
||||
fn draw_indirect<P, S, Pc, V, B, I, O>(self, pipeline: P, dynamic: DynamicState,
|
||||
vertices: V, indirect_buffer: B, sets: S, push_constants: Pc) -> Result<O, CommandAddError>
|
||||
where Self: Sized + AddCommand<commands_extra::CmdDrawIndirect<V, B::Access, P, S, Pc>, Out = O>,
|
||||
S: DescriptorSetsCollection,
|
||||
P: VertexSource<V> + GraphicsPipelineAbstract + Clone,
|
||||
B: Buffer,
|
||||
B::Access: TypedBuffer<Content = [DrawIndirectCommand]>,
|
||||
I: Index + 'static
|
||||
{
|
||||
let cmd = commands_extra::CmdDrawIndirect::new(pipeline, dynamic, vertices, indirect_buffer.access(),
|
||||
sets, push_constants);
|
||||
self.add(cmd)
|
||||
}
|
||||
|
||||
/// Executes a compute shader.
|
||||
fn dispatch<P, S, Pc, O>(self, dimensions: [u32; 3], pipeline: P, sets: S, push_constants: Pc)
|
||||
-> Result<O, CommandBufferBuilderError<commands_extra::CmdDispatchError>>
|
||||
|
@ -107,6 +107,7 @@ pass_through!((S, D), commands_raw::CmdCopyImage<S, D>);
|
||||
pass_through!((), commands_raw::CmdDispatchRaw);
|
||||
pass_through!((), commands_raw::CmdDrawRaw);
|
||||
pass_through!((), commands_raw::CmdDrawIndexedRaw);
|
||||
pass_through!((B), commands_raw::CmdDrawIndirectRaw<B>);
|
||||
pass_through!((), commands_raw::CmdEndRenderPass);
|
||||
pass_through!((C), commands_raw::CmdExecuteCommands<C>);
|
||||
pass_through!((B), commands_raw::CmdFillBuffer<B>);
|
||||
|
@ -317,6 +317,24 @@ unsafe impl<I, O> AddCommand<commands_raw::CmdDrawIndexedRaw> for SubmitSyncBuil
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<I, O, B> AddCommand<commands_raw::CmdDrawIndirectRaw<B>> for SubmitSyncBuilderLayer<I>
|
||||
where I: AddCommand<commands_raw::CmdDrawIndirectRaw<B>, Out = O>,
|
||||
B: BufferAccess + Send + Sync + Clone + 'static
|
||||
{
|
||||
type Out = SubmitSyncBuilderLayer<O>;
|
||||
|
||||
#[inline]
|
||||
fn add(mut self, command: commands_raw::CmdDrawIndirectRaw<B>) -> Result<Self::Out, CommandAddError> {
|
||||
self.add_buffer(command.buffer(), true);
|
||||
|
||||
Ok(SubmitSyncBuilderLayer {
|
||||
inner: AddCommand::add(self.inner, command)?,
|
||||
buffers: self.buffers,
|
||||
images: self.images,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<I, O> AddCommand<commands_raw::CmdEndRenderPass> for SubmitSyncBuilderLayer<I>
|
||||
where I: AddCommand<commands_raw::CmdEndRenderPass, Out = O>
|
||||
{
|
||||
|
87
vulkano/src/command_buffer/commands_extra/draw_indirect.rs
Normal file
87
vulkano/src/command_buffer/commands_extra/draw_indirect.rs
Normal file
@ -0,0 +1,87 @@
|
||||
// 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 buffer::BufferAccess;
|
||||
use buffer::TypedBuffer;
|
||||
use command_buffer::CommandAddError;
|
||||
use command_buffer::DynamicState;
|
||||
use command_buffer::DrawIndirectCommand;
|
||||
use command_buffer::cb::AddCommand;
|
||||
use command_buffer::commands_raw::CmdBindDescriptorSets;
|
||||
use command_buffer::commands_raw::CmdBindPipeline;
|
||||
use command_buffer::commands_raw::CmdBindVertexBuffers;
|
||||
use command_buffer::commands_raw::CmdDrawIndirectRaw;
|
||||
use command_buffer::commands_raw::CmdPushConstants;
|
||||
use command_buffer::commands_raw::CmdSetState;
|
||||
use descriptor::descriptor_set::DescriptorSetsCollection;
|
||||
use pipeline::GraphicsPipelineAbstract;
|
||||
use pipeline::vertex::VertexSource;
|
||||
|
||||
/// Command that draws non-indexed vertices.
|
||||
pub struct CmdDrawIndirect<V, I, P, S, Pc> {
|
||||
vertex_buffers: CmdBindVertexBuffers<V>,
|
||||
push_constants: CmdPushConstants<Pc, P>,
|
||||
descriptor_sets: CmdBindDescriptorSets<S, P>,
|
||||
set_state: CmdSetState,
|
||||
bind_pipeline: CmdBindPipeline<P>,
|
||||
draw_raw: CmdDrawIndirectRaw<I>,
|
||||
}
|
||||
|
||||
impl<V, I, P, S, Pc> CmdDrawIndirect<V, I, P, S, Pc>
|
||||
where P: GraphicsPipelineAbstract, S: DescriptorSetsCollection,
|
||||
I: BufferAccess + TypedBuffer<Content = [DrawIndirectCommand]>
|
||||
{
|
||||
/// See the documentation of the `draw` method.
|
||||
pub fn new(pipeline: P, dynamic: DynamicState, vertices: V, indirect_buffer: I, sets: S,
|
||||
push_constants: Pc) -> CmdDrawIndirect<V, I, P, S, Pc>
|
||||
where P: VertexSource<V> + Clone
|
||||
{
|
||||
let draw_count = indirect_buffer.len() as u32;
|
||||
|
||||
// TODO: err, how to ensure safety for ranges in the command?
|
||||
|
||||
let bind_pipeline = CmdBindPipeline::bind_graphics_pipeline(pipeline.clone());
|
||||
let device = bind_pipeline.device().clone();
|
||||
let set_state = CmdSetState::new(device, dynamic);
|
||||
let descriptor_sets = CmdBindDescriptorSets::new(true, pipeline.clone(), sets).unwrap() /* TODO: error */;
|
||||
let push_constants = CmdPushConstants::new(pipeline.clone(), push_constants).unwrap() /* TODO: error */;
|
||||
let vertex_buffers = CmdBindVertexBuffers::new(&pipeline, vertices);
|
||||
let draw_raw = unsafe { CmdDrawIndirectRaw::new(indirect_buffer, draw_count) };
|
||||
|
||||
CmdDrawIndirect {
|
||||
vertex_buffers: vertex_buffers,
|
||||
push_constants: push_constants,
|
||||
descriptor_sets: descriptor_sets,
|
||||
set_state: set_state,
|
||||
bind_pipeline: bind_pipeline,
|
||||
draw_raw: draw_raw,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<Cb, V, I, P, S, Pc, O, O1, O2, O3, O4, O5> AddCommand<CmdDrawIndirect<V, I, P, S, Pc>> for Cb
|
||||
where Cb: AddCommand<CmdBindVertexBuffers<V>, Out = O1>,
|
||||
O1: AddCommand<CmdPushConstants<Pc, P>, Out = O2>,
|
||||
O2: AddCommand<CmdBindDescriptorSets<S, P>, Out = O3>,
|
||||
O3: AddCommand<CmdSetState, Out = O4>,
|
||||
O4: AddCommand<CmdBindPipeline<P>, Out = O5>,
|
||||
O5: AddCommand<CmdDrawIndirectRaw<I>, Out = O>
|
||||
{
|
||||
type Out = O;
|
||||
|
||||
#[inline]
|
||||
fn add(self, command: CmdDrawIndirect<V, I, P, S, Pc>) -> Result<Self::Out, CommandAddError> {
|
||||
Ok(self.add(command.vertex_buffers)?
|
||||
.add(command.push_constants)?
|
||||
.add(command.descriptor_sets)?
|
||||
.add(command.set_state)?
|
||||
.add(command.bind_pipeline)?
|
||||
.add(command.draw_raw)?)
|
||||
}
|
||||
}
|
@ -15,8 +15,10 @@ pub use self::dispatch::{CmdDispatch, CmdDispatchError};
|
||||
//pub use self::dispatch_indirect::{CmdDispatchIndirect, CmdDispatchIndirectError};
|
||||
pub use self::draw::CmdDraw;
|
||||
pub use self::draw_indexed::CmdDrawIndexed;
|
||||
pub use self::draw_indirect::CmdDrawIndirect;
|
||||
|
||||
mod dispatch;
|
||||
//mod dispatch_indirect;
|
||||
mod draw;
|
||||
mod draw_indexed;
|
||||
mod draw_indirect;
|
||||
|
@ -21,28 +21,33 @@ use vk;
|
||||
|
||||
pub struct CmdDrawIndirectRaw<B> {
|
||||
buffer: B,
|
||||
offset: vk::DeviceSize,
|
||||
draw_count: u32,
|
||||
stride: u32,
|
||||
}
|
||||
|
||||
impl<B> CmdDrawIndirectRaw<B> where B: BufferAccess {
|
||||
#[inline]
|
||||
pub unsafe fn new(buffer: B, offset: usize, draw_count: u32) -> CmdDrawIndirectRaw<B> {
|
||||
let real_offset = offset + buffer.inner().offset;
|
||||
assert_eq!(real_offset % 4, 0);
|
||||
pub unsafe fn new(buffer: B, draw_count: u32) -> CmdDrawIndirectRaw<B> {
|
||||
assert_eq!(buffer.inner().offset % 4, 0);
|
||||
|
||||
// FIXME: all checks are missing here
|
||||
|
||||
CmdDrawIndirectRaw {
|
||||
buffer: buffer,
|
||||
offset: real_offset as vk::DeviceSize,
|
||||
draw_count: draw_count,
|
||||
stride: 16, // TODO:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<B> CmdDrawIndirectRaw<B> {
|
||||
/// Returns the buffer that contains the indirect command.
|
||||
#[inline]
|
||||
pub fn buffer(&self) -> &B {
|
||||
&self.buffer
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<B> DeviceOwned for CmdDrawIndirectRaw<B>
|
||||
where B: DeviceOwned
|
||||
{
|
||||
@ -64,7 +69,8 @@ unsafe impl<'a, B, P> AddCommand<&'a CmdDrawIndirectRaw<B>> for UnsafeCommandBuf
|
||||
let vk = self.device().pointers();
|
||||
let cmd = self.internal_object();
|
||||
vk.CmdDrawIndirect(cmd, command.buffer.inner().buffer.internal_object(),
|
||||
command.offset, command.draw_count, command.stride);
|
||||
command.buffer.inner().offset as vk::DeviceSize,
|
||||
command.draw_count, command.stride);
|
||||
}
|
||||
|
||||
Ok(self)
|
||||
|
Loading…
Reference in New Issue
Block a user