From 52c2aac6a6381b596aa399538f983d4aadd5e323 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 19 Oct 2016 19:48:39 +0200 Subject: [PATCH] Rework the vertex definition traits --- vulkano/src/command_buffer/std/draw.rs | 48 ++++++++++++---------- vulkano/src/command_buffer/std/mod.rs | 2 +- vulkano/src/command_buffer/sys.rs | 9 +++-- vulkano/src/pipeline/vertex.rs | 56 ++++++++++---------------- 4 files changed, 53 insertions(+), 62 deletions(-) diff --git a/vulkano/src/command_buffer/std/draw.rs b/vulkano/src/command_buffer/std/draw.rs index 13dcf4d4..f7bbc0e8 100644 --- a/vulkano/src/command_buffer/std/draw.rs +++ b/vulkano/src/command_buffer/std/draw.rs @@ -11,7 +11,6 @@ use std::iter; use std::sync::Arc; use smallvec::SmallVec; -use buffer::Buffer; use command_buffer::DynamicState; use command_buffer::StatesManager; use command_buffer::SubmitInfo; @@ -34,7 +33,7 @@ use VulkanObject; use vk; /// Wraps around a commands list and adds a draw command at the end of it. -pub struct DrawCommand<'a, L, Pv, Pl, Prp, S, Pc> +pub struct DrawCommand<'a, L, V, Pv, Pl, Prp, S, Pc> where L: CommandsList, Pl: PipelineLayoutRef, S: TrackedDescriptorSetsCollection, Pc: 'a { // Parent commands list. @@ -47,8 +46,9 @@ pub struct DrawCommand<'a, L, Pv, Pl, Prp, S, Pc> pipeline_barrier: (usize, PipelineBarrierBuilder), // The push constants. TODO: use Cow push_constants: &'a Pc, - // FIXME: strong typing and state transitions - vertex_buffers: SmallVec<[Arc; 4]>, + // FIXME: state transitions + vertex_buffers: V, + raw_vertex_buffers: SmallVec<[(vk::Buffer, usize); 4]>, // States of the resources, or `None` if it has been extracted. resources_states: Option, // Actual type of draw. @@ -74,14 +74,14 @@ enum DrawInner { // TODO: indirect rendering } -impl<'a, L, Pv, Pl, Prp, S, Pc> DrawCommand<'a, L, Pv, Pl, Prp, S, Pc> +impl<'a, L, V, Pv, Pl, Prp, S, Pc> DrawCommand<'a, L, V, Pv, Pl, Prp, S, Pc> where L: CommandsList + CommandsListPossibleInsideRenderPass, Pl: PipelineLayoutRef, S: TrackedDescriptorSetsCollection, Pc: 'a { /// See the documentation of the `draw` method. - pub fn regular(mut previous: L, pipeline: Arc>, - dynamic: &DynamicState, vertices: V, sets: S, push_constants: &'a Pc) - -> DrawCommand<'a, L, Pv, Pl, Prp, S, Pc> + pub fn regular(mut previous: L, pipeline: Arc>, + dynamic: &DynamicState, vertices: V, sets: S, push_constants: &'a Pc) + -> DrawCommand<'a, L, V, Pv, Pl, Prp, S, Pc> where Pv: Source { let mut states = previous.extract_states(); @@ -92,8 +92,11 @@ impl<'a, L, Pv, Pl, Prp, S, Pc> DrawCommand<'a, L, Pv, Pl, Prp, S, Pc> // FIXME: lot of stuff missing here - let (buffers, num_vertices, num_instances) = pipeline.vertex_definition().decode(vertices); - let buffers = buffers.collect(); + let (raw_buffers, num_vertices, num_instances) = { + let (raw_buffers, num_vertices, num_instances) = pipeline.vertex_definition().decode(&vertices); + let raw_buffers = raw_buffers.iter().map(|b| (b.buffer.internal_object(), b.offset)).collect(); + (raw_buffers, num_vertices, num_instances) + }; DrawCommand { previous: previous, @@ -101,7 +104,8 @@ impl<'a, L, Pv, Pl, Prp, S, Pc> DrawCommand<'a, L, Pv, Pl, Prp, S, Pc> sets: sets, pipeline_barrier: (barrier_loc, barrier), push_constants: push_constants, - vertex_buffers: buffers, + vertex_buffers: vertices, + raw_vertex_buffers: raw_buffers, resources_states: Some(states), inner: DrawInner::Regular { vertex_count: num_vertices as u32, @@ -113,7 +117,7 @@ impl<'a, L, Pv, Pl, Prp, S, Pc> DrawCommand<'a, L, Pv, Pl, Prp, S, Pc> } } -unsafe impl<'a, L, Pv, Pl, Prp, S, Pc> CommandsList for DrawCommand<'a, L, Pv, Pl, Prp, S, Pc> +unsafe impl<'a, L, V, Pv, Pl, Prp, S, Pc> CommandsList for DrawCommand<'a, L, V, Pv, Pl, Prp, S, Pc> where L: CommandsList, Pl: PipelineLayoutRef, S: TrackedDescriptorSetsCollection, Pc: 'a { #[inline] @@ -151,11 +155,11 @@ unsafe impl<'a, L, Pv, Pl, Prp, S, Pc> CommandsList for DrawCommand<'a, L, Pv, P } } -unsafe impl<'a, L, Pv, Pl, Prp, S, Pc> CommandsListConcrete for DrawCommand<'a, L, Pv, Pl, Prp, S, Pc> +unsafe impl<'a, L, V, Pv, Pl, Prp, S, Pc> CommandsListConcrete for DrawCommand<'a, L, V, Pv, Pl, Prp, S, Pc> where L: CommandsListConcrete, Pl: PipelineLayoutRef, S: TrackedDescriptorSetsCollection, Pc: 'a { type Pool = L::Pool; - type Output = DrawCommandCb; + type Output = DrawCommandCb; unsafe fn raw_build(self, in_s: &mut StatesManager, out: &mut StatesManager, @@ -192,7 +196,7 @@ unsafe impl<'a, L, Pv, Pl, Prp, S, Pc> CommandsListConcrete for DrawCommand<'a, let bind_pipeline = !self.previous.is_graphics_pipeline_bound(my_pipeline.internal_object()); let my_sets = self.sets; let my_push_constants = self.push_constants; - let my_vertex_buffers = self.vertex_buffers; + let my_vertex_buffers = self.raw_vertex_buffers; let my_inner = self.inner; // Passing to the parent. @@ -207,7 +211,7 @@ unsafe impl<'a, L, Pv, Pl, Prp, S, Pc> CommandsListConcrete for DrawCommand<'a, cb.push_constants(my_pipeline.layout(), ShaderStages::all(), 0, // TODO: stages &my_push_constants); - cb.bind_vertex_buffers(0, my_vertex_buffers.iter().map(|buf| (buf.inner().buffer, 0))); + cb.bind_vertex_buffers(0, my_vertex_buffers.iter().cloned()); match my_inner { DrawInner::Regular { vertex_count, instance_count, @@ -231,12 +235,12 @@ unsafe impl<'a, L, Pv, Pl, Prp, S, Pc> CommandsListConcrete for DrawCommand<'a, previous: parent, pipeline: my_pipeline, sets: my_sets, - vertex_buffers: my_vertex_buffers, + vertex_buffers: self.vertex_buffers, } } } -unsafe impl<'a, L, Pv, Pl, Prp, S, Pc> CommandsListPossibleInsideRenderPass for DrawCommand<'a, L, Pv, Pl, Prp, S, Pc> +unsafe impl<'a, L, V, Pv, Pl, Prp, S, Pc> CommandsListPossibleInsideRenderPass for DrawCommand<'a, L, V, Pv, Pl, Prp, S, Pc> where L: CommandsList + CommandsListPossibleInsideRenderPass, Pl: PipelineLayoutRef, S: TrackedDescriptorSetsCollection, Pc: 'a { @@ -259,7 +263,7 @@ unsafe impl<'a, L, Pv, Pl, Prp, S, Pc> CommandsListPossibleInsideRenderPass for } /// Wraps around a command buffer and adds an update buffer command at the end of it. -pub struct DrawCommandCb +pub struct DrawCommandCb where L: CommandsListOutput, Pl: PipelineLayoutRef, S: TrackedDescriptorSetsCollection { // The previous commands. @@ -268,11 +272,11 @@ pub struct DrawCommandCb pipeline: Arc>, // The descriptor sets. Stored here to keep them alive. sets: S, - // FIXME: strong typing and state transitions - vertex_buffers: SmallVec<[Arc; 4]>, + // The vertex buffers used. + vertex_buffers: V, } -unsafe impl CommandsListOutput for DrawCommandCb +unsafe impl CommandsListOutput for DrawCommandCb where L: CommandsListOutput, Pl: PipelineLayoutRef, S: TrackedDescriptorSetsCollection { #[inline] diff --git a/vulkano/src/command_buffer/std/mod.rs b/vulkano/src/command_buffer/std/mod.rs index 1404d97d..e4a3a864 100644 --- a/vulkano/src/command_buffer/std/mod.rs +++ b/vulkano/src/command_buffer/std/mod.rs @@ -140,7 +140,7 @@ pub unsafe trait CommandsList { fn draw<'a, Pv, Pl, Prp, S, Pc, V>(self, pipeline: Arc>, dynamic: &DynamicState, vertices: V, sets: S, push_constants: &'a Pc) - -> draw::DrawCommand<'a, Self, Pv, Pl, Prp, S, Pc> + -> draw::DrawCommand<'a, Self, V, Pv, Pl, Prp, S, Pc> where Self: Sized + CommandsList + CommandsListPossibleInsideRenderPass, Pl: PipelineLayoutRef, S: TrackedDescriptorSetsCollection, Pc: 'a, Pv: Source { diff --git a/vulkano/src/command_buffer/sys.rs b/vulkano/src/command_buffer/sys.rs index 81ad64f2..7deda726 100644 --- a/vulkano/src/command_buffer/sys.rs +++ b/vulkano/src/command_buffer/sys.rs @@ -936,17 +936,18 @@ impl

UnsafeCommandBufferBuilder

where P: CommandPool { /// /// - Panics if one of the buffers was not created with the same device as this command buffer. /// - // TODO: don't request UnsafeBuffer + // TODO: don't request vk::Buffer #[inline] pub unsafe fn bind_vertex_buffers<'a, I>(&mut self, first_binding: u32, buffers: I) - where I: IntoIterator + where I: IntoIterator { let mut raw_buffers: SmallVec<[_; 8]> = SmallVec::new(); let mut raw_offsets: SmallVec<[_; 8]> = SmallVec::new(); for (buf, off) in buffers { - assert_eq!(buf.device().internal_object(), self.device.internal_object()); - raw_buffers.push(buf.internal_object()); + // TODO: restore + //assert_eq!(buf.device().internal_object(), self.device.internal_object()); + raw_buffers.push(buf); raw_offsets.push(off as vk::DeviceSize); } diff --git a/vulkano/src/pipeline/vertex.rs b/vulkano/src/pipeline/vertex.rs index 85ee599b..ac90b333 100644 --- a/vulkano/src/pipeline/vertex.rs +++ b/vulkano/src/pipeline/vertex.rs @@ -68,10 +68,9 @@ use std::fmt; use std::marker::PhantomData; use std::mem; use std::option::IntoIter as OptionIntoIter; -use std::sync::Arc; use std::vec::IntoIter as VecIntoIter; -use buffer::Buffer; +use buffer::BufferInner; use buffer::TypedBuffer; use format::Format; use pipeline::shader::ShaderInterfaceDef; @@ -217,13 +216,12 @@ impl fmt::Display for IncompatibleVertexDefinitionError { /// Extension trait of `Definition`. The `L` parameter is an acceptable vertex source for this /// vertex definition. -pub unsafe trait Source: 'static + Send + Sync { - /// Iterator used by `decode`. - type Iter: ExactSizeIterator>; - - /// Checks and returns the list of buffers, number of vertices and number of instances. +pub unsafe trait Source { + /// Checks and returns the list of buffers with offsets, number of vertices and number of instances. // TODO: return error if problem - fn decode(&self, L) -> (Self::Iter, usize, usize); + // TODO: better than a Vec + // TODO: return a struct instead + fn decode<'l>(&self, &'l L) -> (Vec>, usize, usize); } /// Implementation of `Definition` for a single vertex buffer. @@ -279,15 +277,12 @@ unsafe impl Definition for SingleBufferDefinition } } -unsafe impl<'a, B, V> Source<&'a Arc> for SingleBufferDefinition - where B: TypedBuffer + 'static, V: Vertex + 'static +unsafe impl<'a, B, V> Source for SingleBufferDefinition + where B: TypedBuffer, V: Vertex { - type Iter = OptionIntoIter>; - #[inline] - fn decode(&self, source: &'a Arc) -> (OptionIntoIter>, usize, usize) { - let iter = Some(source.clone() as Arc<_>).into_iter(); - (iter, source.len(), 1) + fn decode<'l>(&self, source: &'l B) -> (Vec>, usize, usize) { + (vec![source.inner()], source.len(), 1) } } @@ -352,18 +347,14 @@ unsafe impl Definition for TwoBuffersDefinition } } -unsafe impl<'a, T, U, Bt, Bu> Source<(&'a Arc, &'a Arc)> for TwoBuffersDefinition - where T: Vertex + 'static, Bt: TypedBuffer + 'static, T: 'static, - U: Vertex + 'static, Bu: TypedBuffer + 'static, T: 'static +unsafe impl<'a, T, U, Bt, Bu> Source<(Bt, Bu)> for TwoBuffersDefinition + where T: Vertex, Bt: TypedBuffer, + U: Vertex, Bu: TypedBuffer { - type Iter = VecIntoIter>; - #[inline] - fn decode(&self, source: (&'a Arc, &'a Arc)) - -> (VecIntoIter>, usize, usize) - { - let iter = vec![source.0.clone() as Arc<_>, source.1.clone() as Arc<_>].into_iter(); - (iter, [source.0.len(), source.1.len()].iter().cloned().min().unwrap(), 1) + fn decode<'l>(&self, source: &'l (Bt, Bu)) -> (Vec>, usize, usize) { + let vertices = [source.0.len(), source.1.len()].iter().cloned().min().unwrap(); + (vec![source.0.inner(), source.1.inner()], vertices, 1) } } @@ -428,18 +419,13 @@ unsafe impl Definition for OneVertexOneInstanceDefinition } } -unsafe impl<'a, T, U, Bt, Bu> Source<(&'a Arc, &'a Arc)> for OneVertexOneInstanceDefinition - where T: Vertex + 'static, Bt: TypedBuffer + 'static, T: 'static, - U: Vertex + 'static, Bu: TypedBuffer + 'static, U: 'static +unsafe impl<'a, T, U, Bt, Bu> Source<(Bt, Bu)> for OneVertexOneInstanceDefinition + where T: Vertex, Bt: TypedBuffer, + U: Vertex, Bu: TypedBuffer { - type Iter = VecIntoIter>; - #[inline] - fn decode(&self, source: (&'a Arc, &'a Arc)) - -> (VecIntoIter>, usize, usize) - { - let iter = vec![source.0.clone() as Arc<_>, source.1.clone() as Arc<_>].into_iter(); - (iter, source.0.len(), source.1.len()) + fn decode<'l>(&self, source: &'l (Bt, Bu)) -> (Vec>, usize, usize) { + (vec![source.0.inner(), source.1.inner()], source.0.len(), source.1.len()) } }