Restore CmdDrawIndexed

- restore CmdDrawIndexed
- add a method `draw_indexed` to `CommandBufferBuilder`
- pass through relative `AddCommand`-impls to relative layers and
finally to `AutoCommandBufferBuilder`.
- make the teapot example work again
This commit is contained in:
Luxko 2017-03-16 21:55:01 +08:00
parent c85258de55
commit f82ceaf35c
7 changed files with 136 additions and 115 deletions

View File

@ -17,11 +17,10 @@ extern crate vulkano;
extern crate vulkano_win;
use vulkano_win::VkSurfaceBuild;
use vulkano::command_buffer::CommandsList;
use vulkano::command_buffer::Submit;
use vulkano::command_buffer::CommandBufferBuilder;
use vulkano::sync::GpuFuture;
use std::sync::Arc;
use std::time::Duration;
mod vs { include!{concat!(env!("OUT_DIR"), "/shaders/src/bin/teapot_vs.glsl")} }
mod fs { include!{concat!(env!("OUT_DIR"), "/shaders/src/bin/teapot_fs.glsl")} }
@ -100,33 +99,30 @@ fn main() {
let vs = vs::Shader::load(&device).expect("failed to create shader module");
let fs = fs::Shader::load(&device).expect("failed to create shader module");
mod renderpass {
single_pass_renderpass!{
let renderpass = Arc::new(
single_pass_renderpass!(device.clone(),
attachments: {
color: {
load: Clear,
store: Store,
format: ::vulkano::format::Format,
format: images[0].format(),
samples: 1,
},
depth: {
load: Clear,
store: DontCare,
format: ::vulkano::format::D16Unorm,
format: vulkano::image::Image::format(&depth_buffer),
samples: 1,
}
},
pass: {
color: [color],
depth_stencil: {depth}
}
}
}
).unwrap()
);
let renderpass = renderpass::CustomRenderPass::new(&device, &renderpass::Formats {
color: (images[0].format(), 1),
depth: (vulkano::format::D16Unorm, 1)
}).unwrap();
let pipeline = vulkano::pipeline::GraphicsPipeline::new(&device, vulkano::pipeline::GraphicsPipelineParams {
let pipeline = Arc::new(vulkano::pipeline::GraphicsPipeline::new(&device, vulkano::pipeline::GraphicsPipelineParams {
vertex_input: vulkano::pipeline::vertex::TwoBuffersDefinition::new(),
vertex_shader: vs.main_entry_point(),
input_assembly: vulkano::pipeline::input_assembly::InputAssembly::triangle_list(),
@ -148,43 +144,31 @@ fn main() {
depth_stencil: vulkano::pipeline::depth_stencil::DepthStencil::simple_depth_test(),
blend: vulkano::pipeline::blend::Blend::pass_through(),
render_pass: vulkano::framebuffer::Subpass::from(renderpass.clone(), 0).unwrap(),
}).unwrap();
}).unwrap());
let set = Arc::new(simple_descriptor_set!(pipeline.clone(), 0, {
uniforms: uniform_buffer.clone()
}));
let framebuffers = images.iter().map(|image| {
let attachments = renderpass::AList {
color: image.clone(),
depth: depth_buffer.clone(),
};
let attachments = renderpass.desc().start_attachments()
.color(image.clone()).depth(depth_buffer.clone());
let dimensions = [image.dimensions()[0], image.dimensions()[1], 1];
vulkano::framebuffer::StdFramebuffer::new(renderpass.clone(), [image.dimensions()[0], image.dimensions()[1], 1], attachments).unwrap()
vulkano::framebuffer::Framebuffer::new(renderpass.clone(), dimensions, attachments).unwrap()
}).collect::<Vec<_>>();
let command_buffers = framebuffers.iter().map(|framebuffer| {
Arc::new(vulkano::command_buffer::empty()
.begin_render_pass(framebuffer.clone(), false, renderpass::ClearValues {
color: [0.0, 0.0, 1.0, 1.0],
depth: 1.0,
})
.draw_indexed(pipeline.clone(), vulkano::command_buffer::DynamicState::none(),
(vertex_buffer.clone(), normals_buffer.clone()), index_buffer.clone(), set.clone(), ())
.end_render_pass().unwrap()
.build_primary(&device, queue.family()).unwrap())
}).collect::<Vec<_>>();
let mut submissions: Vec<vulkano::command_buffer::Submission> = Vec::new();
let mut submissions: Vec<Box<GpuFuture>> = Vec::new();
loop {
submissions.retain(|s| s.destroying_would_block());
while submissions.len() >= 4 {
submissions.remove(0);
}
{
// aquiring write lock for the uniform buffer
let mut buffer_content = uniform_buffer.write(Duration::new(1, 0)).unwrap();
let mut buffer_content = uniform_buffer.write().unwrap();
let rotation = cgmath::Matrix3::from_angle_y(cgmath::Rad(time::precise_time_ns() as f32 * 0.000000001));
@ -193,9 +177,26 @@ fn main() {
buffer_content.world = cgmath::Matrix4::from(rotation).into();
}
let image_num = swapchain.acquire_next_image(Duration::from_millis(1)).unwrap();
submissions.push(command_buffers[image_num].clone().submit(&queue).unwrap());
swapchain.present(&queue, image_num).unwrap();
let (image_num, future) = swapchain.acquire_next_image(std::time::Duration::new(1, 0)).unwrap();
let command_buffer = vulkano::command_buffer::AutoCommandBufferBuilder::new(device.clone(), queue.family()).unwrap()
.begin_render_pass(
framebuffers[image_num].clone(), false,
renderpass.desc().start_clear_values()
.color([0.0, 0.0, 1.0, 1.0]).depth((1f32)))
.draw_indexed(
pipeline.clone(), vulkano::command_buffer::DynamicState::none(),
(vertex_buffer.clone(), normals_buffer.clone()),
index_buffer.clone(), set.clone(), ())
.end_render_pass()
.build();
let future = future
.then_execute(queue.clone(), command_buffer)
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
.then_signal_fence();
future.flush().unwrap();
submissions.push(Box::new(future) as Box<_>);
for ev in window.window().poll_events() {
match ev {

View File

@ -147,6 +147,7 @@ pass_through!((), cmd::CmdClearAttachments);
pass_through!((S, D), cmd::CmdCopyBuffer<S, D>);
pass_through!((S, D), cmd::CmdCopyBufferToImage<S, D>);
pass_through!((), cmd::CmdDrawRaw);
pass_through!((), cmd::CmdDrawIndexedRaw);
pass_through!((), cmd::CmdEndRenderPass);
pass_through!((C), cmd::CmdExecuteCommands<C>);
pass_through!((B), cmd::CmdFillBuffer<B>);

View File

@ -10,6 +10,7 @@
use std::sync::Arc;
use buffer::Buffer;
use buffer::TypedBuffer;
use device::DeviceOwned;
use command_buffer::DynamicState;
use command_buffer::cb::AddCommand;
@ -23,6 +24,7 @@ use image::Image;
use pipeline::ComputePipelineAbstract;
use pipeline::GraphicsPipelineAbstract;
use pipeline::vertex::VertexSource;
use pipeline::input_assembly::Index;
///
/// > **Note**: This trait is just a utility trait. Do not implement it yourself. Instead
@ -154,6 +156,22 @@ pub unsafe trait CommandBufferBuilder: DeviceOwned {
self.add(cmd)
}
/// Adds a command that draws indexed vertices.
///
/// Can only be used from inside a render pass.
#[inline]
fn draw_indexed<P, S, Pc, V, Ib, I, O>(self, pipeline: P, dynamic: DynamicState,
vertices: V, index_buffer: Ib, sets: S, push_constants: Pc) -> O
where Self: Sized + AddCommand<cmd::CmdDrawIndexed<V, Ib, P, S, Pc>, Out = O>,
S: DescriptorSetsCollection,
P: VertexSource<V> + GraphicsPipelineAbstract + Clone,
Ib: Buffer + TypedBuffer<Content = [I]>,
I: Index + 'static
{
let cmd = cmd::CmdDrawIndexed::new(pipeline, dynamic, vertices, index_buffer, 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, cmd::CmdDispatchError>

View File

@ -95,6 +95,7 @@ pass_through!((S, D), cmd::CmdCopyBufferToImage<S, D>);
pass_through!((S, D), cmd::CmdCopyImage<S, D>);
pass_through!((), cmd::CmdDispatchRaw);
pass_through!((), cmd::CmdDrawRaw);
pass_through!((), cmd::CmdDrawIndexedRaw);
pass_through!((), cmd::CmdEndRenderPass);
pass_through!((C), cmd::CmdExecuteCommands<C>);
pass_through!((B), cmd::CmdFillBuffer<B>);

View File

@ -291,6 +291,21 @@ unsafe impl<I, O> AddCommand<cmd::CmdDrawRaw> for SubmitSyncBuilderLayer<I>
}
}
unsafe impl<I, O> AddCommand<cmd::CmdDrawIndexedRaw> for SubmitSyncBuilderLayer<I>
where I: AddCommand<cmd::CmdDrawIndexedRaw, Out = O>
{
type Out = SubmitSyncBuilderLayer<O>;
#[inline]
fn add(self, command: cmd::CmdDrawIndexedRaw) -> Self::Out {
SubmitSyncBuilderLayer {
inner: AddCommand::add(self.inner, command),
buffers: self.buffers,
images: self.images,
}
}
}
unsafe impl<I, O> AddCommand<cmd::CmdEndRenderPass> for SubmitSyncBuilderLayer<I>
where I: AddCommand<cmd::CmdEndRenderPass, Out = O>
{

View File

@ -7,109 +7,94 @@
// notice may not be copied, modified, or distributed except
// according to those terms.
use std::sync::Arc;
use buffer::Buffer;
use buffer::TypedBuffer;
use command_buffer::DynamicState;
use command_buffer::cb::AddCommand;
use command_buffer::cmd::CmdBindDescriptorSets;
use command_buffer::cmd::CmdBindIndexBuffer;
use command_buffer::cmd::CmdBindPipeline;
use command_buffer::cmd::CmdBindVertexBuffers;
use command_buffer::cmd::CmdPushConstants;
use command_buffer::cmd::CmdSetState;
use command_buffer::RawCommandBufferPrototype;
use command_buffer::CommandsList;
use command_buffer::CommandsListSink;
use descriptor::PipelineLayoutAbstract;
use descriptor::descriptor_set::collection::TrackedDescriptorSetsCollection;
use device::DeviceOwned;
use pipeline::GraphicsPipeline;
use command_buffer::cmd::CmdDrawIndexedRaw;
use descriptor::descriptor_set::DescriptorSetsCollection;
use pipeline::GraphicsPipelineAbstract;
use pipeline::input_assembly::Index;
use pipeline::vertex::Source;
use VulkanPointers;
use pipeline::vertex::VertexSource;
/// Command that draws indexed vertices.
pub struct CmdDrawIndexed<L, V, Ib, Pv, Pl, Prp, S, Pc>
where L: CommandsList, Pl: PipelineLayoutAbstract, S: TrackedDescriptorSetsCollection
pub struct CmdDrawIndexed<V, Ib, P, S, Pc>
{
// Parent commands list.
previous: CmdBindIndexBuffer<
CmdBindVertexBuffers<
CmdPushConstants<
CmdBindDescriptorSets<
CmdSetState<
CmdBindPipeline<L, Arc<GraphicsPipeline<Pv, Pl, Prp>>>
>,
S, Arc<GraphicsPipeline<Pv, Pl, Prp>>
>,
Pc, Arc<GraphicsPipeline<Pv, Pl, Prp>>
>,
V
>,
Ib
>,
// Parameters for vkCmdDrawIndexedIndexed.
index_count: u32,
instance_count: u32,
first_index: u32,
vertex_offset: i32,
first_instance: u32,
vertex_buffers: CmdBindVertexBuffers<V>,
index_buffer: CmdBindIndexBuffer<Ib>,
push_constants: CmdPushConstants<Pc, P>,
descriptor_sets: CmdBindDescriptorSets<S, P>,
set_state: CmdSetState,
bind_pipeline: CmdBindPipeline<P>,
draw_indexed_raw: CmdDrawIndexedRaw,
}
impl<L, V, I, Ib, Pv, Pl, Prp, S, Pc> CmdDrawIndexed<L, V, Ib, Pv, Pl, Prp, S, Pc>
where L: CommandsList,
Pl: PipelineLayoutAbstract,
S: TrackedDescriptorSetsCollection,
impl<V, Ib, I, P, S, Pc> CmdDrawIndexed<V, Ib, P, S, Pc>
where P: GraphicsPipelineAbstract,
S: DescriptorSetsCollection,
Ib: Buffer + TypedBuffer<Content = [I]>,
I: Index + 'static
{
/// See the documentation of the `draw` method.
pub fn new(previous: L, pipeline: Arc<GraphicsPipeline<Pv, Pl, Prp>>,
dynamic: DynamicState, vertices: V, index_buffer: Ib, sets: S, push_constants: Pc)
-> CmdDrawIndexed<L, V, Ib, Pv, Pl, Prp, S, Pc>
where Pv: Source<V>
pub fn new(pipeline: P, dynamic: DynamicState,
vertices: V, index_buffer: Ib, sets: S, push_constants: Pc)
-> CmdDrawIndexed<V, Ib, P, S, Pc>
where P: VertexSource<V> + Clone
{
let index_count = index_buffer.len();
let (_, _, instance_count) = pipeline.vertex_definition().decode(&vertices);
let previous = CmdBindPipeline::bind_graphics_pipeline(previous, pipeline.clone());
let device = previous.device().clone();
let previous = CmdSetState::new(previous, device, dynamic);
let previous = CmdBindDescriptorSets::new(previous, true, pipeline.clone(), sets).unwrap() /* TODO: error */;
let previous = CmdPushConstants::new(previous, pipeline.clone(), push_constants).unwrap() /* TODO: error */;
let previous = CmdBindVertexBuffers::new(previous, pipeline.vertex_definition(), vertices);
let previous = CmdBindIndexBuffer::new(previous, index_buffer);
let (_, _, instance_count) = pipeline.decode(&vertices);
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 index_buffer = CmdBindIndexBuffer::new(index_buffer);
let draw_indexed_raw = unsafe {
CmdDrawIndexedRaw::new(
index_count as u32, instance_count as u32,
0, 0, 0
)
};
// TODO: check that dynamic state is not missing some elements required by the pipeline
CmdDrawIndexed {
previous: previous,
index_count: index_count as u32,
instance_count: instance_count as u32,
first_index: 0,
vertex_offset: 0,
first_instance: 0,
vertex_buffers: vertex_buffers,
index_buffer: index_buffer,
push_constants: push_constants,
descriptor_sets: descriptor_sets,
set_state: set_state,
bind_pipeline: bind_pipeline,
draw_indexed_raw: draw_indexed_raw,
}
}
}
unsafe impl<L, V, Ib, Pv, Pl, Prp, S, Pc> CommandsList for CmdDrawIndexed<L, V, Ib, Pv, Pl, Prp, S, Pc>
where L: CommandsList, Pl: PipelineLayoutAbstract, S: TrackedDescriptorSetsCollection,
Ib: Buffer
unsafe impl<Cb, V, Ib, P, S, Pc, O, O1, O2, O3, O4, O5, O6> AddCommand<CmdDrawIndexed<V, Ib, P, S, Pc>> for Cb
where Cb: AddCommand<CmdBindVertexBuffers<V>, Out = O1>,
O1: AddCommand<CmdBindIndexBuffer<Ib>, Out = O2>,
O2: AddCommand<CmdPushConstants<Pc, P>, Out = O3>,
O3: AddCommand<CmdBindDescriptorSets<S, P>, Out = O4>,
O4: AddCommand<CmdSetState, Out = O5>,
O5: AddCommand<CmdBindPipeline<P>, Out = O6>,
O6: AddCommand<CmdDrawIndexedRaw, Out = O>
{
type Out = O;
#[inline]
fn append<'a>(&'a self, builder: &mut CommandsListSink<'a>) {
self.previous.append(builder);
builder.add_command(Box::new(move |raw: &mut RawCommandBufferPrototype| {
unsafe {
let vk = raw.device.pointers();
let cmd = raw.command_buffer.clone().take().unwrap();
vk.CmdDrawIndexed(cmd, self.index_count, self.instance_count, self.first_index,
self.vertex_offset, self.first_instance);
}
}));
fn add(self, command: CmdDrawIndexed<V, Ib, P, S, Pc>) -> O {
self.add(command.vertex_buffers)
.add(command.index_buffer)
.add(command.push_constants)
.add(command.descriptor_sets)
.add(command.set_state)
.add(command.bind_pipeline)
.add(command.draw_indexed_raw)
}
}

View File

@ -23,7 +23,7 @@ pub use self::dispatch::{CmdDispatch, CmdDispatchError};
//pub use self::dispatch_indirect::{CmdDispatchIndirect, CmdDispatchIndirectError};
pub use self::dispatch_raw::{CmdDispatchRaw, CmdDispatchRawError};
pub use self::draw::CmdDraw;
//pub use self::draw_indexed::CmdDrawIndexed;
pub use self::draw_indexed::CmdDrawIndexed;
pub use self::draw_indexed_raw::CmdDrawIndexedRaw;
pub use self::draw_indirect_raw::CmdDrawIndirectRaw;
pub use self::draw_raw::CmdDrawRaw;
@ -52,7 +52,7 @@ mod dispatch;
//mod dispatch_indirect;
mod dispatch_raw;
mod draw;
//mod draw_indexed;
mod draw_indexed;
mod draw_indexed_raw;
mod draw_indirect_raw;
mod draw_raw;