Skip to content

Commit acbb0df

Browse files
authored
Merge pull request #6 from walseb/storage-buffers
Added initial storage buffer support
2 parents 0b27f31 + ef4fbb7 commit acbb0df

File tree

16 files changed

+185
-126
lines changed

16 files changed

+185
-126
lines changed

ghengin-core/ghengin-core-indep/Ghengin/Core/Shader/Data.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ class Block ty => ShaderData ty where
3333

3434
-- | The primitive FIR shader type whose memory representation matches the result
3535
-- of serializing this datatype using 'Poke'. This is the promise that if
36-
-- your shader expects @FirType ty@ in a uniform location, writing @ty@ into the
37-
-- buffer will be sound, and the shader will find @ty@'s laid out in memory
38-
-- according to @FirType ty@'s expected memory layout.
36+
-- your shader expects @FirType ty@ in a uniform/storage location, writing @ty@
37+
-- into the buffer will be sound, and the shader will find @ty@'s laid out
38+
-- in memory according to @FirType ty@'s expected memory layout.
3939
--
4040
-- === _Example_
4141
--

ghengin-core/ghengin-core-indep/Ghengin/Core/Type/Compatible.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ type family DSetBinding (set :: Nat) (binding :: Nat) (info :: PipelineInfo) ::
172172
type family DSetBinding' (set :: Nat) (binding :: Nat) (info :: PipelineInfo) :: Type where
173173
DSetBinding' set binding info =
174174
FromMaybe (DSetBinding set binding info)
175-
(TypeError (Text "Uniform [Descriptor Set #" :<>: ShowType set :<>: Text ", Binding #" :<>: ShowType binding :<>: Text "] not found in " :<>: ShowType info))
175+
(TypeError (Text "Descriptor [Descriptor Set #" :<>: ShowType set :<>: Text ", Binding #" :<>: ShowType binding :<>: Text "] not found in " :<>: ShowType info))
176176

177177
type family FindDSetInput (set :: Nat) (binding :: Nat) (inputs :: [TLInterfaceVariable]) :: Maybe Type where
178178
FindDSetInput set binding '[] = 'Nothing

ghengin-core/ghengin-core.cabal

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ library backend-independent-bits
180180
-- TODO: NOT DEPEND ON VULKAN IN CORE INDEP
181181
vulkan,
182182
linear-base,
183-
reference-counting,
183+
reference-counting >= 0.2.0.0,
184184

185185
template-haskell,
186186
containers,
@@ -237,7 +237,7 @@ library vulkan
237237
vulkan,
238238
GLFW-b,
239239
linear-base,
240-
reference-counting,
240+
reference-counting >= 0.2.0.0,
241241
-- ghengin-core MISTAKE!(#23322, could we depend on ghengin-core for non-indefinite modules only?)
242242
ghengin-core:backend-independent-bits,
243243
gl-block,

ghengin-core/ghengin-core/Ghengin/Core/Material.hs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import Ghengin.Core.Render.Pipeline ( RenderPipeline(..) )
1313
import Ghengin.Core.Renderer.Kernel
1414
import Ghengin.Core.Renderer.DescriptorSet
1515

16+
import qualified Data.IntMap.Strict as IM
17+
1618
import qualified Data.Linear.Alias as Alias
1719

1820
{-
@@ -100,7 +102,7 @@ instance HasProperties Material where
100102
material :: α π β. CompatibleMaterial α π
101103
=> PropertyBindings α RenderPipeline π β Renderer (Material α, RenderPipeline π β)
102104
material props0 (RenderProperty pr rps) = material props0 rps >>= \case (m, rp) -> pure (m, RenderProperty pr rp)
103-
material props0 (RenderPipeline gpip rpass (rdset, rres, dpool0) shaders uq) = Linear.do
105+
material props0 (RenderPipeline gpip rpass (rdset, rres, (Ur bmap), dpool0) shaders uq) = Linear.do
104106

105107
-- Make the unique identifier for this material
106108
Ur uniq <- liftSystemIOU newUnique
@@ -112,7 +114,7 @@ material props0 (RenderPipeline gpip rpass (rdset, rres, dpool0) shaders uq) = L
112114

113115
-- Make the resource map for this material
114116
-- Will also count texture references
115-
(resources0, props1) <- makeResources props0
117+
(resources0, props1) <- makeResources (fromMaybe (error "DescriptorSetMap doesn't contain material descriptors.") (IM.lookup 1 bmap)) props0
116118

117119
-- Create the descriptor set with the written descriptors based on the
118120
-- created resource map
@@ -125,7 +127,7 @@ material props0 (RenderPipeline gpip rpass (rdset, rres, dpool0) shaders uq) = L
125127
-- updated information.
126128
pure
127129
( mkMat (Done (dset2, resources2, Ur uniq)) props1
128-
, RenderPipeline gpip rpass (rdset, rres, dpool3) shaders uq
130+
, RenderPipeline gpip rpass (rdset, rres, (Ur bmap), dpool3) shaders uq
129131
)
130132
where
131133
mkMat :: b. Material '[] PropertyBindings b Material b

ghengin-core/ghengin-core/Ghengin/Core/Mesh.hs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import Ghengin.Core.Renderer.DescriptorSet
3636
import Ghengin.Core.Log
3737
import Ghengin.Core.Type.Utils (Some(..))
3838

39+
import qualified Data.IntMap.Strict as IM
40+
3941
import qualified Data.Linear.Alias as Alias
4042

4143
{-
@@ -128,14 +130,14 @@ createMesh :: (CompatibleMesh props π, CompatibleVertex ts π, Storable (Vertex
128130
-- ^ Vertices
129131
-> Renderer (Mesh ts props, RenderPipeline π bs)
130132
createMesh (RenderProperty pr rps) props0 vs = createMesh rps props0 vs >>= \case (m, rp) -> pure (m, RenderProperty pr rp)
131-
createMesh (RenderPipeline gpip rpass (rdset, rres, dpool0) shaders uq) props0 (SV.fromList -> vs) = enterD "createMesh" Linear.do
133+
createMesh (RenderPipeline gpip rpass (rdset, rres, (Ur bmap), dpool0) shaders uq) props0 (SV.fromList -> vs) = enterD "createMesh" Linear.do
132134
Ur uniq <- liftSystemIOU newUnique
133135
vertexBuffer <- createVertexBuffer vs
134136

135-
(dset0, rmap0, dpool1, props1) <- allocateDescriptorsForMeshes dpool0 props0
137+
(dset0, rmap0, dpool1, props1) <- allocateDescriptorsForMeshes bmap dpool0 props0
136138

137139
pure ( mkMesh (SimpleMesh vertexBuffer (dset0, rmap0) uniq) props1
138-
, RenderPipeline gpip rpass (rdset, rres, dpool1) shaders uq
140+
, RenderPipeline gpip rpass (rdset, rres, (Ur bmap), dpool1) shaders uq
139141
)
140142

141143
-- | Like 'createMesh', but create the mesh using a vertex buffer created from
@@ -149,23 +151,23 @@ createMeshWithIxs :: HasCallStack => (CompatibleMesh props π, CompatibleVertex
149151
-- ^ Indices
150152
-> Renderer (Mesh ts props, RenderPipeline π bs)
151153
createMeshWithIxs (RenderProperty pr rps) props0 vs ixs = createMeshWithIxs rps props0 vs ixs >>= \case (m, rp) -> pure (m, RenderProperty pr rp)
152-
createMeshWithIxs (RenderPipeline gpip rpass (rdset, rres, dpool0) shaders uq) props0 (SV.fromList -> vertices) (SV.fromList -> ixs) = enterD "createMeshWithIxs" Linear.do
154+
createMeshWithIxs (RenderPipeline gpip rpass (rdset, rres, (Ur bmap), dpool0) shaders uq) props0 (SV.fromList -> vertices) (SV.fromList -> ixs) = enterD "createMeshWithIxs" Linear.do
153155
Ur uniq <- liftSystemIOU newUnique
154156
vertexBuffer <- createVertexBuffer vertices
155157
indexBuffer <- createIndex32Buffer ixs
156158

157-
(dset0, rmap0, dpool1, props1) <- allocateDescriptorsForMeshes dpool0 props0
159+
(dset0, rmap0, dpool1, props1) <- allocateDescriptorsForMeshes bmap dpool0 props0
158160

159161
pure ( mkMesh (IndexedMesh vertexBuffer indexBuffer (dset0, rmap0) uniq) props1
160-
, RenderPipeline gpip rpass (rdset, rres, dpool1) shaders uq
162+
, RenderPipeline gpip rpass (rdset, rres, (Ur bmap), dpool1) shaders uq
161163
)
162164

163165
mkMesh :: t b. Mesh t '[] PropertyBindings b Mesh t b
164166
mkMesh x GHNil = x
165167
mkMesh x (p :## pl) = MeshProperty p (mkMesh x pl)
166168

167-
allocateDescriptorsForMeshes :: Alias DescriptorPool PropertyBindings props Renderer (Alias DescriptorSet, Alias ResourceMap, Alias DescriptorPool, PropertyBindings props)
168-
allocateDescriptorsForMeshes dpool0 props0 = Linear.do
169+
allocateDescriptorsForMeshes :: DescriptorSetMap -> Alias DescriptorPool PropertyBindings props Renderer (Alias DescriptorSet, Alias ResourceMap, Alias DescriptorPool, PropertyBindings props)
170+
allocateDescriptorsForMeshes bmap dpool0 props0 = Linear.do
169171
-- Mostly just the same as in 'material' in Ghengin.Core.Material
170172

171173
logT "Allocating descriptor set"
@@ -175,7 +177,7 @@ allocateDescriptorsForMeshes dpool0 props0 = Linear.do
175177

176178
logT "Allocating resource map"
177179
-- Make the resource map for this material
178-
(resources0, props1) <- makeResources props0
180+
(resources0, props1) <- makeResources (fromMaybe (error "DescriptorSetMap doesn't contain mesh descriptors.") (IM.lookup 2 bmap)) props0
179181

180182
logT "Updating descriptor with resources"
181183
-- Create the descriptor set with the written descriptors based on the created resource map

ghengin-core/ghengin-core/Ghengin/Core/Render.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ import qualified Data.Linear.Alias as Alias
2828

2929
-- I don't know where exactly to put this, so put it here for now
3030
getDescriptorResource :: ResourceMap Int -> Renderer (DescriptorResource, ResourceMap)
31-
getDescriptorResource resourcemap i = enterD "getUniformBuffer" $
31+
getDescriptorResource resourcemap i = enterD "getDescriptorResource" $
3232
IM.lookupM i resourcemap >>= \case
3333
(Just x, rmap1) -> pure (x, rmap1)
3434
(Nothing, rmap1) -> Linear.do
3535
Alias.forget rmap1
36-
error $ "Expecting a uniform descriptor resource at binding " <> show i <> " but found nothing!"
36+
error $ "Expecting a descriptor resource at binding " <> show i <> " but found nothing!"
37+

ghengin-core/ghengin-core/Ghengin/Core/Render/Pipeline.hs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ import qualified FIR.Pipeline
4040

4141
import qualified Data.Linear.Alias as Alias
4242

43+
import qualified Data.IntMap.Strict as IM
44+
4345
import Ghengin.Core.Render.Property
4446
import Ghengin.Core.Shader.Pipeline ( ShaderPipeline )
4547
import Data.Unique
@@ -58,7 +60,7 @@ data RenderPipeline info tys where
5860

5961
RenderPipeline :: RendererPipeline Graphics -- ^ The graphics pipeline underlying this render pipeline. Can a graphics pipeline be shared amongst Render Pipelines such that this field needs to be ref counted?
6062
Alias RenderPass -- ^ A reference counted reference to a render pass, since we might share render passes amongst pipelines
61-
(Alias DescriptorSet, Alias ResourceMap, Alias DescriptorPool) -- A descriptor set per frame; currently we are screwing up drawing multiple frames. Descriptor Set for the render properties.
63+
(Alias DescriptorSet, Alias ResourceMap, Ur DescriptorSetMap, Alias DescriptorPool) -- A descriptor set per frame; currently we are screwing up drawing multiple frames. Descriptor Set for the render properties.
6264
ShaderPipeline info
6365
-> Unique
6466
-> RenderPipeline info '[]
@@ -77,9 +79,9 @@ data SomePipeline = ∀ α β. SomePipeline (RenderPipeline α β)
7779
-- Shader pipeline and buffers are only be created once and reused across
7880
-- render packets that use the same one (Note that render packets store
7981
-- references to these things).
80-
-- TODO: Currently we assume all our descriptor sets are Uniform buffers and
81-
-- our buffers too but eventually Uniform will be just a constructor of a more
82-
-- general Buffer and we should select the correct type of buffer individually.
82+
-- TODO: Currently we assume all our descriptor sets are Uniform or Storage buffers
83+
-- and our buffers too but eventually Uniform & Storage will be just a constructor of
84+
-- a more general Buffer and we should select the correct type of buffer individually.
8385
makeRenderPipeline :: forall τ info tops descs strides
8486
. ( PipelineConstraints info tops descs strides
8587
, CompatiblePipeline τ info
@@ -105,7 +107,7 @@ makeRenderPipelineWith gps renderPass shaderPipeline props0 = Linear.do
105107
-- Create the descriptor sets and graphics pipeline based on the shader
106108
-- pipeline
107109
--
108-
-- (1) Create the uniform buffers and the mapped memory
110+
-- (1) Create the uniform/storage buffers and the mapped memory
109111
-- (2) Create the descriptor sets from the descriptor set layout
110112
-- (3) Update the descriptor sets with the buffers information
111113
--
@@ -122,8 +124,10 @@ makeRenderPipelineWith gps renderPass shaderPipeline props0 = Linear.do
122124
-- properties.
123125
-- Each Material and Mesh then allocates additional descriptor sets from this pool on creation.
124126

127+
(Ur descSetMap) <- pure $ createDescriptorSetBindingsMap shaderPipeline
128+
125129
logT "Creating descriptor pool"
126-
dpool0 <- createDescriptorPool shaderPipeline
130+
dpool0 <- createDescriptorPool descSetMap
127131

128132
-- Allocate descriptor set #0 to be used by this render pipeline's
129133
-- render properties
@@ -135,7 +139,7 @@ makeRenderPipelineWith gps renderPass shaderPipeline props0 = Linear.do
135139

136140
-- Make the resource map for this render pipeline using the dummyRP
137141
logT "Making resources"
138-
(resources0, props1) <- makeResources props0
142+
(resources0, props1) <- makeResources ((fromMaybe (error "DescriptorSetMap doesn't contain shader pipeline descriptors.") (IM.lookup 0 descSetMap))) props0
139143

140144
-- Bind resources to descriptor set
141145
logT "Updating descriptor set"
@@ -161,7 +165,7 @@ makeRenderPipelineWith gps renderPass shaderPipeline props0 = Linear.do
161165
-- Make the unique identifier for this pipeline reference
162166
Ur uniq <- liftSystemIOU newUnique
163167

164-
pure $ mkRP (RenderPipeline pipeline renderPass (dset2, resources2, dpool5) shaderPipeline uniq) props1
168+
pure $ mkRP (RenderPipeline pipeline renderPass (dset2, resources2, (Ur descSetMap), dpool5) shaderPipeline uniq) props1
165169
where
166170
mkRP :: info (b :: [Type]). RenderPipeline info '[] PropertyBindings b RenderPipeline info b
167171
mkRP x GHNil = x
@@ -182,9 +186,9 @@ instance HasProperties (RenderPipeline π) where
182186

183187
descriptors :: RenderPipeline π α Renderer (Alias DescriptorSet, Alias ResourceMap, RenderPipeline π α)
184188
descriptors = \case
185-
RenderPipeline gpip rpass (dset0, rmap0, dpool) spip uq -> Linear.do
189+
RenderPipeline gpip rpass (dset0, rmap0, dmap, dpool) spip uq -> Linear.do
186190
((dset1, rmap1), (dset2, rmap2)) <- Alias.share (dset0, rmap0)
187-
pure (dset1, rmap1, RenderPipeline gpip rpass (dset2, rmap2, dpool) spip uq)
191+
pure (dset1, rmap1, RenderPipeline gpip rpass (dset2, rmap2, dmap, dpool) spip uq)
188192
RenderProperty p xs -> Linear.do
189193
(dset, rmap, mat') <- descriptors xs
190194
pure (dset, rmap, RenderProperty p mat')
@@ -197,7 +201,7 @@ destroyRenderPipeline :: RenderPipeline α τ ⊸ Renderer ()
197201
destroyRenderPipeline (RenderProperty b rp) = enterD "Destroying render pipeline" Linear.do
198202
Alias.forget b
199203
destroyRenderPipeline rp
200-
destroyRenderPipeline (RenderPipeline gp rp (a,b,c) _ _) = enterD "Destroying render pipeline" Linear.do
204+
destroyRenderPipeline (RenderPipeline gp rp (a,b,(Ur _),c) _ _) = enterD "Destroying render pipeline" Linear.do
201205
Alias.forget a >> Alias.forget b >> Alias.forget c
202206
Alias.forget rp
203207
destroyPipeline gp

0 commit comments

Comments
 (0)