Flutter Impeller
command_buffer_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 
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "fml/logging.h"
19 
20 namespace impeller {
21 
22 CommandBufferVK::CommandBufferVK(
23  std::weak_ptr<const Context> context,
24  std::weak_ptr<const DeviceHolderVK> device_holder,
25  std::shared_ptr<TrackedObjectsVK> tracked_objects)
26  : CommandBuffer(std::move(context)),
27  device_holder_(std::move(device_holder)),
28  tracked_objects_(std::move(tracked_objects)) {}
29 
30 CommandBufferVK::~CommandBufferVK() = default;
31 
32 void CommandBufferVK::SetLabel(std::string_view label) const {
33 #ifdef IMPELLER_DEBUG
34  auto context = context_.lock();
35  if (!context) {
36  return;
37  }
38  ContextVK::Cast(*context).SetDebugName(GetCommandBuffer(), label);
39 #endif // IMPELLER_DEBUG
40 }
41 
42 bool CommandBufferVK::IsValid() const {
43  return true;
44 }
45 
46 bool CommandBufferVK::OnSubmitCommands(bool block_on_schedule,
47  CompletionCallback callback) {
48  FML_UNREACHABLE()
49 }
50 
51 void CommandBufferVK::OnWaitUntilCompleted() {}
52 
53 void CommandBufferVK::OnWaitUntilScheduled() {}
54 
55 std::shared_ptr<RenderPass> CommandBufferVK::OnCreateRenderPass(
56  RenderTarget target) {
57  auto context = context_.lock();
58  if (!context) {
59  return nullptr;
60  }
61  auto pass =
62  std::shared_ptr<RenderPassVK>(new RenderPassVK(context, //
63  target, //
64  shared_from_this() //
65  ));
66  if (!pass->IsValid()) {
67  return nullptr;
68  }
69  return pass;
70 }
71 
72 std::shared_ptr<BlitPass> CommandBufferVK::OnCreateBlitPass() {
73  if (!IsValid()) {
74  return nullptr;
75  }
76  auto context = context_.lock();
77  if (!context) {
78  return nullptr;
79  }
80  auto pass = std::shared_ptr<BlitPassVK>(new BlitPassVK(
81  shared_from_this(), ContextVK::Cast(*context).GetWorkarounds()));
82  if (!pass->IsValid()) {
83  return nullptr;
84  }
85  return pass;
86 }
87 
88 std::shared_ptr<ComputePass> CommandBufferVK::OnCreateComputePass() {
89  if (!IsValid()) {
90  return nullptr;
91  }
92  auto context = context_.lock();
93  if (!context) {
94  return nullptr;
95  }
96  auto pass =
97  std::shared_ptr<ComputePassVK>(new ComputePassVK(context, //
98  shared_from_this() //
99  ));
100  if (!pass->IsValid()) {
101  return nullptr;
102  }
103  return pass;
104 }
105 
106 bool CommandBufferVK::EndCommandBuffer() const {
107  InsertDebugMarker("QueueSubmit");
108 
109  auto command_buffer = GetCommandBuffer();
110  tracked_objects_->GetGPUProbe().RecordCmdBufferEnd(command_buffer);
111 
112  auto status = command_buffer.end();
113  if (status != vk::Result::eSuccess) {
114  VALIDATION_LOG << "Failed to end command buffer: " << vk::to_string(status);
115  return false;
116  }
117  return true;
118 }
119 
120 vk::CommandBuffer CommandBufferVK::GetCommandBuffer() const {
121  if (tracked_objects_) {
122  return tracked_objects_->GetCommandBuffer();
123  }
124  return {};
125 }
126 
127 bool CommandBufferVK::Track(const std::shared_ptr<SharedObjectVK>& object) {
128  if (!IsValid()) {
129  return false;
130  }
131  tracked_objects_->Track(object);
132  return true;
133 }
134 
135 bool CommandBufferVK::Track(const std::shared_ptr<const DeviceBuffer>& buffer) {
136  if (!IsValid()) {
137  return false;
138  }
139  tracked_objects_->Track(buffer);
140  return true;
141 }
142 
143 bool CommandBufferVK::Track(
144  const std::shared_ptr<const TextureSourceVK>& texture) {
145  if (!IsValid()) {
146  return false;
147  }
148  tracked_objects_->Track(texture);
149  return true;
150 }
151 
152 bool CommandBufferVK::Track(const std::shared_ptr<const Texture>& texture) {
153  if (!IsValid()) {
154  return false;
155  }
156  if (!texture) {
157  return true;
158  }
159  return Track(TextureVK::Cast(*texture).GetTextureSource());
160 }
161 
162 fml::StatusOr<vk::DescriptorSet> CommandBufferVK::AllocateDescriptorSets(
163  const vk::DescriptorSetLayout& layout,
164  PipelineKey pipeline_key,
165  const ContextVK& context) {
166  if (!IsValid()) {
167  return fml::Status(fml::StatusCode::kUnknown, "command encoder invalid");
168  }
169 
170  return tracked_objects_->GetDescriptorPool().AllocateDescriptorSets(
171  layout, pipeline_key, context);
172 }
173 
174 void CommandBufferVK::PushDebugGroup(std::string_view label) const {
175  if (!HasValidationLayers()) {
176  return;
177  }
178  vk::DebugUtilsLabelEXT label_info;
179  label_info.pLabelName = label.data();
180  if (auto command_buffer = GetCommandBuffer()) {
181  command_buffer.beginDebugUtilsLabelEXT(label_info);
182  }
183 }
184 
185 void CommandBufferVK::PopDebugGroup() const {
186  if (!HasValidationLayers()) {
187  return;
188  }
189  if (auto command_buffer = GetCommandBuffer()) {
190  command_buffer.endDebugUtilsLabelEXT();
191  }
192 }
193 
194 void CommandBufferVK::InsertDebugMarker(std::string_view label) const {
195  if (!HasValidationLayers()) {
196  return;
197  }
198  vk::DebugUtilsLabelEXT label_info;
199  label_info.pLabelName = label.data();
200  if (auto command_buffer = GetCommandBuffer()) {
201  command_buffer.insertDebugUtilsLabelEXT(label_info);
202  }
203 }
204 
205 DescriptorPoolVK& CommandBufferVK::GetDescriptorPool() const {
206  return tracked_objects_->GetDescriptorPool();
207 }
208 
209 } // namespace impeller
A per-frame descriptor pool. Descriptors from this pool don't need to be freed individually....
int64_t PipelineKey
Definition: pipeline.h:21
bool HasValidationLayers()
Definition: context_vk.cc:53
Definition: comparable.h:95
#define VALIDATION_LOG
Definition: validation.h:91