{- | 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