Skip to content

Commit 7a4ec13

Browse files
trivedivivekSS-JIA
andauthored
[ET-VK] 1/n Split dispatches between multiple command buffers. Add semaphore support in command buffer. (#12519)
Stack from [ghstack](https://github.com/ezyang/ghstack) (oldest at bottom): * #12525 * #12523 * #12522 * __->__ #12519 execute stage ## Context This following diffs aims to improve the performance of the Executorch Vulkan backend by adding a mechanism to issue multiple command buffers in prepack and execute function, so GPU work is issues while CPU is still working on issuing new work. ## This Diff ### Summary This diff is the first in a series of diffs that aim to split dispatches between multiple command buffers and add semaphore support in the command buffer. The changes in this diff include: * Adding a `VkSemaphore` parameter to the `CommandBuffer` constructor in `vk_api/Command.cpp` and `vk_api/Command.h` to support signaling when the command buffer has completed execution. * Modifying the `CommandBuffer` constructor in `vk_api/Command.h` and `vk_api/Command.cpp` to include the `VkSemaphore` parameter. * Updating the `CommandBuffer` object in `api/Context.cpp` to include the `VkSemaphore` parameter. Differential Revision: [D78282194](https://our.internmc.facebook.com/intern/diff/D78282194/) --------- Co-authored-by: Stephen Jia <[email protected]>
1 parent 24a1e2f commit 7a4ec13

File tree

3 files changed

+41
-4
lines changed

3 files changed

+41
-4
lines changed

backends/vulkan/runtime/api/Context.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Context::Context(vkapi::Adapter* adapter, const ContextConfig& config)
3838
querypool_(config_.query_pool_config, nullptr),
3939
// Command buffer submission
4040
cmd_mutex_{},
41-
cmd_(VK_NULL_HANDLE, 0u),
41+
cmd_(VK_NULL_HANDLE, VK_NULL_HANDLE, 0u),
4242
submit_count_{0u},
4343
// Memory Management
4444
buffer_clearlist_mutex_{},

backends/vulkan/runtime/vk_api/Command.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,34 @@ namespace vkapi {
2020

2121
CommandBuffer::CommandBuffer(
2222
VkCommandBuffer handle,
23+
VkSemaphore semaphore,
2324
const VkCommandBufferUsageFlags flags)
2425
: handle_(handle),
26+
signal_semaphore_(semaphore),
2527
flags_(flags),
2628
state_(CommandBuffer::State::NEW),
2729
bound_{} {}
2830

2931
CommandBuffer::CommandBuffer(CommandBuffer&& other) noexcept
3032
: handle_(other.handle_),
33+
signal_semaphore_(other.signal_semaphore_),
3134
flags_(other.flags_),
32-
state_(CommandBuffer::State::INVALID),
35+
state_(other.state_),
3336
bound_(other.bound_) {
3437
other.handle_ = VK_NULL_HANDLE;
38+
other.signal_semaphore_ = VK_NULL_HANDLE;
3539
other.bound_.reset();
3640
}
3741

3842
CommandBuffer& CommandBuffer::operator=(CommandBuffer&& other) noexcept {
3943
handle_ = other.handle_;
44+
signal_semaphore_ = other.signal_semaphore_;
4045
flags_ = other.flags_;
4146
state_ = other.state_;
4247
bound_ = other.bound_;
4348

4449
other.handle_ = VK_NULL_HANDLE;
50+
other.signal_semaphore_ = VK_NULL_HANDLE;
4551
other.bound_.reset();
4652
other.state_ = CommandBuffer::State::INVALID;
4753

@@ -304,6 +310,12 @@ CommandPool::~CommandPool() {
304310
if (pool_ == VK_NULL_HANDLE) {
305311
return;
306312
}
313+
for (auto& semaphore : semaphores_) {
314+
if (semaphore != VK_NULL_HANDLE) {
315+
vkDestroySemaphore(device_, semaphore, nullptr);
316+
}
317+
}
318+
307319
vkDestroyCommandPool(device_, pool_, nullptr);
308320
}
309321

@@ -314,14 +326,15 @@ CommandBuffer CommandPool::get_new_cmd(bool reusable) {
314326
allocate_new_batch(config_.cmd_pool_batch_size);
315327

316328
VkCommandBuffer handle = buffers_[in_use_];
329+
VkSemaphore semaphore = semaphores_[in_use_];
317330

318331
VkCommandBufferUsageFlags cmd_flags = 0u;
319332
if (!reusable) {
320333
cmd_flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
321334
}
322335

323336
in_use_++;
324-
return CommandBuffer(handle, cmd_flags);
337+
return CommandBuffer(handle, semaphore, cmd_flags);
325338
}
326339

327340
void CommandPool::flush() {
@@ -337,6 +350,7 @@ void CommandPool::allocate_new_batch(const uint32_t count) {
337350
}
338351

339352
buffers_.resize(buffers_.size() + count);
353+
semaphores_.resize(buffers_.size() + count);
340354

341355
const VkCommandBufferAllocateInfo allocate_info{
342356
VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType
@@ -348,6 +362,17 @@ void CommandPool::allocate_new_batch(const uint32_t count) {
348362

349363
VK_CHECK(vkAllocateCommandBuffers(
350364
device_, &allocate_info, buffers_.data() + in_use_));
365+
366+
const VkSemaphoreCreateInfo semaphoreCreateInfo = {
367+
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
368+
369+
for (uint32_t i = 0; i < count; i++) {
370+
VK_CHECK(vkCreateSemaphore(
371+
device_,
372+
&semaphoreCreateInfo,
373+
nullptr,
374+
semaphores_.data() + in_use_ + i));
375+
}
351376
}
352377

353378
} // namespace vkapi

backends/vulkan/runtime/vk_api/Command.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ namespace vkapi {
2626

2727
class CommandBuffer final {
2828
public:
29-
explicit CommandBuffer(VkCommandBuffer, const VkCommandBufferUsageFlags);
29+
explicit CommandBuffer(
30+
VkCommandBuffer,
31+
VkSemaphore,
32+
const VkCommandBufferUsageFlags);
3033

3134
CommandBuffer(const CommandBuffer&) = delete;
3235
CommandBuffer& operator=(const CommandBuffer&) = delete;
@@ -70,6 +73,8 @@ class CommandBuffer final {
7073

7174
private:
7275
VkCommandBuffer handle_;
76+
// Semaphore to signal when the command buffer has completed execution
77+
VkSemaphore signal_semaphore_;
7378
VkCommandBufferUsageFlags flags_;
7479
State state_;
7580
Bound bound_;
@@ -81,6 +86,7 @@ class CommandBuffer final {
8186

8287
inline void invalidate() {
8388
handle_ = VK_NULL_HANDLE;
89+
signal_semaphore_ = VK_NULL_HANDLE;
8490
bound_.reset();
8591
}
8692

@@ -100,6 +106,10 @@ class CommandBuffer final {
100106

101107
VkCommandBuffer get_submit_handle(const bool final_use = false);
102108

109+
VkSemaphore get_signal_semaphore() const {
110+
return signal_semaphore_;
111+
}
112+
103113
inline operator bool() const {
104114
return handle_ != VK_NULL_HANDLE;
105115
}
@@ -130,6 +140,8 @@ class CommandPool final {
130140
// New Buffers
131141
std::mutex mutex_;
132142
std::vector<VkCommandBuffer> buffers_;
143+
// Semaphores corresponding to the command buffers
144+
std::vector<VkSemaphore> semaphores_;
133145
size_t in_use_;
134146

135147
public:

0 commit comments

Comments
 (0)