Rework the vertex definition traits

This commit is contained in:
Pierre Krieger 2016-10-19 19:48:39 +02:00
parent 8ceb12dce3
commit 52c2aac6a6
4 changed files with 53 additions and 62 deletions

View File

@ -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<Buffer>; 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<StatesManager>,
// 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<V>(mut previous: L, pipeline: Arc<GraphicsPipeline<Pv, Pl, Prp>>,
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<GraphicsPipeline<Pv, Pl, Prp>>,
dynamic: &DynamicState, vertices: V, sets: S, push_constants: &'a Pc)
-> DrawCommand<'a, L, V, Pv, Pl, Prp, S, Pc>
where Pv: Source<V>
{
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<L::Output, Pv, Pl, Prp, S>;
type Output = DrawCommandCb<L::Output, V, Pv, Pl, Prp, S>;
unsafe fn raw_build<I, F>(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<L, Pv, Pl, Prp, S>
pub struct DrawCommandCb<L, V, Pv, Pl, Prp, S>
where L: CommandsListOutput, Pl: PipelineLayoutRef, S: TrackedDescriptorSetsCollection
{
// The previous commands.
@ -268,11 +272,11 @@ pub struct DrawCommandCb<L, Pv, Pl, Prp, S>
pipeline: Arc<GraphicsPipeline<Pv, Pl, Prp>>,
// The descriptor sets. Stored here to keep them alive.
sets: S,
// FIXME: strong typing and state transitions
vertex_buffers: SmallVec<[Arc<Buffer>; 4]>,
// The vertex buffers used.
vertex_buffers: V,
}
unsafe impl<L, Pv, Pl, Prp, S> CommandsListOutput for DrawCommandCb<L, Pv, Pl, Prp, S>
unsafe impl<L, V, Pv, Pl, Prp, S> CommandsListOutput for DrawCommandCb<L, V, Pv, Pl, Prp, S>
where L: CommandsListOutput, Pl: PipelineLayoutRef, S: TrackedDescriptorSetsCollection
{
#[inline]

View File

@ -140,7 +140,7 @@ pub unsafe trait CommandsList {
fn draw<'a, Pv, Pl, Prp, S, Pc, V>(self, pipeline: Arc<GraphicsPipeline<Pv, Pl, Prp>>,
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<V>
{

View File

@ -936,17 +936,18 @@ impl<P> UnsafeCommandBufferBuilder<P> 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<Item = (&'a UnsafeBuffer, usize)>
where I: IntoIterator<Item = (vk::Buffer, usize)>
{
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);
}

View File

@ -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<L>: 'static + Send + Sync {
/// Iterator used by `decode`.
type Iter: ExactSizeIterator<Item = Arc<Buffer>>;
/// Checks and returns the list of buffers, number of vertices and number of instances.
pub unsafe trait Source<L> {
/// 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<BufferInner<'l>>, usize, usize);
}
/// Implementation of `Definition` for a single vertex buffer.
@ -279,15 +277,12 @@ unsafe impl<T, I> Definition<I> for SingleBufferDefinition<T>
}
}
unsafe impl<'a, B, V> Source<&'a Arc<B>> for SingleBufferDefinition<V>
where B: TypedBuffer<Content = [V]> + 'static, V: Vertex + 'static
unsafe impl<'a, B, V> Source<B> for SingleBufferDefinition<V>
where B: TypedBuffer<Content = [V]>, V: Vertex
{
type Iter = OptionIntoIter<Arc<Buffer>>;
#[inline]
fn decode(&self, source: &'a Arc<B>) -> (OptionIntoIter<Arc<Buffer>>, usize, usize) {
let iter = Some(source.clone() as Arc<_>).into_iter();
(iter, source.len(), 1)
fn decode<'l>(&self, source: &'l B) -> (Vec<BufferInner<'l>>, usize, usize) {
(vec![source.inner()], source.len(), 1)
}
}
@ -352,18 +347,14 @@ unsafe impl<T, U, I> Definition<I> for TwoBuffersDefinition<T, U>
}
}
unsafe impl<'a, T, U, Bt, Bu> Source<(&'a Arc<Bt>, &'a Arc<Bu>)> for TwoBuffersDefinition<T, U>
where T: Vertex + 'static, Bt: TypedBuffer<Content = [T]> + 'static, T: 'static,
U: Vertex + 'static, Bu: TypedBuffer<Content = [U]> + 'static, T: 'static
unsafe impl<'a, T, U, Bt, Bu> Source<(Bt, Bu)> for TwoBuffersDefinition<T, U>
where T: Vertex, Bt: TypedBuffer<Content = [T]>,
U: Vertex, Bu: TypedBuffer<Content = [U]>
{
type Iter = VecIntoIter<Arc<Buffer>>;
#[inline]
fn decode(&self, source: (&'a Arc<Bt>, &'a Arc<Bu>))
-> (VecIntoIter<Arc<Buffer>>, 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<BufferInner<'l>>, 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<T, U, I> Definition<I> for OneVertexOneInstanceDefinition<T, U>
}
}
unsafe impl<'a, T, U, Bt, Bu> Source<(&'a Arc<Bt>, &'a Arc<Bu>)> for OneVertexOneInstanceDefinition<T, U>
where T: Vertex + 'static, Bt: TypedBuffer<Content = [T]> + 'static, T: 'static,
U: Vertex + 'static, Bu: TypedBuffer<Content = [U]> + 'static, U: 'static
unsafe impl<'a, T, U, Bt, Bu> Source<(Bt, Bu)> for OneVertexOneInstanceDefinition<T, U>
where T: Vertex, Bt: TypedBuffer<Content = [T]>,
U: Vertex, Bu: TypedBuffer<Content = [U]>
{
type Iter = VecIntoIter<Arc<Buffer>>;
#[inline]
fn decode(&self, source: (&'a Arc<Bt>, &'a Arc<Bu>))
-> (VecIntoIter<Arc<Buffer>>, 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<BufferInner<'l>>, usize, usize) {
(vec![source.0.inner(), source.1.inner()], source.0.len(), source.1.len())
}
}