module Render.Unlit.TileMap.Model
  ( Model
  , VertexAttrs
  , vkVertexAttrs

  , InstanceAttrs(..)
  -- , instanceAttrs

  , StorableAttrs
  -- , storableAttrs1

  , InstanceBuffers(..)

  , TileMapParams(..)
  , vkInstanceTileMap

  , allocateInstancesWith
  , allocateInstancesCoherent
  , allocateInstancesCoherent_
  , updateCoherentResize_
  , Transform
  ) where

import RIO

import Foreign (Storable(..))
import Geomancy (IVec4, Transform, Vec2)
import Geomancy.Vec3 qualified as Vec3
import RIO.Vector.Storable qualified as Storable
import UnliftIO.Resource (MonadResource, ReleaseKey, ResourceT, allocate)
import Vulkan.Core10 qualified as Vk
import Vulkan.NamedType ((:::))
import Vulkan.Zero (Zero(..))

import Engine.Vulkan.Types (HasVulkan)
import Resource.Buffer qualified as Buffer
import Resource.Model qualified as Model

type Model buf = Model.Indexed buf Vec3.Packed VertexAttrs

type VertexAttrs = "uv" ::: Vec2

vkVertexAttrs :: [Vk.Format]
vkVertexAttrs :: [Format]
vkVertexAttrs =
  [ Format
Vk.FORMAT_R32G32_SFLOAT -- vTexCoord :: vec2
  ]

-- | Data for a single element.
data InstanceAttrs = InstanceAttrs
  { InstanceAttrs -> TileMapParams
tilemapParams :: TileMapParams
  , InstanceAttrs -> Transform
transformMat4 :: Transform
  }

instance Zero InstanceAttrs where
  zero :: InstanceAttrs
zero = InstanceAttrs :: TileMapParams -> Transform -> InstanceAttrs
InstanceAttrs
    { $sel:tilemapParams:InstanceAttrs :: TileMapParams
tilemapParams = TileMapParams
forall a. Zero a => a
zero
    , $sel:transformMat4:InstanceAttrs :: Transform
transformMat4 = Transform
forall a. Monoid a => a
mempty
    }

-- | Intermediate data to be shipped.
type StorableAttrs =
  ( Storable.Vector TileMapParams
  , Storable.Vector Transform
  )

-- | GPU-bound data.
data InstanceBuffers tilemapStage transformStage = InstanceBuffers
  { forall (tilemapStage :: Store) (transformStage :: Store).
InstanceBuffers tilemapStage transformStage
-> InstanceTileMap tilemapStage
ibTileMap   :: InstanceTileMap tilemapStage
  , forall (tilemapStage :: Store) (transformStage :: Store).
InstanceBuffers tilemapStage transformStage
-> InstanceTransform transformStage
ibTransform :: InstanceTransform transformStage
  }

type InstanceTileMap stage = Buffer.Allocated stage TileMapParams

type InstanceTransform stage = Buffer.Allocated stage Transform

instance Model.HasVertexBuffers (InstanceBuffers tilemapStage transformStage) where
  type VertexBuffersOf (InstanceBuffers tilemapStage transformStage) = InstanceAttrs

  {-# INLINE getVertexBuffers #-}
  getVertexBuffers :: InstanceBuffers tilemapStage transformStage -> [Buffer]
getVertexBuffers InstanceBuffers{InstanceTileMap tilemapStage
InstanceTransform transformStage
ibTransform :: InstanceTransform transformStage
ibTileMap :: InstanceTileMap tilemapStage
$sel:ibTransform:InstanceBuffers :: forall (tilemapStage :: Store) (transformStage :: Store).
InstanceBuffers tilemapStage transformStage
-> InstanceTransform transformStage
$sel:ibTileMap:InstanceBuffers :: forall (tilemapStage :: Store) (transformStage :: Store).
InstanceBuffers tilemapStage transformStage
-> InstanceTileMap tilemapStage
..} =
    [ InstanceTileMap tilemapStage -> Buffer
forall (s :: Store) a. Allocated s a -> Buffer
Buffer.aBuffer InstanceTileMap tilemapStage
ibTileMap
    , InstanceTransform transformStage -> Buffer
forall (s :: Store) a. Allocated s a -> Buffer
Buffer.aBuffer InstanceTransform transformStage
ibTransform
    ]

  {-# INLINE getInstanceCount #-}
  getInstanceCount :: InstanceBuffers tilemapStage transformStage -> Word32
getInstanceCount InstanceBuffers{InstanceTileMap tilemapStage
InstanceTransform transformStage
ibTransform :: InstanceTransform transformStage
ibTileMap :: InstanceTileMap tilemapStage
$sel:ibTransform:InstanceBuffers :: forall (tilemapStage :: Store) (transformStage :: Store).
InstanceBuffers tilemapStage transformStage
-> InstanceTransform transformStage
$sel:ibTileMap:InstanceBuffers :: forall (tilemapStage :: Store) (transformStage :: Store).
InstanceBuffers tilemapStage transformStage
-> InstanceTileMap tilemapStage
..} =
    Word32 -> Word32 -> Word32
forall a. Ord a => a -> a -> a
min
      (InstanceTileMap tilemapStage -> Word32
forall (s :: Store) a. Allocated s a -> Word32
Buffer.aUsed InstanceTileMap tilemapStage
ibTileMap)
      (InstanceTransform transformStage -> Word32
forall (s :: Store) a. Allocated s a -> Word32
Buffer.aUsed InstanceTransform transformStage
ibTransform)

data TileMapParams = TileMapParams
  { TileMapParams -> IVec4
tmpTextureIds         :: IVec4
  , TileMapParams -> Vec2
tmpViewOffset         :: Vec2
  , TileMapParams -> Vec2
tmpViewportSize       :: Vec2
  , TileMapParams -> Vec2
tmpMapTextureSize     :: Vec2
  , TileMapParams -> Vec2
tmpTilesetTextureSize :: Vec2
  , TileMapParams -> Vec2
tmpTileSize           :: Vec2
  }
  deriving (Int -> TileMapParams -> ShowS
[TileMapParams] -> ShowS
TileMapParams -> String
(Int -> TileMapParams -> ShowS)
-> (TileMapParams -> String)
-> ([TileMapParams] -> ShowS)
-> Show TileMapParams
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TileMapParams] -> ShowS
$cshowList :: [TileMapParams] -> ShowS
show :: TileMapParams -> String
$cshow :: TileMapParams -> String
showsPrec :: Int -> TileMapParams -> ShowS
$cshowsPrec :: Int -> TileMapParams -> ShowS
Show)

instance Zero TileMapParams where
  zero :: TileMapParams
zero = TileMapParams :: IVec4 -> Vec2 -> Vec2 -> Vec2 -> Vec2 -> Vec2 -> TileMapParams
TileMapParams
    { $sel:tmpTextureIds:TileMapParams :: IVec4
tmpTextureIds         = IVec4
0
    , $sel:tmpViewOffset:TileMapParams :: Vec2
tmpViewOffset         = Vec2
0
    , $sel:tmpViewportSize:TileMapParams :: Vec2
tmpViewportSize       = Vec2
1
    , $sel:tmpMapTextureSize:TileMapParams :: Vec2
tmpMapTextureSize     = Vec2
1
    , $sel:tmpTilesetTextureSize:TileMapParams :: Vec2
tmpTilesetTextureSize = Vec2
1
    , $sel:tmpTileSize:TileMapParams :: Vec2
tmpTileSize           = Vec2
1
    }

instance Storable TileMapParams where
  alignment :: TileMapParams -> Int
alignment ~TileMapParams
_ = Int
4

  sizeOf :: TileMapParams -> Int
sizeOf ~TileMapParams
_ = Int
16 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
8

  poke :: Ptr TileMapParams -> TileMapParams -> IO ()
poke Ptr TileMapParams
ptr TileMapParams{Vec2
IVec4
tmpTileSize :: Vec2
tmpTilesetTextureSize :: Vec2
tmpMapTextureSize :: Vec2
tmpViewportSize :: Vec2
tmpViewOffset :: Vec2
tmpTextureIds :: IVec4
$sel:tmpTileSize:TileMapParams :: TileMapParams -> Vec2
$sel:tmpTilesetTextureSize:TileMapParams :: TileMapParams -> Vec2
$sel:tmpMapTextureSize:TileMapParams :: TileMapParams -> Vec2
$sel:tmpViewportSize:TileMapParams :: TileMapParams -> Vec2
$sel:tmpViewOffset:TileMapParams :: TileMapParams -> Vec2
$sel:tmpTextureIds:TileMapParams :: TileMapParams -> IVec4
..} = do
    Ptr TileMapParams -> Int -> IVec4 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr TileMapParams
ptr  Int
0 IVec4
tmpTextureIds
    Ptr TileMapParams -> Int -> Vec2 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr TileMapParams
ptr Int
16 Vec2
tmpViewOffset
    Ptr TileMapParams -> Int -> Vec2 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr TileMapParams
ptr Int
24 Vec2
tmpViewportSize
    Ptr TileMapParams -> Int -> Vec2 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr TileMapParams
ptr Int
32 Vec2
tmpMapTextureSize
    Ptr TileMapParams -> Int -> Vec2 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr TileMapParams
ptr Int
40 Vec2
tmpTilesetTextureSize
    Ptr TileMapParams -> Int -> Vec2 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr TileMapParams
ptr Int
48 Vec2
tmpTileSize

  peek :: Ptr TileMapParams -> IO TileMapParams
peek Ptr TileMapParams
ptr = do
    IVec4
tmpTextureIds         <- Ptr TileMapParams -> Int -> IO IVec4
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr TileMapParams
ptr  Int
0
    Vec2
tmpViewOffset         <- Ptr TileMapParams -> Int -> IO Vec2
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr TileMapParams
ptr Int
16
    Vec2
tmpViewportSize       <- Ptr TileMapParams -> Int -> IO Vec2
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr TileMapParams
ptr Int
24
    Vec2
tmpMapTextureSize     <- Ptr TileMapParams -> Int -> IO Vec2
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr TileMapParams
ptr Int
32
    Vec2
tmpTilesetTextureSize <- Ptr TileMapParams -> Int -> IO Vec2
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr TileMapParams
ptr Int
48
    Vec2
tmpTileSize           <- Ptr TileMapParams -> Int -> IO Vec2
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr TileMapParams
ptr Int
56
    pure TileMapParams :: IVec4 -> Vec2 -> Vec2 -> Vec2 -> Vec2 -> Vec2 -> TileMapParams
TileMapParams{Vec2
IVec4
tmpTileSize :: Vec2
tmpTilesetTextureSize :: Vec2
tmpMapTextureSize :: Vec2
tmpViewportSize :: Vec2
tmpViewOffset :: Vec2
tmpTextureIds :: IVec4
$sel:tmpTileSize:TileMapParams :: Vec2
$sel:tmpTilesetTextureSize:TileMapParams :: Vec2
$sel:tmpMapTextureSize:TileMapParams :: Vec2
$sel:tmpViewportSize:TileMapParams :: Vec2
$sel:tmpViewOffset:TileMapParams :: Vec2
$sel:tmpTextureIds:TileMapParams :: IVec4
..}

vkInstanceTileMap :: [Vk.Format]
vkInstanceTileMap :: [Format]
vkInstanceTileMap =
  [ Format
Vk.FORMAT_R32G32B32A32_SINT -- tmpTextureIds         :: IVec4
  , Format
Vk.FORMAT_R32G32_SFLOAT     -- tmpViewOffset         :: Vec2
  , Format
Vk.FORMAT_R32G32_SFLOAT     -- tmpViewportSize       :: Vec2
  , Format
Vk.FORMAT_R32G32_SFLOAT     -- tmpMapTextureSize     :: Vec2
  , Format
Vk.FORMAT_R32G32_SFLOAT     -- tmpTilesetTextureSize :: Vec2
  , Format
Vk.FORMAT_R32G32_SFLOAT     -- tmpTileSize           :: Vec2
  ]

allocateInstancesWith
  :: ( MonadResource m
     , MonadUnliftIO m
     )
  => (Vk.BufferUsageFlagBits -> Int -> Storable.Vector TileMapParams -> m (InstanceTileMap texture))
  -> (Vk.BufferUsageFlagBits -> Int -> Storable.Vector Transform -> m (InstanceTransform transform))
  -> (forall stage a . Buffer.Allocated stage a -> m ())
  -> [InstanceAttrs]
  -> m (ReleaseKey, InstanceBuffers texture transform)
allocateInstancesWith :: forall (m :: * -> *) (texture :: Store) (transform :: Store).
(MonadResource m, MonadUnliftIO m) =>
(BufferUsageFlagBits
 -> Int -> Vector TileMapParams -> m (InstanceTileMap texture))
-> (BufferUsageFlagBits
    -> Int -> Vector Transform -> m (InstanceTransform transform))
-> (forall (stage :: Store) a. Allocated stage a -> m ())
-> [InstanceAttrs]
-> m (ReleaseKey, InstanceBuffers texture transform)
allocateInstancesWith BufferUsageFlagBits
-> Int -> Vector TileMapParams -> m (InstanceTileMap texture)
createTextures BufferUsageFlagBits
-> Int -> Vector Transform -> m (InstanceTransform transform)
createTransforms forall (stage :: Store) a. Allocated stage a -> m ()
bufferDestroy [InstanceAttrs]
instances = do
  UnliftIO m
ul <- m (UnliftIO m)
forall (m :: * -> *). MonadUnliftIO m => m (UnliftIO m)
askUnliftIO
  IO (InstanceBuffers texture transform)
-> (InstanceBuffers texture transform -> IO ())
-> m (ReleaseKey, InstanceBuffers texture transform)
forall (m :: * -> *) a.
MonadResource m =>
IO a -> (a -> IO ()) -> m (ReleaseKey, a)
allocate (UnliftIO m -> IO (InstanceBuffers texture transform)
create UnliftIO m
ul) (UnliftIO m -> InstanceBuffers texture transform -> IO ()
destroy UnliftIO m
ul)
  where
    textures :: Vector TileMapParams
textures   = [TileMapParams] -> Vector TileMapParams
forall a. Storable a => [a] -> Vector a
Storable.fromList ([TileMapParams] -> Vector TileMapParams)
-> [TileMapParams] -> Vector TileMapParams
forall a b. (a -> b) -> a -> b
$ (InstanceAttrs -> TileMapParams)
-> [InstanceAttrs] -> [TileMapParams]
forall a b. (a -> b) -> [a] -> [b]
map InstanceAttrs -> TileMapParams
tilemapParams [InstanceAttrs]
instances
    transforms :: Vector Transform
transforms = [Transform] -> Vector Transform
forall a. Storable a => [a] -> Vector a
Storable.fromList ([Transform] -> Vector Transform)
-> [Transform] -> Vector Transform
forall a b. (a -> b) -> a -> b
$ (InstanceAttrs -> Transform) -> [InstanceAttrs] -> [Transform]
forall a b. (a -> b) -> [a] -> [b]
map InstanceAttrs -> Transform
transformMat4 [InstanceAttrs]
instances
    numInstances :: Int
numInstances = Vector TileMapParams -> Int
forall a. Storable a => Vector a -> Int
Storable.length Vector TileMapParams
textures

    create :: UnliftIO m -> IO (InstanceBuffers texture transform)
create (UnliftIO forall a. m a -> IO a
ul) = m (InstanceBuffers texture transform)
-> IO (InstanceBuffers texture transform)
forall a. m a -> IO a
ul do
      InstanceTileMap texture
ibTileMap   <- BufferUsageFlagBits
-> Int -> Vector TileMapParams -> m (InstanceTileMap texture)
createTextures   BufferUsageFlagBits
Vk.BUFFER_USAGE_VERTEX_BUFFER_BIT Int
numInstances Vector TileMapParams
textures
      InstanceTransform transform
ibTransform <- BufferUsageFlagBits
-> Int -> Vector Transform -> m (InstanceTransform transform)
createTransforms BufferUsageFlagBits
Vk.BUFFER_USAGE_VERTEX_BUFFER_BIT Int
numInstances Vector Transform
transforms
      pure InstanceBuffers :: forall (tilemapStage :: Store) (transformStage :: Store).
InstanceTileMap tilemapStage
-> InstanceTransform transformStage
-> InstanceBuffers tilemapStage transformStage
InstanceBuffers{InstanceTileMap texture
InstanceTransform transform
ibTransform :: InstanceTransform transform
ibTileMap :: InstanceTileMap texture
$sel:ibTransform:InstanceBuffers :: InstanceTransform transform
$sel:ibTileMap:InstanceBuffers :: InstanceTileMap texture
..}

    destroy :: UnliftIO m -> InstanceBuffers texture transform -> IO ()
destroy (UnliftIO forall a. m a -> IO a
ul) InstanceBuffers{InstanceTileMap texture
InstanceTransform transform
ibTransform :: InstanceTransform transform
ibTileMap :: InstanceTileMap texture
$sel:ibTransform:InstanceBuffers :: forall (tilemapStage :: Store) (transformStage :: Store).
InstanceBuffers tilemapStage transformStage
-> InstanceTransform transformStage
$sel:ibTileMap:InstanceBuffers :: forall (tilemapStage :: Store) (transformStage :: Store).
InstanceBuffers tilemapStage transformStage
-> InstanceTileMap tilemapStage
..} = m () -> IO ()
forall a. m a -> IO a
ul do
      InstanceTileMap texture -> m ()
forall (stage :: Store) a. Allocated stage a -> m ()
bufferDestroy InstanceTileMap texture
ibTileMap
      InstanceTransform transform -> m ()
forall (stage :: Store) a. Allocated stage a -> m ()
bufferDestroy InstanceTransform transform
ibTransform

allocateInstancesCoherent
  :: ( MonadReader env m
     , HasVulkan env
     , MonadResource m
     , MonadUnliftIO m
     )
  => [InstanceAttrs]
  -> m (ReleaseKey, InstanceBuffers 'Buffer.Coherent 'Buffer.Coherent)
allocateInstancesCoherent :: forall env (m :: * -> *).
(MonadReader env m, HasVulkan env, MonadResource m,
 MonadUnliftIO m) =>
[InstanceAttrs]
-> m (ReleaseKey, InstanceBuffers 'Coherent 'Coherent)
allocateInstancesCoherent [InstanceAttrs]
instances = do
  env
context <- m env
forall r (m :: * -> *). MonadReader r m => m r
ask
  (BufferUsageFlagBits
 -> Int -> Vector TileMapParams -> m (InstanceTileMap 'Coherent))
-> (BufferUsageFlagBits
    -> Int -> Vector Transform -> m (InstanceTransform 'Coherent))
-> (forall (stage :: Store) a. Allocated stage a -> m ())
-> [InstanceAttrs]
-> m (ReleaseKey, InstanceBuffers 'Coherent 'Coherent)
forall (m :: * -> *) (texture :: Store) (transform :: Store).
(MonadResource m, MonadUnliftIO m) =>
(BufferUsageFlagBits
 -> Int -> Vector TileMapParams -> m (InstanceTileMap texture))
-> (BufferUsageFlagBits
    -> Int -> Vector Transform -> m (InstanceTransform transform))
-> (forall (stage :: Store) a. Allocated stage a -> m ())
-> [InstanceAttrs]
-> m (ReleaseKey, InstanceBuffers texture transform)
allocateInstancesWith
    (env
-> BufferUsageFlagBits
-> Int
-> Vector TileMapParams
-> m (InstanceTileMap 'Coherent)
forall a context (io :: * -> *).
(Storable a, HasVulkan context, MonadUnliftIO io) =>
context
-> BufferUsageFlagBits
-> Int
-> Vector a
-> io (Allocated 'Coherent a)
Buffer.createCoherent env
context)
    (env
-> BufferUsageFlagBits
-> Int
-> Vector Transform
-> m (InstanceTransform 'Coherent)
forall a context (io :: * -> *).
(Storable a, HasVulkan context, MonadUnliftIO io) =>
context
-> BufferUsageFlagBits
-> Int
-> Vector a
-> io (Allocated 'Coherent a)
Buffer.createCoherent env
context)
    (env -> Allocated stage a -> m ()
forall (io :: * -> *) context (s :: Store) a.
(MonadUnliftIO io, HasVulkan context) =>
context -> Allocated s a -> io ()
Buffer.destroy env
context)
    [InstanceAttrs]
instances

allocateInstancesCoherent_
  :: (HasVulkan env)
  => Int
  -> ResourceT (RIO env) (InstanceBuffers 'Buffer.Coherent 'Buffer.Coherent)
allocateInstancesCoherent_ :: forall env.
HasVulkan env =>
Int -> ResourceT (RIO env) (InstanceBuffers 'Coherent 'Coherent)
allocateInstancesCoherent_ Int
n =
  ((ReleaseKey, InstanceBuffers 'Coherent 'Coherent)
 -> InstanceBuffers 'Coherent 'Coherent)
-> ResourceT
     (RIO env) (ReleaseKey, InstanceBuffers 'Coherent 'Coherent)
-> ResourceT (RIO env) (InstanceBuffers 'Coherent 'Coherent)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ReleaseKey, InstanceBuffers 'Coherent 'Coherent)
-> InstanceBuffers 'Coherent 'Coherent
forall a b. (a, b) -> b
snd (ResourceT
   (RIO env) (ReleaseKey, InstanceBuffers 'Coherent 'Coherent)
 -> ResourceT (RIO env) (InstanceBuffers 'Coherent 'Coherent))
-> ResourceT
     (RIO env) (ReleaseKey, InstanceBuffers 'Coherent 'Coherent)
-> ResourceT (RIO env) (InstanceBuffers 'Coherent 'Coherent)
forall a b. (a -> b) -> a -> b
$ [InstanceAttrs]
-> ResourceT
     (RIO env) (ReleaseKey, InstanceBuffers 'Coherent 'Coherent)
forall env (m :: * -> *).
(MonadReader env m, HasVulkan env, MonadResource m,
 MonadUnliftIO m) =>
[InstanceAttrs]
-> m (ReleaseKey, InstanceBuffers 'Coherent 'Coherent)
allocateInstancesCoherent (Int -> InstanceAttrs -> [InstanceAttrs]
forall a. Int -> a -> [a]
replicate Int
n InstanceAttrs
forall a. Zero a => a
zero)

updateCoherentResize_
  :: ( HasVulkan context
     , MonadUnliftIO m
     )
  => context
  -> InstanceBuffers 'Buffer.Coherent 'Buffer.Coherent
  -> (Storable.Vector TileMapParams, Storable.Vector Transform)
  -> m (InstanceBuffers 'Buffer.Coherent 'Buffer.Coherent)
updateCoherentResize_ :: forall context (m :: * -> *).
(HasVulkan context, MonadUnliftIO m) =>
context
-> InstanceBuffers 'Coherent 'Coherent
-> (Vector TileMapParams, Vector Transform)
-> m (InstanceBuffers 'Coherent 'Coherent)
updateCoherentResize_ context
context InstanceBuffers{InstanceTransform 'Coherent
InstanceTileMap 'Coherent
ibTransform :: InstanceTransform 'Coherent
ibTileMap :: InstanceTileMap 'Coherent
$sel:ibTransform:InstanceBuffers :: forall (tilemapStage :: Store) (transformStage :: Store).
InstanceBuffers tilemapStage transformStage
-> InstanceTransform transformStage
$sel:ibTileMap:InstanceBuffers :: forall (tilemapStage :: Store) (transformStage :: Store).
InstanceBuffers tilemapStage transformStage
-> InstanceTileMap tilemapStage
..} (Vector TileMapParams
textures, Vector Transform
transforms) =
  InstanceTileMap 'Coherent
-> InstanceTransform 'Coherent
-> InstanceBuffers 'Coherent 'Coherent
forall (tilemapStage :: Store) (transformStage :: Store).
InstanceTileMap tilemapStage
-> InstanceTransform transformStage
-> InstanceBuffers tilemapStage transformStage
InstanceBuffers
    (InstanceTileMap 'Coherent
 -> InstanceTransform 'Coherent
 -> InstanceBuffers 'Coherent 'Coherent)
-> m (InstanceTileMap 'Coherent)
-> m (InstanceTransform 'Coherent
      -> InstanceBuffers 'Coherent 'Coherent)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> context
-> InstanceTileMap 'Coherent
-> Vector TileMapParams
-> m (InstanceTileMap 'Coherent)
forall a context (io :: * -> *).
(Storable a, HasVulkan context, MonadUnliftIO io) =>
context
-> Allocated 'Coherent a -> Vector a -> io (Allocated 'Coherent a)
Buffer.updateCoherentResize_ context
context InstanceTileMap 'Coherent
ibTileMap Vector TileMapParams
textures
    m (InstanceTransform 'Coherent
   -> InstanceBuffers 'Coherent 'Coherent)
-> m (InstanceTransform 'Coherent)
-> m (InstanceBuffers 'Coherent 'Coherent)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> context
-> InstanceTransform 'Coherent
-> Vector Transform
-> m (InstanceTransform 'Coherent)
forall a context (io :: * -> *).
(Storable a, HasVulkan context, MonadUnliftIO io) =>
context
-> Allocated 'Coherent a -> Vector a -> io (Allocated 'Coherent a)
Buffer.updateCoherentResize_ context
context InstanceTransform 'Coherent
ibTransform Vector Transform
transforms