| Flutter Impeller |

command_queue_vk.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "fml/status.h"
6
7 #include "impeller/renderer/backend/vulkan/command_queue_vk.h"
8
9 #include "impeller/base/validation.h"
10 #include "impeller/renderer/backend/vulkan/command_buffer_vk.h"
11 #include "impeller/renderer/backend/vulkan/context_vk.h"
12 #include "impeller/renderer/backend/vulkan/fence_waiter_vk.h"
13 #include "impeller/renderer/backend/vulkan/tracked_objects_vk.h"
14 #include "impeller/renderer/command_buffer.h"
15
16 namespace impeller {
17
18 CommandQueueVK::CommandQueueVK(const std::weak_ptr<ContextVK>& context)
19 : context_(context) {}
20
21 CommandQueueVK::~CommandQueueVK() = default;
22
23 fml::Status CommandQueueVK::Submit(
24 const std::vector<std::shared_ptr<CommandBuffer>>& buffers,
25 const CompletionCallback& completion_callback) {
26 if (buffers.empty()) {
27 return fml::Status(fml::StatusCode::kInvalidArgument,
28 "No command buffers provided.");
29 }
30 // Success or failure, you only get to submit once.
31 fml::ScopedCleanupClosure reset([&]() {
32 if (completion_callback) {
33 completion_callback(CommandBuffer::Status::kError);
34 }
35 });
36
37 std::vector<vk::CommandBuffer> vk_buffers;
38 std::vector<std::shared_ptr<TrackedObjectsVK>> tracked_objects;
39 vk_buffers.reserve(buffers.size());
40 tracked_objects.reserve(buffers.size());
41 for (const std::shared_ptr<CommandBuffer>& buffer : buffers) {
42 CommandBufferVK& command_buffer = CommandBufferVK::Cast(*buffer);
43 if (!command_buffer.EndCommandBuffer()) {
44 return fml::Status(fml::StatusCode::kCancelled,
45 "Failed to end command buffer.");
46 }
47 vk_buffers.push_back(command_buffer.GetCommandBuffer());
48 tracked_objects.push_back(std::move(command_buffer.tracked_objects_));
49 }
50
51 auto context = context_.lock();
52 if (!context) {
53 VALIDATION_LOG << "Device lost.";
54 return fml::Status(fml::StatusCode::kCancelled, "Device lost.");
55 }
56 auto [fence_result, fence] = context->GetDevice().createFenceUnique({});
57 if (fence_result != vk::Result::eSuccess) {
58 VALIDATION_LOG << "Failed to create fence: " << vk::to_string(fence_result);
59 return fml::Status(fml::StatusCode::kCancelled, "Failed to create fence.");
60 }
61
62 vk::SubmitInfo submit_info;
63 submit_info.setCommandBuffers(vk_buffers);
64 auto status = context->GetGraphicsQueue()->Submit(submit_info, *fence);
65 if (status != vk::Result::eSuccess) {
66 VALIDATION_LOG << "Failed to submit queue: " << vk::to_string(status);
67 return fml::Status(fml::StatusCode::kCancelled, "Failed to submit queue: ");
68 }
69
70 // Submit will proceed, call callback with true when it is done and do not
71 // call when `reset` is collected.
72 auto added_fence = context->GetFenceWaiter()->AddFence(
73 std::move(fence), [completion_callback, tracked_objects = std::move(
74 tracked_objects)]() mutable {
75 // Ensure tracked objects are destructed before calling any final
76 // callbacks.
77 tracked_objects.clear();
78 if (completion_callback) {
79 completion_callback(CommandBuffer::Status::kCompleted);
80 }
81 });
82 if (!added_fence) {
83 return fml::Status(fml::StatusCode::kCancelled, "Failed to add fence.");
84 }
85 reset.Release();
86 return fml::Status();
87 }
88
89 } // namespace impeller
impeller::CommandBuffer::Status::kError
@ kError
fence_waiter_vk.h
tracked_objects_vk.h
validation.h
impeller::CommandQueueVK::Submit
fml::Status Submit(const std::vector< std::shared_ptr< CommandBuffer >> &buffers, const CompletionCallback &completion_callback={}) override
Submit one or more command buffer objects to be encoded and executed on the GPU.
Definition: command_queue_vk.cc:23
impeller::CommandBufferVK::GetCommandBuffer
vk::CommandBuffer GetCommandBuffer() const
Retrieve the native command buffer from this object.
Definition: command_buffer_vk.cc:119
command_buffer_vk.h
impeller::CommandQueueVK::~CommandQueueVK
~CommandQueueVK() override
impeller::CommandBufferVK::EndCommandBuffer
bool EndCommandBuffer() const
End recording of the current command buffer.
Definition: command_buffer_vk.cc:105
impeller::CommandQueue::CompletionCallback
std::function< void(CommandBuffer::Status)> CompletionCallback
Definition: command_queue.h:19
impeller::CommandQueueVK::CommandQueueVK
CommandQueueVK(const std::weak_ptr< ContextVK > &context)
Definition: command_queue_vk.cc:18
impeller::CommandBufferVK
Definition: command_buffer_vk.h:24
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91
command_buffer.h
impeller::CommandBuffer::Status::kCompleted
@ kCompleted
impeller::BackendCast< CommandBufferVK, CommandBuffer >::Cast
static CommandBufferVK & Cast(CommandBuffer &base)
Definition: backend_cast.h:13
command_queue_vk.h
context_vk.h
impeller
Definition: allocation.cc:12