mirror of
https://github.com/Drezil/dear-imgui.hs.git
synced 2024-12-27 06:56:35 +00:00
0b86356a49
This commit adds the Vulkan backend and SDL2 integration, and provides the `vulkan` example project.
247 lines
8.8 KiB
Haskell
247 lines
8.8 KiB
Haskell
{-# LANGUAGE BlockArguments #-}
|
|
{-# LANGUAGE DataKinds #-}
|
|
{-# LANGUAGE DeriveTraversable #-}
|
|
{-# LANGUAGE DerivingStrategies #-}
|
|
{-# LANGUAGE PatternSynonyms #-}
|
|
{-# LANGUAGE RecordWildCards #-}
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
|
{-# LANGUAGE TypeApplications #-}
|
|
|
|
module Attachments where
|
|
|
|
-- base
|
|
import Data.Word
|
|
( Word32 )
|
|
|
|
-- vector
|
|
import qualified Data.Vector as Boxed
|
|
( Vector )
|
|
import qualified Data.Vector as Boxed.Vector
|
|
( empty )
|
|
|
|
-- vulkan
|
|
import qualified Vulkan
|
|
import qualified Vulkan.Core10.Pass as Vulkan.AttachmentReference
|
|
( AttachmentReference(..) )
|
|
import qualified Vulkan.Zero as Vulkan
|
|
|
|
-- dear-imgui
|
|
import Util
|
|
( iunzipWith )
|
|
|
|
---------------------------------------------------------------
|
|
-- Attachment types and their corresponding image layouts.
|
|
|
|
data AttachmentAccess
|
|
= ReadAttachment
|
|
| ReadWriteAttachment
|
|
deriving stock ( Eq, Show )
|
|
|
|
data DepthStencilType =
|
|
DepthStencilType
|
|
{ depth :: Maybe AttachmentAccess
|
|
, stencil :: Maybe AttachmentAccess
|
|
}
|
|
deriving stock ( Eq, Show )
|
|
|
|
data InputAttachmentType
|
|
= ColorInputAttachment
|
|
| DepthInputAttachment
|
|
| StencilInputAttachment
|
|
| DepthStencilInputAttachment
|
|
deriving stock ( Eq, Show )
|
|
|
|
data AttachmentType
|
|
= ColorAttachment
|
|
| DepthStencilAttachment DepthStencilType
|
|
| InputAttachment InputAttachmentType
|
|
deriving stock ( Eq, Show )
|
|
|
|
data AttachmentUsage
|
|
= UseAttachment
|
|
| PreserveAttachment
|
|
| ResolveAttachment
|
|
deriving stock ( Eq, Show )
|
|
|
|
|
|
depthStencilAttachmentLayout :: DepthStencilType -> Vulkan.ImageLayout
|
|
depthStencilAttachmentLayout
|
|
( DepthStencilType Nothing Nothing )
|
|
= Vulkan.IMAGE_LAYOUT_GENERAL
|
|
depthStencilAttachmentLayout
|
|
( DepthStencilType (Just ReadAttachment) Nothing )
|
|
= Vulkan.IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR
|
|
depthStencilAttachmentLayout
|
|
( DepthStencilType (Just ReadWriteAttachment) Nothing )
|
|
= Vulkan.IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR
|
|
depthStencilAttachmentLayout
|
|
( DepthStencilType Nothing (Just ReadAttachment) )
|
|
= Vulkan.IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR
|
|
depthStencilAttachmentLayout
|
|
( DepthStencilType Nothing (Just ReadWriteAttachment) )
|
|
= Vulkan.IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR
|
|
depthStencilAttachmentLayout
|
|
( DepthStencilType (Just ReadAttachment) (Just ReadAttachment) )
|
|
= Vulkan.IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
|
|
depthStencilAttachmentLayout
|
|
( DepthStencilType (Just ReadWriteAttachment) (Just ReadAttachment) )
|
|
= Vulkan.IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR
|
|
depthStencilAttachmentLayout
|
|
( DepthStencilType (Just ReadAttachment) (Just ReadWriteAttachment) )
|
|
= Vulkan.IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR
|
|
depthStencilAttachmentLayout
|
|
( DepthStencilType (Just ReadWriteAttachment) (Just ReadWriteAttachment) )
|
|
= Vulkan.IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
|
|
|
|
|
|
inputAttachmentLayout :: InputAttachmentType -> Vulkan.ImageLayout
|
|
inputAttachmentLayout ColorInputAttachment
|
|
= Vulkan.IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
|
|
inputAttachmentLayout DepthInputAttachment
|
|
= depthStencilAttachmentLayout ( DepthStencilType (Just ReadAttachment) Nothing )
|
|
inputAttachmentLayout StencilInputAttachment
|
|
= depthStencilAttachmentLayout ( DepthStencilType Nothing (Just ReadAttachment) )
|
|
inputAttachmentLayout DepthStencilInputAttachment
|
|
= depthStencilAttachmentLayout ( DepthStencilType (Just ReadAttachment) (Just ReadAttachment) )
|
|
|
|
attachmentLayout :: AttachmentType -> Vulkan.ImageLayout
|
|
attachmentLayout ColorAttachment
|
|
= Vulkan.IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
|
attachmentLayout (DepthStencilAttachment depthStencilType)
|
|
= depthStencilAttachmentLayout depthStencilType
|
|
attachmentLayout (InputAttachment inputAttachmentType)
|
|
= inputAttachmentLayout inputAttachmentType
|
|
|
|
---------------------------------------------------------------
|
|
-- Some simple attachment descriptions, for convenience.
|
|
|
|
presentableColorAttachmentDescription :: Vulkan.Format -> ( Vulkan.AttachmentDescription, AttachmentType )
|
|
presentableColorAttachmentDescription colorFormat =
|
|
( description, ColorAttachment )
|
|
where
|
|
description =
|
|
Vulkan.AttachmentDescription
|
|
{ flags = Vulkan.zero
|
|
, format = colorFormat
|
|
, samples = Vulkan.SAMPLE_COUNT_1_BIT
|
|
, loadOp = Vulkan.ATTACHMENT_LOAD_OP_CLEAR
|
|
, storeOp = Vulkan.ATTACHMENT_STORE_OP_STORE
|
|
, stencilLoadOp = Vulkan.ATTACHMENT_LOAD_OP_DONT_CARE
|
|
, stencilStoreOp = Vulkan.ATTACHMENT_STORE_OP_DONT_CARE
|
|
, initialLayout = Vulkan.IMAGE_LAYOUT_UNDEFINED
|
|
, finalLayout = Vulkan.IMAGE_LAYOUT_PRESENT_SRC_KHR
|
|
}
|
|
|
|
|
|
depthAttachmentDescription :: Vulkan.Format -> ( Vulkan.AttachmentDescription, AttachmentType )
|
|
depthAttachmentDescription depthFormat =
|
|
( description, DepthStencilAttachment ( DepthStencilType (Just ReadWriteAttachment) Nothing ) )
|
|
where
|
|
description =
|
|
Vulkan.AttachmentDescription
|
|
{ flags = Vulkan.zero
|
|
, format = depthFormat
|
|
, samples = Vulkan.SAMPLE_COUNT_1_BIT
|
|
, loadOp = Vulkan.ATTACHMENT_LOAD_OP_CLEAR
|
|
, storeOp = Vulkan.ATTACHMENT_STORE_OP_STORE
|
|
, stencilLoadOp = Vulkan.ATTACHMENT_LOAD_OP_DONT_CARE
|
|
, stencilStoreOp = Vulkan.ATTACHMENT_STORE_OP_DONT_CARE
|
|
, initialLayout = Vulkan.IMAGE_LAYOUT_UNDEFINED
|
|
, finalLayout = Vulkan.IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
|
|
}
|
|
|
|
msDepthAttachmentDescription
|
|
:: Vulkan.SampleCountFlagBits
|
|
-> Vulkan.Format
|
|
-> ( Vulkan.AttachmentDescription, AttachmentType )
|
|
msDepthAttachmentDescription samples depthFormat =
|
|
( description, DepthStencilAttachment ( DepthStencilType (Just ReadWriteAttachment) Nothing ) )
|
|
where
|
|
description =
|
|
Vulkan.AttachmentDescription
|
|
{ flags = Vulkan.zero
|
|
, format = depthFormat
|
|
, samples = samples
|
|
, loadOp = Vulkan.ATTACHMENT_LOAD_OP_CLEAR
|
|
, storeOp = Vulkan.ATTACHMENT_STORE_OP_STORE
|
|
, stencilLoadOp = Vulkan.ATTACHMENT_LOAD_OP_DONT_CARE
|
|
, stencilStoreOp = Vulkan.ATTACHMENT_STORE_OP_DONT_CARE
|
|
, initialLayout = Vulkan.IMAGE_LAYOUT_UNDEFINED
|
|
, finalLayout = Vulkan.IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
|
|
}
|
|
|
|
msColorAttachmentDescription
|
|
:: Vulkan.SampleCountFlagBits
|
|
-> Vulkan.Format
|
|
-> ( Vulkan.AttachmentDescription, AttachmentType )
|
|
msColorAttachmentDescription samples colorFormat =
|
|
( description, ColorAttachment )
|
|
where
|
|
description =
|
|
Vulkan.AttachmentDescription
|
|
{ flags = Vulkan.zero
|
|
, format = colorFormat
|
|
, samples = samples
|
|
, loadOp = Vulkan.ATTACHMENT_LOAD_OP_CLEAR
|
|
, storeOp = Vulkan.ATTACHMENT_STORE_OP_STORE
|
|
, stencilLoadOp = Vulkan.ATTACHMENT_LOAD_OP_DONT_CARE
|
|
, stencilStoreOp = Vulkan.ATTACHMENT_STORE_OP_DONT_CARE
|
|
, initialLayout = Vulkan.IMAGE_LAYOUT_UNDEFINED
|
|
, finalLayout = Vulkan.IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
|
}
|
|
|
|
---------------------------------------------------------------
|
|
-- Set the attachments in a subpass.
|
|
|
|
data SubpassAttachments a
|
|
= SubpassAttachments
|
|
{ colorAttachments :: Boxed.Vector a
|
|
, mbDepthStencilAttachment :: Maybe a
|
|
, inputAttachments :: Boxed.Vector a
|
|
, preserveAttachments :: Boxed.Vector a
|
|
, resolveAttachments :: Boxed.Vector a
|
|
} deriving stock ( Functor, Foldable, Traversable )
|
|
|
|
type SubpassAttachmentReferences = SubpassAttachments Vulkan.AttachmentReference
|
|
|
|
|
|
noAttachments :: SubpassAttachments a
|
|
noAttachments =
|
|
SubpassAttachments
|
|
Boxed.Vector.empty
|
|
Nothing
|
|
Boxed.Vector.empty
|
|
Boxed.Vector.empty
|
|
Boxed.Vector.empty
|
|
|
|
|
|
createSubpass
|
|
:: SubpassAttachmentReferences
|
|
-> Vulkan.SubpassDescription
|
|
createSubpass SubpassAttachments { .. } =
|
|
Vulkan.SubpassDescription
|
|
{ flags = Vulkan.zero
|
|
, colorAttachments = colorAttachments
|
|
, pipelineBindPoint = Vulkan.PIPELINE_BIND_POINT_GRAPHICS
|
|
, depthStencilAttachment = mbDepthStencilAttachment
|
|
, inputAttachments = inputAttachments
|
|
, preserveAttachments = fmap Vulkan.AttachmentReference.attachment preserveAttachments
|
|
, resolveAttachments = resolveAttachments
|
|
}
|
|
|
|
attachmentReference :: Word32 -> AttachmentType -> Vulkan.AttachmentReference
|
|
attachmentReference attachmentNumber attachmentType =
|
|
Vulkan.AttachmentReference
|
|
{ attachment = attachmentNumber
|
|
, layout = attachmentLayout attachmentType
|
|
}
|
|
|
|
attachmentReferencesAndDescriptions
|
|
:: forall t. Traversable t
|
|
=> t ( Vulkan.AttachmentDescription, AttachmentType )
|
|
-> ( t Vulkan.AttachmentReference, [ Vulkan.AttachmentDescription ] )
|
|
attachmentReferencesAndDescriptions =
|
|
iunzipWith
|
|
( \ i -> attachmentReference i . snd )
|
|
( const fst )
|