packages feed

keid-render-basic-0.1.12.0: src/Render/Lit/Material/Pipeline.hs

module Render.Lit.Material.Pipeline
  ( Pipeline
  , allocate
  , allocateBlend

  , Config
  , config
  , configBlend

  , 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.Lit.Material.Code qualified as Code
import Render.Lit.Material.Model qualified as Model
import Render.Lit.Specialization (Specialization)

type Pipeline = Graphics.Pipeline '[Scene] Model.Vertex Model.InstanceAttrs
type Config = Graphics.Configure Pipeline
type instance Graphics.Specialization Pipeline = Specialization

allocate
  :: ( HasVulkan env
     , HasRenderPass renderpass
     )
  => Specialization
  -> Vk.SampleCountFlagBits
  -> Tagged Scene DsLayoutBindings
  -> renderpass
  -> ResourceT (RIO env) Pipeline
allocate spec multisample tset0 rp = do
  (_, p) <- Graphics.allocate
    Nothing
    multisample
    (config spec tset0)
    rp
  pure p

allocateBlend
  :: ( HasVulkan env
     , HasRenderPass renderpass
     )
  => Specialization
  -> Vk.SampleCountFlagBits
  -> Tagged Scene DsLayoutBindings
  -> renderpass
  -> ResourceT (RIO env) Pipeline
allocateBlend spec multisample tset0 rp = do
  (_, p) <- Graphics.allocate
    Nothing
    multisample
    (configBlend spec tset0)
    rp
  pure p

config :: Specialization -> Tagged Scene DsLayoutBindings -> Config
config spec (Tagged set0) = Graphics.baseConfig
  { Graphics.cDescLayouts    = Tagged @'[Scene] [set0]
  , Graphics.cStages         = stageSpirv
  , Graphics.cVertexInput    = Graphics.vertexInput @Pipeline
  , Graphics.cDepthWrite     = False -- XXX: Lit pipelines require depth pre-pass
  , Graphics.cDepthCompare   = Vk.COMPARE_OP_EQUAL
  , Graphics.cSpecialization = spec
  }

configBlend :: Specialization -> Tagged Scene DsLayoutBindings -> Config
configBlend spec tset0 = (config spec tset0)
  { Graphics.cBlend =
      True
  , Graphics.cDepthCompare =
      -- XXX: blended objects aren't a part of depth prepass
      Vk.COMPARE_OP_GREATER_OR_EQUAL
  }

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)