Skip to content

Commit 662086f

Browse files
committed
Manually free uniform sets.
See #735
1 parent f2bdc4c commit 662086f

4 files changed

+26
-0
lines changed

engine/detail_rendering/render_detail_texture_gpu_task.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,8 @@ void RenderDetailTextureGPUTask::prepare(GPUTaskContext &ctx) {
289289

290290
// Make compute list
291291

292+
_uniform_sets_to_free.reserve(5 + modifiers.size());
293+
292294
const int compute_list_id = rd.compute_list_begin();
293295

294296
// Gather hits
@@ -310,6 +312,7 @@ void RenderDetailTextureGPUTask::prepare(GPUTaskContext &ctx) {
310312
gather_hits_uniforms[5] = hit_positions_uniform;
311313

312314
const RID gather_hits_uniform_set_rid = uniform_set_create(rd, gather_hits_uniforms, gather_hits_shader_rid, 0);
315+
_uniform_sets_to_free.push_back(gather_hits_uniform_set_rid);
313316

314317
rd.compute_list_bind_compute_pipeline(compute_list_id, _gather_hits_pipeline_rid);
315318
rd.compute_list_bind_uniform_set(compute_list_id, gather_hits_uniform_set_rid, 0);
@@ -350,6 +353,7 @@ void RenderDetailTextureGPUTask::prepare(GPUTaskContext &ctx) {
350353
}
351354

352355
const RID detail_generator_uniform_set = uniform_set_create(rd, detail_generator_uniforms, shader_rid, 0);
356+
_uniform_sets_to_free.push_back(detail_generator_uniform_set);
353357

354358
rd.compute_list_bind_compute_pipeline(compute_list_id, _detail_generator_pipeline_rid);
355359
rd.compute_list_bind_uniform_set(compute_list_id, detail_generator_uniform_set, 0);
@@ -402,6 +406,7 @@ void RenderDetailTextureGPUTask::prepare(GPUTaskContext &ctx) {
402406

403407
const RID detail_modifier_uniform_set =
404408
uniform_set_create(rd, detail_modifier_uniforms, modifier_shader_rid, 0);
409+
_uniform_sets_to_free.push_back(detail_modifier_uniform_set);
405410

406411
const RID pipeline_rid = _detail_modifier_pipelines[modifier_index];
407412
rd.compute_list_bind_compute_pipeline(compute_list_id, pipeline_rid);
@@ -440,6 +445,7 @@ void RenderDetailTextureGPUTask::prepare(GPUTaskContext &ctx) {
440445

441446
const RID detail_normalmap_uniform_set_rid =
442447
uniform_set_create(rd, detail_normalmap_uniforms, detail_normalmap_shader_rid, 0);
448+
_uniform_sets_to_free.push_back(detail_normalmap_uniform_set_rid);
443449

444450
rd.compute_list_bind_compute_pipeline(compute_list_id, _detail_normalmap_pipeline_rid);
445451
rd.compute_list_bind_uniform_set(compute_list_id, detail_normalmap_uniform_set_rid, 0);
@@ -470,6 +476,7 @@ void RenderDetailTextureGPUTask::prepare(GPUTaskContext &ctx) {
470476
dilation_uniforms[1] = image1_uniform;
471477
dilation_uniforms[2] = dilation_params_uniform;
472478
const RID dilation_uniform_set_rid = uniform_set_create(rd, dilation_uniforms, dilation_shader_rid, 0);
479+
_uniform_sets_to_free.push_back(dilation_uniform_set_rid);
473480

474481
rd.compute_list_bind_compute_pipeline(compute_list_id, _normalmap_dilation_pipeline_rid);
475482
rd.compute_list_bind_uniform_set(compute_list_id, dilation_uniform_set_rid, 0);
@@ -506,6 +513,7 @@ void RenderDetailTextureGPUTask::prepare(GPUTaskContext &ctx) {
506513
dilation_uniforms[2] = dilation_params_uniform;
507514
// TODO Do I really have to create a new uniform set every time I modify just one of the passed values?
508515
const RID dilation_uniform_set_rid = uniform_set_create(rd, dilation_uniforms, dilation_shader_rid, 0);
516+
_uniform_sets_to_free.push_back(dilation_uniform_set_rid);
509517

510518
rd.compute_list_bind_uniform_set(compute_list_id, dilation_uniform_set_rid, 0);
511519

@@ -550,6 +558,14 @@ PackedByteArray RenderDetailTextureGPUTask::collect_texture_and_cleanup(
550558
free_rendering_device_rid(rd, rid);
551559
}
552560

561+
// This is not documented: from dev source, uniform sets are "automatically freed by their dependencies". So
562+
// apparently we don't *have* to free them. However, I got a bug report where RID limit got exceeded after
563+
// several minutes, unless those RIDs get freed after use... something odd is going on, but absence of
564+
// documentation on the automatic behavior doesn't help.
565+
for (RID rid : _uniform_sets_to_free) {
566+
free_rendering_device_rid(rd, rid);
567+
}
568+
553569
storage_buffer_pool.recycle(_mesh_vertices_sb);
554570
storage_buffer_pool.recycle(_mesh_indices_sb);
555571
storage_buffer_pool.recycle(_cell_triangles_sb);

engine/detail_rendering/render_detail_texture_gpu_task.h

+1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class RenderDetailTextureGPUTask : public IGPUTask {
8585
RID _detail_normalmap_pipeline_rid;
8686
RID _normalmap_dilation_pipeline_rid;
8787
StdVector<RID> _detail_modifier_pipelines;
88+
StdVector<RID> _uniform_sets_to_free;
8889

8990
GPUStorageBuffer _mesh_vertices_sb;
9091
GPUStorageBuffer _mesh_indices_sb;

generators/generate_block_gpu_task.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ void GenerateBlockGPUTask::prepare(GPUTaskContext &ctx) {
130130

131131
// Generate
132132

133+
_uniform_sets_to_free.reserve(_boxes_data.size() * (1 + modifiers.size()));
134+
133135
for (unsigned int box_index = 0; box_index < _boxes_data.size(); ++box_index) {
134136
BoxData &bd = _boxes_data[box_index];
135137

@@ -153,6 +155,7 @@ void GenerateBlockGPUTask::prepare(GPUTaskContext &ctx) {
153155
// Mutex (instead of BinaryMutex)
154156
const RID generator_uniform_set =
155157
zylann::godot::uniform_set_create(rd, generator_uniforms, generator_shader_rid, 0);
158+
_uniform_sets_to_free.push_back(generator_uniform_set);
156159

157160
{
158161
ZN_PROFILE_SCOPE_NAMED("compute_list_bind_compute_pipeline");
@@ -212,6 +215,7 @@ void GenerateBlockGPUTask::prepare(GPUTaskContext &ctx) {
212215

213216
const RID modifier_uniform_set =
214217
zylann::godot::uniform_set_create(rd, modifier_uniforms, modifier_shader_rid, 0);
218+
_uniform_sets_to_free.push_back(modifier_uniform_set);
215219

216220
const RID pipeline_rid = _modifier_pipelines[modifier_index];
217221
rd.compute_list_bind_compute_pipeline(compute_list_id, pipeline_rid);
@@ -469,6 +473,10 @@ void GenerateBlockGPUTask::collect(GPUTaskContext &ctx) {
469473
zylann::godot::free_rendering_device_rid(rd, rid);
470474
}
471475

476+
for (const RID rid : _uniform_sets_to_free) {
477+
zylann::godot::free_rendering_device_rid(rd, rid);
478+
}
479+
472480
// We leave conversion to the CPU task, because we have only one thread for GPU work and it only exists for waiting
473481
// blocking functions, not doing work
474482
consumer_task->set_gpu_results(std::move(results));

generators/generate_block_gpu_task.h

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ class GenerateBlockGPUTask : public IGPUTask {
8484
StdVector<BoxData> _boxes_data;
8585
RID _generator_pipeline_rid;
8686
StdVector<RID> _modifier_pipelines;
87+
StdVector<RID> _uniform_sets_to_free;
8788
};
8889

8990
} // namespace zylann::voxel

0 commit comments

Comments
 (0)