Flutter Impeller
context_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 "fml/concurrent_message_loop.h"
11 
12 #ifdef FML_OS_ANDROID
13 #include <pthread.h>
14 #include <sys/resource.h>
15 #include <sys/time.h>
16 #endif // FML_OS_ANDROID
17 
18 #include <map>
19 #include <memory>
20 #include <optional>
21 #include <string>
22 #include <vector>
23 
24 #include "flutter/fml/cpu_affinity.h"
25 #include "flutter/fml/trace_event.h"
39 
40 VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
41 
42 namespace impeller {
43 
44 static bool gHasValidationLayers = false;
45 
47  return gHasValidationLayers;
48 }
49 
50 static std::optional<vk::PhysicalDevice> PickPhysicalDevice(
51  const CapabilitiesVK& caps,
52  const vk::Instance& instance) {
53  for (const auto& device : instance.enumeratePhysicalDevices().value) {
54  if (caps.GetEnabledDeviceFeatures(device).has_value()) {
55  return device;
56  }
57  }
58  return std::nullopt;
59 }
60 
61 static std::vector<vk::DeviceQueueCreateInfo> GetQueueCreateInfos(
62  std::initializer_list<QueueIndexVK> queues) {
63  std::map<size_t /* family */, size_t /* index */> family_index_map;
64  for (const auto& queue : queues) {
65  family_index_map[queue.family] = 0;
66  }
67  for (const auto& queue : queues) {
68  auto value = family_index_map[queue.family];
69  family_index_map[queue.family] = std::max(value, queue.index);
70  }
71 
72  static float kQueuePriority = 1.0f;
73  std::vector<vk::DeviceQueueCreateInfo> infos;
74  for (const auto& item : family_index_map) {
75  vk::DeviceQueueCreateInfo info;
76  info.setQueueFamilyIndex(item.first);
77  info.setQueueCount(item.second + 1);
78  info.setQueuePriorities(kQueuePriority);
79  infos.push_back(info);
80  }
81  return infos;
82 }
83 
84 static std::optional<QueueIndexVK> PickQueue(const vk::PhysicalDevice& device,
85  vk::QueueFlagBits flags) {
86  // This can be modified to ensure that dedicated queues are returned for each
87  // queue type depending on support.
88  const auto families = device.getQueueFamilyProperties();
89  for (size_t i = 0u; i < families.size(); i++) {
90  if (!(families[i].queueFlags & flags)) {
91  continue;
92  }
93  return QueueIndexVK{.family = i, .index = 0};
94  }
95  return std::nullopt;
96 }
97 
98 std::shared_ptr<ContextVK> ContextVK::Create(Settings settings) {
99  auto context = std::shared_ptr<ContextVK>(new ContextVK());
100  context->Setup(std::move(settings));
101  if (!context->IsValid()) {
102  return nullptr;
103  }
104  return context;
105 }
106 
107 // static
108 size_t ContextVK::ChooseThreadCountForWorkers(size_t hardware_concurrency) {
109  // Never create more than 4 worker threads. Attempt to use up to
110  // half of the available concurrency.
111  return std::clamp(hardware_concurrency / 2ull, /*lo=*/1ull, /*hi=*/4ull);
112 }
113 
114 namespace {
115 thread_local uint64_t tls_context_count = 0;
116 uint64_t CalculateHash(void* ptr) {
117  // You could make a context once per nanosecond for 584 years on one thread
118  // before this overflows.
119  return ++tls_context_count;
120 }
121 } // namespace
122 
123 ContextVK::ContextVK() : hash_(CalculateHash(this)) {}
124 
126  if (device_holder_ && device_holder_->device) {
127  [[maybe_unused]] auto result = device_holder_->device->waitIdle();
128  }
130 }
131 
134 }
135 
136 void ContextVK::Setup(Settings settings) {
137  TRACE_EVENT0("impeller", "ContextVK::Setup");
138 
139  if (!settings.proc_address_callback) {
140  return;
141  }
142 
143  raster_message_loop_ = fml::ConcurrentMessageLoop::Create(
144  ChooseThreadCountForWorkers(std::thread::hardware_concurrency()));
145  raster_message_loop_->PostTaskToAllWorkers([]() {
146  // Currently we only use the worker task pool for small parts of a frame
147  // workload, if this changes this setting may need to be adjusted.
148  fml::RequestAffinity(fml::CpuAffinity::kNotPerformance);
149 #ifdef FML_OS_ANDROID
150  if (::setpriority(PRIO_PROCESS, gettid(), -5) != 0) {
151  FML_LOG(ERROR) << "Failed to set Workers task runner priority";
152  }
153 #endif // FML_OS_ANDROID
154  });
155 
156  auto& dispatcher = VULKAN_HPP_DEFAULT_DISPATCHER;
157  dispatcher.init(settings.proc_address_callback);
158 
159  auto caps = std::shared_ptr<CapabilitiesVK>(new CapabilitiesVK(
160  settings.enable_validation, settings.fatal_missing_validations));
161 
162  if (!caps->IsValid()) {
163  VALIDATION_LOG << "Could not determine device capabilities.";
164  return;
165  }
166 
167  gHasValidationLayers = caps->AreValidationsEnabled();
168 
169  auto enabled_layers = caps->GetEnabledLayers();
170  auto enabled_extensions = caps->GetEnabledInstanceExtensions();
171 
172  if (!enabled_layers.has_value() || !enabled_extensions.has_value()) {
173  VALIDATION_LOG << "Device has insufficient capabilities.";
174  return;
175  }
176 
177  vk::InstanceCreateFlags instance_flags = {};
178 
179  if (std::find(enabled_extensions.value().begin(),
180  enabled_extensions.value().end(),
181  "VK_KHR_portability_enumeration") !=
182  enabled_extensions.value().end()) {
183  instance_flags |= vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR;
184  }
185 
186  std::vector<const char*> enabled_layers_c;
187  std::vector<const char*> enabled_extensions_c;
188 
189  for (const auto& layer : enabled_layers.value()) {
190  enabled_layers_c.push_back(layer.c_str());
191  }
192 
193  for (const auto& ext : enabled_extensions.value()) {
194  enabled_extensions_c.push_back(ext.c_str());
195  }
196 
197  vk::ApplicationInfo application_info;
198  application_info.setApplicationVersion(VK_API_VERSION_1_0);
199  application_info.setApiVersion(VK_API_VERSION_1_1);
200  application_info.setEngineVersion(VK_API_VERSION_1_0);
201  application_info.setPEngineName("Impeller");
202  application_info.setPApplicationName("Impeller");
203 
204  vk::StructureChain<vk::InstanceCreateInfo, vk::ValidationFeaturesEXT>
205  instance_chain;
206 
207  if (!caps->AreValidationsEnabled()) {
208  instance_chain.unlink<vk::ValidationFeaturesEXT>();
209  }
210 
211  std::vector<vk::ValidationFeatureEnableEXT> enabled_validations = {
212  vk::ValidationFeatureEnableEXT::eSynchronizationValidation,
213  };
214 
215  auto validation = instance_chain.get<vk::ValidationFeaturesEXT>();
216  validation.setEnabledValidationFeatures(enabled_validations);
217 
218  auto instance_info = instance_chain.get<vk::InstanceCreateInfo>();
219  instance_info.setPEnabledLayerNames(enabled_layers_c);
220  instance_info.setPEnabledExtensionNames(enabled_extensions_c);
221  instance_info.setPApplicationInfo(&application_info);
222  instance_info.setFlags(instance_flags);
223 
224  auto device_holder = std::make_shared<DeviceHolderImpl>();
225  {
226  auto instance = vk::createInstanceUnique(instance_info);
227  if (instance.result != vk::Result::eSuccess) {
228  VALIDATION_LOG << "Could not create Vulkan instance: "
229  << vk::to_string(instance.result);
230  return;
231  }
232  device_holder->instance = std::move(instance.value);
233  }
234  dispatcher.init(device_holder->instance.get());
235 
236  //----------------------------------------------------------------------------
237  /// Setup the debug report.
238  ///
239  /// Do this as early as possible since we could use the debug report from
240  /// initialization issues.
241  ///
242  auto debug_report =
243  std::make_unique<DebugReportVK>(*caps, device_holder->instance.get());
244 
245  if (!debug_report->IsValid()) {
246  VALIDATION_LOG << "Could not set up debug report.";
247  return;
248  }
249 
250  //----------------------------------------------------------------------------
251  /// Pick the physical device.
252  ///
253  {
254  auto physical_device =
255  PickPhysicalDevice(*caps, device_holder->instance.get());
256  if (!physical_device.has_value()) {
257  VALIDATION_LOG << "No valid Vulkan device found.";
258  return;
259  }
260  device_holder->physical_device = physical_device.value();
261  }
262 
263  //----------------------------------------------------------------------------
264  /// Pick device queues.
265  ///
266  auto graphics_queue =
267  PickQueue(device_holder->physical_device, vk::QueueFlagBits::eGraphics);
268  auto transfer_queue =
269  PickQueue(device_holder->physical_device, vk::QueueFlagBits::eTransfer);
270  auto compute_queue =
271  PickQueue(device_holder->physical_device, vk::QueueFlagBits::eCompute);
272 
273  if (!graphics_queue.has_value()) {
274  VALIDATION_LOG << "Could not pick graphics queue.";
275  return;
276  }
277  if (!transfer_queue.has_value()) {
278  transfer_queue = graphics_queue.value();
279  }
280  if (!compute_queue.has_value()) {
281  VALIDATION_LOG << "Could not pick compute queue.";
282  return;
283  }
284 
285  //----------------------------------------------------------------------------
286  /// Create the logical device.
287  ///
288  auto enabled_device_extensions =
289  caps->GetEnabledDeviceExtensions(device_holder->physical_device);
290  if (!enabled_device_extensions.has_value()) {
291  // This shouldn't happen since we already did device selection. But
292  // doesn't hurt to check again.
293  return;
294  }
295 
296  std::vector<const char*> enabled_device_extensions_c;
297  for (const auto& ext : enabled_device_extensions.value()) {
298  enabled_device_extensions_c.push_back(ext.c_str());
299  }
300 
301  const auto queue_create_infos = GetQueueCreateInfos(
302  {graphics_queue.value(), compute_queue.value(), transfer_queue.value()});
303 
304  const auto enabled_features =
305  caps->GetEnabledDeviceFeatures(device_holder->physical_device);
306  if (!enabled_features.has_value()) {
307  // This shouldn't happen since the device can't be picked if this was not
308  // true. But doesn't hurt to check.
309  return;
310  }
311 
312  vk::DeviceCreateInfo device_info;
313 
314  device_info.setPNext(&enabled_features.value().get());
315  device_info.setQueueCreateInfos(queue_create_infos);
316  device_info.setPEnabledExtensionNames(enabled_device_extensions_c);
317  // Device layers are deprecated and ignored.
318 
319  {
320  auto device_result =
321  device_holder->physical_device.createDeviceUnique(device_info);
322  if (device_result.result != vk::Result::eSuccess) {
323  VALIDATION_LOG << "Could not create logical device.";
324  return;
325  }
326  device_holder->device = std::move(device_result.value);
327  }
328 
329  if (!caps->SetPhysicalDevice(device_holder->physical_device,
330  *enabled_features)) {
331  VALIDATION_LOG << "Capabilities could not be updated.";
332  return;
333  }
334 
335  //----------------------------------------------------------------------------
336  /// Create the allocator.
337  ///
338  auto allocator = std::shared_ptr<AllocatorVK>(new AllocatorVK(
339  weak_from_this(), //
340  application_info.apiVersion, //
341  device_holder->physical_device, //
342  device_holder, //
343  device_holder->instance.get(), //
344  *caps //
345  ));
346 
347  if (!allocator->IsValid()) {
348  VALIDATION_LOG << "Could not create memory allocator.";
349  return;
350  }
351 
352  //----------------------------------------------------------------------------
353  /// Setup the pipeline library.
354  ///
355  auto pipeline_library = std::shared_ptr<PipelineLibraryVK>(
356  new PipelineLibraryVK(device_holder, //
357  caps, //
358  std::move(settings.cache_directory), //
359  raster_message_loop_->GetTaskRunner() //
360  ));
361 
362  if (!pipeline_library->IsValid()) {
363  VALIDATION_LOG << "Could not create pipeline library.";
364  return;
365  }
366 
367  auto sampler_library =
368  std::shared_ptr<SamplerLibraryVK>(new SamplerLibraryVK(device_holder));
369 
370  auto shader_library = std::shared_ptr<ShaderLibraryVK>(
371  new ShaderLibraryVK(device_holder, //
372  settings.shader_libraries_data) //
373  );
374 
375  if (!shader_library->IsValid()) {
376  VALIDATION_LOG << "Could not create shader library.";
377  return;
378  }
379 
380  //----------------------------------------------------------------------------
381  /// Create the fence waiter.
382  ///
383  auto fence_waiter =
384  std::shared_ptr<FenceWaiterVK>(new FenceWaiterVK(device_holder));
385 
386  //----------------------------------------------------------------------------
387  /// Create the resource manager and command pool recycler.
388  ///
389  auto resource_manager = ResourceManagerVK::Create();
390  if (!resource_manager) {
391  VALIDATION_LOG << "Could not create resource manager.";
392  return;
393  }
394 
395  auto command_pool_recycler =
396  std::make_shared<CommandPoolRecyclerVK>(weak_from_this());
397  if (!command_pool_recycler) {
398  VALIDATION_LOG << "Could not create command pool recycler.";
399  return;
400  }
401 
402  auto descriptor_pool_recycler =
403  std::make_shared<DescriptorPoolRecyclerVK>(weak_from_this());
404  if (!descriptor_pool_recycler) {
405  VALIDATION_LOG << "Could not create descriptor pool recycler.";
406  return;
407  }
408 
409  //----------------------------------------------------------------------------
410  /// Fetch the queues.
411  ///
412  QueuesVK queues(device_holder->device.get(), //
413  graphics_queue.value(), //
414  compute_queue.value(), //
415  transfer_queue.value() //
416  );
417  if (!queues.IsValid()) {
418  VALIDATION_LOG << "Could not fetch device queues.";
419  return;
420  }
421 
422  VkPhysicalDeviceProperties physical_device_properties;
423  dispatcher.vkGetPhysicalDeviceProperties(device_holder->physical_device,
424  &physical_device_properties);
425 
426  //----------------------------------------------------------------------------
427  /// All done!
428  ///
429  device_holder_ = std::move(device_holder);
430  driver_info_ =
431  std::make_unique<DriverInfoVK>(device_holder_->physical_device);
432  debug_report_ = std::move(debug_report);
433  allocator_ = std::move(allocator);
434  shader_library_ = std::move(shader_library);
435  sampler_library_ = std::move(sampler_library);
436  pipeline_library_ = std::move(pipeline_library);
437  yuv_conversion_library_ = std::shared_ptr<YUVConversionLibraryVK>(
438  new YUVConversionLibraryVK(device_holder_));
439  queues_ = std::move(queues);
440  device_capabilities_ = std::move(caps);
441  fence_waiter_ = std::move(fence_waiter);
442  resource_manager_ = std::move(resource_manager);
443  command_pool_recycler_ = std::move(command_pool_recycler);
444  descriptor_pool_recycler_ = std::move(descriptor_pool_recycler);
445  device_name_ = std::string(physical_device_properties.deviceName);
446  command_queue_vk_ = std::make_shared<CommandQueueVK>(weak_from_this());
447  should_disable_surface_control_ = settings.disable_surface_control;
448  is_valid_ = true;
449 
450  // Create the GPU Tracer later because it depends on state from
451  // the ContextVK.
452  gpu_tracer_ = std::make_shared<GPUTracerVK>(weak_from_this(),
453  settings.enable_gpu_tracing);
454  gpu_tracer_->InitializeQueryPool(*this);
455 
456  //----------------------------------------------------------------------------
457  /// Label all the relevant objects. This happens after setup so that the
458  /// debug messengers have had a chance to be set up.
459  ///
460  SetDebugName(GetDevice(), device_holder_->device.get(), "ImpellerDevice");
461 }
462 
464  CapabilitiesVK::Cast(*device_capabilities_).SetOffscreenFormat(pixel_format);
465 }
466 
467 // |Context|
468 std::string ContextVK::DescribeGpuModel() const {
469  return device_name_;
470 }
471 
472 bool ContextVK::IsValid() const {
473  return is_valid_;
474 }
475 
476 std::shared_ptr<Allocator> ContextVK::GetResourceAllocator() const {
477  return allocator_;
478 }
479 
480 std::shared_ptr<ShaderLibrary> ContextVK::GetShaderLibrary() const {
481  return shader_library_;
482 }
483 
484 std::shared_ptr<SamplerLibrary> ContextVK::GetSamplerLibrary() const {
485  return sampler_library_;
486 }
487 
488 std::shared_ptr<PipelineLibrary> ContextVK::GetPipelineLibrary() const {
489  return pipeline_library_;
490 }
491 
492 std::shared_ptr<CommandBuffer> ContextVK::CreateCommandBuffer() const {
493  const auto& recycler = GetCommandPoolRecycler();
494  auto tls_pool = recycler->Get();
495  if (!tls_pool) {
496  return nullptr;
497  }
498 
499  auto tracked_objects = std::make_shared<TrackedObjectsVK>(
500  weak_from_this(), std::move(tls_pool), GetGPUTracer()->CreateGPUProbe());
501  auto queue = GetGraphicsQueue();
502 
503  if (!tracked_objects || !tracked_objects->IsValid() || !queue) {
504  return nullptr;
505  }
506 
507  vk::CommandBufferBeginInfo begin_info;
508  begin_info.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit;
509  if (tracked_objects->GetCommandBuffer().begin(begin_info) !=
510  vk::Result::eSuccess) {
511  VALIDATION_LOG << "Could not begin command buffer.";
512  return nullptr;
513  }
514 
515  tracked_objects->GetGPUProbe().RecordCmdBufferStart(
516  tracked_objects->GetCommandBuffer());
517 
518  return std::shared_ptr<CommandBufferVK>(new CommandBufferVK(
519  shared_from_this(), //
520  GetDeviceHolder(), //
521  std::move(tracked_objects), //
522  GetFenceWaiter() //
523  ));
524 }
525 
526 vk::Instance ContextVK::GetInstance() const {
527  return *device_holder_->instance;
528 }
529 
530 const vk::Device& ContextVK::GetDevice() const {
531  return device_holder_->device.get();
532 }
533 
534 const std::shared_ptr<fml::ConcurrentTaskRunner>
536  return raster_message_loop_->GetTaskRunner();
537 }
538 
540  // There are multiple objects, for example |CommandPoolVK|, that in their
541  // destructors make a strong reference to |ContextVK|. Resetting these shared
542  // pointers ensures that cleanup happens in a correct order.
543  //
544  // tl;dr: Without it, we get thread::join failures on shutdown.
545  fence_waiter_.reset();
546  resource_manager_.reset();
547 
548  raster_message_loop_->Terminate();
549 }
550 
551 std::shared_ptr<SurfaceContextVK> ContextVK::CreateSurfaceContext() {
552  return std::make_shared<SurfaceContextVK>(shared_from_this());
553 }
554 
555 const std::shared_ptr<const Capabilities>& ContextVK::GetCapabilities() const {
556  return device_capabilities_;
557 }
558 
559 const std::shared_ptr<QueueVK>& ContextVK::GetGraphicsQueue() const {
560  return queues_.graphics_queue;
561 }
562 
563 vk::PhysicalDevice ContextVK::GetPhysicalDevice() const {
564  return device_holder_->physical_device;
565 }
566 
567 std::shared_ptr<FenceWaiterVK> ContextVK::GetFenceWaiter() const {
568  return fence_waiter_;
569 }
570 
571 std::shared_ptr<ResourceManagerVK> ContextVK::GetResourceManager() const {
572  return resource_manager_;
573 }
574 
575 std::shared_ptr<CommandPoolRecyclerVK> ContextVK::GetCommandPoolRecycler()
576  const {
577  return command_pool_recycler_;
578 }
579 
580 std::shared_ptr<GPUTracerVK> ContextVK::GetGPUTracer() const {
581  return gpu_tracer_;
582 }
583 
584 std::shared_ptr<DescriptorPoolRecyclerVK> ContextVK::GetDescriptorPoolRecycler()
585  const {
586  return descriptor_pool_recycler_;
587 }
588 
589 std::shared_ptr<CommandQueue> ContextVK::GetCommandQueue() const {
590  return command_queue_vk_;
591 }
592 
593 // Creating a render pass is observed to take an additional 6ms on a Pixel 7
594 // device as the driver will lazily bootstrap and compile shaders to do so.
595 // The render pass does not need to be begun or executed.
598  RenderTarget render_target =
599  rt_allocator.CreateOffscreenMSAA(*this, {1, 1}, 1);
600 
601  RenderPassBuilderVK builder;
602  for (const auto& [bind_point, color] : render_target.GetColorAttachments()) {
603  builder.SetColorAttachment(
604  bind_point, //
605  color.texture->GetTextureDescriptor().format, //
606  color.texture->GetTextureDescriptor().sample_count, //
607  color.load_action, //
608  color.store_action //
609  );
610  }
611 
612  if (auto depth = render_target.GetDepthAttachment(); depth.has_value()) {
614  depth->texture->GetTextureDescriptor().format, //
615  depth->texture->GetTextureDescriptor().sample_count, //
616  depth->load_action, //
617  depth->store_action //
618  );
619  } else if (auto stencil = render_target.GetStencilAttachment();
620  stencil.has_value()) {
621  builder.SetStencilAttachment(
622  stencil->texture->GetTextureDescriptor().format, //
623  stencil->texture->GetTextureDescriptor().sample_count, //
624  stencil->load_action, //
625  stencil->store_action //
626  );
627  }
628 
629  auto pass = builder.Build(GetDevice());
630 }
631 
633  command_pool_recycler_->Dispose();
634 }
635 
636 const std::shared_ptr<YUVConversionLibraryVK>&
638  return yuv_conversion_library_;
639 }
640 
641 const std::unique_ptr<DriverInfoVK>& ContextVK::GetDriverInfo() const {
642  return driver_info_;
643 }
644 
646  return should_disable_surface_control_;
647 }
648 
649 } // namespace impeller
impeller::ContextVK::GetCapabilities
const std::shared_ptr< const Capabilities > & GetCapabilities() const override
Get the capabilities of Impeller context. All optionally supported feature of the platform,...
Definition: context_vk.cc:555
impeller::ContextVK::GetConcurrentWorkerTaskRunner
const std::shared_ptr< fml::ConcurrentTaskRunner > GetConcurrentWorkerTaskRunner() const
Definition: context_vk.cc:535
impeller::ContextVK::GetDeviceHolder
std::shared_ptr< DeviceHolderVK > GetDeviceHolder() const
Definition: context_vk.h:137
fence_waiter_vk.h
impeller::CapabilitiesVK::SetOffscreenFormat
void SetOffscreenFormat(PixelFormat pixel_format) const
Definition: capabilities_vk.cc:464
gpu_tracer_vk.h
impeller::ResourceManagerVK::Create
static std::shared_ptr< ResourceManagerVK > Create()
Creates a shared resource manager (a dedicated thread).
Definition: resource_manager_vk.cc:14
impeller::QueueIndexVK
Definition: queue_vk.h:15
allocator_vk.h
impeller::gHasValidationLayers
static bool gHasValidationLayers
Definition: context_vk.cc:44
impeller::CommandPoolRecyclerVK::DestroyThreadLocalPools
static void DestroyThreadLocalPools(const ContextVK *context)
Clean up resources held by all per-thread command pools associated with the given context.
Definition: command_pool_vk.cc:285
impeller::ContextVK::GetCommandQueue
std::shared_ptr< CommandQueue > GetCommandQueue() const override
Return the graphics queue for submitting command buffers.
Definition: context_vk.cc:589
impeller::Context::BackendType
BackendType
Definition: context.h:48
impeller::ContextVK::IsValid
bool IsValid() const override
Determines if a context is valid. If the caller ever receives an invalid context, they must discard i...
Definition: context_vk.cc:472
impeller::ContextVK::GetInstance
vk::Instance GetInstance() const
Definition: context_vk.cc:526
impeller::PickPhysicalDevice
static std::optional< vk::PhysicalDevice > PickPhysicalDevice(const CapabilitiesVK &caps, const vk::Instance &instance)
Definition: context_vk.cc:50
impeller::RenderPassBuilderVK::SetStencilAttachment
RenderPassBuilderVK & SetStencilAttachment(PixelFormat format, SampleCount sample_count, LoadAction load_action, StoreAction store_action)
Definition: render_pass_builder_vk.cc:74
impeller::ContextVK::GetPhysicalDevice
vk::PhysicalDevice GetPhysicalDevice() const
Definition: context_vk.cc:563
impeller::ContextVK::GetResourceAllocator
std::shared_ptr< Allocator > GetResourceAllocator() const override
Returns the allocator used to create textures and buffers on the device.
Definition: context_vk.cc:476
impeller::ContextVK::GetBackendType
BackendType GetBackendType() const override
Get the graphics backend of an Impeller context.
Definition: context_vk.cc:132
impeller::ContextVK::CreateCommandBuffer
std::shared_ptr< CommandBuffer > CreateCommandBuffer() const override
Create a new command buffer. Command buffers can be used to encode graphics, blit,...
Definition: context_vk.cc:492
yuv_conversion_library_vk.h
impeller::RenderPassBuilderVK
Definition: render_pass_builder_vk.h:17
surface_context_vk.h
impeller::RenderTarget::GetColorAttachments
const std::map< size_t, ColorAttachment > & GetColorAttachments() const
Definition: render_target.cc:198
validation.h
impeller::CapabilitiesVK::GetEnabledDeviceFeatures
std::optional< PhysicalDeviceFeatures > GetEnabledDeviceFeatures(const vk::PhysicalDevice &physical_device) const
Definition: capabilities_vk.cc:353
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
impeller::GetQueueCreateInfos
static std::vector< vk::DeviceQueueCreateInfo > GetQueueCreateInfos(std::initializer_list< QueueIndexVK > queues)
Definition: context_vk.cc:61
capabilities_vk.h
impeller::RenderPassBuilderVK::SetDepthStencilAttachment
RenderPassBuilderVK & SetDepthStencilAttachment(PixelFormat format, SampleCount sample_count, LoadAction load_action, StoreAction store_action)
Definition: render_pass_builder_vk.cc:56
command_pool_vk.h
impeller::ContextVK::Settings
Definition: context_vk.h:46
command_buffer_vk.h
impeller::RenderTarget::GetDepthAttachment
const std::optional< DepthAttachment > & GetDepthAttachment() const
Definition: render_target.cc:203
impeller::ContextVK::CreateSurfaceContext
std::shared_ptr< SurfaceContextVK > CreateSurfaceContext()
Definition: context_vk.cc:551
debug_report_vk.h
impeller::ContextVK::GetShaderLibrary
std::shared_ptr< ShaderLibrary > GetShaderLibrary() const override
Returns the library of shaders used to specify the programmable stages of a pipeline.
Definition: context_vk.cc:480
impeller::ContextVK::GetShouldDisableSurfaceControlSwapchain
bool GetShouldDisableSurfaceControlSwapchain() const
Whether the Android Surface control based swapchain should be disabled, even if the device is capable...
Definition: context_vk.cc:645
impeller::ContextVK::GetGraphicsQueue
const std::shared_ptr< QueueVK > & GetGraphicsQueue() const
Definition: context_vk.cc:559
impeller::ContextVK::GetDescriptorPoolRecycler
std::shared_ptr< DescriptorPoolRecyclerVK > GetDescriptorPoolRecycler() const
Definition: context_vk.cc:584
impeller::QueuesVK::graphics_queue
std::shared_ptr< QueueVK > graphics_queue
Definition: queue_vk.h:64
impeller::RenderPassBuilderVK::SetColorAttachment
RenderPassBuilderVK & SetColorAttachment(size_t index, PixelFormat format, SampleCount sample_count, LoadAction load_action, StoreAction store_action)
Definition: render_pass_builder_vk.cc:29
render_pass_builder_vk.h
capabilities.h
impeller::RenderTarget
Definition: render_target.h:38
impeller::ContextVK::Create
static std::shared_ptr< ContextVK > Create(Settings settings)
Definition: context_vk.cc:98
impeller::CapabilitiesVK
The Vulkan layers and extensions wrangler.
Definition: capabilities_vk.h:169
impeller::CommandBufferVK
Definition: command_buffer_vk.h:23
impeller::ContextVK::SetDebugName
bool SetDebugName(T handle, std::string_view label) const
Definition: context_vk.h:109
impeller::ContextVK::GetCommandPoolRecycler
std::shared_ptr< CommandPoolRecyclerVK > GetCommandPoolRecycler() const
Definition: context_vk.cc:575
impeller::RenderTargetAllocator::CreateOffscreenMSAA
virtual RenderTarget CreateOffscreenMSAA(const Context &context, ISize size, int mip_count, const std::string &label="Offscreen MSAA", RenderTarget::AttachmentConfigMSAA color_attachment_config=RenderTarget::kDefaultColorAttachmentConfigMSAA, std::optional< RenderTarget::AttachmentConfig > stencil_attachment_config=RenderTarget::kDefaultStencilAttachmentConfig, const std::shared_ptr< Texture > &existing_color_msaa_texture=nullptr, const std::shared_ptr< Texture > &existing_color_resolve_texture=nullptr, const std::shared_ptr< Texture > &existing_depth_stencil_texture=nullptr)
Definition: render_target.cc:313
impeller::RenderTargetAllocator
a wrapper around the impeller [Allocator] instance that can be used to provide caching of allocated r...
Definition: render_target.h:142
impeller::ContextVK::GetGPUTracer
std::shared_ptr< GPUTracerVK > GetGPUTracer() const
Definition: context_vk.cc:580
impeller::ContextVK
Definition: context_vk.h:42
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91
impeller::ContextVK::InitializeCommonlyUsedShadersIfNeeded
void InitializeCommonlyUsedShadersIfNeeded() const override
Definition: context_vk.cc:596
impeller::Context::BackendType::kVulkan
@ kVulkan
resource_manager_vk.h
impeller::ContextVK::~ContextVK
~ContextVK() override
Definition: context_vk.cc:125
impeller::ContextVK::GetSamplerLibrary
std::shared_ptr< SamplerLibrary > GetSamplerLibrary() const override
Returns the library of combined image samplers used in shaders.
Definition: context_vk.cc:484
impeller::ContextVK::GetDevice
const vk::Device & GetDevice() const
Definition: context_vk.cc:530
impeller::ContextVK::ChooseThreadCountForWorkers
static size_t ChooseThreadCountForWorkers(size_t hardware_concurrency)
Definition: context_vk.cc:108
impeller::BackendCast< CapabilitiesVK, Capabilities >::Cast
static CapabilitiesVK & Cast(Capabilities &base)
Definition: backend_cast.h:13
impeller::ContextVK::GetResourceManager
std::shared_ptr< ResourceManagerVK > GetResourceManager() const
Definition: context_vk.cc:571
command_queue_vk.h
impeller::ContextVK::GetDriverInfo
const std::unique_ptr< DriverInfoVK > & GetDriverInfo() const
Definition: context_vk.cc:641
impeller::PickQueue
static std::optional< QueueIndexVK > PickQueue(const vk::PhysicalDevice &device, vk::QueueFlagBits flags)
Definition: context_vk.cc:84
color
DlColor color
Definition: dl_golden_blur_unittests.cc:24
impeller::ContextVK::GetYUVConversionLibrary
const std::shared_ptr< YUVConversionLibraryVK > & GetYUVConversionLibrary() const
Definition: context_vk.cc:637
impeller::ContextVK::GetPipelineLibrary
std::shared_ptr< PipelineLibrary > GetPipelineLibrary() const override
Returns the library of pipelines used by render or compute commands.
Definition: context_vk.cc:488
impeller::ContextVK::DescribeGpuModel
std::string DescribeGpuModel() const override
Definition: context_vk.cc:468
impeller::ContextVK::GetFenceWaiter
std::shared_ptr< FenceWaiterVK > GetFenceWaiter() const
Definition: context_vk.cc:567
impeller::RenderPassBuilderVK::Build
vk::UniqueRenderPass Build(const vk::Device &device) const
Definition: render_pass_builder_vk.cc:92
render_target.h
impeller::QueueIndexVK::family
size_t family
Definition: queue_vk.h:16
impeller::ContextVK::SetOffscreenFormat
void SetOffscreenFormat(PixelFormat pixel_format)
Definition: context_vk.cc:463
impeller::RenderTarget::GetStencilAttachment
const std::optional< StencilAttachment > & GetStencilAttachment() const
Definition: render_target.cc:207
context_vk.h
impeller::interop::Create
ScopedObject< Object > Create(CtorArgs &&... args)
Definition: object.h:160
impeller::HasValidationLayers
bool HasValidationLayers()
Definition: context_vk.cc:46
impeller::ContextVK::Shutdown
void Shutdown() override
Force all pending asynchronous work to finish. This is achieved by deleting all owned concurrent mess...
Definition: context_vk.cc:539
impeller
Definition: allocation.cc:12
impeller::ContextVK::DisposeThreadLocalCachedResources
void DisposeThreadLocalCachedResources() override
Definition: context_vk.cc:632