module Render.Draw
( triangle_
, triangles_
, quads
, indexed
, indexedRanges
, indexedParts
, indexedPos
, indexedPosRanges
, unsafeIndexedRanges
, unsafeIndexedParts
) where
import RIO
import Data.Vector qualified as Vector
import Vulkan.Core10 qualified as Vk
import Engine.Vulkan.Types (Bound(..))
import Resource.Buffer qualified as Buffer
import Resource.Model qualified as Model
triangle_ :: MonadUnliftIO m => Vk.CommandBuffer -> Bound dsl () () m ()
triangle_ :: forall (m :: * -> *) (dsl :: [*]).
MonadUnliftIO m =>
CommandBuffer -> Bound dsl () () m ()
triangle_ CommandBuffer
cb = forall (m :: * -> *) (dsl :: [*]).
MonadUnliftIO m =>
CommandBuffer -> Word32 -> Bound dsl () () m ()
triangles_ CommandBuffer
cb Word32
1
triangles_ :: MonadUnliftIO m => Vk.CommandBuffer -> Word32 -> Bound dsl () () m ()
triangles_ :: forall (m :: * -> *) (dsl :: [*]).
MonadUnliftIO m =>
CommandBuffer -> Word32 -> Bound dsl () () m ()
triangles_ CommandBuffer
cb Word32
num =
forall (dsl :: [*]) vertices instances (m :: * -> *) a.
m a -> Bound dsl vertices instances m a
Bound forall a b. (a -> b) -> a -> b
$ forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> Word32 -> Word32 -> Word32 -> Word32 -> io ()
Vk.cmdDraw CommandBuffer
cb Word32
3 Word32
num Word32
0 Word32
0
quads
:: MonadUnliftIO m
=> Vk.CommandBuffer
-> Buffer.Allocated stage instances
-> Bound dsl () instances m ()
quads :: forall (m :: * -> *) (stage :: Store) instances (dsl :: [*]).
MonadUnliftIO m =>
CommandBuffer
-> Allocated stage instances -> Bound dsl () instances m ()
quads CommandBuffer
cb Allocated stage instances
instances = forall (dsl :: [*]) vertices instances (m :: * -> *) a.
m a -> Bound dsl vertices instances m a
Bound do
forall (io :: * -> *).
MonadIO io =>
CommandBuffer
-> Word32
-> ("buffers" ::: Vector Buffer)
-> ("offsets" ::: Vector DeviceSize)
-> io ()
Vk.cmdBindVertexBuffers CommandBuffer
cb Word32
0 (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (s :: Store) a. Allocated s a -> Buffer
Buffer.aBuffer Allocated stage instances
instances) (forall (f :: * -> *) a. Applicative f => a -> f a
pure DeviceSize
0)
forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> Word32 -> Word32 -> Word32 -> Word32 -> io ()
Vk.cmdDraw CommandBuffer
cb Word32
6 (forall (s :: Store) a. Allocated s a -> Word32
Buffer.aUsed Allocated stage instances
instances) Word32
0 Word32
0
indexed
:: (MonadUnliftIO m, Model.HasVertexBuffers instances)
=> Vk.CommandBuffer
-> Model.Indexed storage pos attrs
-> instances
-> Bound dsl (Model.Vertex pos attrs) (Model.VertexBuffersOf instances) m ()
indexed :: forall (m :: * -> *) instances (storage :: Store) pos attrs
(dsl :: [*]).
(MonadUnliftIO m, HasVertexBuffers instances) =>
CommandBuffer
-> Indexed storage pos attrs
-> instances
-> Bound dsl (Vertex pos attrs) (VertexBuffersOf instances) m ()
indexed CommandBuffer
cmd Indexed storage pos attrs
model instances
instances = forall (m :: * -> *) instances (storage :: Store) pos attrs
(dsl :: [*]).
(MonadUnliftIO m, HasVertexBuffers instances) =>
CommandBuffer
-> Indexed storage pos attrs
-> instances
-> [IndexRange]
-> Bound dsl (Vertex pos attrs) (VertexBuffersOf instances) m ()
indexedRanges CommandBuffer
cmd Indexed storage pos attrs
model instances
instances [IndexRange
wholeIndexed]
where
wholeIndexed :: IndexRange
wholeIndexed = Model.IndexRange
{ $sel:irFirstIndex:IndexRange :: Word32
irFirstIndex = Word32
0
, $sel:irIndexCount:IndexRange :: Word32
irIndexCount = forall (s :: Store) a. Allocated s a -> Word32
Buffer.aUsed (forall (storage :: Store) pos attrs.
Indexed storage pos attrs -> Allocated storage Word32
Model.iIndices Indexed storage pos attrs
model)
}
indexedRanges
:: (MonadUnliftIO m, Model.HasVertexBuffers instances)
=> Vk.CommandBuffer
-> Model.Indexed storage pos attrs
-> instances
-> [Model.IndexRange]
-> Bound dsl (Model.Vertex pos attrs) (Model.VertexBuffersOf instances) m ()
indexedRanges :: forall (m :: * -> *) instances (storage :: Store) pos attrs
(dsl :: [*]).
(MonadUnliftIO m, HasVertexBuffers instances) =>
CommandBuffer
-> Indexed storage pos attrs
-> instances
-> [IndexRange]
-> Bound dsl (Vertex pos attrs) (VertexBuffersOf instances) m ()
indexedRanges CommandBuffer
cmd Indexed storage pos attrs
model instances
instances [IndexRange]
ranges = do
[IndexRange]
checkedRanges <- forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse IndexRange
-> Bound
dsl (Vertex pos attrs) (VertexBuffersOf instances) m IndexRange
check [IndexRange]
ranges
forall (dsl :: [*]) vertices instances (m :: * -> *) a.
m a -> Bound dsl vertices instances m a
Bound forall a b. (a -> b) -> a -> b
$ forall (io :: * -> *) instances (t :: * -> *) (storage :: Store)
pos attrs.
(MonadUnliftIO io, HasVertexBuffers instances, Foldable t) =>
Bool
-> CommandBuffer
-> Indexed storage pos attrs
-> instances
-> t IndexRange
-> io ()
unsafeIndexedRanges Bool
True CommandBuffer
cmd Indexed storage pos attrs
model instances
instances [IndexRange]
checkedRanges
where
check :: IndexRange
-> Bound
dsl (Vertex pos attrs) (VertexBuffersOf instances) m IndexRange
check ir :: IndexRange
ir@Model.IndexRange{Word32
irIndexCount :: Word32
irFirstIndex :: Word32
$sel:irIndexCount:IndexRange :: IndexRange -> Word32
$sel:irFirstIndex:IndexRange :: IndexRange -> Word32
..}
| Word32
irFirstIndex forall a. Ord a => a -> a -> Bool
> Word32
maxIndex =
forall (m :: * -> *) a. (MonadIO m, HasCallStack) => String -> m a
throwString String
"firstIndex is over the actual buffer size"
| Word32
irFirstIndex forall a. Num a => a -> a -> a
+ Word32
irIndexCount forall a. Ord a => a -> a -> Bool
> Word32
maxIndex =
forall (m :: * -> *) a. (MonadIO m, HasCallStack) => String -> m a
throwString String
"firstIndex + indexCount is over the actual buffer size"
| Bool
otherwise =
forall (f :: * -> *) a. Applicative f => a -> f a
pure IndexRange
ir
maxIndex :: Word32
maxIndex = forall (s :: Store) a. Allocated s a -> Word32
Buffer.aUsed (forall (storage :: Store) pos attrs.
Indexed storage pos attrs -> Allocated storage Word32
Model.iIndices Indexed storage pos attrs
model)
indexedParts
:: (MonadUnliftIO m, Model.HasVertexBuffers instances, Foldable t)
=> Bool
-> Vk.CommandBuffer
-> Model.Indexed storage pos attrs
-> instances
-> Int
-> t Model.IndexRange
-> Bound dsl (Model.Vertex pos attrs) (Model.VertexBuffersOf instances) m ()
indexedParts :: forall (m :: * -> *) instances (t :: * -> *) (storage :: Store) pos
attrs (dsl :: [*]).
(MonadUnliftIO m, HasVertexBuffers instances, Foldable t) =>
Bool
-> CommandBuffer
-> Indexed storage pos attrs
-> instances
-> Int
-> t IndexRange
-> Bound dsl (Vertex pos attrs) (VertexBuffersOf instances) m ()
indexedParts Bool
drawAttrs CommandBuffer
cmd Indexed storage pos attrs
model instances
instances Int
startInstance t IndexRange
parts =
forall (dsl :: [*]) vertices instances (m :: * -> *) a.
m a -> Bound dsl vertices instances m a
Bound forall a b. (a -> b) -> a -> b
$ forall (io :: * -> *) instances (t :: * -> *) (storage :: Store)
pos attrs.
(MonadUnliftIO io, HasVertexBuffers instances, Foldable t) =>
Bool
-> CommandBuffer
-> Indexed storage pos attrs
-> instances
-> Int
-> t IndexRange
-> io ()
unsafeIndexedParts Bool
drawAttrs CommandBuffer
cmd Indexed storage pos attrs
model instances
instances Int
startInstance t IndexRange
parts
indexedPos
:: (MonadUnliftIO m, Model.HasVertexBuffers instances)
=> Vk.CommandBuffer
-> Model.Indexed storage pos unusedAttrs
-> instances
-> Bound dsl (Model.Vertex pos ignoreAttrs) (Model.VertexBuffersOf instances) m ()
indexedPos :: forall (m :: * -> *) instances (storage :: Store) pos unusedAttrs
(dsl :: [*]) ignoreAttrs.
(MonadUnliftIO m, HasVertexBuffers instances) =>
CommandBuffer
-> Indexed storage pos unusedAttrs
-> instances
-> Bound
dsl (Vertex pos ignoreAttrs) (VertexBuffersOf instances) m ()
indexedPos CommandBuffer
cmd Indexed storage pos unusedAttrs
model instances
instances = forall (m :: * -> *) instances (storage :: Store) pos unusedAttrs
(dsl :: [*]) ignoreAttrs.
(MonadUnliftIO m, HasVertexBuffers instances) =>
CommandBuffer
-> Indexed storage pos unusedAttrs
-> instances
-> [IndexRange]
-> Bound
dsl (Vertex pos ignoreAttrs) (VertexBuffersOf instances) m ()
indexedPosRanges CommandBuffer
cmd Indexed storage pos unusedAttrs
model instances
instances [IndexRange
wholeIndexed]
where
wholeIndexed :: IndexRange
wholeIndexed = Model.IndexRange
{ $sel:irFirstIndex:IndexRange :: Word32
irFirstIndex = Word32
0
, $sel:irIndexCount:IndexRange :: Word32
irIndexCount = forall (s :: Store) a. Allocated s a -> Word32
Buffer.aUsed (forall (storage :: Store) pos attrs.
Indexed storage pos attrs -> Allocated storage Word32
Model.iIndices Indexed storage pos unusedAttrs
model)
}
indexedPosRanges
:: (MonadUnliftIO m, Model.HasVertexBuffers instances)
=> Vk.CommandBuffer
-> Model.Indexed storage pos unusedAttrs
-> instances
-> [Model.IndexRange]
-> Bound dsl (Model.Vertex pos ignoreAttrs) (Model.VertexBuffersOf instances) m ()
indexedPosRanges :: forall (m :: * -> *) instances (storage :: Store) pos unusedAttrs
(dsl :: [*]) ignoreAttrs.
(MonadUnliftIO m, HasVertexBuffers instances) =>
CommandBuffer
-> Indexed storage pos unusedAttrs
-> instances
-> [IndexRange]
-> Bound
dsl (Vertex pos ignoreAttrs) (VertexBuffersOf instances) m ()
indexedPosRanges CommandBuffer
cmd Indexed storage pos unusedAttrs
model instances
instances [IndexRange]
ranges = do
[IndexRange]
checkedRanges <- forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse IndexRange
-> Bound
dsl
(Vertex pos ignoreAttrs)
(VertexBuffersOf instances)
m
IndexRange
check [IndexRange]
ranges
forall (dsl :: [*]) vertices instances (m :: * -> *) a.
m a -> Bound dsl vertices instances m a
Bound forall a b. (a -> b) -> a -> b
$ forall (io :: * -> *) instances (t :: * -> *) (storage :: Store)
pos attrs.
(MonadUnliftIO io, HasVertexBuffers instances, Foldable t) =>
Bool
-> CommandBuffer
-> Indexed storage pos attrs
-> instances
-> t IndexRange
-> io ()
unsafeIndexedRanges Bool
False CommandBuffer
cmd Indexed storage pos unusedAttrs
model instances
instances [IndexRange]
checkedRanges
where
check :: IndexRange
-> Bound
dsl
(Vertex pos ignoreAttrs)
(VertexBuffersOf instances)
m
IndexRange
check ir :: IndexRange
ir@Model.IndexRange{Word32
irIndexCount :: Word32
irFirstIndex :: Word32
$sel:irIndexCount:IndexRange :: IndexRange -> Word32
$sel:irFirstIndex:IndexRange :: IndexRange -> Word32
..}
| Word32
irFirstIndex forall a. Ord a => a -> a -> Bool
> Word32
maxIndex =
forall (m :: * -> *) a. (MonadIO m, HasCallStack) => String -> m a
throwString String
"firstIndex is over the actual buffer size"
| Word32
irFirstIndex forall a. Num a => a -> a -> a
+ Word32
irIndexCount forall a. Ord a => a -> a -> Bool
> Word32
maxIndex =
forall (m :: * -> *) a. (MonadIO m, HasCallStack) => String -> m a
throwString String
"firstIndex + indexCount is over the actual buffer size"
| Bool
otherwise =
forall (f :: * -> *) a. Applicative f => a -> f a
pure IndexRange
ir
maxIndex :: Word32
maxIndex = forall (s :: Store) a. Allocated s a -> Word32
Buffer.aUsed (forall (storage :: Store) pos attrs.
Indexed storage pos attrs -> Allocated storage Word32
Model.iIndices Indexed storage pos unusedAttrs
model)
unsafeIndexedRanges
:: (MonadUnliftIO io, Model.HasVertexBuffers instances, Foldable t)
=> Bool
-> Vk.CommandBuffer
-> Model.Indexed storage pos attrs
-> instances
-> t Model.IndexRange
-> io ()
unsafeIndexedRanges :: forall (io :: * -> *) instances (t :: * -> *) (storage :: Store)
pos attrs.
(MonadUnliftIO io, HasVertexBuffers instances, Foldable t) =>
Bool
-> CommandBuffer
-> Indexed storage pos attrs
-> instances
-> t IndexRange
-> io ()
unsafeIndexedRanges Bool
drawAttrs CommandBuffer
cmd Model.Indexed{Maybe Text
Allocated storage pos
Allocated storage attrs
Allocated storage Word32
$sel:iAttrs:Indexed :: forall (storage :: Store) pos attrs.
Indexed storage pos attrs -> Allocated storage attrs
$sel:iPositions:Indexed :: forall (storage :: Store) pos attrs.
Indexed storage pos attrs -> Allocated storage pos
$sel:iLabel:Indexed :: forall (storage :: Store) pos attrs.
Indexed storage pos attrs -> Maybe Text
iIndices :: Allocated storage Word32
iAttrs :: Allocated storage attrs
iPositions :: Allocated storage pos
iLabel :: Maybe Text
$sel:iIndices:Indexed :: forall (storage :: Store) pos attrs.
Indexed storage pos attrs -> Allocated storage Word32
..} instances
instances t IndexRange
indexRanges =
case forall (t :: * -> *) a. Foldable t => t a -> [a]
toList t IndexRange
indexRanges of
[] ->
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
[IndexRange]
_skip | Word32
instanceCount forall a. Ord a => a -> a -> Bool
< Word32
1 ->
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
[IndexRange]
someRanges -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO do
forall (io :: * -> *).
MonadIO io =>
CommandBuffer
-> Word32
-> ("buffers" ::: Vector Buffer)
-> ("offsets" ::: Vector DeviceSize)
-> io ()
Vk.cmdBindVertexBuffers CommandBuffer
cmd Word32
0 "buffers" ::: Vector Buffer
vertexBuffers "offsets" ::: Vector DeviceSize
bufferOffsets
forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> Buffer -> DeviceSize -> IndexType -> io ()
Vk.cmdBindIndexBuffer CommandBuffer
cmd (forall (s :: Store) a. Allocated s a -> Buffer
Buffer.aBuffer Allocated storage Word32
iIndices) DeviceSize
indexBufferOffset IndexType
Vk.INDEX_TYPE_UINT32
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [IndexRange]
someRanges \Model.IndexRange{Word32
irIndexCount :: Word32
irFirstIndex :: Word32
$sel:irIndexCount:IndexRange :: IndexRange -> Word32
$sel:irFirstIndex:IndexRange :: IndexRange -> Word32
..} ->
forall (io :: * -> *).
MonadIO io =>
CommandBuffer
-> Word32
-> Word32
-> Word32
-> ("vertexOffset" ::: Int32)
-> Word32
-> io ()
Vk.cmdDrawIndexed CommandBuffer
cmd Word32
irIndexCount Word32
instanceCount Word32
irFirstIndex "vertexOffset" ::: Int32
vertexOffset Word32
firstInstance
where
indexBufferOffset :: DeviceSize
indexBufferOffset = DeviceSize
0
vertexOffset :: "vertexOffset" ::: Int32
vertexOffset = "vertexOffset" ::: Int32
0
instanceCount :: Word32
instanceCount = forall a. HasVertexBuffers a => a -> Word32
Model.getInstanceCount instances
instances
firstInstance :: Word32
firstInstance = Word32
0
vertexBuffers :: "buffers" ::: Vector Buffer
vertexBuffers = forall a. [a] -> Vector a
Vector.fromList forall a b. (a -> b) -> a -> b
$
if Bool
drawAttrs then
forall (s :: Store) a. Allocated s a -> Buffer
Buffer.aBuffer Allocated storage pos
iPositions forall a. a -> [a] -> [a]
:
forall (s :: Store) a. Allocated s a -> Buffer
Buffer.aBuffer Allocated storage attrs
iAttrs forall a. a -> [a] -> [a]
:
forall a. HasVertexBuffers a => a -> [Buffer]
Model.getVertexBuffers instances
instances
else
forall (s :: Store) a. Allocated s a -> Buffer
Buffer.aBuffer Allocated storage pos
iPositions forall a. a -> [a] -> [a]
:
forall a. HasVertexBuffers a => a -> [Buffer]
Model.getVertexBuffers instances
instances
bufferOffsets :: "offsets" ::: Vector DeviceSize
bufferOffsets =
forall a. Int -> a -> Vector a
Vector.replicate (forall a. Vector a -> Int
Vector.length "buffers" ::: Vector Buffer
vertexBuffers) DeviceSize
0
unsafeIndexedParts
:: (MonadUnliftIO io, Model.HasVertexBuffers instances, Foldable t)
=> Bool
-> Vk.CommandBuffer
-> Model.Indexed storage pos attrs
-> instances
-> Int
-> t Model.IndexRange
-> io ()
unsafeIndexedParts :: forall (io :: * -> *) instances (t :: * -> *) (storage :: Store)
pos attrs.
(MonadUnliftIO io, HasVertexBuffers instances, Foldable t) =>
Bool
-> CommandBuffer
-> Indexed storage pos attrs
-> instances
-> Int
-> t IndexRange
-> io ()
unsafeIndexedParts Bool
drawAttrs CommandBuffer
cmd Model.Indexed{Maybe Text
Allocated storage pos
Allocated storage attrs
Allocated storage Word32
iIndices :: Allocated storage Word32
iAttrs :: Allocated storage attrs
iPositions :: Allocated storage pos
iLabel :: Maybe Text
$sel:iAttrs:Indexed :: forall (storage :: Store) pos attrs.
Indexed storage pos attrs -> Allocated storage attrs
$sel:iPositions:Indexed :: forall (storage :: Store) pos attrs.
Indexed storage pos attrs -> Allocated storage pos
$sel:iLabel:Indexed :: forall (storage :: Store) pos attrs.
Indexed storage pos attrs -> Maybe Text
$sel:iIndices:Indexed :: forall (storage :: Store) pos attrs.
Indexed storage pos attrs -> Allocated storage Word32
..} instances
instances Int
startInstance t IndexRange
parts =
case forall a. Int -> [a] -> [a]
drop Int
startInstance (forall (t :: * -> *) a. Foldable t => t a -> [a]
toList t IndexRange
parts) of
[] ->
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
[IndexRange]
_skip | Word32
instanceCount forall a. Ord a => a -> a -> Bool
< Word32
1 ->
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
[IndexRange]
someRanges -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO do
forall (io :: * -> *).
MonadIO io =>
CommandBuffer
-> Word32
-> ("buffers" ::: Vector Buffer)
-> ("offsets" ::: Vector DeviceSize)
-> io ()
Vk.cmdBindVertexBuffers CommandBuffer
cmd Word32
0 "buffers" ::: Vector Buffer
vertexBuffers "offsets" ::: Vector DeviceSize
bufferOffsets
forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> Buffer -> DeviceSize -> IndexType -> io ()
Vk.cmdBindIndexBuffer CommandBuffer
cmd (forall (s :: Store) a. Allocated s a -> Buffer
Buffer.aBuffer Allocated storage Word32
iIndices) DeviceSize
indexBufferOffset IndexType
Vk.INDEX_TYPE_UINT32
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (forall a b. [a] -> [b] -> [(a, b)]
zip [forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
startInstance ..] [IndexRange]
someRanges) \(Word32
firstInstance, Model.IndexRange{Word32
irIndexCount :: Word32
irFirstIndex :: Word32
$sel:irIndexCount:IndexRange :: IndexRange -> Word32
$sel:irFirstIndex:IndexRange :: IndexRange -> Word32
..}) ->
forall (io :: * -> *).
MonadIO io =>
CommandBuffer
-> Word32
-> Word32
-> Word32
-> ("vertexOffset" ::: Int32)
-> Word32
-> io ()
Vk.cmdDrawIndexed CommandBuffer
cmd Word32
irIndexCount Word32
instanceCount Word32
irFirstIndex "vertexOffset" ::: Int32
vertexOffset Word32
firstInstance
where
indexBufferOffset :: DeviceSize
indexBufferOffset = DeviceSize
0
vertexOffset :: "vertexOffset" ::: Int32
vertexOffset = "vertexOffset" ::: Int32
0
instanceCount :: Word32
instanceCount = Word32
1
vertexBuffers :: "buffers" ::: Vector Buffer
vertexBuffers = forall a. [a] -> Vector a
Vector.fromList forall a b. (a -> b) -> a -> b
$
if Bool
drawAttrs then
forall (s :: Store) a. Allocated s a -> Buffer
Buffer.aBuffer Allocated storage pos
iPositions forall a. a -> [a] -> [a]
:
forall (s :: Store) a. Allocated s a -> Buffer
Buffer.aBuffer Allocated storage attrs
iAttrs forall a. a -> [a] -> [a]
:
forall a. HasVertexBuffers a => a -> [Buffer]
Model.getVertexBuffers instances
instances
else
forall (s :: Store) a. Allocated s a -> Buffer
Buffer.aBuffer Allocated storage pos
iPositions forall a. a -> [a] -> [a]
:
forall a. HasVertexBuffers a => a -> [Buffer]
Model.getVertexBuffers instances
instances
bufferOffsets :: "offsets" ::: Vector DeviceSize
bufferOffsets =
forall a. Int -> a -> Vector a
Vector.replicate (forall a. Vector a -> Int
Vector.length "buffers" ::: Vector Buffer
vertexBuffers) DeviceSize
0