packages feed

keid-render-basic-0.1.8.0: src/Render/Unlit/Sprite/Pipeline.hs

{-# LANGUAGE OverloadedLists #-}

module Render.Unlit.Sprite.Pipeline
  ( Pipeline
  , Config
  , config
  , allocate
  -- , allocateOutline
  , stageCode
  , stageSpirv
  ) where

import RIO

import Control.Monad.Trans.Resource (ResourceT)
import Data.Tagged (Tagged(..))
import Vulkan.Core10 qualified as Vk

import Engine.Vulkan.Pipeline.Graphics qualified as Graphics
import Engine.Vulkan.Types (DsLayoutBindings, HasVulkan, HasRenderPass(..))
import Render.Code (compileVert, compileFrag)
import Render.DescSets.Set0 (Scene)
import Render.Unlit.Sprite.Code qualified as Code
import Render.Unlit.Sprite.Model qualified as Model

type Pipeline = Graphics.Pipeline '[Scene] () Model.InstanceAttrs
type Config = Graphics.Configure Pipeline
type instance Graphics.Specialization Pipeline = (Float, Bool)

allocate
  :: ( HasVulkan env
     , HasRenderPass renderpass
     )
  => Vk.SampleCountFlagBits
  -> Maybe Float
  -> Bool
  -> Tagged Scene DsLayoutBindings
  -> renderpass
  -> ResourceT (RIO env) Pipeline
allocate multisample discardAlpha outline set0 = do
  fmap snd . Graphics.allocate
    Nothing
    multisample
    (config discardAlpha outline set0)

config
  :: Maybe Float
  -> Bool
  -> Tagged Scene DsLayoutBindings
  -> Config
config discardAlpha outline (Tagged set0) =
  Graphics.baseConfig
    { Graphics.cStages         = stageSpirv
    , Graphics.cDescLayouts    = Tagged @'[Scene] [set0]
    , Graphics.cVertexInput    = Graphics.vertexInput @Pipeline
    , Graphics.cDepthTest      = False
    , Graphics.cDepthWrite     = False
    , Graphics.cBlend          = True
    , Graphics.cCull           = Vk.CULL_MODE_NONE
    , Graphics.cSpecialization = specs
    }
  where
    specs =
      ( fromMaybe 0.0 discardAlpha
      , outline
      )

stageCode :: Graphics.StageCode
stageCode = Graphics.basicStages Code.vert Code.frag

stageSpirv :: Graphics.StageSpirv
stageSpirv = Graphics.basicStages vertSpirv fragSpirv

vertSpirv :: ByteString
vertSpirv = $(compileVert Code.vert)

fragSpirv :: ByteString
fragSpirv = $(compileFrag Code.frag)