keid-render-basic 0.1.4.0 → 0.1.5.0
raw patch · 20 files changed
+669/−98 lines, 20 filesdep ~keid-corePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: keid-core
API changes (from Hackage documentation)
- Render.Basic: [$sel:pDebug:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: Settings :: Word32 -> Word32 -> Settings
+ Render.Basic: [$sel:pDebugShadow:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pDebugTexture:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pDebugUV:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pDepthOnly:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pTileMap:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:pTileMapBlend:Pipelines] :: Pipelines -> Pipeline
+ Render.Basic: [$sel:sShadowLayers:Settings] :: Settings -> Word32
+ Render.Basic: [$sel:sShadowSize:Settings] :: Settings -> Word32
+ Render.Basic: allocate :: (HasSwapchain swapchain, HasLogFunc env, HasVulkan env) => Settings -> swapchain -> ResourceT (RIO env) RenderPasses
+ Render.Basic: allocate_ :: (HasSwapchain swapchain, HasLogFunc env, HasVulkan env) => swapchain -> ResourceT (RIO env) RenderPasses
+ Render.Basic: data Settings
+ Render.Basic: instance GHC.Classes.Eq Render.Basic.Settings
+ Render.Basic: instance GHC.Show.Show Render.Basic.Settings
+ Render.Basic: instance Vulkan.Zero.Zero Render.Basic.Settings
+ Render.Debug.Pipeline: Shadow :: Word32 -> Mode
+ Render.Debug.Pipeline: Texture :: Mode
+ Render.Debug.Pipeline: UV :: Mode
+ Render.Debug.Pipeline: data Mode
+ Render.Debug.Pipeline: instance Engine.Vulkan.Shader.Specialization Render.Debug.Pipeline.Mode
+ Render.Debug.Pipeline: instance GHC.Classes.Eq Render.Debug.Pipeline.Mode
+ Render.Debug.Pipeline: instance GHC.Classes.Ord Render.Debug.Pipeline.Mode
+ Render.Debug.Pipeline: instance GHC.Show.Show Render.Debug.Pipeline.Mode
+ Render.DepthOnly.Pipeline: allocate :: (HasVulkan env, HasRenderPass renderpass) => SampleCountFlagBits -> Tagged Scene DsBindings -> renderpass -> ResourceT (RIO env) Pipeline
+ Render.DepthOnly.Pipeline: config :: Tagged Scene DsBindings -> Config
+ Render.DepthOnly.Pipeline: type Config = Configure Pipeline ()
+ Render.DepthOnly.Pipeline: type Pipeline = Pipeline '[Scene] () Transform
+ Render.Unlit.TileMap.Model: InstanceAttrs :: TileMapParams -> Transform -> InstanceAttrs
+ Render.Unlit.TileMap.Model: InstanceBuffers :: InstanceTileMap tilemapStage -> InstanceTransform transformStage -> InstanceBuffers tilemapStage transformStage
+ Render.Unlit.TileMap.Model: TileMapParams :: IVec4 -> Vec2 -> Vec2 -> Vec2 -> Vec2 -> Vec2 -> TileMapParams
+ Render.Unlit.TileMap.Model: [$sel:ibTileMap:InstanceBuffers] :: InstanceBuffers tilemapStage transformStage -> InstanceTileMap tilemapStage
+ Render.Unlit.TileMap.Model: [$sel:ibTransform:InstanceBuffers] :: InstanceBuffers tilemapStage transformStage -> InstanceTransform transformStage
+ Render.Unlit.TileMap.Model: [$sel:tilemapParams:InstanceAttrs] :: InstanceAttrs -> TileMapParams
+ Render.Unlit.TileMap.Model: [$sel:tmpMapTextureSize:TileMapParams] :: TileMapParams -> Vec2
+ Render.Unlit.TileMap.Model: [$sel:tmpTextureIds:TileMapParams] :: TileMapParams -> IVec4
+ Render.Unlit.TileMap.Model: [$sel:tmpTileSize:TileMapParams] :: TileMapParams -> Vec2
+ Render.Unlit.TileMap.Model: [$sel:tmpTilesetTextureSize:TileMapParams] :: TileMapParams -> Vec2
+ Render.Unlit.TileMap.Model: [$sel:tmpViewOffset:TileMapParams] :: TileMapParams -> Vec2
+ Render.Unlit.TileMap.Model: [$sel:tmpViewportSize:TileMapParams] :: TileMapParams -> Vec2
+ Render.Unlit.TileMap.Model: [$sel:transformMat4:InstanceAttrs] :: InstanceAttrs -> Transform
+ Render.Unlit.TileMap.Model: allocateInstancesCoherent :: (MonadReader env m, HasVulkan env, MonadResource m, MonadUnliftIO m) => [InstanceAttrs] -> m (ReleaseKey, InstanceBuffers 'Coherent 'Coherent)
+ Render.Unlit.TileMap.Model: allocateInstancesCoherent_ :: HasVulkan env => Int -> ResourceT (RIO env) (InstanceBuffers 'Coherent 'Coherent)
+ Render.Unlit.TileMap.Model: allocateInstancesWith :: (MonadResource m, MonadUnliftIO m) => (BufferUsageFlagBits -> Int -> Vector TileMapParams -> m (InstanceTileMap texture)) -> (BufferUsageFlagBits -> Int -> Vector Transform -> m (InstanceTransform transform)) -> (forall stage a. Allocated stage a -> m ()) -> [InstanceAttrs] -> m (ReleaseKey, InstanceBuffers texture transform)
+ Render.Unlit.TileMap.Model: data InstanceAttrs
+ Render.Unlit.TileMap.Model: data InstanceBuffers tilemapStage transformStage
+ Render.Unlit.TileMap.Model: data TileMapParams
+ Render.Unlit.TileMap.Model: data Transform
+ Render.Unlit.TileMap.Model: instance Foreign.Storable.Storable Render.Unlit.TileMap.Model.TileMapParams
+ Render.Unlit.TileMap.Model: instance GHC.Show.Show Render.Unlit.TileMap.Model.TileMapParams
+ Render.Unlit.TileMap.Model: instance Resource.Model.HasVertexBuffers (Render.Unlit.TileMap.Model.InstanceBuffers tilemapStage transformStage)
+ Render.Unlit.TileMap.Model: instance Vulkan.Zero.Zero Render.Unlit.TileMap.Model.InstanceAttrs
+ Render.Unlit.TileMap.Model: instance Vulkan.Zero.Zero Render.Unlit.TileMap.Model.TileMapParams
+ Render.Unlit.TileMap.Model: type Model buf = Indexed buf Packed VertexAttrs
+ Render.Unlit.TileMap.Model: type StorableAttrs = (Vector TileMapParams, Vector Transform)
+ Render.Unlit.TileMap.Model: type VertexAttrs = "uv" ::: Vec2
+ Render.Unlit.TileMap.Model: updateCoherentResize_ :: (HasVulkan context, MonadUnliftIO m) => context -> InstanceBuffers 'Coherent 'Coherent -> (Vector TileMapParams, Vector Transform) -> m (InstanceBuffers 'Coherent 'Coherent)
+ Render.Unlit.TileMap.Model: vkInstanceTileMap :: [Format]
+ Render.Unlit.TileMap.Model: vkVertexAttrs :: [Format]
+ Render.Unlit.TileMap.Pipeline: allocate :: (HasVulkan env, HasRenderPass renderpass) => SampleCountFlagBits -> Tagged Scene DsBindings -> renderpass -> ResourceT (RIO env) Pipeline
+ Render.Unlit.TileMap.Pipeline: allocateBlend :: (HasVulkan env, HasRenderPass renderpass) => SampleCountFlagBits -> Tagged Scene DsBindings -> renderpass -> ResourceT (RIO env) Pipeline
+ Render.Unlit.TileMap.Pipeline: config :: Tagged Scene DsBindings -> Config
+ Render.Unlit.TileMap.Pipeline: configBlend :: Tagged Scene DsBindings -> Config
+ Render.Unlit.TileMap.Pipeline: type Config = Configure Pipeline ()
+ Render.Unlit.TileMap.Pipeline: type Pipeline = Pipeline '[Scene] VertexAttrs InstanceAttrs
- Render.Basic: Pipelines :: SampleCountFlagBits -> Tagged Scene DsBindings -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipelines
+ Render.Basic: Pipelines :: SampleCountFlagBits -> Tagged Scene DsBindings -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipeline -> Pipelines
- Render.Debug.Pipeline: allocate :: (HasVulkan env, HasRenderPass renderpass) => SampleCountFlagBits -> Tagged Scene DsBindings -> renderpass -> ResourceT (RIO env) Pipeline
+ Render.Debug.Pipeline: allocate :: (HasVulkan env, HasRenderPass renderpass) => Mode -> SampleCountFlagBits -> Tagged Scene DsBindings -> renderpass -> ResourceT (RIO env) Pipeline
- Render.Lit.Colored.Pipeline: type Config = Config '[Scene] VertexAttrs InstanceAttrs
+ Render.Lit.Colored.Pipeline: type Config = Configure Pipeline ()
- Render.Lit.Material.Pipeline: type Config = Config '[Scene] VertexAttrs InstanceAttrs
+ Render.Lit.Material.Pipeline: type Config = Configure Pipeline ()
- Render.Lit.Textured.Pipeline: type Config = Config '[Scene] VertexAttrs InstanceAttrs
+ Render.Lit.Textured.Pipeline: type Config = Configure Pipeline ()
- Render.ShadowMap.Pipeline: type Config = Config '[Sun] () Transform
+ Render.ShadowMap.Pipeline: type Config = Configure Pipeline ()
- Render.Unlit.Colored.Pipeline: type Config = Config '[Scene] VertexAttrs InstanceAttrs
+ Render.Unlit.Colored.Pipeline: type Config = Configure Pipeline ()
- Render.Unlit.Textured.Pipeline: type Config = Config '[Scene] VertexAttrs InstanceAttrs
+ Render.Unlit.Textured.Pipeline: type Config = Configure Pipeline ()
Files
- ChangeLog.md +11/−0
- README.md +6/−1
- keid-render-basic.cabal +5/−2
- src/Render/Basic.hs +62/−16
- src/Render/Code/Lit.hs +1/−1
- src/Render/Debug/Pipeline.hs +54/−26
- src/Render/DepthOnly/Pipeline.hs +81/−0
- src/Render/Font/EvanwSdf/Pipeline.hs +9/−11
- src/Render/ForwardMsaa.hs +4/−7
- src/Render/Lit/Colored/Pipeline.hs +6/−3
- src/Render/Lit/Material/Pipeline.hs +13/−5
- src/Render/Lit/Textured/Pipeline.hs +9/−4
- src/Render/ShadowMap/Pipeline.hs +2/−3
- src/Render/ShadowMap/RenderPass.hs +0/−2
- src/Render/Skybox/Pipeline.hs +5/−7
- src/Render/Unlit/Colored/Pipeline.hs +5/−5
- src/Render/Unlit/Textured/Pipeline.hs +5/−5
- src/Render/Unlit/TileMap/Model.hs +203/−0
- src/Render/Unlit/TileMap/Pipeline.hs +179/−0
- src/Stage/Loader/Setup.hs +9/−0
ChangeLog.md view
@@ -1,5 +1,16 @@ # Changelog for keid-render-basic +## 0.1.5.0++- Extracted deprecated `allocateRenderpass_` into `Render.Basic.allocate`.+- Extracted hardcoded shadowmap params into `Render.Basic.Settings`.+- Added `Render.Unlit.TileMap` pipeline.+- Added `Render.DepthOnly` pipeline.+- Updated lit pipelines to match vertex position calculation.+- Fixed shadowmap index guard.+- Pipelines updated for new configs with specialization.+ * `pDebug` is split into multiple pipelines, specialized by mode.+ ## 0.1.4.0 Update to match `keid-core-0.1.4.0`.
README.md view
@@ -5,12 +5,17 @@ * Unlit pipelines * Colored * Textured+ * Tile map+ * Wires * Lit pipelines * Colored * Textured * Material * Skybox pipeline- * Debug pipeline+ * Debug pipelines+ * UV+ * Shadowmap - Shadowmap pass * Shadow-casting pipeline+- Depth-only - Asset loader stage
keid-render-basic.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: keid-render-basic-version: 0.1.4.0+version: 0.1.5.0 synopsis: Basic rendering programs for Keid engine. category: Game Engine author: IC Rainbow@@ -38,6 +38,7 @@ Render.Code.Lit Render.Debug.Model Render.Debug.Pipeline+ Render.DepthOnly.Pipeline Render.DescSets.Set0 Render.DescSets.Set0.Code Render.DescSets.Sun@@ -59,6 +60,8 @@ Render.Unlit.Colored.Pipeline Render.Unlit.Textured.Model Render.Unlit.Textured.Pipeline+ Render.Unlit.TileMap.Model+ Render.Unlit.TileMap.Pipeline Resource.Font Resource.Font.EvanW Resource.Mesh.Lit@@ -139,7 +142,7 @@ , distributive , file-embed >=0.0.10 , geomancy- , keid-core >=0.1.4.0+ , keid-core >=0.1.5.0 , keid-geometry , neat-interpolation , resourcet
src/Render/Basic.hs view
@@ -10,6 +10,7 @@ import Data.Tagged (Tagged(..)) import RIO.Vector.Partial as Vector (headM) import Vulkan.Core10 qualified as Vk+import Vulkan.Zero (Zero(..)) -- keid-core @@ -17,11 +18,12 @@ import Engine.Types qualified as Engine import Engine.Vulkan.Pipeline qualified as Pipeline import Engine.Vulkan.Swapchain qualified as Swapchain-import Engine.Vulkan.Types (DsBindings, HasSwapchain, RenderPass(..))+import Engine.Vulkan.Types (DsBindings, HasSwapchain, HasVulkan, RenderPass(..)) -- keid-render-basic import Render.Debug.Pipeline qualified as Debug+import Render.DepthOnly.Pipeline qualified as DepthOnly import Render.DescSets.Set0 (Scene) import Render.DescSets.Set0 qualified as Scene import Render.DescSets.Sun (Sun)@@ -39,6 +41,7 @@ import Render.Skybox.Pipeline qualified as Skybox import Render.Unlit.Colored.Pipeline qualified as UnlitColored import Render.Unlit.Textured.Pipeline qualified as UnlitTextured+import Render.Unlit.TileMap.Pipeline qualified as UnlitTileMap type Stage = Engine.Stage RenderPasses Pipelines type Frame = Engine.Frame RenderPasses Pipelines@@ -50,33 +53,67 @@ } 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+ updateRenderpass swapchain RenderPasses{..} = RenderPasses+ <$> ForwardMsaa.updateMsaa swapchain rpForwardMsaa <*> pure rpShadowPass -- XXX: not a screen pass refcountRenderpass RenderPasses{..} = do refcountRenderpass rpForwardMsaa refcountRenderpass rpShadowPass +data Settings = Settings+ { sShadowSize :: Word32+ , sShadowLayers :: Word32+ }+ deriving (Eq, Show)++instance Zero Settings where+ zero = Settings+ -- XXX: 1x1 placeholder image+ { sShadowSize = 1+ , sShadowLayers = 1+ }++allocate+ :: ( HasSwapchain swapchain+ , HasLogFunc env+ , HasVulkan env+ )+ => Settings+ -> swapchain+ -> ResourceT (RIO env) RenderPasses+allocate Settings{..} swapchain = do+ rpForwardMsaa <- ForwardMsaa.allocateMsaa swapchain++ rpShadowPass <- ShadowPass.allocate+ swapchain+ sShadowSize+ sShadowLayers++ pure RenderPasses{..}++allocate_+ :: ( HasSwapchain swapchain+ , HasLogFunc env+ , HasVulkan env+ )+ => swapchain+ -> ResourceT (RIO env) RenderPasses+allocate_ = allocate zero+ data Pipelines = Pipelines { pMSAA :: Vk.SampleCountFlagBits , pSceneBinds :: Tagged Scene DsBindings , pEvanwSdf :: EvanwSdf.Pipeline , pSkybox :: Skybox.Pipeline- , pDebug :: Debug.Pipeline + , pDebugUV :: Debug.Pipeline+ , pDebugTexture :: Debug.Pipeline+ , pDebugShadow :: Debug.Pipeline++ , pDepthOnly :: DepthOnly.Pipeline+ , pLitColored :: LitColored.Pipeline , pLitColoredBlend :: LitColored.Pipeline , pLitMaterial :: LitMaterial.Pipeline@@ -88,6 +125,8 @@ , pUnlitColoredNoDepth :: UnlitColored.Pipeline , pUnlitTextured :: UnlitTextured.Pipeline , pUnlitTexturedBlend :: UnlitTextured.Pipeline+ , pTileMap :: UnlitTileMap.Pipeline+ , pTileMapBlend :: UnlitTileMap.Pipeline , pWireframe :: UnlitColored.Pipeline , pWireframeNoDepth :: UnlitColored.Pipeline @@ -114,10 +153,15 @@ -> RenderPasses -> ResourceT (StageRIO st) Pipelines allocatePipelines pSceneBinds pMSAA RenderPasses{..} = do- pDebug <- Debug.allocate pMSAA pSceneBinds rpForwardMsaa+ pDebugUV <- Debug.allocate Debug.UV pMSAA pSceneBinds rpForwardMsaa+ pDebugTexture <- Debug.allocate Debug.Texture pMSAA pSceneBinds rpForwardMsaa+ pDebugShadow <- Debug.allocate (Debug.Shadow 1) pMSAA pSceneBinds rpForwardMsaa+ pEvanwSdf <- EvanwSdf.allocate pMSAA pSceneBinds rpForwardMsaa pSkybox <- Skybox.allocate pMSAA pSceneBinds rpForwardMsaa + pDepthOnly <- DepthOnly.allocate pMSAA pSceneBinds rpForwardMsaa+ pLitColored <- LitColored.allocate pMSAA pSceneBinds rpForwardMsaa pLitColoredBlend <- LitColored.allocateBlend pMSAA pSceneBinds rpForwardMsaa pLitMaterial <- LitMaterial.allocate pMSAA pSceneBinds rpForwardMsaa@@ -129,6 +173,8 @@ pUnlitColoredNoDepth <- UnlitColored.allocate False pMSAA pSceneBinds rpForwardMsaa pUnlitTextured <- UnlitTextured.allocate pMSAA pSceneBinds rpForwardMsaa pUnlitTexturedBlend <- UnlitTextured.allocateBlend pMSAA pSceneBinds rpForwardMsaa+ pTileMap <- UnlitTileMap.allocate pMSAA pSceneBinds rpForwardMsaa+ pTileMapBlend <- UnlitTileMap.allocateBlend pMSAA pSceneBinds rpForwardMsaa pWireframe <- UnlitColored.allocateWireframe True pMSAA pSceneBinds rpForwardMsaa pWireframeNoDepth <- UnlitColored.allocateWireframe False pMSAA pSceneBinds rpForwardMsaa
src/Render/Code/Lit.hs view
@@ -141,7 +141,7 @@ vec3 lightDir = normalize(lights[l].direction.xyz); // L float shade = 1.0; // XXX: 0 - occluded, 1 - lit- if (lights[l].shadow.z > 0) {+ if (lights[l].shadow.z > -1) { vec4 light_space_pos = lights[l].viewProjection * fPosition; vec4 shadowCoord = light_space_pos /= light_space_pos.w;
src/Render/Debug/Pipeline.hs view
@@ -1,6 +1,7 @@ module Render.Debug.Pipeline ( Pipeline , allocate+ , Mode(..) ) where import RIO@@ -8,9 +9,9 @@ import Control.Monad.Trans.Resource (ResourceT) import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk-import Vulkan.Zero (zero) import Engine.Vulkan.Pipeline qualified as Pipeline+import Engine.Vulkan.Shader qualified as Shader import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings) import Render.Code (compileVert, compileFrag, glsl) import Render.Debug.Model qualified as Model@@ -19,27 +20,41 @@ type Pipeline = Pipeline.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs +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 )- => Vk.SampleCountFlagBits+ => Mode+ -> Vk.SampleCountFlagBits -> Tagged Scene DsBindings -> renderpass -> ResourceT (RIO env) Pipeline-allocate multisample (Tagged set0) rp = do- (_, p) <- Pipeline.allocate- Nothing- multisample- (zero- { Pipeline.cDescLayouts = Tagged @'[Scene] [set0]- , Pipeline.cVertexCode = Just vertCode- , Pipeline.cVertexInput = vertexInput- , Pipeline.cFragmentCode = Just fragCode- })- rp- pure p+allocate mode multisample (Tagged set0) = do+ fmap snd . Pipeline.allocate Nothing multisample config where+ config = Pipeline.baseConfig+ { Pipeline.cDescLayouts = Tagged @'[Scene] [set0]+ , Pipeline.cVertexCode = Just vertCode+ , Pipeline.cVertexInput = vertexInput+ , Pipeline.cFragmentCode = Just fragCode+ , Pipeline.cSpecialization = mode+ }+ vertexInput = Pipeline.vertexInput [ vertexPos -- vPosition , (Vk.VERTEX_INPUT_RATE_VERTEX, Model.vkVertexAttrs)@@ -72,11 +87,12 @@ layout(location = 2) flat out ivec2 fTextureIds; void main() {+ vec4 fPosition = iModel * vec4(vPosition, 1.0);+ gl_Position = scene.projection * scene.view- * iModel- * vec4(vPosition, 1.0);+ * fPosition; fTexCoord = vTexCoord * iTextureScaleOffset.st + iTextureScaleOffset.pq; fTextureGamma = iTextureGamma;@@ -102,7 +118,8 @@ layout(location = 0) out vec4 oColor; - const int mode = 1;+ layout (constant_id=0) const uint mode = 0;+ layout (constant_id=1) const uint shadow_mask = 0; void main() { vec4 texel = vec4(0);@@ -125,17 +142,28 @@ break; case 2:- float d0 = texture(- shadowmaps,- vec3(fTexCoord, 0.0)- ).x;+ float d0 = 1.0;+ if ((shadow_mask & 1) == 1)+ d0 = texture(+ shadowmaps,+ vec3(fTexCoord, 0.0)+ ).x; - float d1 = texture(- shadowmaps,- vec3(fTexCoord, 1.0)- ).x;+ float d1 = 1.0;+ if ((shadow_mask & 2) == 2)+ d1 = texture(+ shadowmaps,+ vec3(fTexCoord, 1.0)+ ).x; - texel = vec4(1-d0, 0, 1-d1, 1.0);+ float d2 = 1.0;+ if ((shadow_mask & 4) == 4)+ d2 = texture(+ shadowmaps,+ vec3(fTexCoord, 2.0)+ ).x;++ texel = vec4(1-d0, 1-d1, 1-d2, 1.0); break; default:
+ src/Render/DepthOnly/Pipeline.hs view
@@ -0,0 +1,81 @@+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;+ }+ |])
src/Render/Font/EvanwSdf/Pipeline.hs view
@@ -10,9 +10,7 @@ import Control.Monad.Trans.Resource (ResourceT) import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk-import Vulkan.Zero (Zero(..)) -import Engine.Vulkan.Pipeline (Config(..)) import Engine.Vulkan.Pipeline qualified as Pipeline import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings) import Render.Code (compileVert, compileFrag, glsl)@@ -34,15 +32,15 @@ fmap snd . Pipeline.allocate Nothing multisample- zero- { cVertexCode = Just vertCode- , cFragmentCode = Just fragCode- , cDescLayouts = Tagged @'[Scene] [set0]- , cVertexInput = vertexInput- , cDepthTest = False- , cDepthWrite = False- , cBlend = True- , cCull = Vk.CULL_MODE_NONE+ Pipeline.baseConfig+ { Pipeline.cVertexCode = Just vertCode+ , Pipeline.cFragmentCode = Just fragCode+ , Pipeline.cDescLayouts = Tagged @'[Scene] [set0]+ , Pipeline.cVertexInput = vertexInput+ , Pipeline.cDepthTest = False+ , Pipeline.cDepthWrite = False+ , Pipeline.cBlend = True+ , Pipeline.cCull = Vk.CULL_MODE_NONE } where vertexInput = Pipeline.vertexInput
src/Render/ForwardMsaa.hs view
@@ -33,16 +33,13 @@ } instance HasRenderPass ForwardMsaa where- getRenderPass = fmRenderPass- getFramebuffers = fmFrameBuffers- getClearValues = fmClear- getRenderArea = fmRenderArea+ getRenderPass = fmRenderPass+ getFramebuffers = fmFrameBuffers+ getClearValues = fmClear+ getRenderArea = fmRenderArea instance RenderPass ForwardMsaa where- allocateRenderpass_ = allocateMsaa -- error "Thou shalt allocateMsaa instead"- updateRenderpass = updateMsaa- refcountRenderpass = resourceTRefCount . fmRelease allocateMsaa
src/Render/Lit/Colored/Pipeline.hs view
@@ -13,7 +13,6 @@ import Control.Monad.Trans.Resource (ResourceT) import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk-import Vulkan.Zero (zero) import Engine.Vulkan.Pipeline qualified as Pipeline import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)@@ -23,7 +22,7 @@ import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2, set0binding3, set0binding4, set0binding5) import Render.Lit.Colored.Model qualified as Model -type Config = Pipeline.Config '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Config = Pipeline.Configure Pipeline () type Pipeline = Pipeline.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs allocate@@ -59,7 +58,7 @@ pure p config :: Tagged Scene DsBindings -> Config-config (Tagged set0) = zero+config (Tagged set0) = Pipeline.baseConfig { Pipeline.cDescLayouts = Tagged @'[Scene] [set0] , Pipeline.cVertexCode = Just vertCode , Pipeline.cVertexInput = vertexInput@@ -83,6 +82,8 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable + invariant gl_Position;+ ${set0binding0} layout(location = 0) in vec3 vPosition;@@ -123,6 +124,8 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable++ layout(early_fragment_tests) in; // TODO: move to spec constant const uint MAX_LIGHTS = 255;
src/Render/Lit/Material/Pipeline.hs view
@@ -13,7 +13,6 @@ import Control.Monad.Trans.Resource (ResourceT) import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk-import Vulkan.Zero (zero) import Engine.Vulkan.Pipeline qualified as Pipeline import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)@@ -23,7 +22,7 @@ import Render.Code.Lit (litMain, shadowFuns, structLight, structMaterial, brdfSpecular) import Render.Lit.Material.Model qualified as Model -type Config = Pipeline.Config '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Config = Pipeline.Configure Pipeline () type Pipeline = Pipeline.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs allocate@@ -59,11 +58,13 @@ pure p config :: Tagged Scene DsBindings -> Config-config (Tagged set0) = zero+config (Tagged set0) = Pipeline.baseConfig { Pipeline.cDescLayouts = Tagged @'[Scene] [set0] , Pipeline.cVertexCode = Just vertCode , Pipeline.cVertexInput = vertexInput , Pipeline.cFragmentCode = Just fragCode+ , Pipeline.cDepthWrite = False -- XXX: Lit pipelines require depth pre-pass+ , Pipeline.cDepthCompare = Vk.COMPARE_OP_EQUAL } where vertexInput = Pipeline.vertexInput@@ -74,8 +75,11 @@ configBlend :: Tagged Scene DsBindings -> Config configBlend tset0 = (config tset0)- { Pipeline.cBlend = True- , Pipeline.cDepthWrite = False+ { Pipeline.cBlend =+ True+ , Pipeline.cDepthCompare =+ -- XXX: blended objects aren't a part of depth prepass+ Vk.COMPARE_OP_LESS_OR_EQUAL } vertCode :: ByteString@@ -84,6 +88,8 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable + invariant gl_Position;+ ${set0binding0} // vertexPos@@ -130,6 +136,8 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable++ layout(early_fragment_tests) in; // XXX: copypasta from Lit.Colored // TODO: move to spec constant
src/Render/Lit/Textured/Pipeline.hs view
@@ -13,7 +13,6 @@ import Control.Monad.Trans.Resource (ResourceT) import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk-import Vulkan.Zero (zero) import Engine.Vulkan.Pipeline qualified as Pipeline import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)@@ -23,7 +22,7 @@ import Render.Code.Lit (litMain, shadowFuns, structLight, brdfSpecular) import Render.Lit.Textured.Model qualified as Model -type Config = Pipeline.Config '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Config = Pipeline.Configure Pipeline () type Pipeline = Pipeline.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs allocate@@ -59,11 +58,13 @@ pure p config :: Tagged Scene DsBindings -> Config-config (Tagged set0) = zero+config (Tagged set0) = Pipeline.baseConfig { Pipeline.cDescLayouts = Tagged @'[Scene] [set0] , Pipeline.cVertexCode = Just vertCode , Pipeline.cVertexInput = vertexInput , Pipeline.cFragmentCode = Just fragCode+ , Pipeline.cDepthWrite = False -- XXX: Lit pipelines require depth pre-pass+ , Pipeline.cDepthCompare = Vk.COMPARE_OP_EQUAL } where vertexInput = Pipeline.vertexInput@@ -76,7 +77,7 @@ configBlend :: Tagged Scene DsBindings -> Config configBlend tset0 = (config tset0) { Pipeline.cBlend = True- , Pipeline.cDepthWrite = False+ , Pipeline.cDepthCompare = Vk.COMPARE_OP_LESS_OR_EQUAL } vertCode :: ByteString@@ -85,6 +86,8 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable + invariant gl_Position;+ ${set0binding0} // vertexPos@@ -128,6 +131,8 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable++ layout(early_fragment_tests) in; // XXX: copypasta from Lit.Colored // TODO: move to spec constant
src/Render/ShadowMap/Pipeline.hs view
@@ -15,7 +15,6 @@ import Data.Tagged (Tagged(..)) import Geomancy (Transform) import Vulkan.Core10 qualified as Vk-import Vulkan.Zero (zero) import Engine.Vulkan.Pipeline qualified as Pipeline import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)@@ -24,7 +23,7 @@ import Render.DescSets.Set0 (vertexPos, instanceTransform) import Render.DescSets.Sun (Sun, pattern MAX_VIEWS) -type Config = Pipeline.Config '[Sun] () Transform+type Config = Pipeline.Configure Pipeline () type Pipeline = Pipeline.Pipeline '[Sun] () Transform data Settings = Settings@@ -55,7 +54,7 @@ pure p config :: Tagged Sun DsBindings -> Settings -> Config-config (Tagged set0) Settings{..} = zero+config (Tagged set0) Settings{..} = Pipeline.baseConfig { Pipeline.cDescLayouts = Tagged @'[Sun] [set0] , Pipeline.cVertexCode = Just vertCode , Pipeline.cVertexInput = vertexInput
src/Render/ShadowMap/RenderPass.hs view
@@ -44,8 +44,6 @@ getRenderArea = smRenderArea instance RenderPass ShadowMap where- allocateRenderpass_ = error "Don't allocate ShadowMap via class"- updateRenderpass = error "Don't recreate ShadowMap on resize" refcountRenderpass = resourceTRefCount . smRelease allocate
src/Render/Skybox/Pipeline.hs view
@@ -10,9 +10,7 @@ import Control.Monad.Trans.Resource (ResourceT) import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk-import Vulkan.Zero (Zero(..)) -import Engine.Vulkan.Pipeline (Config(..)) import Engine.Vulkan.Pipeline qualified as Pipeline import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings) import Render.Code (compileVert, compileFrag, glsl)@@ -33,11 +31,11 @@ fmap snd . Pipeline.allocate Nothing multisample- zero- { cVertexCode = Just vertCode- , cFragmentCode = Just fragCode- , cDescLayouts = Tagged @'[Scene] [set0]- , cCull = Vk.CULL_MODE_NONE+ Pipeline.baseConfig+ { Pipeline.cVertexCode = Just vertCode+ , Pipeline.cFragmentCode = Just fragCode+ , Pipeline.cDescLayouts = Tagged @'[Scene] [set0]+ , Pipeline.cCull = Vk.CULL_MODE_NONE } vertCode :: ByteString
src/Render/Unlit/Colored/Pipeline.hs view
@@ -13,7 +13,6 @@ import Control.Monad.Trans.Resource (ResourceT) import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk-import Vulkan.Zero (zero) import Engine.Vulkan.Pipeline qualified as Pipeline import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)@@ -22,7 +21,7 @@ import Render.DescSets.Set0.Code (set0binding0) import Render.Unlit.Colored.Model qualified as Model -type Config = Pipeline.Config '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Config = Pipeline.Configure Pipeline () type Pipeline = Pipeline.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs allocate@@ -60,7 +59,7 @@ pure p config :: Bool -> Tagged Scene DsBindings -> Config-config useDepth (Tagged set0) = zero+config useDepth (Tagged set0) = Pipeline.baseConfig { Pipeline.cDescLayouts = Tagged @'[Scene] [set0] , Pipeline.cVertexCode = Just vertCode , Pipeline.cVertexInput = vertexInput@@ -97,11 +96,12 @@ layout(location = 0) out vec4 fColor; void main() {+ vec4 fPosition = iModel * vec4(vPosition, 1.0);+ gl_Position = scene.projection * scene.view- * iModel- * vec4(vPosition, 1.0);+ * fPosition; fColor = vColor; fColor.rgb * fColor.a;
src/Render/Unlit/Textured/Pipeline.hs view
@@ -14,7 +14,6 @@ import Control.Monad.Trans.Resource (ResourceT) import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk-import Vulkan.Zero (zero) import Engine.Vulkan.Pipeline qualified as Pipeline import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings)@@ -22,7 +21,7 @@ import Render.DescSets.Set0 (Scene, vertexPos, instanceTransform) import Render.Unlit.Textured.Model qualified as Model -type Config = Pipeline.Config '[Scene] Model.VertexAttrs Model.InstanceAttrs+type Config = Pipeline.Configure Pipeline () type Pipeline = Pipeline.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs allocate@@ -58,7 +57,7 @@ pure p config :: Tagged Scene DsBindings -> Config-config (Tagged set0) = zero+config (Tagged set0) = Pipeline.baseConfig { Pipeline.cDescLayouts = Tagged @'[Scene] [set0] , Pipeline.cVertexCode = Just vertCode , Pipeline.cVertexInput = vertexInput@@ -103,11 +102,12 @@ layout(location = 2) flat out ivec2 fTextureIds; void main() {+ vec4 fPosition = iModel * vec4(vPosition, 1.0);+ gl_Position = scene.projection * scene.view- * iModel- * vec4(vPosition, 1.0);+ * fPosition; fTexCoord = vTexCoord * iTextureScaleOffset.st + iTextureScaleOffset.pq; fTextureGamma = iTextureGamma;
+ src/Render/Unlit/TileMap/Model.hs view
@@ -0,0 +1,203 @@+module Render.Unlit.TileMap.Model+ ( Model+ , VertexAttrs+ , vkVertexAttrs++ , InstanceAttrs(..)+ -- , instanceAttrs++ , StorableAttrs+ -- , storableAttrs1++ , InstanceBuffers(..)++ , TileMapParams(..)+ , vkInstanceTileMap++ , allocateInstancesWith+ , allocateInstancesCoherent+ , allocateInstancesCoherent_+ , updateCoherentResize_+ , Transform+ ) where++import RIO++import Foreign (Storable(..))+import Geomancy (IVec4, Transform, Vec2)+import Geomancy.Vec3 qualified as Vec3+import RIO.Vector.Storable qualified as Storable+import UnliftIO.Resource (MonadResource, ReleaseKey, ResourceT, allocate)+import Vulkan.Core10 qualified as Vk+import Vulkan.NamedType ((:::))+import Vulkan.Zero (Zero(..))++import Engine.Vulkan.Types (HasVulkan)+import Resource.Buffer qualified as Buffer+import Resource.Model qualified as Model++type Model buf = Model.Indexed buf Vec3.Packed VertexAttrs++type VertexAttrs = "uv" ::: Vec2++vkVertexAttrs :: [Vk.Format]+vkVertexAttrs =+ [ Vk.FORMAT_R32G32_SFLOAT -- vTexCoord :: vec2+ ]++-- | Data for a single element.+data InstanceAttrs = InstanceAttrs+ { tilemapParams :: TileMapParams+ , transformMat4 :: Transform+ }++instance Zero InstanceAttrs where+ zero = InstanceAttrs+ { tilemapParams = zero+ , transformMat4 = mempty+ }++-- | Intermediate data to be shipped.+type StorableAttrs =+ ( Storable.Vector TileMapParams+ , Storable.Vector Transform+ )++-- | GPU-bound data.+data InstanceBuffers tilemapStage transformStage = InstanceBuffers+ { ibTileMap :: InstanceTileMap tilemapStage+ , ibTransform :: InstanceTransform transformStage+ }++type InstanceTileMap stage = Buffer.Allocated stage TileMapParams++type InstanceTransform stage = Buffer.Allocated stage Transform++instance Model.HasVertexBuffers (InstanceBuffers tilemapStage transformStage) where+ type VertexBuffersOf (InstanceBuffers tilemapStage transformStage) = InstanceAttrs++ {-# INLINE getVertexBuffers #-}+ getVertexBuffers InstanceBuffers{..} =+ [ Buffer.aBuffer ibTileMap+ , Buffer.aBuffer ibTransform+ ]++ {-# INLINE getInstanceCount #-}+ getInstanceCount InstanceBuffers{..} =+ min+ (Buffer.aUsed ibTileMap)+ (Buffer.aUsed ibTransform)++data TileMapParams = TileMapParams+ { tmpTextureIds :: IVec4+ , tmpViewOffset :: Vec2+ , tmpViewportSize :: Vec2+ , tmpMapTextureSize :: Vec2+ , tmpTilesetTextureSize :: Vec2+ , tmpTileSize :: Vec2+ }+ deriving (Show)++instance Zero TileMapParams where+ zero = TileMapParams+ { tmpTextureIds = 0+ , tmpViewOffset = 0+ , tmpViewportSize = 1+ , tmpMapTextureSize = 1+ , tmpTilesetTextureSize = 1+ , tmpTileSize = 1+ }++instance Storable TileMapParams where+ alignment ~_ = 4++ sizeOf ~_ = 16 + 8 + 8 + 8 + 8 + 8++ poke ptr TileMapParams{..} = do+ pokeByteOff ptr 0 tmpTextureIds+ pokeByteOff ptr 16 tmpViewOffset+ pokeByteOff ptr 24 tmpViewportSize+ pokeByteOff ptr 32 tmpMapTextureSize+ pokeByteOff ptr 40 tmpTilesetTextureSize+ pokeByteOff ptr 48 tmpTileSize++ peek ptr = do+ tmpTextureIds <- peekByteOff ptr 0+ tmpViewOffset <- peekByteOff ptr 16+ tmpViewportSize <- peekByteOff ptr 24+ tmpMapTextureSize <- peekByteOff ptr 32+ tmpTilesetTextureSize <- peekByteOff ptr 48+ tmpTileSize <- peekByteOff ptr 56+ pure TileMapParams{..}++vkInstanceTileMap :: [Vk.Format]+vkInstanceTileMap =+ [ Vk.FORMAT_R32G32B32A32_SINT -- tmpTextureIds :: IVec4+ , Vk.FORMAT_R32G32_SFLOAT -- tmpViewOffset :: Vec2+ , Vk.FORMAT_R32G32_SFLOAT -- tmpViewportSize :: Vec2+ , Vk.FORMAT_R32G32_SFLOAT -- tmpMapTextureSize :: Vec2+ , Vk.FORMAT_R32G32_SFLOAT -- tmpTilesetTextureSize :: Vec2+ , Vk.FORMAT_R32G32_SFLOAT -- tmpTileSize :: Vec2+ ]++allocateInstancesWith+ :: ( MonadResource m+ , MonadUnliftIO m+ )+ => (Vk.BufferUsageFlagBits -> Int -> Storable.Vector TileMapParams -> m (InstanceTileMap texture))+ -> (Vk.BufferUsageFlagBits -> Int -> Storable.Vector Transform -> m (InstanceTransform transform))+ -> (forall stage a . Buffer.Allocated stage a -> m ())+ -> [InstanceAttrs]+ -> m (ReleaseKey, InstanceBuffers texture transform)+allocateInstancesWith createTextures createTransforms bufferDestroy instances = do+ ul <- askUnliftIO+ allocate (create ul) (destroy ul)+ where+ textures = Storable.fromList $ map tilemapParams instances+ transforms = Storable.fromList $ map transformMat4 instances+ numInstances = Storable.length textures++ create (UnliftIO ul) = ul do+ ibTileMap <- createTextures Vk.BUFFER_USAGE_VERTEX_BUFFER_BIT numInstances textures+ ibTransform <- createTransforms Vk.BUFFER_USAGE_VERTEX_BUFFER_BIT numInstances transforms+ pure InstanceBuffers{..}++ destroy (UnliftIO ul) InstanceBuffers{..} = ul do+ bufferDestroy ibTileMap+ bufferDestroy ibTransform++allocateInstancesCoherent+ :: ( MonadReader env m+ , HasVulkan env+ , MonadResource m+ , MonadUnliftIO m+ )+ => [InstanceAttrs]+ -> m (ReleaseKey, InstanceBuffers 'Buffer.Coherent 'Buffer.Coherent)+allocateInstancesCoherent instances = do+ context <- ask+ allocateInstancesWith+ (Buffer.createCoherent context)+ (Buffer.createCoherent context)+ (Buffer.destroy context)+ instances++allocateInstancesCoherent_+ :: (HasVulkan env)+ => Int+ -> ResourceT (RIO env) (InstanceBuffers 'Buffer.Coherent 'Buffer.Coherent)+allocateInstancesCoherent_ n =+ fmap snd $ allocateInstancesCoherent (replicate n zero)++updateCoherentResize_+ :: ( HasVulkan context+ , MonadUnliftIO m+ )+ => context+ -> InstanceBuffers 'Buffer.Coherent 'Buffer.Coherent+ -> (Storable.Vector TileMapParams, Storable.Vector Transform)+ -> m (InstanceBuffers 'Buffer.Coherent 'Buffer.Coherent)+updateCoherentResize_ context InstanceBuffers{..} (textures, transforms) =+ InstanceBuffers+ <$> Buffer.updateCoherentResize_ context ibTileMap textures+ <*> Buffer.updateCoherentResize_ context ibTransform transforms
+ src/Render/Unlit/TileMap/Pipeline.hs view
@@ -0,0 +1,179 @@+module Render.Unlit.TileMap.Pipeline+ ( Pipeline+ , allocate+ , allocateBlend++ , Config+ , config+ , configBlend+ ) where++import RIO+import Render.DescSets.Set0.Code++import Control.Monad.Trans.Resource (ResourceT)+import Data.Tagged (Tagged(..))+import Vulkan.Core10 qualified as Vk++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.Unlit.TileMap.Model qualified as Model++type Config = Pipeline.Configure Pipeline ()+type Pipeline = Pipeline.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs++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++allocateBlend+ :: ( HasVulkan env+ , HasRenderPass renderpass+ )+ => Vk.SampleCountFlagBits+ -> Tagged Scene DsBindings+ -> renderpass+ -> ResourceT (RIO env) Pipeline+allocateBlend multisample tset0 rp = do+ (_, p) <- Pipeline.allocate+ Nothing+ multisample+ (configBlend 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 = Just fragCode+ }+ where+ vertexInput = Pipeline.vertexInput+ [ vertexPos+ , (Vk.VERTEX_INPUT_RATE_VERTEX, Model.vkVertexAttrs)+ , (Vk.VERTEX_INPUT_RATE_INSTANCE, Model.vkInstanceTileMap)+ , instanceTransform+ ]++configBlend :: Tagged Scene DsBindings -> Config+configBlend tset0 = (config tset0)+ { Pipeline.cBlend = True+ , Pipeline.cDepthWrite = False+ }++vertCode :: ByteString+vertCode =+ $(compileVert [glsl|+ #version 450+ #extension GL_ARB_separate_shader_objects : enable++ ${set0binding0}++ // vertexPos+ layout(location = 0) in vec3 vPosition;+ // vertexAttrs+ layout(location = 1) in vec2 vTexCoord;+ // tilemapParams+ layout(location = 2) in ivec4 iTextureIds; // combined: tileset, tileset sampler, map, repeat+ layout(location = 3) in vec2 iViewOffset;+ layout(location = 4) in vec2 iViewportSize;+ layout(location = 5) in vec2 iMapTextureSize;+ layout(location = 6) in vec2 iTilesetTextureSize;+ layout(location = 7) in vec2 iTileSize;++ // transformMat+ layout(location = 8) in mat4 iModel;++ layout(location = 0) out vec2 fTexCoord;+ layout(location = 1) out vec2 fPixCoord;+ layout(location = 2) flat out ivec4 fTextureIds;+ layout(location = 3) flat out vec2 fTilesetTextureSize;+ layout(location = 4) flat out vec2 fTileSize;++ void main() {+ vec4 fPosition = iModel * vec4(vPosition, 1.0);++ gl_Position+ = scene.projection+ * scene.view+ * fPosition;++ fPixCoord = (vTexCoord * iViewportSize) + iViewOffset;+ fTexCoord = fPixCoord / iMapTextureSize / iTileSize;++ fTextureIds = iTextureIds;+ fTilesetTextureSize = iTilesetTextureSize;+ fTileSize = iTileSize;+ }+ |])++fragCode :: ByteString+fragCode =+ $(compileFrag [glsl|+ #version 450+ #extension GL_ARB_separate_shader_objects : enable+ #extension GL_EXT_nonuniform_qualifier : enable++ ${set0binding1}+ ${set0binding2}++ layout(location = 0) in vec2 fTexCoord;+ layout(location = 1) in vec2 fPixCoord;++ // combined: tileset, tileset sampler, map, repeat+ layout(location = 2) flat in ivec4 fTextureIds;+ layout(location = 3) flat in vec2 fTilesetTextureSize;+ layout(location = 4) flat in vec2 fTileSize;++ layout(location = 0) out vec4 oColor;++ int tilesetTextureIx = fTextureIds[0];+ int tilesetSamplerIx = fTextureIds[1];+ int mapTextureIx = fTextureIds[2];+ int repeatTiles = fTextureIds[3];++ // TODO+ // const vec4 fTextureGamma = vec4(1.0);++ void main() {+ if (repeatTiles == 0 && (fTexCoord.x < 0.0 || fTexCoord.y < 0.0 || fTexCoord.x > 1.0 || fTexCoord.y > 1.0)) {+ discard;+ }++ vec4 map = texture(+ sampler2D(+ textures[nonuniformEXT(mapTextureIx)],+ samplers[7] // nearest+ ),+ fTexCoord+ );++ vec2 spriteOffset = floor(map.xy * 256.0) * fTileSize;+ vec2 spriteCoord = mod(fPixCoord, fTileSize);+ vec2 spriteUV = (spriteOffset + spriteCoord) / fTilesetTextureSize;++ oColor = texture(+ sampler2D(+ textures[nonuniformEXT(tilesetTextureIx)],+ samplers[nonuniformEXT(tilesetSamplerIx)]+ ),+ spriteUV+ );+ }+ |])
src/Stage/Loader/Setup.hs view
@@ -122,6 +122,7 @@ loaderStage loadAction nextStage uiSettings = Stage { sTitle = "Loader" + , sAllocateRP = allocateRenderPass , sAllocateP = allocatePipelines , sInitialRS = initialRunState loadAction nextStage uiSettings , sInitialRR = initialFrameResources uiSettings@@ -133,6 +134,14 @@ , sAfterLoop = pure } where+ allocateRenderPass swapchain = do+ Basic.allocate+ Basic.Settings+ { sShadowLayers = 1+ , sShadowSize = 1+ }+ swapchain+ allocatePipelines swapchain rps = do logDebug "Allocating loader pipelines" (_, samplers) <- Samplers.allocate