Skip to content

Commit 0b86356

Browse files
authored
Vulkan backend (#2)
This commit adds the Vulkan backend and SDL2 integration, and provides the `vulkan` example project.
1 parent d227561 commit 0b86356

File tree

10 files changed

+1878
-1
lines changed

10 files changed

+1878
-1
lines changed

cabal.project

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
packages: *.cabal
22
package dear-imgui
3-
flags: +sdl2 +opengl
3+
flags: +sdl2 +opengl +vulkan

dear-imgui.cabal

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ flag opengl
1111
manual:
1212
False
1313

14+
flag vulkan
15+
description:
16+
Enable Vulkan backend.
17+
default:
18+
False
19+
manual:
20+
True
21+
1422
flag sdl
1523
description:
1624
Enable SDL backend.
@@ -64,6 +72,27 @@ library
6472
extra-libraries:
6573
GL
6674

75+
if flag(vulkan)
76+
exposed-modules:
77+
DearImGui.Vulkan
78+
other-modules:
79+
DearImGui.Vulkan.Types
80+
build-depends:
81+
vulkan
82+
, unliftio
83+
cxx-sources:
84+
imgui/backends/imgui_impl_vulkan.cpp
85+
if os(windows)
86+
extra-libraries:
87+
vulkan-1
88+
else
89+
if os(darwin)
90+
extra-libraries:
91+
vulkan
92+
else
93+
pkgconfig-depends:
94+
vulkan
95+
6796
if flag(sdl)
6897
exposed-modules:
6998
DearImGui.SDL
@@ -83,6 +112,10 @@ library
83112
exposed-modules:
84113
DearImGui.SDL.OpenGL
85114

115+
if flag(vulkan)
116+
exposed-modules:
117+
DearImGui.SDL.Vulkan
118+
86119

87120
executable test
88121
main-is: Main.hs
@@ -97,3 +130,38 @@ executable readme
97130
default-language: Haskell2010
98131
build-depends: base, sdl2, gl, dear-imgui, managed
99132
ghc-options: -Wall
133+
134+
executable vulkan
135+
main-is: Main.hs
136+
other-modules: Attachments, Backend, Input, Util
137+
hs-source-dirs: examples/vulkan
138+
default-language: Haskell2010
139+
build-depends:
140+
dear-imgui
141+
, base
142+
>= 4.13 && < 4.16
143+
, bytestring
144+
>= 0.10.10.0 && < 0.12
145+
, containers
146+
^>= 0.6.2.1
147+
, logging-effect
148+
^>= 1.3.12
149+
, resourcet
150+
^>= 1.2.4.2
151+
, sdl2
152+
^>= 2.5.3.0
153+
, text-short
154+
^>= 0.1.3
155+
, transformers
156+
^>= 0.5.6.2
157+
, unliftio
158+
>= 0.2.13 && < 0.2.15
159+
, unliftio-core
160+
^>= 0.2.0.1
161+
, vector
162+
^>= 0.12.1.2
163+
, vulkan
164+
^>= 3.9
165+
, vulkan-utils
166+
^>= 0.4.1
167+
ghc-options: -Wall

examples/vulkan/Attachments.hs

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
{-# LANGUAGE BlockArguments #-}
2+
{-# LANGUAGE DataKinds #-}
3+
{-# LANGUAGE DeriveTraversable #-}
4+
{-# LANGUAGE DerivingStrategies #-}
5+
{-# LANGUAGE PatternSynonyms #-}
6+
{-# LANGUAGE RecordWildCards #-}
7+
{-# LANGUAGE ScopedTypeVariables #-}
8+
{-# LANGUAGE TypeApplications #-}
9+
10+
module Attachments where
11+
12+
-- base
13+
import Data.Word
14+
( Word32 )
15+
16+
-- vector
17+
import qualified Data.Vector as Boxed
18+
( Vector )
19+
import qualified Data.Vector as Boxed.Vector
20+
( empty )
21+
22+
-- vulkan
23+
import qualified Vulkan
24+
import qualified Vulkan.Core10.Pass as Vulkan.AttachmentReference
25+
( AttachmentReference(..) )
26+
import qualified Vulkan.Zero as Vulkan
27+
28+
-- dear-imgui
29+
import Util
30+
( iunzipWith )
31+
32+
---------------------------------------------------------------
33+
-- Attachment types and their corresponding image layouts.
34+
35+
data AttachmentAccess
36+
= ReadAttachment
37+
| ReadWriteAttachment
38+
deriving stock ( Eq, Show )
39+
40+
data DepthStencilType =
41+
DepthStencilType
42+
{ depth :: Maybe AttachmentAccess
43+
, stencil :: Maybe AttachmentAccess
44+
}
45+
deriving stock ( Eq, Show )
46+
47+
data InputAttachmentType
48+
= ColorInputAttachment
49+
| DepthInputAttachment
50+
| StencilInputAttachment
51+
| DepthStencilInputAttachment
52+
deriving stock ( Eq, Show )
53+
54+
data AttachmentType
55+
= ColorAttachment
56+
| DepthStencilAttachment DepthStencilType
57+
| InputAttachment InputAttachmentType
58+
deriving stock ( Eq, Show )
59+
60+
data AttachmentUsage
61+
= UseAttachment
62+
| PreserveAttachment
63+
| ResolveAttachment
64+
deriving stock ( Eq, Show )
65+
66+
67+
depthStencilAttachmentLayout :: DepthStencilType -> Vulkan.ImageLayout
68+
depthStencilAttachmentLayout
69+
( DepthStencilType Nothing Nothing )
70+
= Vulkan.IMAGE_LAYOUT_GENERAL
71+
depthStencilAttachmentLayout
72+
( DepthStencilType (Just ReadAttachment) Nothing )
73+
= Vulkan.IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR
74+
depthStencilAttachmentLayout
75+
( DepthStencilType (Just ReadWriteAttachment) Nothing )
76+
= Vulkan.IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR
77+
depthStencilAttachmentLayout
78+
( DepthStencilType Nothing (Just ReadAttachment) )
79+
= Vulkan.IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR
80+
depthStencilAttachmentLayout
81+
( DepthStencilType Nothing (Just ReadWriteAttachment) )
82+
= Vulkan.IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR
83+
depthStencilAttachmentLayout
84+
( DepthStencilType (Just ReadAttachment) (Just ReadAttachment) )
85+
= Vulkan.IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
86+
depthStencilAttachmentLayout
87+
( DepthStencilType (Just ReadWriteAttachment) (Just ReadAttachment) )
88+
= Vulkan.IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR
89+
depthStencilAttachmentLayout
90+
( DepthStencilType (Just ReadAttachment) (Just ReadWriteAttachment) )
91+
= Vulkan.IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR
92+
depthStencilAttachmentLayout
93+
( DepthStencilType (Just ReadWriteAttachment) (Just ReadWriteAttachment) )
94+
= Vulkan.IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
95+
96+
97+
inputAttachmentLayout :: InputAttachmentType -> Vulkan.ImageLayout
98+
inputAttachmentLayout ColorInputAttachment
99+
= Vulkan.IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
100+
inputAttachmentLayout DepthInputAttachment
101+
= depthStencilAttachmentLayout ( DepthStencilType (Just ReadAttachment) Nothing )
102+
inputAttachmentLayout StencilInputAttachment
103+
= depthStencilAttachmentLayout ( DepthStencilType Nothing (Just ReadAttachment) )
104+
inputAttachmentLayout DepthStencilInputAttachment
105+
= depthStencilAttachmentLayout ( DepthStencilType (Just ReadAttachment) (Just ReadAttachment) )
106+
107+
attachmentLayout :: AttachmentType -> Vulkan.ImageLayout
108+
attachmentLayout ColorAttachment
109+
= Vulkan.IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
110+
attachmentLayout (DepthStencilAttachment depthStencilType)
111+
= depthStencilAttachmentLayout depthStencilType
112+
attachmentLayout (InputAttachment inputAttachmentType)
113+
= inputAttachmentLayout inputAttachmentType
114+
115+
---------------------------------------------------------------
116+
-- Some simple attachment descriptions, for convenience.
117+
118+
presentableColorAttachmentDescription :: Vulkan.Format -> ( Vulkan.AttachmentDescription, AttachmentType )
119+
presentableColorAttachmentDescription colorFormat =
120+
( description, ColorAttachment )
121+
where
122+
description =
123+
Vulkan.AttachmentDescription
124+
{ flags = Vulkan.zero
125+
, format = colorFormat
126+
, samples = Vulkan.SAMPLE_COUNT_1_BIT
127+
, loadOp = Vulkan.ATTACHMENT_LOAD_OP_CLEAR
128+
, storeOp = Vulkan.ATTACHMENT_STORE_OP_STORE
129+
, stencilLoadOp = Vulkan.ATTACHMENT_LOAD_OP_DONT_CARE
130+
, stencilStoreOp = Vulkan.ATTACHMENT_STORE_OP_DONT_CARE
131+
, initialLayout = Vulkan.IMAGE_LAYOUT_UNDEFINED
132+
, finalLayout = Vulkan.IMAGE_LAYOUT_PRESENT_SRC_KHR
133+
}
134+
135+
136+
depthAttachmentDescription :: Vulkan.Format -> ( Vulkan.AttachmentDescription, AttachmentType )
137+
depthAttachmentDescription depthFormat =
138+
( description, DepthStencilAttachment ( DepthStencilType (Just ReadWriteAttachment) Nothing ) )
139+
where
140+
description =
141+
Vulkan.AttachmentDescription
142+
{ flags = Vulkan.zero
143+
, format = depthFormat
144+
, samples = Vulkan.SAMPLE_COUNT_1_BIT
145+
, loadOp = Vulkan.ATTACHMENT_LOAD_OP_CLEAR
146+
, storeOp = Vulkan.ATTACHMENT_STORE_OP_STORE
147+
, stencilLoadOp = Vulkan.ATTACHMENT_LOAD_OP_DONT_CARE
148+
, stencilStoreOp = Vulkan.ATTACHMENT_STORE_OP_DONT_CARE
149+
, initialLayout = Vulkan.IMAGE_LAYOUT_UNDEFINED
150+
, finalLayout = Vulkan.IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
151+
}
152+
153+
msDepthAttachmentDescription
154+
:: Vulkan.SampleCountFlagBits
155+
-> Vulkan.Format
156+
-> ( Vulkan.AttachmentDescription, AttachmentType )
157+
msDepthAttachmentDescription samples depthFormat =
158+
( description, DepthStencilAttachment ( DepthStencilType (Just ReadWriteAttachment) Nothing ) )
159+
where
160+
description =
161+
Vulkan.AttachmentDescription
162+
{ flags = Vulkan.zero
163+
, format = depthFormat
164+
, samples = samples
165+
, loadOp = Vulkan.ATTACHMENT_LOAD_OP_CLEAR
166+
, storeOp = Vulkan.ATTACHMENT_STORE_OP_STORE
167+
, stencilLoadOp = Vulkan.ATTACHMENT_LOAD_OP_DONT_CARE
168+
, stencilStoreOp = Vulkan.ATTACHMENT_STORE_OP_DONT_CARE
169+
, initialLayout = Vulkan.IMAGE_LAYOUT_UNDEFINED
170+
, finalLayout = Vulkan.IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
171+
}
172+
173+
msColorAttachmentDescription
174+
:: Vulkan.SampleCountFlagBits
175+
-> Vulkan.Format
176+
-> ( Vulkan.AttachmentDescription, AttachmentType )
177+
msColorAttachmentDescription samples colorFormat =
178+
( description, ColorAttachment )
179+
where
180+
description =
181+
Vulkan.AttachmentDescription
182+
{ flags = Vulkan.zero
183+
, format = colorFormat
184+
, samples = samples
185+
, loadOp = Vulkan.ATTACHMENT_LOAD_OP_CLEAR
186+
, storeOp = Vulkan.ATTACHMENT_STORE_OP_STORE
187+
, stencilLoadOp = Vulkan.ATTACHMENT_LOAD_OP_DONT_CARE
188+
, stencilStoreOp = Vulkan.ATTACHMENT_STORE_OP_DONT_CARE
189+
, initialLayout = Vulkan.IMAGE_LAYOUT_UNDEFINED
190+
, finalLayout = Vulkan.IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
191+
}
192+
193+
---------------------------------------------------------------
194+
-- Set the attachments in a subpass.
195+
196+
data SubpassAttachments a
197+
= SubpassAttachments
198+
{ colorAttachments :: Boxed.Vector a
199+
, mbDepthStencilAttachment :: Maybe a
200+
, inputAttachments :: Boxed.Vector a
201+
, preserveAttachments :: Boxed.Vector a
202+
, resolveAttachments :: Boxed.Vector a
203+
} deriving stock ( Functor, Foldable, Traversable )
204+
205+
type SubpassAttachmentReferences = SubpassAttachments Vulkan.AttachmentReference
206+
207+
208+
noAttachments :: SubpassAttachments a
209+
noAttachments =
210+
SubpassAttachments
211+
Boxed.Vector.empty
212+
Nothing
213+
Boxed.Vector.empty
214+
Boxed.Vector.empty
215+
Boxed.Vector.empty
216+
217+
218+
createSubpass
219+
:: SubpassAttachmentReferences
220+
-> Vulkan.SubpassDescription
221+
createSubpass SubpassAttachments { .. } =
222+
Vulkan.SubpassDescription
223+
{ flags = Vulkan.zero
224+
, colorAttachments = colorAttachments
225+
, pipelineBindPoint = Vulkan.PIPELINE_BIND_POINT_GRAPHICS
226+
, depthStencilAttachment = mbDepthStencilAttachment
227+
, inputAttachments = inputAttachments
228+
, preserveAttachments = fmap Vulkan.AttachmentReference.attachment preserveAttachments
229+
, resolveAttachments = resolveAttachments
230+
}
231+
232+
attachmentReference :: Word32 -> AttachmentType -> Vulkan.AttachmentReference
233+
attachmentReference attachmentNumber attachmentType =
234+
Vulkan.AttachmentReference
235+
{ attachment = attachmentNumber
236+
, layout = attachmentLayout attachmentType
237+
}
238+
239+
attachmentReferencesAndDescriptions
240+
:: forall t. Traversable t
241+
=> t ( Vulkan.AttachmentDescription, AttachmentType )
242+
-> ( t Vulkan.AttachmentReference, [ Vulkan.AttachmentDescription ] )
243+
attachmentReferencesAndDescriptions =
244+
iunzipWith
245+
( \ i -> attachmentReference i . snd )
246+
( const fst )

0 commit comments

Comments
 (0)