module Engine.Vulkan.Pipeline
  ( Pipeline(..)
  , destroy
  , Specialization
  ) where

import RIO

import Data.Kind (Type)
import Data.Tagged (Tagged(..))
import Data.Vector qualified as Vector
import Vulkan.Core10 qualified as Vk

import Engine.Vulkan.Types (HasVulkan(..), DsLayouts)

data Pipeline (dsl :: [Type]) vertices instances = Pipeline
  { forall (dsl :: [*]) vertices instances.
Pipeline dsl vertices instances -> Pipeline
pipeline     :: Vk.Pipeline
  , forall (dsl :: [*]) vertices instances.
Pipeline dsl vertices instances -> Tagged dsl PipelineLayout
pLayout      :: Tagged dsl Vk.PipelineLayout
  , forall (dsl :: [*]) vertices instances.
Pipeline dsl vertices instances -> Tagged dsl DsLayouts
pDescLayouts :: Tagged dsl DsLayouts
  }

destroy
  :: ( MonadIO io
     , HasVulkan ctx
     )
  => ctx
  -> Pipeline dsl vertices instances
  -> io ()
destroy :: forall (io :: * -> *) ctx (dsl :: [*]) vertices instances.
(MonadIO io, HasVulkan ctx) =>
ctx -> Pipeline dsl vertices instances -> io ()
destroy ctx
context Pipeline{Pipeline
Tagged dsl DsLayouts
Tagged dsl PipelineLayout
pDescLayouts :: Tagged dsl DsLayouts
pLayout :: Tagged dsl PipelineLayout
pipeline :: Pipeline
$sel:pDescLayouts:Pipeline :: forall (dsl :: [*]) vertices instances.
Pipeline dsl vertices instances -> Tagged dsl DsLayouts
$sel:pLayout:Pipeline :: forall (dsl :: [*]) vertices instances.
Pipeline dsl vertices instances -> Tagged dsl PipelineLayout
$sel:pipeline:Pipeline :: forall (dsl :: [*]) vertices instances.
Pipeline dsl vertices instances -> Pipeline
..} = do
  forall (m :: * -> *) a b. Monad m => Vector a -> (a -> m b) -> m ()
Vector.forM_ (forall {k} (s :: k) b. Tagged s b -> b
unTagged Tagged dsl DsLayouts
pDescLayouts) \DescriptorSetLayout
dsLayout ->
    forall (io :: * -> *).
MonadIO io =>
Device
-> DescriptorSetLayout
-> ("allocator" ::: Maybe AllocationCallbacks)
-> io ()
Vk.destroyDescriptorSetLayout Device
device DescriptorSetLayout
dsLayout forall a. Maybe a
Nothing
  forall (io :: * -> *).
MonadIO io =>
Device
-> Pipeline -> ("allocator" ::: Maybe AllocationCallbacks) -> io ()
Vk.destroyPipeline Device
device Pipeline
pipeline forall a. Maybe a
Nothing
  forall (io :: * -> *).
MonadIO io =>
Device
-> PipelineLayout
-> ("allocator" ::: Maybe AllocationCallbacks)
-> io ()
Vk.destroyPipelineLayout Device
device (forall {k} (s :: k) b. Tagged s b -> b
unTagged Tagged dsl PipelineLayout
pLayout) forall a. Maybe a
Nothing
  where
    device :: Device
device = forall a. HasVulkan a => a -> Device
getDevice ctx
context

type family Specialization pipeline