{-# LANGUAGE OverloadedLists #-}
module Vulkan.Utils.DynamicState
(
DynamicState (..)
, defaultDynamicState
, dynamicStateFor
, applyDynamicStates
, allDynamicStates
, depthOnlyDynamicStates
, defaultDynamicStatesFor
, minimalDynamicStates
, noDynamicStates
, preRasterizationStates
, fragmentTestStates
, fragmentOutputStates
, fullViewport
, fullScissor
) where
import Control.Monad.IO.Class (MonadIO)
import Data.Foldable (traverse_)
import Data.Vector (Vector)
import qualified Data.Vector as V
import Data.Word (Word32)
import qualified Vulkan.Core10 as Rect2D (Rect2D (..))
import qualified Vulkan.Core10 as Viewport (Viewport (..))
import qualified Vulkan.Core10 as Vk
import qualified Vulkan.Core13 as Vk
import Vulkan.Zero (zero)
fullViewport :: Vk.Extent2D -> Vk.Viewport
fullViewport :: Extent2D -> Viewport
fullViewport (Vk.Extent2D Word32
w Word32
h) =
Viewport
forall a. Zero a => a
zero
{ Viewport.width = realToFrac w
, Viewport.height = realToFrac h
, Viewport.maxDepth = 1
}
fullScissor :: Vk.Extent2D -> Vk.Rect2D
fullScissor :: Extent2D -> Rect2D
fullScissor Extent2D
extent = Rect2D
forall a. Zero a => a
zero{Rect2D.extent = extent}
data DynamicState = DynamicState
{
DynamicState -> Vector Viewport
viewports :: Vector Vk.Viewport
, DynamicState -> Vector Rect2D
scissors :: Vector Vk.Rect2D
, DynamicState -> PrimitiveTopology
topology :: Vk.PrimitiveTopology
, DynamicState -> Bool
primitiveRestart :: Bool
, DynamicState -> CullModeFlags
cullMode :: Vk.CullModeFlags
, DynamicState -> FrontFace
frontFace :: Vk.FrontFace
, DynamicState -> Bool
rasterizerDiscard :: Bool
, DynamicState -> Float
lineWidth :: Float
, DynamicState -> Bool
depthBiasEnable :: Bool
, DynamicState -> (Float, Float, Float)
depthBias :: (Float, Float, Float)
,
DynamicState -> Bool
depthTest :: Bool
, DynamicState -> Bool
depthWrite :: Bool
, DynamicState -> CompareOp
depthCompareOp :: Vk.CompareOp
, DynamicState -> Bool
depthBoundsTest :: Bool
, DynamicState -> (Float, Float)
depthBounds :: (Float, Float)
, DynamicState -> Bool
stencilTest :: Bool
, DynamicState -> StencilOp
stencilFailOp :: Vk.StencilOp
, DynamicState -> StencilOp
stencilPassOp :: Vk.StencilOp
, DynamicState -> StencilOp
stencilDepthFailOp :: Vk.StencilOp
, DynamicState -> CompareOp
stencilCompareOp :: Vk.CompareOp
, DynamicState -> Word32
stencilCompareMask :: Word32
, DynamicState -> Word32
stencilWriteMask :: Word32
, DynamicState -> Word32
stencilReference :: Word32
,
DynamicState -> (Float, Float, Float, Float)
blendConstants :: (Float, Float, Float, Float)
}
defaultDynamicState :: DynamicState
defaultDynamicState :: DynamicState
defaultDynamicState =
DynamicState
{ viewports :: Vector Viewport
viewports = Vector Viewport
forall a. Vector a
V.empty
, scissors :: Vector Rect2D
scissors = Vector Rect2D
forall a. Vector a
V.empty
, topology :: PrimitiveTopology
topology = PrimitiveTopology
Vk.PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
, primitiveRestart :: Bool
primitiveRestart = Bool
False
, cullMode :: CullModeFlags
cullMode = CullModeFlags
Vk.CULL_MODE_NONE
, frontFace :: FrontFace
frontFace = FrontFace
Vk.FRONT_FACE_COUNTER_CLOCKWISE
, rasterizerDiscard :: Bool
rasterizerDiscard = Bool
False
, lineWidth :: Float
lineWidth = Float
1
, depthBiasEnable :: Bool
depthBiasEnable = Bool
False
, depthBias :: (Float, Float, Float)
depthBias = (Float
0, Float
0, Float
0)
, depthTest :: Bool
depthTest = Bool
False
, depthWrite :: Bool
depthWrite = Bool
False
, depthCompareOp :: CompareOp
depthCompareOp = CompareOp
Vk.COMPARE_OP_NEVER
, depthBoundsTest :: Bool
depthBoundsTest = Bool
False
, depthBounds :: (Float, Float)
depthBounds = (Float
0, Float
0)
, stencilTest :: Bool
stencilTest = Bool
False
, stencilFailOp :: StencilOp
stencilFailOp = StencilOp
Vk.STENCIL_OP_KEEP
, stencilPassOp :: StencilOp
stencilPassOp = StencilOp
Vk.STENCIL_OP_KEEP
, stencilDepthFailOp :: StencilOp
stencilDepthFailOp = StencilOp
Vk.STENCIL_OP_KEEP
, stencilCompareOp :: CompareOp
stencilCompareOp = CompareOp
Vk.COMPARE_OP_NEVER
, stencilCompareMask :: Word32
stencilCompareMask = Word32
0
, stencilWriteMask :: Word32
stencilWriteMask = Word32
0
, stencilReference :: Word32
stencilReference = Word32
0
, blendConstants :: (Float, Float, Float, Float)
blendConstants = (Float
0, Float
0, Float
0, Float
0)
}
dynamicStateFor :: Vk.Extent2D -> DynamicState
dynamicStateFor :: Extent2D -> DynamicState
dynamicStateFor Extent2D
ext =
DynamicState
defaultDynamicState
{ viewports = V.singleton (fullViewport ext)
, scissors = V.singleton (fullScissor ext)
}
preRasterizationStates :: Vector Vk.DynamicState
preRasterizationStates :: Vector DynamicState
preRasterizationStates =
[ Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_VIEWPORT_WITH_COUNT
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_SCISSOR_WITH_COUNT
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_PRIMITIVE_TOPOLOGY
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_CULL_MODE
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_FRONT_FACE
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_LINE_WIDTH
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_DEPTH_BIAS_ENABLE
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_DEPTH_BIAS
]
fragmentTestStates :: Vector Vk.DynamicState
fragmentTestStates :: Vector DynamicState
fragmentTestStates =
[ Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_DEPTH_TEST_ENABLE
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_DEPTH_WRITE_ENABLE
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_DEPTH_COMPARE_OP
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_DEPTH_BOUNDS
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_STENCIL_TEST_ENABLE
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_STENCIL_OP
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_STENCIL_COMPARE_MASK
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_STENCIL_WRITE_MASK
, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_STENCIL_REFERENCE
]
fragmentOutputStates :: Vector Vk.DynamicState
fragmentOutputStates :: Vector DynamicState
fragmentOutputStates = [Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_BLEND_CONSTANTS]
allDynamicStates :: Vector Vk.DynamicState
allDynamicStates :: Vector DynamicState
allDynamicStates =
Vector DynamicState
preRasterizationStates Vector DynamicState -> Vector DynamicState -> Vector DynamicState
forall a. Semigroup a => a -> a -> a
<> Vector DynamicState
fragmentTestStates Vector DynamicState -> Vector DynamicState -> Vector DynamicState
forall a. Semigroup a => a -> a -> a
<> Vector DynamicState
fragmentOutputStates
depthOnlyDynamicStates :: Vector Vk.DynamicState
depthOnlyDynamicStates :: Vector DynamicState
depthOnlyDynamicStates = Vector DynamicState
preRasterizationStates Vector DynamicState -> Vector DynamicState -> Vector DynamicState
forall a. Semigroup a => a -> a -> a
<> Vector DynamicState
fragmentTestStates
defaultDynamicStatesFor
:: Bool
-> Vector Vk.DynamicState
defaultDynamicStatesFor :: Bool -> Vector DynamicState
defaultDynamicStatesFor Bool
hasColor
| Bool
hasColor = Vector DynamicState
allDynamicStates
| Bool
otherwise = Vector DynamicState
depthOnlyDynamicStates
minimalDynamicStates :: Vector Vk.DynamicState
minimalDynamicStates :: Vector DynamicState
minimalDynamicStates =
[Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_VIEWPORT, Item (Vector DynamicState)
DynamicState
Vk.DYNAMIC_STATE_SCISSOR]
noDynamicStates :: Maybe (Vector Vk.DynamicState)
noDynamicStates :: Maybe (Vector DynamicState)
noDynamicStates = Vector DynamicState -> Maybe (Vector DynamicState)
forall a. a -> Maybe a
Just Vector DynamicState
forall a. Vector a
V.empty
applyDynamicStates
:: (MonadIO m) => Vector Vk.DynamicState -> Vk.CommandBuffer -> DynamicState -> m ()
applyDynamicStates :: forall (m :: * -> *).
MonadIO m =>
Vector DynamicState -> CommandBuffer -> DynamicState -> m ()
applyDynamicStates Vector DynamicState
states CommandBuffer
cb DynamicState
s = (DynamicState -> m ()) -> Vector DynamicState -> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ DynamicState -> m ()
go Vector DynamicState
states
where
DynamicState{Bool
Float
Word32
(Float, Float)
(Float, Float, Float)
(Float, Float, Float, Float)
Vector Rect2D
Vector Viewport
CompareOp
CullModeFlags
FrontFace
PrimitiveTopology
StencilOp
lineWidth :: DynamicState -> Float
topology :: DynamicState -> PrimitiveTopology
viewports :: DynamicState -> Vector Viewport
scissors :: DynamicState -> Vector Rect2D
primitiveRestart :: DynamicState -> Bool
cullMode :: DynamicState -> CullModeFlags
frontFace :: DynamicState -> FrontFace
rasterizerDiscard :: DynamicState -> Bool
depthBiasEnable :: DynamicState -> Bool
depthBias :: DynamicState -> (Float, Float, Float)
depthTest :: DynamicState -> Bool
depthWrite :: DynamicState -> Bool
depthCompareOp :: DynamicState -> CompareOp
depthBoundsTest :: DynamicState -> Bool
depthBounds :: DynamicState -> (Float, Float)
stencilTest :: DynamicState -> Bool
stencilFailOp :: DynamicState -> StencilOp
stencilPassOp :: DynamicState -> StencilOp
stencilDepthFailOp :: DynamicState -> StencilOp
stencilCompareOp :: DynamicState -> CompareOp
stencilCompareMask :: DynamicState -> Word32
stencilWriteMask :: DynamicState -> Word32
stencilReference :: DynamicState -> Word32
blendConstants :: DynamicState -> (Float, Float, Float, Float)
viewports :: Vector Viewport
scissors :: Vector Rect2D
topology :: PrimitiveTopology
primitiveRestart :: Bool
cullMode :: CullModeFlags
frontFace :: FrontFace
rasterizerDiscard :: Bool
lineWidth :: Float
depthBiasEnable :: Bool
depthBias :: (Float, Float, Float)
depthTest :: Bool
depthWrite :: Bool
depthCompareOp :: CompareOp
depthBoundsTest :: Bool
depthBounds :: (Float, Float)
stencilTest :: Bool
stencilFailOp :: StencilOp
stencilPassOp :: StencilOp
stencilDepthFailOp :: StencilOp
stencilCompareOp :: CompareOp
stencilCompareMask :: Word32
stencilWriteMask :: Word32
stencilReference :: Word32
blendConstants :: (Float, Float, Float, Float)
..} = DynamicState
s
bothFaces :: StencilFaceFlagBits
bothFaces = StencilFaceFlagBits
Vk.STENCIL_FACE_FRONT_AND_BACK
(Float
biasConstant, Float
biasClamp, Float
biasSlope) = (Float, Float, Float)
depthBias
(Float
minBound', Float
maxBound') = (Float, Float)
depthBounds
go :: DynamicState -> m ()
go = \case
DynamicState
Vk.DYNAMIC_STATE_VIEWPORT_WITH_COUNT -> CommandBuffer -> Vector Viewport -> m ()
forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> Vector Viewport -> io ()
Vk.cmdSetViewportWithCount CommandBuffer
cb Vector Viewport
viewports
DynamicState
Vk.DYNAMIC_STATE_SCISSOR_WITH_COUNT -> CommandBuffer -> Vector Rect2D -> m ()
forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> Vector Rect2D -> io ()
Vk.cmdSetScissorWithCount CommandBuffer
cb Vector Rect2D
scissors
DynamicState
Vk.DYNAMIC_STATE_PRIMITIVE_TOPOLOGY -> CommandBuffer -> PrimitiveTopology -> m ()
forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> PrimitiveTopology -> io ()
Vk.cmdSetPrimitiveTopology CommandBuffer
cb PrimitiveTopology
topology
DynamicState
Vk.DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE -> CommandBuffer -> Bool -> m ()
forall (io :: * -> *). MonadIO io => CommandBuffer -> Bool -> io ()
Vk.cmdSetPrimitiveRestartEnable CommandBuffer
cb Bool
primitiveRestart
DynamicState
Vk.DYNAMIC_STATE_CULL_MODE -> CommandBuffer -> CullModeFlags -> m ()
forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> CullModeFlags -> io ()
Vk.cmdSetCullMode CommandBuffer
cb CullModeFlags
cullMode
DynamicState
Vk.DYNAMIC_STATE_FRONT_FACE -> CommandBuffer -> FrontFace -> m ()
forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> FrontFace -> io ()
Vk.cmdSetFrontFace CommandBuffer
cb FrontFace
frontFace
DynamicState
Vk.DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE -> CommandBuffer -> Bool -> m ()
forall (io :: * -> *). MonadIO io => CommandBuffer -> Bool -> io ()
Vk.cmdSetRasterizerDiscardEnable CommandBuffer
cb Bool
rasterizerDiscard
DynamicState
Vk.DYNAMIC_STATE_LINE_WIDTH -> CommandBuffer -> Float -> m ()
forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> Float -> io ()
Vk.cmdSetLineWidth CommandBuffer
cb Float
lineWidth
DynamicState
Vk.DYNAMIC_STATE_DEPTH_BIAS_ENABLE -> CommandBuffer -> Bool -> m ()
forall (io :: * -> *). MonadIO io => CommandBuffer -> Bool -> io ()
Vk.cmdSetDepthBiasEnable CommandBuffer
cb Bool
depthBiasEnable
DynamicState
Vk.DYNAMIC_STATE_DEPTH_BIAS -> CommandBuffer -> Float -> Float -> Float -> m ()
forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> Float -> Float -> Float -> io ()
Vk.cmdSetDepthBias CommandBuffer
cb Float
biasConstant Float
biasClamp Float
biasSlope
DynamicState
Vk.DYNAMIC_STATE_DEPTH_TEST_ENABLE -> CommandBuffer -> Bool -> m ()
forall (io :: * -> *). MonadIO io => CommandBuffer -> Bool -> io ()
Vk.cmdSetDepthTestEnable CommandBuffer
cb Bool
depthTest
DynamicState
Vk.DYNAMIC_STATE_DEPTH_WRITE_ENABLE -> CommandBuffer -> Bool -> m ()
forall (io :: * -> *). MonadIO io => CommandBuffer -> Bool -> io ()
Vk.cmdSetDepthWriteEnable CommandBuffer
cb Bool
depthWrite
DynamicState
Vk.DYNAMIC_STATE_DEPTH_COMPARE_OP -> CommandBuffer -> CompareOp -> m ()
forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> CompareOp -> io ()
Vk.cmdSetDepthCompareOp CommandBuffer
cb CompareOp
depthCompareOp
DynamicState
Vk.DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE -> CommandBuffer -> Bool -> m ()
forall (io :: * -> *). MonadIO io => CommandBuffer -> Bool -> io ()
Vk.cmdSetDepthBoundsTestEnable CommandBuffer
cb Bool
depthBoundsTest
DynamicState
Vk.DYNAMIC_STATE_DEPTH_BOUNDS -> CommandBuffer -> Float -> Float -> m ()
forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> Float -> Float -> io ()
Vk.cmdSetDepthBounds CommandBuffer
cb Float
minBound' Float
maxBound'
DynamicState
Vk.DYNAMIC_STATE_STENCIL_TEST_ENABLE -> CommandBuffer -> Bool -> m ()
forall (io :: * -> *). MonadIO io => CommandBuffer -> Bool -> io ()
Vk.cmdSetStencilTestEnable CommandBuffer
cb Bool
stencilTest
DynamicState
Vk.DYNAMIC_STATE_STENCIL_OP ->
CommandBuffer
-> StencilFaceFlagBits
-> StencilOp
-> StencilOp
-> StencilOp
-> CompareOp
-> m ()
forall (io :: * -> *).
MonadIO io =>
CommandBuffer
-> StencilFaceFlagBits
-> StencilOp
-> StencilOp
-> StencilOp
-> CompareOp
-> io ()
Vk.cmdSetStencilOp CommandBuffer
cb StencilFaceFlagBits
bothFaces StencilOp
stencilFailOp StencilOp
stencilPassOp StencilOp
stencilDepthFailOp CompareOp
stencilCompareOp
DynamicState
Vk.DYNAMIC_STATE_STENCIL_COMPARE_MASK -> CommandBuffer -> StencilFaceFlagBits -> Word32 -> m ()
forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> StencilFaceFlagBits -> Word32 -> io ()
Vk.cmdSetStencilCompareMask CommandBuffer
cb StencilFaceFlagBits
bothFaces Word32
stencilCompareMask
DynamicState
Vk.DYNAMIC_STATE_STENCIL_WRITE_MASK -> CommandBuffer -> StencilFaceFlagBits -> Word32 -> m ()
forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> StencilFaceFlagBits -> Word32 -> io ()
Vk.cmdSetStencilWriteMask CommandBuffer
cb StencilFaceFlagBits
bothFaces Word32
stencilWriteMask
DynamicState
Vk.DYNAMIC_STATE_STENCIL_REFERENCE -> CommandBuffer -> StencilFaceFlagBits -> Word32 -> m ()
forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> StencilFaceFlagBits -> Word32 -> io ()
Vk.cmdSetStencilReference CommandBuffer
cb StencilFaceFlagBits
bothFaces Word32
stencilReference
DynamicState
Vk.DYNAMIC_STATE_BLEND_CONSTANTS -> CommandBuffer -> (Float, Float, Float, Float) -> m ()
forall (io :: * -> *).
MonadIO io =>
CommandBuffer -> (Float, Float, Float, Float) -> io ()
Vk.cmdSetBlendConstants CommandBuffer
cb (Float, Float, Float, Float)
blendConstants
DynamicState
_ -> () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()