packages feed

keid-render-basic-0.1.7.0: src/Render/ShadowMap/Pipeline.hs

module Render.ShadowMap.Pipeline
  ( Settings(..)
  , defaults

  , Pipeline
  , allocate

  , Config
  , config

  , stageCode
  , stageSpirv
  ) where

import RIO

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

import Engine.Vulkan.Pipeline.Graphics qualified as Graphics
import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)
import Render.Code (compileVert)
import Render.DescSets.Set0 (vertexPos, instanceTransform)
import Render.DescSets.Sun (Sun)
import Render.ShadowMap.Code qualified as Code

type Pipeline = Graphics.Pipeline '[Sun] () Transform
type Config = Graphics.Configure Pipeline
type instance Graphics.Specialization Pipeline = ()

data Settings = Settings
  { cull      :: Vk.CullModeFlagBits
  , depthBias :: Maybe (Float, Float)
  }

defaults :: Settings
defaults = Settings
  { cull      = Vk.CULL_MODE_BACK_BIT
  , depthBias = Just (2.0, 2.5)
  }

allocate
  :: ( HasVulkan env
     , HasRenderPass renderpass
     )
  => Tagged Sun DsBindings
  -> renderpass
  -> Settings
  -> ResourceT (RIO env) Pipeline
allocate tset0 rp settings = do
  (_, p) <- Graphics.allocate
    Nothing
    Vk.SAMPLE_COUNT_1_BIT
    (config tset0 settings)
    rp
  pure p

config :: Tagged Sun DsBindings -> Settings -> Config
config (Tagged set0) Settings{..} = Graphics.baseConfig
  { Graphics.cDescLayouts  = Tagged @'[Sun] [set0]
  , Graphics.cStages       = stageSpirv
  , Graphics.cVertexInput  = vertexInput
  , Graphics.cDepthBias    = depthBias
  , Graphics.cCull         = cull
  }
  where
    vertexInput = Graphics.vertexInput
      [ vertexPos
      , instanceTransform
      ]

stageSpirv :: Graphics.StageSpirv
stageSpirv = Graphics.vertexOnly vertSpirv

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

stageCode :: Graphics.StageCode
stageCode = Graphics.vertexOnly Code.vert