@@ -155,55 +155,82 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
155
155
156
156
inline uint32_t getBindingCount () const { return count; }
157
157
158
- inline storage_offset_t getStorageOffset (const binding_number_t binding, uint32_t index = Invalid) const
158
+ // Returns index into the binding property arrays below (including `storageOffsets`), for the given binding number `binding`.
159
+ // Assumes `bindingNumbers` is sorted and that there are no duplicate values in it.
160
+ inline uint32_t searchForBinding (const binding_number_t binding) const
159
161
{
160
- if (index == Invalid)
161
- {
162
- index = searchForBinding (binding);
163
- if (index == Invalid)
164
- return Invalid;
165
- }
162
+ if (!bindingNumbers)
163
+ return Invalid;
166
164
167
- return (index == 0u ) ? 0u : storageOffsets[index - 1 ];
165
+ assert (storageOffsets && (count != 0u ));
166
+
167
+ auto found = std::lower_bound (bindingNumbers, bindingNumbers + count, binding, [](binding_number_t a, binding_number_t b) -> bool {return a.data < b.data ; });
168
+
169
+ if ((found >= bindingNumbers + count) || (found->data != binding.data ))
170
+ return Invalid;
171
+
172
+ const uint32_t foundIndex = found - bindingNumbers;
173
+ assert (foundIndex < count);
174
+ return foundIndex;
168
175
}
169
176
170
- inline uint32_t getDescriptorCount (const binding_number_t binding, uint32_t index = Invalid ) const
177
+ inline binding_number_t getBindingNumber (const uint32_t index) const
171
178
{
172
- if (index == Invalid)
173
- {
174
- index = searchForBinding (binding);
175
- if (index == Invalid)
176
- return Invalid;
177
- }
179
+ assert (index < count);
180
+ return bindingNumbers[index];
181
+ }
178
182
183
+ inline core::bitflag<IShader::E_SHADER_STAGE> getStageFlags (const uint32_t index) const
184
+ {
185
+ assert (index < count);
186
+ return stageFlags[index];
187
+ }
188
+
189
+ inline uint32_t getCount (const uint32_t index) const
190
+ {
191
+ assert (index < count);
179
192
return (index == 0u ) ? storageOffsets[index].data : storageOffsets[index].data - storageOffsets[index - 1 ].data ;
180
193
}
181
194
182
- inline uint32_t getTotalDescriptorCount () const { return (count == 0ull ) ? 0u : storageOffsets[count - 1 ].data ; }
195
+ inline storage_offset_t getStorageOffset (const uint32_t index) const
196
+ {
197
+ assert (index < count);
198
+ return (index == 0u ) ? 0u : storageOffsets[index - 1 ];
199
+ }
183
200
184
- // TODO(achal): I shouldn't be needing these anymore.
185
- inline const binding_number_t * getBindingNumbers () const { return bindingNumbers; }
186
- inline const storage_offset_t * getStorageOffsets () const { return storageOffsets; }
187
201
188
- // Returns index into the binding property arrays below (including `storageOffsets`), for the given binding number `binding`.
189
- // Assumes `bindingNumbers` is sorted and that there are no duplicate values in it.
190
- inline uint32_t searchForBinding (const binding_number_t binding) const
202
+ // The follwoing are merely convienience functions for one off use.
203
+ // If you already have an index (the result of `searchForBinding`) lying around use the above functions for quick lookups.
204
+
205
+ inline core::bitflag<IShader::E_SHADER_STAGE> getStageFlags (const binding_number_t binding) const
191
206
{
192
- if (!bindingNumbers)
207
+ const auto index = searchForBinding (binding);
208
+ if (index == Invalid)
193
209
return Invalid;
194
210
195
- assert (storageOffsets && (count != 0u ));
211
+ return getStageFlags (index);
212
+ }
196
213
197
- auto found = std::lower_bound (bindingNumbers, bindingNumbers + count, binding, [](binding_number_t a, binding_number_t b) -> bool {return a.data < b.data ; });
214
+ inline uint32_t getCount (const binding_number_t binding) const
215
+ {
216
+ const auto index = searchForBinding (binding);
217
+ if (index == Invalid)
218
+ return Invalid;
198
219
199
- if ((found >= bindingNumbers + count) || (found->data != binding.data ))
220
+ return getDescriptorCount (index);
221
+ }
222
+
223
+ inline storage_offset_t getStorageOffset (const binding_number_t binding) const
224
+ {
225
+ const auto index = searchForBinding (binding);
226
+ if (index == Invalid)
200
227
return Invalid;
201
228
202
- const uint32_t foundIndex = found - bindingNumbers;
203
- assert (foundIndex < count);
204
- return foundIndex;
229
+ return getStorageOffset (index);
205
230
}
206
231
232
+ inline uint32_t getTotalCount () const { return (count == 0ull ) ? 0u : storageOffsets[count - 1 ].data ; }
233
+
207
234
private:
208
235
friend class IDescriptorSetLayout ;
209
236
struct SBuildInfo
@@ -230,12 +257,23 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
230
257
sizeof (storage_offset_t ));
231
258
232
259
data = std::make_unique<uint8_t []>(requiredMemSize);
233
- dataAllocator = core::LinearAddressAllocator<uint32_t >(nullptr , 0u , 0u , 1u , requiredMemSize);
260
+ {
261
+ uint64_t offset = 0ull ;
262
+
263
+ bindingNumbers = reinterpret_cast <binding_number_t *>(data.get () + offset);
264
+ offset += count * sizeof (binding_number_t );
265
+
266
+ createFlags = reinterpret_cast <core::bitflag<typename SBinding::E_CREATE_FLAGS>*>(data.get () + offset);
267
+ offset += count * sizeof (core::bitflag<typename SBinding::E_CREATE_FLAGS>);
234
268
235
- bindingNumbers = reinterpret_cast <binding_number_t *>(data.get () + dataAllocator.alloc_addr (count * sizeof (binding_number_t ), 1u ));
236
- createFlags = reinterpret_cast <core::bitflag<typename SBinding::E_CREATE_FLAGS>*>(data.get () + dataAllocator.alloc_addr (count * sizeof (core::bitflag<typename SBinding::E_CREATE_FLAGS>), 1u ));
237
- stageFlags = reinterpret_cast <core::bitflag<IShader::E_SHADER_STAGE>*>(data.get () + dataAllocator.alloc_addr (count * sizeof (core::bitflag<IShader::E_SHADER_STAGE>), 1u ));
238
- storageOffsets = reinterpret_cast <storage_offset_t *>(data.get () + dataAllocator.alloc_addr (count * sizeof (storage_offset_t ), 1u ));
269
+ stageFlags = reinterpret_cast <core::bitflag<IShader::E_SHADER_STAGE>*>(data.get () + offset);
270
+ offset += count * sizeof (core::bitflag<IShader::E_SHADER_STAGE>);
271
+
272
+ storageOffsets = reinterpret_cast <storage_offset_t *>(data.get () + offset);
273
+ offset += count * sizeof (storage_offset_t );
274
+
275
+ assert (offset == requiredMemSize);
276
+ }
239
277
240
278
std::sort (info.begin (), info.end ());
241
279
@@ -251,6 +289,29 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
251
289
[](storage_offset_t a, storage_offset_t b) -> storage_offset_t { return storage_offset_t { a.data + b.data }; }, storage_offset_t { 0u });
252
290
}
253
291
292
+ friend class ICPUDescriptorSetLayout ;
293
+ #if 0
294
+ inline CBindingRedirect clone() const
295
+ {
296
+ CBindingRedirect result;
297
+ result.count = count;
298
+
299
+ const size_t requiredMemSize = dataAllocator.get_total_size();
300
+ assert(requiredMemSize == dataAllocator.get_allocated_size());
301
+ result.data = std::make_unique<uint8_t[]>(requiredMemSize);
302
+ result.dataAllocator = core::LinearAddressAllocator<uint32_t>(nullptr, 0u, 0u, 1u, requiredMemSize);
303
+
304
+ memcpy(result.data.get(), data.get(), requiredMemSize);
305
+
306
+ result.bindingNumbers = reinterpret_cast<binding_number_t*>(result.data.get() + result.dataAllocator.alloc_addr(result.count * sizeof(binding_number_t), 1u));
307
+ result.createFlags = reinterpret_cast<core::bitflag<typename SBinding::E_CREATE_FLAGS>*>(result.data.get() + result.dataAllocator.alloc_addr(result.count * sizeof(core::bitflag<typename SBinding::E_CREATE_FLAGS>), 1u));
308
+ result.stageFlags = reinterpret_cast<core::bitflag<IShader::E_SHADER_STAGE>*>(result.data.get() + result.dataAllocator.alloc_addr(result.count * sizeof(core::bitflag<IShader::E_SHADER_STAGE>), 1u));
309
+ result.storageOffsets = reinterpret_cast<storage_offset_t*>(result.data.get() + result.dataAllocator.alloc_addr(result.count * sizeof(storage_offset_t), 1u));
310
+
311
+ return result;
312
+ }
313
+ #endif
314
+
254
315
uint32_t count = 0u ;
255
316
256
317
binding_number_t * bindingNumbers = nullptr ;
@@ -259,7 +320,6 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
259
320
storage_offset_t * storageOffsets = nullptr ;
260
321
261
322
std::unique_ptr<uint8_t []> data = nullptr ;
262
- core::LinearAddressAllocator<uint32_t > dataAllocator;
263
323
};
264
324
265
325
// utility functions
@@ -279,26 +339,32 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
279
339
m_bindings ((_end-_begin) ? core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<SBinding>>(_end-_begin) : nullptr )
280
340
{
281
341
core::vector<CBindingRedirect::SBuildInfo> buildInfo_descriptors[asset::EDT_COUNT];
282
- core::vector<CBindingRedirect::SBuildInfo> buildInfo_samplers;
342
+ core::vector<CBindingRedirect::SBuildInfo> buildInfo_immutableSamplers;
343
+ core::vector<CBindingRedirect::SBuildInfo> buildInfo_mutableSamplers;
283
344
284
345
for (auto b = _begin; b != _end; ++b)
285
346
{
286
347
buildInfo_descriptors[b->type ].emplace_back (b->binding , b->createFlags , b->stageFlags , b->count );
287
- if (b->type == EDT_COMBINED_IMAGE_SAMPLER && b->samplers == nullptr )
288
- buildInfo_samplers.emplace_back (b->binding , b->createFlags , b->stageFlags , b->count );
348
+
349
+ if (b->type == EDT_COMBINED_IMAGE_SAMPLER)
350
+ {
351
+ if (b->samplers )
352
+ buildInfo_immutableSamplers.emplace_back (b->binding , b->createFlags , b->stageFlags , b->count );
353
+ else
354
+ buildInfo_mutableSamplers.emplace_back (b->binding , b->createFlags , b->stageFlags , b->count );
355
+ }
289
356
}
290
357
291
358
for (auto type = 0u ; type < asset::EDT_COUNT; ++type)
292
359
m_descriptorRedirects[type] = CBindingRedirect (std::move (buildInfo_descriptors[type]));
293
- m_samplerRedirects = CBindingRedirect (std::move (buildInfo_samplers));
294
360
295
- const uint32_t immutableSamplerCount = m_descriptorRedirects[EDT_COMBINED_IMAGE_SAMPLER]. getTotalDescriptorCount () - m_samplerRedirects. getTotalDescriptorCount ( );
296
- assert ( static_cast < int32_t >(immutableSamplerCount) >= 0 );
361
+ m_immutableSamplerRedirect = CBindingRedirect ( std::move (buildInfo_immutableSamplers) );
362
+ m_mutableSamplerRedirect = CBindingRedirect ( std::move (buildInfo_mutableSamplers) );
297
363
364
+ const uint32_t immutableSamplerCount = m_immutableSamplerRedirect.getTotalCount ();
298
365
m_samplers = immutableSamplerCount ? core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<core::smart_refctd_ptr<sampler_type>>>(immutableSamplerCount) : nullptr ;
299
366
300
367
size_t bndCount = _end-_begin;
301
-
302
368
size_t immSamplersOffset = 0u ;
303
369
for (size_t i = 0ull ; i < bndCount; ++i)
304
370
{
@@ -359,7 +425,7 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
359
425
360
426
for (uint32_t i = 0u ; i < bindingCount; ++i)
361
427
{
362
- const bool equal = (lhs.bindingNumbers [i].data == rhs.bindingNumbers [i].data ) && (lhs.createFlags [i].value == rhs.createFlags [i].value ) && (lhs.stageFlags [i].value == rhs.stageFlags [i].value ) && (lhs.getDescriptorCount (lhs. bindingNumbers [i], i ) == rhs.getDescriptorCount (rhs. bindingNumbers [i], i));
428
+ const bool equal = (lhs.bindingNumbers [i].data == rhs.bindingNumbers [i].data ) && (lhs.createFlags [i].value == rhs.createFlags [i].value ) && (lhs.stageFlags [i].value == rhs.stageFlags [i].value ) && (lhs.getCount (i ) == rhs.getCount ( i));
363
429
if (!equal)
364
430
return false ;
365
431
}
@@ -387,11 +453,9 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
387
453
}
388
454
}
389
455
390
- // TODO(achal): I shouldn't be needing these anymore.
391
- inline size_t getTotalMutableSamplerCount () const { return m_samplerRedirects.getTotalDescriptorCount (); }
392
- inline size_t getTotalDescriptorCount (const E_DESCRIPTOR_TYPE type) const { return m_descriptorRedirects[type].getTotalDescriptorCount (); }
393
-
394
- core::SRange<const SBinding> getBindings () const { return {m_bindings->data (), m_bindings->data ()+m_bindings->size ()}; }
456
+ // TODO(achal): I'm not sure, should I keep these around?
457
+ inline uint32_t getTotalMutableSamplerCount () const { return m_mutableSamplerRedirect.getTotalCount (); }
458
+ inline uint32_t getTotalDescriptorCount (const E_DESCRIPTOR_TYPE type) const { return m_descriptorRedirects[type].getTotalCount (); }
395
459
396
460
inline uint32_t getTotalBindingCount () const
397
461
{
@@ -403,16 +467,14 @@ class NBL_API IDescriptorSetLayout : public virtual core::IReferenceCounted
403
467
}
404
468
405
469
inline const CBindingRedirect& getDescriptorRedirect (const E_DESCRIPTOR_TYPE type) const { return m_descriptorRedirects[type]; }
406
- inline const CBindingRedirect& getSamplerRedirect () const { return m_samplerRedirects; }
407
-
408
- // TODO(achal): I shouldn't be needing these anymore.
409
- inline uint32_t getDescriptorOffset (const E_DESCRIPTOR_TYPE type, const uint32_t binding) const { return m_descriptorRedirects[type].getStorageOffset (binding).data ; }
410
- inline uint32_t getMutableSamplerOffset (const uint32_t binding) const { return m_samplerRedirects.getStorageOffset (binding).data ; }
470
+ inline const CBindingRedirect& getImmutableSamplerRedirect () const { return m_immutableSamplerRedirect; }
471
+ inline const CBindingRedirect& getMutableSamplerRedirect () const { return m_mutableSamplerRedirect; }
411
472
412
473
protected:
413
474
// Maps a binding number to a local (to descriptor set layout) offset, for a given descriptor type.
414
475
CBindingRedirect m_descriptorRedirects[asset::EDT_COUNT];
415
- CBindingRedirect m_samplerRedirects;
476
+ CBindingRedirect m_immutableSamplerRedirect;
477
+ CBindingRedirect m_mutableSamplerRedirect;
416
478
};
417
479
418
480
}
0 commit comments