{- |
All the provided render passes and pipelines packaged and delivered.
-}
module Render.Basic where
import RIO
import Control.Monad.Trans.Resource (ResourceT)
import Data.Tagged (Tagged(..))
import RIO.Vector.Partial as Vector (headM)
import Vulkan.Core10 qualified as Vk
-- keid-core
import Engine.Types qualified as Engine
import Engine.Types (StageRIO)
import Engine.Vulkan.Pipeline qualified as Pipeline
import Engine.Vulkan.Types (DsBindings, HasSwapchain(getMultisample), RenderPass(..))
-- keid-render-basic
import Render.Debug.Pipeline qualified as Debug
import Render.DescSets.Set0 (Scene)
import Render.DescSets.Set0 qualified as Scene
import Render.DescSets.Sun (Sun)
import Render.DescSets.Sun qualified as Sun
import Render.Font.EvanwSdf.Pipeline qualified as EvanwSdf
import Render.ForwardMsaa (ForwardMsaa)
import Render.ForwardMsaa qualified as ForwardMsaa
import Render.Lit.Colored.Pipeline qualified as LitColored
import Render.Lit.Material.Pipeline qualified as LitMaterial
import Render.Lit.Textured.Pipeline qualified as LitTextured
import Render.Samplers qualified as Samplers
import Render.ShadowMap.Pipeline qualified as ShadowPipe
import Render.ShadowMap.RenderPass (ShadowMap)
import Render.ShadowMap.RenderPass qualified as ShadowPass
import Render.Skybox.Pipeline qualified as Skybox
import Render.Unlit.Colored.Pipeline qualified as UnlitColored
import Render.Unlit.Textured.Pipeline qualified as UnlitTextured
type Stage = Engine.Stage RenderPasses Pipelines
type Frame = Engine.Frame RenderPasses Pipelines
type StageFrameRIO r s a = Engine.StageFrameRIO RenderPasses Pipelines r s a
data RenderPasses = RenderPasses
{ rpForwardMsaa :: ForwardMsaa
, rpShadowPass :: ShadowMap
}
instance RenderPass RenderPasses where
allocateRenderpass_ context = do
rpForwardMsaa <- ForwardMsaa.allocateMsaa context
-- TODO: get from config
let
size = 4096 -- XXX: 2048 is kinda minimum, even with PCF enabled
numLayers = 2 -- XXX: no-cascade sun + moon
rpShadowPass <- ShadowPass.allocate context size numLayers
pure RenderPasses{..}
updateRenderpass context RenderPasses{..} = RenderPasses
<$> ForwardMsaa.updateMsaa context rpForwardMsaa
<*> pure rpShadowPass -- XXX: not a screen pass
refcountRenderpass RenderPasses{..} = do
refcountRenderpass rpForwardMsaa
refcountRenderpass rpShadowPass
data Pipelines = Pipelines
{ pEvanwSdf :: EvanwSdf.Pipeline
, pSkybox :: Skybox.Pipeline
, pDebug :: Debug.Pipeline
, pLitColored :: LitColored.Pipeline
, pLitColoredBlend :: LitColored.Pipeline
, pLitMaterial :: LitMaterial.Pipeline
, pLitMaterialBlend :: LitMaterial.Pipeline
, pLitTextured :: LitTextured.Pipeline
, pLitTexturedBlend :: LitTextured.Pipeline
, pUnlitColored :: UnlitColored.Pipeline
, pUnlitColoredNoDepth :: UnlitColored.Pipeline
, pUnlitTextured :: UnlitTextured.Pipeline
, pUnlitTexturedBlend :: UnlitTextured.Pipeline
, pWireframe :: UnlitColored.Pipeline
, pWireframeNoDepth :: UnlitColored.Pipeline
, pShadowCast :: ShadowPipe.Pipeline
}
allocatePipelines_
:: HasSwapchain swapchain
=> swapchain
-> RenderPasses
-> ResourceT (StageRIO st) Pipelines
allocatePipelines_ swapchain renderpasses = do
(_, samplers) <- Samplers.allocate swapchain
allocatePipelines
(Scene.mkBindings samplers Nothing Nothing 0)
swapchain
renderpasses
allocatePipelines
:: HasSwapchain swapchain
=> Tagged Scene DsBindings
-> swapchain
-> RenderPasses
-> ResourceT (StageRIO st) Pipelines
allocatePipelines sceneBinds swapchain RenderPasses{..} = do
let msaa = getMultisample swapchain
pDebug <- Debug.allocate msaa sceneBinds rpForwardMsaa
pEvanwSdf <- EvanwSdf.allocate msaa sceneBinds rpForwardMsaa
pSkybox <- Skybox.allocate msaa sceneBinds rpForwardMsaa
pLitColored <- LitColored.allocate msaa sceneBinds rpForwardMsaa
pLitColoredBlend <- LitColored.allocateBlend msaa sceneBinds rpForwardMsaa
pLitMaterial <- LitMaterial.allocate msaa sceneBinds rpForwardMsaa
pLitMaterialBlend <- LitMaterial.allocateBlend msaa sceneBinds rpForwardMsaa
pLitTextured <- LitTextured.allocate msaa sceneBinds rpForwardMsaa
pLitTexturedBlend <- LitTextured.allocateBlend msaa sceneBinds rpForwardMsaa
pUnlitColored <- UnlitColored.allocate True msaa sceneBinds rpForwardMsaa
pUnlitColoredNoDepth <- UnlitColored.allocate False msaa sceneBinds rpForwardMsaa
pUnlitTextured <- UnlitTextured.allocate msaa sceneBinds rpForwardMsaa
pUnlitTexturedBlend <- UnlitTextured.allocateBlend msaa sceneBinds rpForwardMsaa
pWireframe <- UnlitColored.allocateWireframe True msaa sceneBinds rpForwardMsaa
pWireframeNoDepth <- UnlitColored.allocateWireframe False msaa sceneBinds rpForwardMsaa
let sunBinds = Sun.set0
pShadowCast <- ShadowPipe.allocate sunBinds rpShadowPass ShadowPipe.defaults
pure Pipelines{..}
getSceneLayout :: Pipelines -> Tagged '[Scene] Vk.DescriptorSetLayout
getSceneLayout Pipelines{pLitColored} =
case Vector.headM (unTagged $ Pipeline.pDescLayouts pLitColored) of
Nothing ->
error "pLitColored has at least set0 in layout"
Just set0layout ->
Tagged set0layout
getSunLayout :: Pipelines -> Tagged '[Sun] Vk.DescriptorSetLayout
getSunLayout Pipelines{pShadowCast} =
case Vector.headM (unTagged $ Pipeline.pDescLayouts pShadowCast) of
Nothing ->
error "pShadowCast has at least set0 in layout"
Just set0layout ->
Tagged set0layout