Skip to content

Commit deb5298

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 15a4052 commit deb5298

File tree

7 files changed

+69
-28
lines changed

7 files changed

+69
-28
lines changed

src/config.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ OPTION(bool, supports_filter_linear, true)
6969
OPTION(std::string, device_extensions, "")
7070
OPTION(std::string, device_extensions_masked, "")
7171

72+
OPTION(bool, reuse_descriptor_set, false)
73+
7274
//
7375
// Logging
7476
//

src/device.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,10 @@ struct cvk_device : public _cl_device_id,
699699
0;
700700
}
701701

702+
bool reuse_descriptor_set() const {
703+
return m_clvk_properties->reuse_descriptor_set();
704+
}
705+
702706
private:
703707
std::string version_desc() const {
704708
std::string ret = "CLVK on Vulkan v";

src/device_properties.cpp

Lines changed: 20 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,34 @@ 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+
if (config.reuse_descriptor_set.set) {
43+
return config.reuse_descriptor_set();
44+
}
45+
return m_driverID == VK_DRIVER_ID_ARM_PROPRIETARY;
46+
}
47+
4048
private:
4149
const uint32_t m_deviceID;
50+
const VkDriverId m_driverID;
4251
};
4352

4453
struct cvk_device_properties_mali_exynos9820
4554
: public cvk_device_properties_mali {
4655
cl_ulong get_global_mem_cache_size() const override final { return 262144; }
4756
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) {}
57+
cvk_device_properties_mali_exynos9820(const uint32_t deviceID,
58+
const VkDriverId driverID)
59+
: cvk_device_properties_mali(deviceID, driverID) {}
5060
};
5161

5262
struct cvk_device_properties_mali_exynos990
5363
: public cvk_device_properties_mali {
5464
cl_ulong get_global_mem_cache_size() const override final { return 262144; }
5565
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) {}
66+
cvk_device_properties_mali_exynos990(const uint32_t deviceID,
67+
const VkDriverId driverID)
68+
: cvk_device_properties_mali(deviceID, driverID) {}
5869
};
5970

6071
static bool isMaliDevice(const char* name, const uint32_t vendorID) {
@@ -264,9 +275,9 @@ std::unique_ptr<cvk_device_properties> create_cvk_device_properties(
264275
cvk_warn("Unable to query 'ro.hardware' system property, some "
265276
"device properties will be incorrect.");
266277
} else if (strcmp(soc, "exynos9820") == 0) {
267-
RETURN(cvk_device_properties_mali_exynos9820, deviceID);
278+
RETURN(cvk_device_properties_mali_exynos9820, deviceID, driverID);
268279
} else if (strcmp(soc, "exynos990") == 0) {
269-
RETURN(cvk_device_properties_mali_exynos990, deviceID);
280+
RETURN(cvk_device_properties_mali_exynos990, deviceID, driverID);
270281
} else {
271282
cvk_warn("Unrecognized 'ro.hardware' value '%s', some device "
272283
"properties will be incorrect.",
@@ -276,7 +287,7 @@ std::unique_ptr<cvk_device_properties> create_cvk_device_properties(
276287
cvk_warn("Unrecognized Mali device, some device properties will be "
277288
"incorrect.");
278289
#endif
279-
RETURN(cvk_device_properties_mali, deviceID);
290+
RETURN(cvk_device_properties_mali, deviceID, driverID);
280291
} else if (strcmp(name, "Adreno (TM) 615") == 0) {
281292
RETURN(cvk_device_properties_adreno_615);
282293
} 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
@@ -71,6 +71,10 @@ struct cvk_device_properties {
7171
return no_disabled_formats;
7272
}
7373

74+
virtual bool reuse_descriptor_set() const {
75+
return config.reuse_descriptor_set();
76+
}
77+
7478
virtual ~cvk_device_properties() {}
7579
};
7680

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_set(m_descriptor_sets);
202198
}
203199

204200
static std::shared_ptr<cvk_kernel_argument_values>
@@ -374,12 +370,7 @@ struct cvk_kernel_argument_values {
374370
std::lock_guard<std::mutex> lock(m_lock);
375371
if (--m_descriptor_sets_refcount == 0) {
376372
m_is_enqueued = false;
377-
for (auto& ds : m_descriptor_sets) {
378-
if (ds != VK_NULL_HANDLE) {
379-
m_entry_point->free_descriptor_set(ds);
380-
ds = VK_NULL_HANDLE;
381-
}
382-
}
373+
m_entry_point->free_descriptor_set(m_descriptor_sets);
383374
}
384375
}
385376

@@ -426,7 +417,6 @@ struct cvk_kernel_argument_values {
426417
std::vector<bool> m_args_set;
427418

428419
std::unique_ptr<cvk_buffer> m_pod_buffer;
429-
std::array<VkDescriptorSet, spir_binary::MAX_DESCRIPTOR_SETS>
430-
m_descriptor_sets;
420+
cvk_descriptor_set_array m_descriptor_sets;
431421
uint32_t m_descriptor_sets_refcount;
432422
};

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 < spir_binary::MAX_DESCRIPTOR_SETS; 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: 26 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+
spir_binary::MAX_DESCRIPTOR_SETS,
449+
descriptor_sets.data());
450+
}
443451
if (m_descriptor_pool != VK_NULL_HANDLE) {
444452
vkDestroyDescriptorPool(vkdev, m_descriptor_pool, nullptr);
445453
}
@@ -458,14 +466,24 @@ 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_set(cvk_descriptor_set_array& descriptor_sets) {
462470
TRACE_FUNCTION();
463471
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);
472+
if (descriptor_sets == cvk_descriptor_set_array{VK_NULL_HANDLE}) {
473+
return;
474+
}
475+
476+
if (m_device->reuse_descriptor_set()) {
477+
m_descriptor_sets_array.push_back(descriptor_sets);
478+
} else {
479+
vkFreeDescriptorSets(m_device->vulkan_device(), m_descriptor_pool,
480+
spir_binary::MAX_DESCRIPTOR_SETS,
481+
descriptor_sets.data());
482+
m_nb_descriptor_set_allocated -= spir_binary::MAX_DESCRIPTOR_SETS;
483+
TRACE_CNT(descriptor_set_allocated_counter,
484+
m_nb_descriptor_set_allocated);
485+
}
486+
descriptor_sets = {VK_NULL_HANDLE};
469487
}
470488

471489
uint32_t num_set_layouts() const { return m_descriptor_set_layouts.size(); }
@@ -572,6 +590,8 @@ class cvk_entry_point {
572590
TRACE_CNT_VAR(descriptor_set_allocated_counter);
573591

574592
bool m_first_allocation_failure;
593+
594+
std::vector<cvk_descriptor_set_array> m_descriptor_sets_array;
575595
};
576596

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

0 commit comments

Comments
 (0)