Skip to content

Commit 5c83b8a

Browse files
committed
Add config option to reuse descriptor_set
On Mali devices, using the ARM DDK, some application quickly get to a point where the driver consider the memory as fragemented and it not capable of allocated new descriptor_set anymore. To avoid that, do not free descriptor_set, reuse ones that have been release from the application point of view.
1 parent 803bde0 commit 5c83b8a

File tree

9 files changed

+67
-30
lines changed

9 files changed

+67
-30
lines changed

src/config.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ OPTION(bool, keep_memory_allocations_mapped, false)
7171
OPTION(std::string, device_extensions, "")
7272
OPTION(std::string, device_extensions_masked, "")
7373

74+
OPTION(bool, reuse_descriptor_set, false)
75+
7476
//
7577
// Logging
7678
//

src/device.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,10 @@ struct cvk_device : public _cl_device_id,
703703
return m_clvk_properties->keep_memory_allocations_mapped();
704704
}
705705

706+
bool reuse_descriptor_set() const {
707+
return m_clvk_properties->reuse_descriptor_set();
708+
}
709+
706710
private:
707711
std::string version_desc() const {
708712
std::string ret = "CLVK on Vulkan v";

src/device_properties.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ struct cvk_device_properties_mali : public cvk_device_properties {
2626
cl_uint get_max_first_cmd_batch_size() const override final { return 10; }
2727
cl_uint get_max_cmd_group_size() const override final { return 1; }
2828

29-
cvk_device_properties_mali(const uint32_t deviceID)
30-
: m_deviceID(deviceID) {}
29+
cvk_device_properties_mali(const uint32_t deviceID,
30+
const VkDriverId driverID)
31+
: m_deviceID(deviceID), m_driverID(driverID) {}
3132

3233
bool is_non_uniform_decoration_broken() const override final {
3334
#define GPU_ID2_ARCH_MAJOR_SHIFT 28
@@ -37,24 +38,31 @@ struct cvk_device_properties_mali : public cvk_device_properties {
3738
return (m_deviceID & GPU_ID2_ARCH_MAJOR) <= bifrost_arch_major;
3839
}
3940

41+
bool reuse_descriptor_set() const override final {
42+
return m_driverID == VK_DRIVER_ID_ARM_PROPRIETARY;
43+
}
44+
4045
private:
4146
const uint32_t m_deviceID;
47+
const VkDriverId m_driverID;
4248
};
4349

4450
struct cvk_device_properties_mali_exynos9820
4551
: public cvk_device_properties_mali {
4652
cl_ulong get_global_mem_cache_size() const override final { return 262144; }
4753
cl_ulong get_num_compute_units() const override final { return 12; }
48-
cvk_device_properties_mali_exynos9820(const uint32_t deviceID)
49-
: cvk_device_properties_mali(deviceID) {}
54+
cvk_device_properties_mali_exynos9820(const uint32_t deviceID,
55+
const VkDriverId driverID)
56+
: cvk_device_properties_mali(deviceID, driverID) {}
5057
};
5158

5259
struct cvk_device_properties_mali_exynos990
5360
: public cvk_device_properties_mali {
5461
cl_ulong get_global_mem_cache_size() const override final { return 262144; }
5562
cl_ulong get_num_compute_units() const override final { return 11; }
56-
cvk_device_properties_mali_exynos990(const uint32_t deviceID)
57-
: cvk_device_properties_mali(deviceID) {}
63+
cvk_device_properties_mali_exynos990(const uint32_t deviceID,
64+
const VkDriverId driverID)
65+
: cvk_device_properties_mali(deviceID, driverID) {}
5866
};
5967

6068
static bool isMaliDevice(const char* name, const uint32_t vendorID) {
@@ -264,9 +272,9 @@ std::unique_ptr<cvk_device_properties> create_cvk_device_properties(
264272
cvk_warn("Unable to query 'ro.hardware' system property, some "
265273
"device properties will be incorrect.");
266274
} else if (strcmp(soc, "exynos9820") == 0) {
267-
RETURN(cvk_device_properties_mali_exynos9820, deviceID);
275+
RETURN(cvk_device_properties_mali_exynos9820, deviceID, driverID);
268276
} else if (strcmp(soc, "exynos990") == 0) {
269-
RETURN(cvk_device_properties_mali_exynos990, deviceID);
277+
RETURN(cvk_device_properties_mali_exynos990, deviceID, driverID);
270278
} else {
271279
cvk_warn("Unrecognized 'ro.hardware' value '%s', some device "
272280
"properties will be incorrect.",
@@ -276,7 +284,7 @@ std::unique_ptr<cvk_device_properties> create_cvk_device_properties(
276284
cvk_warn("Unrecognized Mali device, some device properties will be "
277285
"incorrect.");
278286
#endif
279-
RETURN(cvk_device_properties_mali, deviceID);
287+
RETURN(cvk_device_properties_mali, deviceID, driverID);
280288
} else if (strcmp(name, "Adreno (TM) 615") == 0) {
281289
RETURN(cvk_device_properties_adreno_615);
282290
} else if (strcmp(name, "Adreno (TM) 620") == 0) {

src/device_properties.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ struct cvk_device_properties {
7575
return config.keep_memory_allocations_mapped();
7676
}
7777

78+
virtual bool reuse_descriptor_set() const {
79+
return config.reuse_descriptor_set();
80+
}
81+
7882
virtual ~cvk_device_properties() {}
7983
};
8084

src/kernel.hpp

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,7 @@ struct cvk_kernel_argument_values {
194194
m_descriptor_sets_refcount(0) {}
195195

196196
~cvk_kernel_argument_values() {
197-
for (auto ds : m_descriptor_sets) {
198-
if (ds != VK_NULL_HANDLE) {
199-
m_entry_point->free_descriptor_set(ds);
200-
}
201-
}
197+
m_entry_point->free_descriptor_sets(m_descriptor_sets);
202198
}
203199

204200
static std::shared_ptr<cvk_kernel_argument_values>
@@ -385,12 +381,7 @@ struct cvk_kernel_argument_values {
385381
std::lock_guard<std::mutex> lock(m_lock);
386382
if (--m_descriptor_sets_refcount == 0) {
387383
m_is_enqueued = false;
388-
for (auto& ds : m_descriptor_sets) {
389-
if (ds != VK_NULL_HANDLE) {
390-
m_entry_point->free_descriptor_set(ds);
391-
ds = VK_NULL_HANDLE;
392-
}
393-
}
384+
m_entry_point->free_descriptor_sets(m_descriptor_sets);
394385
}
395386
}
396387

@@ -437,7 +428,6 @@ struct cvk_kernel_argument_values {
437428
std::vector<bool> m_args_set;
438429

439430
std::unique_ptr<cvk_buffer> m_pod_buffer;
440-
std::array<VkDescriptorSet, spir_binary::MAX_DESCRIPTOR_SETS>
441-
m_descriptor_sets;
431+
cvk_descriptor_set_array m_descriptor_sets;
442432
uint32_t m_descriptor_sets_refcount;
443433
};

src/program.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2269,6 +2269,16 @@ bool cvk_entry_point::allocate_descriptor_sets(VkDescriptorSet* ds) {
22692269

22702270
std::lock_guard<std::mutex> lock(m_descriptor_pool_lock);
22712271

2272+
if (m_device->reuse_descriptor_set() && !m_descriptor_sets_array.empty()) {
2273+
cvk_descriptor_set_array descriptor_sets =
2274+
m_descriptor_sets_array.back();
2275+
m_descriptor_sets_array.pop_back();
2276+
for (unsigned i = 0; i < descriptor_sets.size(); i++) {
2277+
ds[i] = descriptor_sets[i];
2278+
}
2279+
return true;
2280+
}
2281+
22722282
#if CLVK_UNIT_TESTING_ENABLED
22732283
if (config.force_descriptor_set_allocation_failure() &&
22742284
m_nb_descriptor_set_allocated + m_descriptor_set_layouts.size() >

src/program.hpp

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,9 @@ using cvk_spec_constant_map = std::map<uint32_t, uint32_t>;
428428

429429
struct cvk_program;
430430

431+
using cvk_descriptor_set_array =
432+
std::array<VkDescriptorSet, spir_binary::MAX_DESCRIPTOR_SETS>;
433+
431434
class cvk_entry_point {
432435
public:
433436
cvk_entry_point(cvk_device* dev, cvk_program* program,
@@ -440,6 +443,11 @@ class cvk_entry_point {
440443
m_name.c_str());
441444
vkDestroyPipeline(vkdev, pipeline.second, nullptr);
442445
}
446+
for (auto& descriptor_sets : m_descriptor_sets_array) {
447+
vkFreeDescriptorSets(m_device->vulkan_device(), m_descriptor_pool,
448+
descriptor_sets.size(),
449+
descriptor_sets.data());
450+
}
443451
if (m_descriptor_pool != VK_NULL_HANDLE) {
444452
vkDestroyDescriptorPool(vkdev, m_descriptor_pool, nullptr);
445453
}
@@ -458,14 +466,23 @@ class cvk_entry_point {
458466

459467
CHECK_RETURN bool allocate_descriptor_sets(VkDescriptorSet* ds);
460468

461-
void free_descriptor_set(VkDescriptorSet ds) {
469+
void free_descriptor_sets(cvk_descriptor_set_array& descriptor_sets) {
462470
TRACE_FUNCTION();
471+
if (descriptor_sets == cvk_descriptor_set_array{VK_NULL_HANDLE}) {
472+
return;
473+
}
463474
std::lock_guard<std::mutex> lock(m_descriptor_pool_lock);
464-
vkFreeDescriptorSets(m_device->vulkan_device(), m_descriptor_pool, 1,
465-
&ds);
466-
m_nb_descriptor_set_allocated--;
467-
TRACE_CNT(descriptor_set_allocated_counter,
468-
m_nb_descriptor_set_allocated);
475+
if (m_device->reuse_descriptor_set()) {
476+
m_descriptor_sets_array.push_back(descriptor_sets);
477+
} else {
478+
vkFreeDescriptorSets(m_device->vulkan_device(), m_descriptor_pool,
479+
descriptor_sets.size(),
480+
descriptor_sets.data());
481+
m_nb_descriptor_set_allocated -= m_descriptor_set_layouts.size();
482+
TRACE_CNT(descriptor_set_allocated_counter,
483+
m_nb_descriptor_set_allocated);
484+
}
485+
descriptor_sets = cvk_descriptor_set_array{VK_NULL_HANDLE};
469486
}
470487

471488
uint32_t num_set_layouts() const { return m_descriptor_set_layouts.size(); }
@@ -572,6 +589,8 @@ class cvk_entry_point {
572589
TRACE_CNT_VAR(descriptor_set_allocated_counter);
573590

574591
bool m_first_allocation_failure;
592+
593+
std::vector<cvk_descriptor_set_array> m_descriptor_sets_array;
575594
};
576595

577596
struct cvk_program : public _cl_program, api_object<object_magic::program> {

tests/perfetto/api_tests.EnqueueTooManyCommandWithRetry-expectation.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"execute_cmds"
3131
"extract_cmds_required_by"
3232
"flush_no_lock"
33-
"free_descriptor_set"
33+
"free_descriptor_sets"
3434
"name"
3535
"set_event_status"
3636
"vkQueueSubmit"

tests/perfetto/simple_test-expectation.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"execute_cmds"
3030
"extract_cmds_required_by"
3131
"flush_no_lock"
32-
"free_descriptor_set"
32+
"free_descriptor_sets"
3333
"name"
3434
"set_event_status"
3535
"vkQueueSubmit"

0 commit comments

Comments
 (0)