1
1
#include " DrawResourcesFiller.h"
2
2
3
- DrawResourcesFiller::DrawResourcesFiller (smart_refctd_ptr<IUtilities>&& utils, IQueue* copyQueue)
4
- {
5
- m_utilities = utils;
6
- m_copyQueue = copyQueue;
7
- }
3
+ DrawResourcesFiller::DrawResourcesFiller ()
4
+ {}
5
+
6
+ DrawResourcesFiller::DrawResourcesFiller (smart_refctd_ptr<IUtilities>&& utils, IQueue* copyQueue) :
7
+ m_utilities(utils),
8
+ m_copyQueue(copyQueue)
9
+ {}
8
10
9
11
// function is called when buffer is filled and we should submit draws and clear the buffers and continue filling
10
12
@@ -118,6 +120,8 @@ void DrawResourcesFiller::allocateStylesBuffer(ILogicalDevice* logicalDevice, ui
118
120
119
121
void DrawResourcesFiller::allocateMSDFTextures (ILogicalDevice* logicalDevice, uint32_t maxMSDFs)
120
122
{
123
+ textureLRUCache = TextureLRUCache (maxMSDFs);
124
+
121
125
asset::E_FORMAT msdfFormat = asset::EF_R8G8B8A8_UNORM; // @Lucas change the format to what MSDFs use
122
126
constexpr asset::VkExtent3D MSDFsExtent = { 32u , 32u , 1u }; // 32x32 images, TODO: maybe make this a paramerter
123
127
assert (maxMSDFs <= logicalDevice->getPhysicalDevice ()->getLimits ().maxImageArrayLayers );
@@ -221,7 +225,7 @@ void DrawResourcesFiller::drawHatch(
221
225
const Hatch& hatch,
222
226
const float32_t4& foregroundColor,
223
227
const float32_t4& backgroundColor,
224
- const uint32_t msdfTextureIdx ,
228
+ const texture_hash msdfTexture ,
225
229
SIntendedSubmitInfo& intendedNextSubmit)
226
230
{
227
231
// TODO[Optimization Idea]: don't draw hatch twice if both colors are visible: instead do the msdf inside the alpha resolve by detecting mainObj being a hatch
@@ -237,12 +241,23 @@ void DrawResourcesFiller::drawHatch(
237
241
void DrawResourcesFiller::drawHatch (
238
242
const Hatch& hatch,
239
243
const float32_t4& color,
240
- const uint32_t msdfTextureIdx ,
244
+ const texture_hash msdfTexture ,
241
245
SIntendedSubmitInfo& intendedNextSubmit)
242
246
{
247
+ uint32_t textureIdx = InvalidTextureIdx;
248
+ if (msdfTexture != InvalidTextureHash)
249
+ {
250
+ TextureReference* tRef = textureLRUCache.get (msdfTexture);
251
+ if (tRef)
252
+ {
253
+ textureIdx = tRef->alloc_idx ;
254
+ tRef->lastUsedSemaphoreValue = intendedNextSubmit.getScratchSemaphoreNextWait ().value ; // update this because the texture will get used on the next submit
255
+ }
256
+ }
257
+
243
258
LineStyleInfo lineStyle = {};
244
259
lineStyle.color = color;
245
- lineStyle.screenSpaceLineWidth = nbl::hlsl::bit_cast<float , uint32_t >(msdfTextureIdx );
260
+ lineStyle.screenSpaceLineWidth = nbl::hlsl::bit_cast<float , uint32_t >(textureIdx );
246
261
// @Lucas we use LineStyle struct for hatches too but we aliased a member with textureId, So you need to do asuint(lineStyle.screenSpaceLineWidth) to get you the index into msdfTextureArray
247
262
248
263
const uint32_t styleIdx = addLineStyle_SubmitIfNeeded (lineStyle, intendedNextSubmit);
@@ -264,38 +279,50 @@ void DrawResourcesFiller::drawHatch(
264
279
265
280
void DrawResourcesFiller::drawHatch (const Hatch& hatch, const float32_t4& color, SIntendedSubmitInfo& intendedNextSubmit)
266
281
{
267
- drawHatch (hatch, color, InvalidTextureIdx , intendedNextSubmit);
282
+ drawHatch (hatch, color, InvalidTextureHash , intendedNextSubmit);
268
283
}
269
284
270
- uint32_t DrawResourcesFiller::addMSDFTexture (ICPUBuffer const * srcBuffer, const asset::IImage::SBufferCopy& region, texture_hash hash)
285
+ void DrawResourcesFiller::addMSDFTexture (ICPUBuffer const * srcBuffer, const asset::IImage::SBufferCopy& region, texture_hash hash, SIntendedSubmitInfo& intendedNextSubmit )
271
286
{
272
- uint32_t ret = InvalidTextureIdx;
287
+ // TextureReferences hold the semaValue related to the "scratch semaphore" in IntendedSubmitInfo
288
+ // Every single submit increases this value by 1
289
+ // The reason for hiolding on to the lastUsedSema is deferred dealloc, which we call in the case of eviction, making sure we get rid of the entry inside the allocator only when the texture is done being used
290
+ uint64_t nextSemaValue = intendedNextSubmit.getScratchSemaphoreNextWait ().value ;
291
+ const auto * signalSema = intendedNextSubmit.getScratchSemaphoreNextWait ().semaphore ;
273
292
274
- // @Lucas TODO: Here should rely the main logic for allocating an index from our allocator and evicting based on LRU Cache if we failed
275
- /*
276
- * look into `textureIdToIndexMap` if we already have the `texture_hash` in the texture array slices (skip if hash is InvalidTextureHash)
277
- * If we found a match we return that index;
278
- * Else:
279
- * LRUIndexAllocator try allocate
280
- * Failure to Alloc Index (Auto-Submission logic):
281
- 1. evict something from LRU cache + remove entry from lookup unordered_map ->
282
- 2. dealloc with deferred (based on next submit signal val) ->
283
- 3. resetGeometryCounters(); (because geometries using previous glyphs are done rendering and should be invalidated)
284
- 4. ret = try alloc again (+ assert it should succeed because we evicted and dealloced)
285
- * Success to Alloc Index: ret = index; add entry to lookup unordered_map
286
- */
287
-
288
- // asuming allocator gave us 0 as index
289
- ret = 0u ;
290
-
291
- // We queue copy and finalize all on `finalizeTextureCopies` function called before draw calls to make sure it's in mem
292
- textureCopies.push_back ({
293
- .srcBuffer = srcBuffer,
294
- .region = region,
295
- .index = ret,
296
- });
293
+ auto evictionCallback = [&](const TextureReference& evicted)
294
+ {
295
+ // @Lucas TODO:
296
+
297
+ // Dealloc:
298
+ // allocator.multi_deallocate(1u,&evicted.alloc_idx,{signalSema,evicted.lastUsedSemaphoreValue});
299
+
300
+ // Overflow Handling:
301
+ // finalizeAllCopiesToGPU(intendedNextSubmit);
302
+ // submitDraws(intendedNextSubmit);
303
+ // resetGeometryCounters();
304
+ // resetMainObjectCounters();
305
+ };
306
+
307
+ // We pass nextSemaValue instead of constructing a new TextureReference and passing it into `insert` that's because we might get a cache hit and only update the value of the nextSema
308
+ TextureReference* inserted = textureLRUCache.insert (hash, nextSemaValue, evictionCallback);
309
+
310
+ // if inserted->alloc_idx was not InvalidTextureIdx then it means we had a cache hit and updated the value of our sema, in which case we don't queue anything for upload, and return the idx
311
+ if (inserted->alloc_idx == InvalidTextureIdx)
312
+ {
313
+ // New insertion == cache miss happened and insertion was successfull
314
+ // allocator.multi_allocate(1u,&inserted->alloc_idx);
315
+ inserted->alloc_idx = 0u ; // temp
316
+
317
+ // We queue copy and finalize all on `finalizeTextureCopies` function called before draw calls to make sure it's in mem
318
+ textureCopies.push_back ({
319
+ .srcBuffer = srcBuffer,
320
+ .region = region,
321
+ .index = inserted->alloc_idx ,
322
+ });
323
+ }
297
324
298
- return ret ;
325
+ assert (inserted-> alloc_idx != InvalidTextureIdx) ;
299
326
}
300
327
301
328
void DrawResourcesFiller::finalizeAllCopiesToGPU (SIntendedSubmitInfo& intendedNextSubmit)
0 commit comments