packages feed

keid-render-basic-0.1.5.0: src/Render/DepthOnly/Pipeline.hs

module Render.DepthOnly.Pipeline
  ( Pipeline
  , allocate

  , Config
  , config
  ) where

import RIO

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

import Geomancy (Transform)
import Engine.Vulkan.Pipeline qualified as Pipeline
import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)
import Render.Code (compileVert, {- compileFrag, -} glsl)
import Render.DescSets.Set0 (Scene, vertexPos, instanceTransform)
import Render.DescSets.Set0.Code (set0binding0)

type Config = Pipeline.Configure Pipeline ()
type Pipeline = Pipeline.Pipeline '[Scene] () Transform

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

config :: Tagged Scene DsBindings -> Config
config (Tagged set0) = Pipeline.baseConfig
  { Pipeline.cDescLayouts  = Tagged @'[Scene] [set0]
  , Pipeline.cVertexCode   = Just vertCode
  , Pipeline.cVertexInput  = vertexInput
  , Pipeline.cFragmentCode = Nothing -- XXX: needed for alpha cut-outs
  }
  where
    vertexInput = Pipeline.vertexInput
      [ vertexPos
      , instanceTransform
      ]

vertCode :: ByteString
vertCode =
  $(compileVert [glsl|
    #version 450
    #extension GL_ARB_separate_shader_objects : enable

    invariant gl_Position;

    ${set0binding0}

    layout(location = 0) in vec3 vPosition;
    layout(location = 1) in mat4 iModel;

    // layout(location = 0) out vec4 fColor;

    void main() {
      vec4 fPosition = iModel * vec4(vPosition, 1.0);

      gl_Position
        = scene.projection
        * scene.view
        * fPosition;

      // XXX: needed for alpha cut-outs
      // fColor = vColor;
      // fColor.rgb * fColor.a;
    }
  |])