Skip to content

Commit 66cabb6

Browse files
committed
resolve conflicts & merge
2 parents cc93fda + a251ec8 commit 66cabb6

File tree

3 files changed

+91
-48
lines changed

3 files changed

+91
-48
lines changed

62_CAD/DrawResourcesFiller.cpp

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
#include "DrawResourcesFiller.h"
22

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+
{}
810

911
// function is called when buffer is filled and we should submit draws and clear the buffers and continue filling
1012

@@ -118,6 +120,8 @@ void DrawResourcesFiller::allocateStylesBuffer(ILogicalDevice* logicalDevice, ui
118120

119121
void DrawResourcesFiller::allocateMSDFTextures(ILogicalDevice* logicalDevice, uint32_t maxMSDFs)
120122
{
123+
textureLRUCache = TextureLRUCache(maxMSDFs);
124+
121125
asset::E_FORMAT msdfFormat = asset::EF_R8G8B8A8_UNORM; // @Lucas change the format to what MSDFs use
122126
constexpr asset::VkExtent3D MSDFsExtent = { 32u, 32u, 1u }; // 32x32 images, TODO: maybe make this a paramerter
123127
assert(maxMSDFs <= logicalDevice->getPhysicalDevice()->getLimits().maxImageArrayLayers);
@@ -221,7 +225,7 @@ void DrawResourcesFiller::drawHatch(
221225
const Hatch& hatch,
222226
const float32_t4& foregroundColor,
223227
const float32_t4& backgroundColor,
224-
const uint32_t msdfTextureIdx,
228+
const texture_hash msdfTexture,
225229
SIntendedSubmitInfo& intendedNextSubmit)
226230
{
227231
// 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(
237241
void DrawResourcesFiller::drawHatch(
238242
const Hatch& hatch,
239243
const float32_t4& color,
240-
const uint32_t msdfTextureIdx,
244+
const texture_hash msdfTexture,
241245
SIntendedSubmitInfo& intendedNextSubmit)
242246
{
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+
243258
LineStyleInfo lineStyle = {};
244259
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);
246261
// @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
247262

248263
const uint32_t styleIdx = addLineStyle_SubmitIfNeeded(lineStyle, intendedNextSubmit);
@@ -264,38 +279,50 @@ void DrawResourcesFiller::drawHatch(
264279

265280
void DrawResourcesFiller::drawHatch(const Hatch& hatch, const float32_t4& color, SIntendedSubmitInfo& intendedNextSubmit)
266281
{
267-
drawHatch(hatch, color, InvalidTextureIdx, intendedNextSubmit);
282+
drawHatch(hatch, color, InvalidTextureHash, intendedNextSubmit);
268283
}
269284

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)
271286
{
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;
273292

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+
}
297324

298-
return ret;
325+
assert(inserted->alloc_idx != InvalidTextureIdx);
299326
}
300327

301328
void DrawResourcesFiller::finalizeAllCopiesToGPU(SIntendedSubmitInfo& intendedNextSubmit)

62_CAD/DrawResourcesFiller.h

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ struct DrawResourcesFiller
3535

3636
typedef uint32_t index_buffer_type;
3737

38-
DrawResourcesFiller() {}
38+
DrawResourcesFiller();
3939

4040
DrawResourcesFiller(smart_refctd_ptr<IUtilities>&& utils, IQueue* copyQueue);
4141

@@ -55,6 +55,12 @@ struct DrawResourcesFiller
5555
void allocateStylesBuffer(ILogicalDevice* logicalDevice, uint32_t lineStylesCount);
5656

5757
void allocateMSDFTextures(ILogicalDevice* logicalDevice, uint32_t maxMSDFs);
58+
59+
using texture_hash = uint64_t;
60+
static constexpr uint64_t InvalidTextureHash = std::numeric_limits<uint64_t>::max();
61+
62+
// ! return index to be used later in hatch fill style or text glyph object
63+
void addMSDFTexture(ICPUBuffer const* srcBuffer, const asset::IImage::SBufferCopy& region, texture_hash hash, SIntendedSubmitInfo& intendedNextSubmit);
5864

5965
//! this function fills buffers required for drawing a polyline and submits a draw through provided callback when there is not enough memory.
6066
void drawPolyline(const CPolylineBase& polyline, const LineStyleInfo& lineStyleInfo, SIntendedSubmitInfo& intendedNextSubmit);
@@ -66,14 +72,14 @@ struct DrawResourcesFiller
6672
const Hatch& hatch,
6773
const float32_t4& foregroundColor,
6874
const float32_t4& backgroundColor,
69-
const uint32_t msdfTextureIdx,
75+
const texture_hash msdfTexture,
7076
SIntendedSubmitInfo& intendedNextSubmit);
7177

7278
// ! Hatch with MSDF Pattern
7379
void drawHatch(
7480
const Hatch& hatch,
7581
const float32_t4& color,
76-
const uint32_t msdfTextureIdx,
82+
const texture_hash msdfTexture,
7783
SIntendedSubmitInfo& intendedNextSubmit);
7884

7985
// ! Solid Fill Hacth
@@ -82,12 +88,6 @@ struct DrawResourcesFiller
8288
const float32_t4& color,
8389
SIntendedSubmitInfo& intendedNextSubmit);
8490

85-
using texture_hash = uint64_t;
86-
static constexpr uint64_t InvalidTextureHash = std::numeric_limits<uint64_t>::max();
87-
88-
// ! return index to be used later in hatch fill style or text glyph object
89-
uint32_t addMSDFTexture(ICPUBuffer const* srcBuffer, const asset::IImage::SBufferCopy& region, texture_hash hash = InvalidTextureHash);
90-
9191
void finalizeAllCopiesToGPU(SIntendedSubmitInfo& intendedNextSubmit);
9292

9393
inline uint32_t getLineStyleCount() const { return currentLineStylesCount; }
@@ -249,8 +249,23 @@ struct DrawResourcesFiller
249249

250250
std::stack<ClipProjectionData> clipProjections; // stack of clip projectios stored so we can resubmit them if geometry buffer got reset.
251251
std::deque<uint64_t> clipProjectionAddresses; // stack of clip projection gpu addresses in geometry buffer. to keep track of them in push/pops
252+
253+
struct TextureReference
254+
{
255+
uint32_t alloc_idx;
256+
uint64_t lastUsedSemaphoreValue;
257+
258+
TextureReference(uint32_t alloc_idx, uint64_t semaphoreVal) : alloc_idx(alloc_idx), lastUsedSemaphoreValue(semaphoreVal) {}
259+
TextureReference(uint64_t semaphoreVal) : TextureReference(InvalidTextureIdx, semaphoreVal) {}
260+
TextureReference() : TextureReference(InvalidTextureIdx, ~0ull) {}
261+
262+
// In LRU Cache `insert` function, in case of cache hit, we need to assign semaphore value to TextureReference without changing `alloc_idx`
263+
inline TextureReference& operator=(uint64_t semamphoreVal) { lastUsedSemaphoreValue = semamphoreVal; return *this; }
264+
};
265+
266+
using TextureLRUCache = core::LRUCache<texture_hash, TextureReference>;
252267

253-
smart_refctd_ptr<IGPUImageView> msdfTextureArray;
254-
std::vector<TextureCopy> textureCopies;
255-
std::unordered_map<texture_hash, uint32_t/*index*/> textureIdToIndexMap;
268+
smart_refctd_ptr<IGPUImageView> msdfTextureArray; // view to the resource holding all the msdfs in it's layers
269+
std::vector<TextureCopy> textureCopies; // queued up texture copies, @Lucas change to deque if possible
270+
TextureLRUCache textureLRUCache; // LRU Cache to evict Least Recently Used in case of overflow
256271
};

62_CAD/main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ using namespace video;
2525

2626
#include "nbl/video/surface/CSurfaceVulkan.h"
2727
#include "nbl/ext/FullScreenTriangle/FullScreenTriangle.h"
28-
#include <chrono>
28+
#include "nbl/core/containers/LRUCache.h"
2929

30+
#include <chrono>
3031
#define BENCHMARK_TILL_FIRST_FRAME
3132

3233
static constexpr bool DebugMode = false;

0 commit comments

Comments
 (0)