mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-25 16:25:31 +00:00
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:
parent
c85258de55
commit
f82ceaf35c
@ -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 {
|
||||
|
@ -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>);
|
||||
|
@ -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>
|
||||
|
@ -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>);
|
||||
|
@ -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>
|
||||
{
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user