Skip to content

Commit

Permalink
sokol: Add resource pool cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
IonAgorria committed May 19, 2024
1 parent 1524d8a commit bf47d9c
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 4 deletions.
39 changes: 37 additions & 2 deletions Source/Render/sokol/SokolRender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ int cSokolRender::Init(int xScr, int yScr, int mode, SDL_Window* wnd, int Refres
return res;
}

ClearPooledResources(0);
ClearCommands();
ClearPipelines();

Expand Down Expand Up @@ -356,6 +357,7 @@ int cSokolRender::Done() {
bool do_sg_shutdown = sdl_window != nullptr;
int ret = cInterfaceRenderDevice::Done();
activeCommand.Clear();
ClearPooledResources(0);
ClearCommands();
ClearPipelines();
shaders.clear();
Expand Down Expand Up @@ -419,6 +421,33 @@ void cSokolRender::DeleteIndexBuffer(IndexBuffer &ib) {
ib.FreeData();
}

#define ClearPooledResources_Debug 0
void cSokolRender::ClearPooledResources(uint32_t max_life) {
if (bufferPool.empty()) {
return;
}
#if defined(PERIMETER_DEBUG) && ClearPooledResources_Debug
size_t count = bufferPool.size();
#endif
auto it = bufferPool.begin();
while (it != bufferPool.end()) {
auto& res = it->second;
res.last_used++;
if (res.last_used >= max_life) {
res.resource->DecRef();
res.resource = nullptr;
it = bufferPool.erase(it);
} else {
it++;
}
}
#if defined(PERIMETER_DEBUG) && ClearPooledResources_Debug
if (count != bufferPool.size()) {
printf("ClearPooledResources %" PRIsize " -> %" PRIsize "\n", count, bufferPool.size());
}
#endif
}

void cSokolRender::ClearCommands() {
std::unordered_set<SokolResourceBuffer*> pooled;
for (SokolCommand* command : commands) {
Expand All @@ -428,15 +457,21 @@ void cSokolRender::ClearCommands() {
&& (vertex_buffer->RefCount() == 1 || pooled.count(vertex_buffer) == 0)) {
command->vertex_buffer = nullptr;
xassert(0 < vertex_buffer->RefCount() && vertex_buffer->RefCount() <= 50);
bufferPool.emplace(vertex_buffer->key, vertex_buffer);
bufferPool.emplace(
vertex_buffer->key,
SokolResourcePooled(vertex_buffer)
);
pooled.emplace(vertex_buffer);
}
SokolResourceBuffer* index_buffer = command->index_buffer;
if (index_buffer && index_buffer->key != SokolResourceKeyNone
&& (index_buffer->RefCount() == 1 || pooled.count(index_buffer) == 0)) {
command->index_buffer = nullptr;
xassert(0 < index_buffer->RefCount() && index_buffer->RefCount() <= 50);
bufferPool.emplace(index_buffer->key, index_buffer);
bufferPool.emplace(
index_buffer->key,
SokolResourcePooled(index_buffer)
);
pooled.emplace(index_buffer);
}

Expand Down
12 changes: 11 additions & 1 deletion Source/Render/sokol/SokolRender.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ struct SokolCommand {
Vect2i clip[2]; //0 Pos 1 Size
};

template<typename T>
struct SokolResourcePooled {
uint32_t last_used = 0;
SokolResource<T>* resource = nullptr;

explicit SokolResourcePooled(SokolResource<T>* res) : resource(res) {
}
};

class cSokolRender: public cInterfaceRenderDevice {
private:
//SDL context
Expand All @@ -60,7 +69,8 @@ class cSokolRender: public cInterfaceRenderDevice {
#endif

//Stores resources for reusing
std::unordered_multimap<uint64_t, SokolResourceBuffer*> bufferPool;
void ClearPooledResources(uint32_t max_life);
std::unordered_multimap<uint64_t, SokolResourcePooled<sg_buffer>> bufferPool;

//For swapchain pass that renders into final device
sg_pass swapchain_pass;
Expand Down
6 changes: 5 additions & 1 deletion Source/Render/sokol/SokolRenderState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ void sokol_metal_render_callback() {
}
#endif

//How many frames to store the resources until freed
const uint32_t MAX_POOLED_RESOURCES_LIFE = 10000;

int cSokolRender::BeginScene() {
RenderSubmitEvent(RenderEvent::BEGIN_SCENE, ActiveScene ? "ActiveScene" : "");
MTG();
Expand Down Expand Up @@ -253,6 +256,7 @@ int cSokolRender::Flush(bool wnd) {
sokol_metal_draw();
#endif

ClearPooledResources(MAX_POOLED_RESOURCES_LIFE);
ClearCommands();

xassert(!activeDrawBuffer || !activeDrawBuffer->written_vertices);
Expand Down Expand Up @@ -316,7 +320,7 @@ void cSokolRender::PrepareSokolBuffer(SokolBuffer*& buffer_ptr, MemoryResource*
sg_buffer
);
} else {
buffer = nh.mapped();
buffer = nh.mapped().resource;
}

resource->dirty = true;
Expand Down

0 comments on commit bf47d9c

Please sign in to comment.