Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
capabilities_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 <algorithm>
8#include <array>
9
14
15// vulkan.hpp generates some clang-tidy warnings.
16// NOLINTBEGIN(clang-analyzer-security.PointerSub)
17
18namespace impeller {
19
20static constexpr const char* kInstanceLayer = "ImpellerInstance";
21
22CapabilitiesVK::CapabilitiesVK(bool enable_validations,
23 bool fatal_missing_validations,
24 bool use_embedder_extensions,
25 std::vector<std::string> instance_extensions,
26 std::vector<std::string> device_extensions)
27 : use_embedder_extensions_(use_embedder_extensions),
28 embedder_instance_extensions_(std::move(instance_extensions)),
29 embedder_device_extensions_(std::move(device_extensions)) {
30 if (!use_embedder_extensions_) {
31 auto extensions = vk::enumerateInstanceExtensionProperties();
32 auto layers = vk::enumerateInstanceLayerProperties();
33
34 if (extensions.result != vk::Result::eSuccess ||
35 layers.result != vk::Result::eSuccess) {
36 return;
37 }
38
39 for (const auto& ext : extensions.value) {
40 exts_[kInstanceLayer].insert(ext.extensionName);
41 }
42
43 for (const auto& layer : layers.value) {
44 const std::string layer_name = layer.layerName;
45 auto layer_exts = vk::enumerateInstanceExtensionProperties(layer_name);
46 if (layer_exts.result != vk::Result::eSuccess) {
47 return;
48 }
49 for (const auto& layer_ext : layer_exts.value) {
50 exts_[layer_name].insert(layer_ext.extensionName);
51 }
52 }
53 } else {
54 for (const auto& ext : embedder_instance_extensions_) {
55 exts_[kInstanceLayer].insert(ext);
56 }
57 }
58
59 validations_enabled_ =
60 enable_validations && HasLayer("VK_LAYER_KHRONOS_validation");
61 if (enable_validations && !validations_enabled_) {
62 FML_LOG(ERROR)
63 << "Requested Impeller context creation with validations but the "
64 "validation layers could not be found. Expect no Vulkan validation "
65 "checks!";
66 if (fatal_missing_validations) {
67 FML_LOG(FATAL) << "Validation missing. Exiting.";
68 }
69 }
70 if (validations_enabled_) {
71 FML_LOG(INFO) << "Vulkan validations are enabled.";
72 }
73 is_valid_ = true;
74}
75
77
79 return is_valid_;
80}
81
83 return validations_enabled_;
84}
85
86std::optional<std::vector<std::string>> CapabilitiesVK::GetEnabledLayers()
87 const {
88 std::vector<std::string> required;
89
90 if (validations_enabled_) {
91 // The presence of this layer is already checked in the ctor.
92 required.push_back("VK_LAYER_KHRONOS_validation");
93 }
94
95 return required;
96}
97
98std::optional<std::vector<std::string>>
100 std::vector<std::string> required;
101
102 if (!HasExtension("VK_KHR_surface")) {
103 // Swapchain support is required and this is a dependency of
104 // VK_KHR_swapchain.
105 VALIDATION_LOG << "Could not find the surface extension.";
106 return std::nullopt;
107 }
108 required.push_back("VK_KHR_surface");
109
110 auto has_wsi = false;
111 if (HasExtension("VK_MVK_macos_surface")) {
112 required.push_back("VK_MVK_macos_surface");
113 has_wsi = true;
114 }
115
116 if (HasExtension("VK_EXT_metal_surface")) {
117 required.push_back("VK_EXT_metal_surface");
118 has_wsi = true;
119 }
120
121 if (HasExtension("VK_KHR_portability_enumeration")) {
122 required.push_back("VK_KHR_portability_enumeration");
123 has_wsi = true;
124 }
125
126 if (HasExtension("VK_KHR_win32_surface")) {
127 required.push_back("VK_KHR_win32_surface");
128 has_wsi = true;
129 }
130
131 if (HasExtension("VK_KHR_android_surface")) {
132 required.push_back("VK_KHR_android_surface");
133 has_wsi = true;
134 }
135
136 if (HasExtension("VK_KHR_xcb_surface")) {
137 required.push_back("VK_KHR_xcb_surface");
138 has_wsi = true;
139 }
140
141 if (HasExtension("VK_KHR_xlib_surface")) {
142 required.push_back("VK_KHR_xlib_surface");
143 has_wsi = true;
144 }
145
146 if (HasExtension("VK_KHR_wayland_surface")) {
147 required.push_back("VK_KHR_wayland_surface");
148 has_wsi = true;
149 }
150
151 if (!has_wsi) {
152 // Don't really care which WSI extension there is as long there is at least
153 // one.
154 VALIDATION_LOG << "Could not find a WSI extension.";
155 return std::nullopt;
156 }
157
158 if (validations_enabled_) {
159 if (!HasExtension("VK_EXT_debug_utils")) {
160 VALIDATION_LOG << "Requested validations but could not find the "
161 "VK_EXT_debug_utils extension.";
162 return std::nullopt;
163 }
164 required.push_back("VK_EXT_debug_utils");
165
166 if (HasExtension("VK_EXT_validation_features")) {
167 // It's valid to not have `VK_EXT_validation_features` available. That's
168 // the case when using AGI as a frame debugger.
169 required.push_back("VK_EXT_validation_features");
170 }
171 }
172
173 return required;
174}
175
177 switch (ext) {
179 return VK_KHR_SWAPCHAIN_EXTENSION_NAME;
181 return "Unknown";
182 }
184}
185
187 switch (ext) {
190 return "VK_ANDROID_external_memory_android_hardware_buffer";
192 return VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME;
194 return VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME;
196 return VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME;
198 return VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME;
200 return "Unknown";
201 }
203}
204
206 switch (ext) {
208 return VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME;
210 return VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME;
212 return VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME;
214 return VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME;
216 return "Unknown";
217 }
218}
219
221 switch (ext) {
223 return VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME;
225 return "VK_KHR_portability_subset";
227 return VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME;
229 return "Unknown";
230 }
232}
233
234template <class T>
235static bool IterateExtensions(const std::function<bool(T)>& it) {
236 if (!it) {
237 return false;
238 }
239 for (size_t i = 0; i < static_cast<uint32_t>(T::kLast); i++) {
240 if (!it(static_cast<T>(i))) {
241 return false;
242 }
243 }
244 return true;
245}
246
247static std::optional<std::set<std::string>> GetSupportedDeviceExtensions(
248 const vk::PhysicalDevice& physical_device) {
249 auto device_extensions = physical_device.enumerateDeviceExtensionProperties();
250 if (device_extensions.result != vk::Result::eSuccess) {
251 return std::nullopt;
252 }
253
254 std::set<std::string> exts;
255 for (const auto& device_extension : device_extensions.value) {
256 exts.insert(device_extension.extensionName);
257 };
258
259 return exts;
260}
261
262std::optional<std::vector<std::string>>
264 const vk::PhysicalDevice& physical_device) const {
265 std::set<std::string> exts;
266
267 if (!use_embedder_extensions_) {
269
270 if (!maybe_exts.has_value()) {
271 return std::nullopt;
272 }
273 exts = maybe_exts.value();
274 } else {
275 for (const auto& ext : embedder_device_extensions_) {
276 exts.insert(ext);
277 }
278 }
279
280 std::vector<std::string> enabled;
281
282 auto for_each_common_extension = [&](RequiredCommonDeviceExtensionVK ext) {
283 auto name = GetExtensionName(ext);
284 if (exts.find(name) == exts.end()) {
285 VALIDATION_LOG << "Device does not support required extension: " << name;
286 return false;
287 }
288 enabled.push_back(name);
289 return true;
290 };
291
292 auto for_each_android_extension = [&](RequiredAndroidDeviceExtensionVK ext) {
293#ifdef FML_OS_ANDROID
294 auto name = GetExtensionName(ext);
295 if (exts.find(name) == exts.end()) {
296 VALIDATION_LOG << "Device does not support required Android extension: "
297 << name;
298 return false;
299 }
300 enabled.push_back(name);
301#endif // FML_OS_ANDROID
302 return true;
303 };
304
305 auto for_each_optional_android_extension =
307#ifdef FML_OS_ANDROID
308 auto name = GetExtensionName(ext);
309 if (exts.find(name) != exts.end()) {
310 enabled.push_back(name);
311 }
312#endif // FML_OS_ANDROID
313 return true;
314 };
315
316 auto for_each_optional_extension = [&](OptionalDeviceExtensionVK ext) {
317 auto name = GetExtensionName(ext);
318 if (exts.find(name) != exts.end()) {
319 enabled.push_back(name);
320 }
321 return true;
322 };
323
324 const auto iterate_extensions =
325 IterateExtensions<RequiredCommonDeviceExtensionVK>(
326 for_each_common_extension) &&
327 IterateExtensions<RequiredAndroidDeviceExtensionVK>(
328 for_each_android_extension) &&
329 IterateExtensions<OptionalDeviceExtensionVK>(
330 for_each_optional_extension) &&
331 IterateExtensions<OptionalAndroidDeviceExtensionVK>(
332 for_each_optional_android_extension);
333
334 if (!iterate_extensions) {
335 VALIDATION_LOG << "Device not suitable since required extensions are not "
336 "supported.";
337 return std::nullopt;
338 }
339
340 return enabled;
341}
342
343static bool HasSuitableColorFormat(const vk::PhysicalDevice& device,
344 vk::Format format) {
345 const auto props = device.getFormatProperties(format);
346 // This needs to be more comprehensive.
347 return !!(props.optimalTilingFeatures &
348 vk::FormatFeatureFlagBits::eColorAttachment);
349}
350
351static bool HasSuitableDepthStencilFormat(const vk::PhysicalDevice& device,
352 vk::Format format) {
353 const auto props = device.getFormatProperties(format);
354 return !!(props.optimalTilingFeatures &
355 vk::FormatFeatureFlagBits::eDepthStencilAttachment);
356}
357
359 const vk::PhysicalDevice& device) {
360 const auto has_color_format =
361 HasSuitableColorFormat(device, vk::Format::eR8G8B8A8Unorm);
362 const auto has_stencil_format =
363 HasSuitableDepthStencilFormat(device, vk::Format::eD32SfloatS8Uint) ||
364 HasSuitableDepthStencilFormat(device, vk::Format::eD24UnormS8Uint);
365 return has_color_format && has_stencil_format;
366}
367
368static bool HasRequiredProperties(const vk::PhysicalDevice& physical_device) {
369 auto properties = physical_device.getProperties();
370 if (!(properties.limits.framebufferColorSampleCounts &
371 (vk::SampleCountFlagBits::e1 | vk::SampleCountFlagBits::e4))) {
372 return false;
373 }
374 return true;
375}
376
377static bool HasRequiredQueues(const vk::PhysicalDevice& physical_device) {
378 auto queue_flags = vk::QueueFlags{};
379 for (const auto& queue : physical_device.getQueueFamilyProperties()) {
380 if (queue.queueCount == 0) {
381 continue;
382 }
383 queue_flags |= queue.queueFlags;
384 }
385 return static_cast<VkQueueFlags>(queue_flags &
386 (vk::QueueFlagBits::eGraphics |
387 vk::QueueFlagBits::eCompute |
388 vk::QueueFlagBits::eTransfer));
389}
390
391template <class ExtensionEnum>
392static bool IsExtensionInList(const std::vector<std::string>& list,
393 ExtensionEnum ext) {
394 const std::string name = GetExtensionName(ext);
395 return std::find(list.begin(), list.end(), name) != list.end();
396}
397
398std::optional<CapabilitiesVK::PhysicalDeviceFeatures>
400 const vk::PhysicalDevice& device) const {
402 VALIDATION_LOG << "Device doesn't support the required formats.";
403 return std::nullopt;
404 }
405
407 VALIDATION_LOG << "Device doesn't support the required properties.";
408 return std::nullopt;
409 }
410
412 VALIDATION_LOG << "Device doesn't support the required queues.";
413 return std::nullopt;
414 }
415
416 const auto enabled_extensions = GetEnabledDeviceExtensions(device);
417 if (!enabled_extensions.has_value()) {
418 VALIDATION_LOG << "Device doesn't support the required queues.";
419 return std::nullopt;
420 }
421
422 PhysicalDeviceFeatures supported_chain;
423
424 // Swiftshader seems to be fussy about just this structure even being in the
425 // chain. Just unlink it if its not supported. We already perform an
426 // extensions check on the other side when reading.
428 enabled_extensions.value(),
430 supported_chain
431 .unlink<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
432 }
433
434 device.getFeatures2(&supported_chain.get());
435
436 PhysicalDeviceFeatures required_chain;
437
438 // Base features.
439 {
440 auto& required = required_chain.get().features;
441 const auto& supported = supported_chain.get().features;
442
443 // We require this for enabling wireframes in the playground. But its not
444 // necessarily a big deal if we don't have this feature.
445 required.fillModeNonSolid = supported.fillModeNonSolid;
446 }
447 // VK_KHR_sampler_ycbcr_conversion features.
449 enabled_extensions.value(),
451 auto& required =
452 required_chain
453 .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
454 const auto& supported =
455 supported_chain
456 .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
457
458 required.samplerYcbcrConversion = supported.samplerYcbcrConversion;
459 }
460
461 // VK_EXT_image_compression_control
463 enabled_extensions.value(),
465 auto& required =
466 required_chain
467 .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
468 const auto& supported =
469 supported_chain
470 .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
471
472 required.imageCompressionControl = supported.imageCompressionControl;
473 } else {
474 required_chain
475 .unlink<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
476 }
477
478 // Vulkan 1.1
479 {
480 auto& required =
481 required_chain.get<vk::PhysicalDevice16BitStorageFeatures>();
482 const auto& supported =
483 supported_chain.get<vk::PhysicalDevice16BitStorageFeatures>();
484
485 required.uniformAndStorageBuffer16BitAccess =
486 supported.uniformAndStorageBuffer16BitAccess;
487 }
488
489 return required_chain;
490}
491
492bool CapabilitiesVK::HasLayer(const std::string& layer) const {
493 for (const auto& [found_layer, exts] : exts_) {
494 if (found_layer == layer) {
495 return true;
496 }
497 }
498 return false;
499}
500
501bool CapabilitiesVK::HasExtension(const std::string& ext) const {
502 for (const auto& [layer, exts] : exts_) {
503 if (exts.find(ext) != exts.end()) {
504 return true;
505 }
506 }
507 return false;
508}
509
511 return has_primitive_restart_;
512}
513
515 return true;
516}
517
519 default_color_format_ = pixel_format;
520}
521
523 const vk::PhysicalDevice& device,
524 const PhysicalDeviceFeatures& enabled_features) {
525 if (HasSuitableColorFormat(device, vk::Format::eR8G8B8A8Unorm)) {
526 default_color_format_ = PixelFormat::kR8G8B8A8UNormInt;
527 } else {
528 default_color_format_ = PixelFormat::kUnknown;
529 }
530
531 if (HasSuitableDepthStencilFormat(device, vk::Format::eD24UnormS8Uint)) {
532 default_depth_stencil_format_ = PixelFormat::kD24UnormS8Uint;
534 vk::Format::eD32SfloatS8Uint)) {
535 default_depth_stencil_format_ = PixelFormat::kD32FloatS8UInt;
536 } else {
537 default_depth_stencil_format_ = PixelFormat::kUnknown;
538 }
539
540 if (HasSuitableDepthStencilFormat(device, vk::Format::eS8Uint)) {
541 default_stencil_format_ = PixelFormat::kS8UInt;
542 } else if (default_depth_stencil_format_ != PixelFormat::kUnknown) {
543 default_stencil_format_ = default_depth_stencil_format_;
544 }
545
546 physical_device_ = device;
547 device_properties_ = device.getProperties();
548
549 auto physical_properties_2 =
550 device.getProperties2<vk::PhysicalDeviceProperties2,
551 vk::PhysicalDeviceSubgroupProperties>();
552
553 // Currently shaders only want access to arithmetic subgroup features.
554 // If that changes this needs to get updated, and so does Metal (which right
555 // now assumes it from compile time flags based on the MSL target version).
556
557 supports_compute_subgroups_ =
558 !!(physical_properties_2.get<vk::PhysicalDeviceSubgroupProperties>()
559 .supportedOperations &
560 vk::SubgroupFeatureFlagBits::eArithmetic);
561
562 {
563 // Query texture support.
564 // TODO(129784): Add a capability check for expected memory types.
565 vk::PhysicalDeviceMemoryProperties memory_properties;
566 device.getMemoryProperties(&memory_properties);
567
568 for (auto i = 0u; i < memory_properties.memoryTypeCount; i++) {
569 if (memory_properties.memoryTypes[i].propertyFlags &
570 vk::MemoryPropertyFlagBits::eLazilyAllocated) {
571 supports_device_transient_textures_ = true;
572 }
573 }
574 }
575
576 // Determine the optional device extensions this physical device supports.
577 {
578 required_common_device_extensions_.clear();
579 required_android_device_extensions_.clear();
580 optional_device_extensions_.clear();
581 optional_android_device_extensions_.clear();
582
583 std::set<std::string> exts;
584 if (!use_embedder_extensions_) {
585 auto maybe_exts = GetSupportedDeviceExtensions(device);
586 if (!maybe_exts.has_value()) {
587 return false;
588 }
589 exts = maybe_exts.value();
590 } else {
591 for (const auto& ext : embedder_device_extensions_) {
592 exts.insert(ext);
593 }
594 }
595
596 IterateExtensions<RequiredCommonDeviceExtensionVK>([&](auto ext) -> bool {
597 auto ext_name = GetExtensionName(ext);
598 if (exts.find(ext_name) != exts.end()) {
599 required_common_device_extensions_.insert(ext);
600 }
601 return true;
602 });
603 IterateExtensions<RequiredAndroidDeviceExtensionVK>([&](auto ext) -> bool {
604 auto ext_name = GetExtensionName(ext);
605 if (exts.find(ext_name) != exts.end()) {
606 required_android_device_extensions_.insert(ext);
607 }
608 return true;
609 });
610 IterateExtensions<OptionalDeviceExtensionVK>([&](auto ext) -> bool {
611 auto ext_name = GetExtensionName(ext);
612 if (exts.find(ext_name) != exts.end()) {
613 optional_device_extensions_.insert(ext);
614 }
615 return true;
616 });
617 IterateExtensions<OptionalAndroidDeviceExtensionVK>(
619 auto name = GetExtensionName(ext);
620 if (exts.find(name) != exts.end()) {
621 optional_android_device_extensions_.insert(ext);
622 }
623 return true;
624 });
625 }
626
627 supports_texture_fixed_rate_compression_ =
628 enabled_features
629 .isLinked<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>() &&
630 enabled_features
631 .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>()
632 .imageCompressionControl;
633
634 max_render_pass_attachment_size_ =
635 ISize{device_properties_.limits.maxFramebufferWidth,
636 device_properties_.limits.maxFramebufferHeight};
637
638 // Molten, Vulkan on Metal, cannot support triangle fans because Metal doesn't
639 // support triangle fans.
640 // See VUID-VkPipelineInputAssemblyStateCreateInfo-triangleFans-04452.
641 has_triangle_fans_ =
643
644 // External Fence/Semaphore for AHB swapchain
649 supports_external_fence_and_semaphore_ = true;
650 }
651
652 minimum_uniform_alignment_ =
653 device_properties_.limits.minUniformBufferOffsetAlignment;
654 minimum_storage_alignment_ =
655 device_properties_.limits.minStorageBufferOffsetAlignment;
656
657 return true;
658}
659
660// |Capabilities|
662 return true;
663}
664
665// |Capabilities|
667 return false;
668}
669
670// |Capabilities|
672 return true;
673}
674
675// |Capabilities|
677 return true;
678}
679
680// |Capabilities|
682 return has_framebuffer_fetch_;
683}
684
685// |Capabilities|
687 // Vulkan 1.1 requires support for compute.
688 return true;
689}
690
691// |Capabilities|
693 // Set by |SetPhysicalDevice|.
694 return supports_compute_subgroups_;
695}
696
697// |Capabilities|
699 return false;
700}
701
703 return true;
704}
705
706// |Capabilities|
708 return supports_device_transient_textures_;
709}
710
711// |Capabilities|
713 return default_color_format_;
714}
715
716// |Capabilities|
718 return default_stencil_format_;
719}
720
721// |Capabilities|
723 return default_depth_stencil_format_;
724}
725
726const vk::PhysicalDeviceProperties&
728 return device_properties_;
729}
730
734
736 return minimum_uniform_alignment_;
737}
738
740 return minimum_storage_alignment_;
741}
742
744 return false;
745}
746
748 return required_common_device_extensions_.find(ext) !=
749 required_common_device_extensions_.end();
750}
751
753 return required_android_device_extensions_.find(ext) !=
754 required_android_device_extensions_.end();
755}
756
758 return optional_device_extensions_.find(ext) !=
759 optional_device_extensions_.end();
760}
761
763 return optional_android_device_extensions_.find(ext) !=
764 optional_android_device_extensions_.end();
765}
766
768 return supports_texture_fixed_rate_compression_;
769}
770
771std::optional<vk::ImageCompressionFixedRateFlagBitsEXT>
773 const FRCFormatDescriptor& desc) const {
774 if (compression_type != CompressionType::kLossy) {
775 return std::nullopt;
776 }
777 if (!supports_texture_fixed_rate_compression_) {
778 return std::nullopt;
779 }
780 // There are opportunities to hash and cache the FRCFormatDescriptor if
781 // needed.
782 vk::StructureChain<vk::PhysicalDeviceImageFormatInfo2,
783 vk::ImageCompressionControlEXT>
784 format_chain;
785
786 auto& format_info = format_chain.get();
787
788 format_info.format = desc.format;
789 format_info.type = desc.type;
790 format_info.tiling = desc.tiling;
791 format_info.usage = desc.usage;
792 format_info.flags = desc.flags;
793
794 const auto kIdealFRCRate = vk::ImageCompressionFixedRateFlagBitsEXT::e4Bpc;
795
796 std::array<vk::ImageCompressionFixedRateFlagsEXT, 1u> rates = {kIdealFRCRate};
797
798 auto& compression = format_chain.get<vk::ImageCompressionControlEXT>();
799 compression.flags = vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit;
800 compression.compressionControlPlaneCount = rates.size();
801 compression.pFixedRateFlags = rates.data();
802
803 const auto [result, supported] = physical_device_.getImageFormatProperties2<
804 vk::ImageFormatProperties2, vk::ImageCompressionPropertiesEXT>(
805 format_chain.get());
806
807 if (result != vk::Result::eSuccess ||
808 !supported.isLinked<vk::ImageCompressionPropertiesEXT>()) {
809 return std::nullopt;
810 }
811
812 const auto& compression_props =
813 supported.get<vk::ImageCompressionPropertiesEXT>();
814
815 if ((compression_props.imageCompressionFlags &
816 vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit) &&
817 (compression_props.imageCompressionFixedRateFlags & kIdealFRCRate)) {
818 return kIdealFRCRate;
819 }
820
821 return std::nullopt;
822}
823
825 return has_triangle_fans_;
826}
827
829 return max_render_pass_attachment_size_;
830}
831
833 has_primitive_restart_ = !workarounds.slow_primitive_restart_performance;
834 has_framebuffer_fetch_ = !workarounds.input_attachment_self_dependency_broken;
835}
836
838 return supports_external_fence_and_semaphore_;
839}
840
842 return false;
843}
844
845} // namespace impeller
846
847// NOLINTEND(clang-analyzer-security.PointerSub)
bool SupportsTriangleFan() const override
Whether the primitive type TriangleFan is supported by the backend.
size_t GetMinimumUniformAlignment() const override
The minimum alignment of uniform value offsets in bytes.
bool SupportsDeviceTransientTextures() const override
Whether the context backend supports allocating StorageMode::kDeviceTransient (aka "memoryless") text...
std::optional< std::vector< std::string > > GetEnabledInstanceExtensions() const
bool SetPhysicalDevice(const vk::PhysicalDevice &physical_device, const PhysicalDeviceFeatures &enabled_features)
ISize GetMaximumRenderPassAttachmentSize() const override
Return the maximum size of a render pass attachment.
bool SupportsSSBO() const override
Whether the context backend supports binding Shader Storage Buffer Objects (SSBOs) to pipelines.
bool SupportsFramebufferFetch() const override
Whether the context backend is able to support pipelines with shaders that read from the framebuffer ...
bool SupportsExternalSemaphoreExtensions() const
CapabilitiesVK(bool enable_validations, bool fatal_missing_validations=false, bool use_embedder_extensions=false, std::vector< std::string > instance_extensions={}, std::vector< std::string > device_extensions={})
bool SupportsOffscreenMSAA() const override
Whether the context backend supports attaching offscreen MSAA color/stencil textures.
bool SupportsCompute() const override
Whether the context backend supports ComputePass.
bool HasExtension(RequiredCommonDeviceExtensionVK ext) const
std::optional< vk::ImageCompressionFixedRateFlagBitsEXT > GetSupportedFRCRate(CompressionType compression_type, const FRCFormatDescriptor &desc) const
Get the fixed compression rate supported by the context for the given format and usage.
void SetOffscreenFormat(PixelFormat pixel_format) const
PixelFormat GetDefaultStencilFormat() const override
Returns a supported PixelFormat for textures that store stencil information. May include a depth chan...
void ApplyWorkarounds(const WorkaroundsVK &workarounds)
Update capabilities for the given set of workarounds.
vk::StructureChain< vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR, vk::PhysicalDevice16BitStorageFeatures, vk::PhysicalDeviceImageCompressionControlFeaturesEXT > PhysicalDeviceFeatures
bool SupportsComputeSubgroups() const override
Whether the context backend supports configuring ComputePass command subgroups.
size_t GetMinimumStorageBufferAlignment() const override
The minimum alignment of storage buffer value offsets in bytes.
PixelFormat GetDefaultDepthStencilFormat() const override
Returns a supported PixelFormat for textures that store both a stencil and depth component....
bool SupportsTextureToTextureBlits() const override
Whether the context backend supports blitting from one texture region to another texture region (via ...
bool Supports32BitPrimitiveIndices() const override
Whether 32-bit values are supported in index buffers used to draw primitives.
std::optional< std::vector< std::string > > GetEnabledDeviceExtensions(const vk::PhysicalDevice &physical_device) const
bool SupportsReadFromResolve() const override
Whether the context backend supports binding the current RenderPass attachments. This is supported if...
bool SupportsDecalSamplerAddressMode() const override
Whether the context backend supports SamplerAddressMode::Decal.
bool SupportsPrimitiveRestart() const override
Whether primitive restart is supported.
std::optional< std::vector< std::string > > GetEnabledLayers() const
bool SupportsTextureFixedRateCompression() const
bool NeedsPartitionedHostBuffer() const override
Whether the host buffer should use separate device buffers for indexes from other data.
PixelFormat GetDefaultGlyphAtlasFormat() const override
Returns the default pixel format for the alpha bitmap glyph atlas.
PixelFormat GetDefaultColorFormat() const override
Returns a supported PixelFormat for textures that store 4-channel colors (red/green/blue/alpha).
const vk::PhysicalDeviceProperties & GetPhysicalDeviceProperties() const
bool SupportsExtendedRangeFormats() const override
Whether the XR formats are supported on this device.
bool SupportsImplicitResolvingMSAA() const override
Whether the context backend supports multisampled rendering to the on-screen surface without requirin...
std::optional< PhysicalDeviceFeatures > GetEnabledDeviceFeatures(const vk::PhysicalDevice &physical_device) const
VkPhysicalDevice physical_device
Definition main.cc:67
VkDevice device
Definition main.cc:69
VkQueue queue
Definition main.cc:71
const FlutterLayer ** layers
uint32_t uint32_t * format
#define FML_LOG(severity)
Definition logging.h:101
#define FML_UNREACHABLE()
Definition logging.h:128
const char * name
Definition fuchsia.cc:49
static bool IterateExtensions(const std::function< bool(T)> &it)
static const char * GetExtensionName(RequiredCommonDeviceExtensionVK ext)
static bool PhysicalDeviceSupportsRequiredFormats(const vk::PhysicalDevice &device)
static bool HasRequiredProperties(const vk::PhysicalDevice &physical_device)
static bool IsExtensionInList(const std::vector< std::string > &list, ExtensionEnum ext)
static bool HasSuitableColorFormat(const vk::PhysicalDevice &device, vk::Format format)
RequiredAndroidDeviceExtensionVK
A device extension available on all Android platforms. Without the presence of these extensions on An...
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition formats.h:99
static std::optional< std::set< std::string > > GetSupportedDeviceExtensions(const vk::PhysicalDevice &physical_device)
static bool HasSuitableDepthStencilFormat(const vk::PhysicalDevice &device, vk::Format format)
RequiredCommonDeviceExtensionVK
A device extension available on all platforms. Without the presence of these extensions,...
OptionalAndroidDeviceExtensionVK
A device extension available on some Android platforms.
static constexpr const char * kInstanceLayer
CompressionType
Additional compression to apply to a texture. This value is ignored on platforms which do not support...
OptionalDeviceExtensionVK
A device extension enabled if available. Subsystems cannot assume availability and must check if thes...
static bool HasRequiredQueues(const vk::PhysicalDevice &physical_device)
Definition ref_ptr.h:261
A pixel format and usage that is sufficient to check if images of that format and usage are suitable ...
A non-exhaustive set of driver specific workarounds.
#define VALIDATION_LOG
Definition validation.h:91