7 #include "flutter/fml/closure.h"
8 #include "fml/status.h"
9 #include "fml/status_or.h"
20 const std::shared_ptr<CommandPoolVK>& pool,
21 std::unique_ptr<GPUProbe> probe)
22 : desc_pool_(context), probe_(
std::move(probe)) {
26 auto buffer = pool->CreateCommandBuffer();
31 buffer_ = std::move(buffer);
39 pool_->CollectCommandBuffer(std::move(buffer_));
42 bool IsValid()
const {
return is_valid_; }
44 void Track(std::shared_ptr<SharedObjectVK>
object) {
48 tracked_objects_.insert(std::move(
object));
51 void Track(std::shared_ptr<const Buffer> buffer) {
55 tracked_buffers_.insert(std::move(buffer));
58 bool IsTracking(
const std::shared_ptr<const Buffer>& buffer)
const {
62 return tracked_buffers_.find(buffer) != tracked_buffers_.end();
65 void Track(std::shared_ptr<const TextureSourceVK> texture) {
69 tracked_textures_.insert(std::move(texture));
72 bool IsTracking(
const std::shared_ptr<const TextureSourceVK>& texture)
const {
76 return tracked_textures_.find(texture) != tracked_textures_.end();
88 std::shared_ptr<CommandPoolVK> pool_;
89 vk::UniqueCommandBuffer buffer_;
90 std::set<std::shared_ptr<SharedObjectVK>> tracked_objects_;
91 std::set<std::shared_ptr<const Buffer>> tracked_buffers_;
92 std::set<std::shared_ptr<const TextureSourceVK>> tracked_textures_;
93 std::unique_ptr<GPUProbe> probe_;
94 bool is_valid_ =
false;
102 const std::weak_ptr<const ContextVK>& context)
103 : context_(context) {}
110 auto context = context_.lock();
114 auto recycler = context->GetCommandPoolRecycler();
118 auto tls_pool = recycler->Get();
123 auto tracked_objects = std::make_shared<TrackedObjectsVK>(
124 context, tls_pool, context->GetGPUTracer()->CreateGPUProbe());
125 auto queue = context->GetGraphicsQueue();
127 if (!tracked_objects || !tracked_objects->IsValid() || !queue) {
131 vk::CommandBufferBeginInfo begin_info;
132 begin_info.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit;
133 if (tracked_objects->GetCommandBuffer().begin(begin_info) !=
134 vk::Result::eSuccess) {
139 if (label_.has_value()) {
140 context->SetDebugName(tracked_objects->GetCommandBuffer(), label_.value());
142 tracked_objects->GetGPUProbe().RecordCmdBufferStart(
143 tracked_objects->GetCommandBuffer());
145 return std::make_shared<CommandEncoderVK>(context->GetDeviceHolder(),
146 tracked_objects, queue,
147 context->GetFenceWaiter());
151 std::weak_ptr<const DeviceHolder> device_holder,
152 std::shared_ptr<TrackedObjectsVK> tracked_objects,
153 const std::shared_ptr<QueueVK>& queue,
154 std::shared_ptr<FenceWaiterVK> fence_waiter)
155 : device_holder_(
std::move(device_holder)),
156 tracked_objects_(
std::move(tracked_objects)),
158 fence_waiter_(
std::move(fence_waiter)) {}
168 bool fail_callback = !!callback;
178 fml::ScopedCleanupClosure reset([&]() {
189 tracked_objects_->GetGPUProbe().RecordCmdBufferEnd(command_buffer);
191 auto status = command_buffer.end();
192 if (status != vk::Result::eSuccess) {
193 VALIDATION_LOG <<
"Failed to end command buffer: " << vk::to_string(status);
196 std::shared_ptr<const DeviceHolder> strong_device = device_holder_.lock();
197 if (!strong_device) {
201 auto [fence_result, fence] = strong_device->GetDevice().createFenceUnique({});
202 if (fence_result != vk::Result::eSuccess) {
203 VALIDATION_LOG <<
"Failed to create fence: " << vk::to_string(fence_result);
207 vk::SubmitInfo submit_info;
208 std::vector<vk::CommandBuffer> buffers = {command_buffer};
209 submit_info.setCommandBuffers(buffers);
210 status = queue_->Submit(submit_info, *fence);
211 if (status != vk::Result::eSuccess) {
212 VALIDATION_LOG <<
"Failed to submit queue: " << vk::to_string(status);
218 fail_callback =
false;
219 return fence_waiter_->AddFence(
221 [callback, tracked_objects = std::move(tracked_objects_)]()
mutable {
224 tracked_objects.reset();
232 if (tracked_objects_) {
233 return tracked_objects_->GetCommandBuffer();
238 void CommandEncoderVK::Reset() {
239 tracked_objects_.reset();
249 tracked_objects_->Track(std::move(
object));
257 tracked_objects_->Track(std::move(buffer));
262 const std::shared_ptr<const Buffer>& buffer)
const {
266 return tracked_objects_->IsTracking(buffer);
273 tracked_objects_->Track(std::move(texture));
288 const std::shared_ptr<const Texture>& texture)
const {
292 std::shared_ptr<const TextureSourceVK> source =
294 return tracked_objects_->IsTracking(source);
297 fml::StatusOr<std::vector<vk::DescriptorSet>>
299 uint32_t buffer_count,
300 uint32_t sampler_count,
301 uint32_t subpass_count,
302 const std::vector<vk::DescriptorSetLayout>& layouts) {
304 return fml::Status(fml::StatusCode::kUnknown,
"command encoder invalid");
307 return tracked_objects_->GetDescriptorPool().AllocateDescriptorSets(
308 buffer_count, sampler_count, subpass_count, layouts);
315 vk::DebugUtilsLabelEXT label_info;
316 label_info.pLabelName = label;
318 command_buffer.beginDebugUtilsLabelEXT(label_info);
327 command_buffer.endDebugUtilsLabelEXT();
335 vk::DebugUtilsLabelEXT label_info;
336 label_info.pLabelName = label;
338 command_buffer.insertDebugUtilsLabelEXT(label_info);
341 queue_->InsertDebugMarker(label);