packages feed

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

module Render.Debug.Pipeline
  ( Config
  , config
  , Pipeline
  , allocate
  , Mode(..)
  , 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.Shader qualified as Shader
import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)
import Render.Code (compileVert, compileFrag)
import Render.Debug.Code qualified as Code
import Render.Debug.Model qualified as Model
import Render.DescSets.Set0 (Scene, vertexPos, instanceTransform)

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

data Mode
  = UV
  | Texture
  | Shadow Word32
  deriving (Eq, Ord, Show)

instance Shader.Specialization Mode where
  specializationData = \case
    UV ->
      [0]
    Texture ->
      [1]
    Shadow bits ->
      [2, bits]

allocate
  :: ( HasVulkan env
     , HasRenderPass renderpass
     )
  => Mode
  -> Vk.SampleCountFlagBits
  -> Tagged Scene DsBindings
  -> renderpass
  -> ResourceT (RIO env) Pipeline
allocate mode multisample tset0 = do
  fmap snd . Graphics.allocate Nothing multisample (config mode tset0)

config :: Mode -> Tagged Scene DsBindings -> Config
config mode (Tagged set0) = Graphics.baseConfig
  { Graphics.cDescLayouts    = Tagged @'[Scene] [set0]
  , Graphics.cStages         = stageSpirv
  , Graphics.cVertexInput    = vertexInput
  , Graphics.cSpecialization = mode
  }
  where
    vertexInput = Graphics.vertexInput
      [ vertexPos -- vPosition
      , (Vk.VERTEX_INPUT_RATE_VERTEX,   Model.vkVertexAttrs)
      , (Vk.VERTEX_INPUT_RATE_INSTANCE, Model.vkInstanceTexture)
      , instanceTransform
      ]

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)