| Flutter Impeller |

Public Types | Public Member Functions | List of all members
impeller::CapabilitiesVK Class Referencefinal

The Vulkan layers and extensions wrangler. More...

`#include <capabilities_vk.h>`

Inheritance diagram for impeller::CapabilitiesVK:

## Public Types
using | PhysicalDeviceFeatures = vk::StructureChain< vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR, vk::PhysicalDevice16BitStorageFeatures, vk::PhysicalDeviceImageCompressionControlFeaturesEXT >

## Public Member Functions
| CapabilitiesVK (bool enable_validations, bool fatal_missing_validations=false)
| ~CapabilitiesVK ()
bool | IsValid () const
bool | AreValidationsEnabled () const
bool | HasExtension (RequiredCommonDeviceExtensionVK ext) const
bool | HasExtension (RequiredAndroidDeviceExtensionVK ext) const
bool | HasExtension (OptionalDeviceExtensionVK ext) const
std::optional< std::vector< std::string > > | GetEnabledLayers () const
std::optional< std::vector< std::string > > | GetEnabledInstanceExtensions () const
std::optional< std::vector< std::string > > | GetEnabledDeviceExtensions (const vk::PhysicalDevice &physical_device) const
std::optional< PhysicalDeviceFeatures > | GetEnabledDeviceFeatures (const vk::PhysicalDevice &physical_device) const
bool | SetPhysicalDevice (const vk::PhysicalDevice &physical_device, const PhysicalDeviceFeatures &enabled_features)
const vk::PhysicalDeviceProperties & | GetPhysicalDeviceProperties () const
void | SetOffscreenFormat (PixelFormat pixel_format) const
bool | SupportsOffscreenMSAA () const override
| Whether the context backend supports attaching offscreen MSAA color/stencil textures. More...
bool | SupportsImplicitResolvingMSAA () const override
| Whether the context backend supports multisampled rendering to the on-screen surface without requiring an explicit resolve of the MSAA color attachment. More...
bool | SupportsSSBO () const override
| Whether the context backend supports binding Shader Storage Buffer Objects (SSBOs) to pipelines. More...
bool | SupportsTextureToTextureBlits () const override
| Whether the context backend supports blitting from one texture region to another texture region (via the relevant `BlitPass::AddCopy` overloads). More...
bool | SupportsFramebufferFetch () const override
| Whether the context backend is able to support pipelines with shaders that read from the framebuffer (i.e. pixels that have been written by previous draw calls in the current render pass). More...
bool | SupportsCompute () const override
| Whether the context backend supports `ComputePass`. More...
bool | SupportsComputeSubgroups () const override
| Whether the context backend supports configuring `ComputePass` command subgroups. More...
bool | SupportsReadFromResolve () const override
| Whether the context backend supports binding the current `RenderPass` attachments. This is supported if the backend can guarantee that attachment textures will not be mutated until the render pass has fully completed. More...
bool | SupportsDecalSamplerAddressMode () const override
| Whether the context backend supports `SamplerAddressMode::Decal`. More...
bool | SupportsDeviceTransientTextures () const override
| Whether the context backend supports allocating `StorageMode::kDeviceTransient` (aka "memoryless") textures, which are temporary textures kept in tile memory for the duration of the `RenderPass` it's attached to. More...
bool | SupportsTriangleFan () const override
| Whether the primitive type TriangleFan is supported by the backend. More...
PixelFormat | GetDefaultColorFormat () const override
| Returns a supported `PixelFormat` for textures that store 4-channel colors (red/green/blue/alpha). More...
PixelFormat | GetDefaultStencilFormat () const override
| Returns a supported `PixelFormat` for textures that store stencil information. May include a depth channel if a stencil-only format is not available. More...
PixelFormat | GetDefaultDepthStencilFormat () const override
| Returns a supported `PixelFormat` for textures that store both a stencil and depth component. This will never return a depth-only or stencil-only texture. Returns `PixelFormat::kUnknown` if no suitable depth+stencil format was found. More...
PixelFormat | GetDefaultGlyphAtlasFormat () const override
| Returns the default pixel format for the alpha bitmap glyph atlas. More...
ISize | GetMaximumRenderPassAttachmentSize () const override
| Return the maximum size of a render pass attachment. More...
bool | SupportsTextureFixedRateCompression () 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. More...
Public Member Functions inherited from impeller::Capabilities
virtual | ~Capabilities ()

## Additional Inherited Members
Static Public Member Functions inherited from impeller::BackendCast< CapabilitiesVK, Capabilities >
static CapabilitiesVK & | Cast (Capabilities &base)
static const CapabilitiesVK & | Cast (const Capabilities &base)
static CapabilitiesVK * | Cast (Capabilities *base)
static const CapabilitiesVK * | Cast (const Capabilities *base)
Protected Member Functions inherited from impeller::Capabilities
| Capabilities ()
| Capabilities (const Capabilities &)=delete
Capabilities & | operator= (const Capabilities &)=delete

## Detailed Description

The Vulkan layers and extensions wrangler.

Definition at line 169 of file capabilities_vk.h.

## Member Typedef Documentation

## ◆ PhysicalDeviceFeatures

using impeller::CapabilitiesVK::PhysicalDeviceFeatures = vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR, vk::PhysicalDevice16BitStorageFeatures, vk::PhysicalDeviceImageCompressionControlFeaturesEXT>

Definition at line 198 of file capabilities_vk.h.

## Constructor & Destructor Documentation

## ◆ CapabilitiesVK()

impeller::CapabilitiesVK::CapabilitiesVK | ( | bool | enable_validations,
|  | bool | fatal_missing_validations = `false`
| ) |  |
| explicit

Definition at line 18 of file capabilities_vk.cc.

19 {
20 auto extensions = vk::enumerateInstanceExtensionProperties();
21 auto layers = vk::enumerateInstanceLayerProperties();
22
23 if (extensions.result != vk::Result::eSuccess ||
24 layers.result != vk::Result::eSuccess) {
25 return;
26 }
27
28 for (const auto& ext : extensions.value) {
29 exts_[kInstanceLayer].insert(ext.extensionName);
30 }
31
32 for (const auto& layer : layers.value) {
33 const std::string layer_name = layer.layerName;
34 auto layer_exts = vk::enumerateInstanceExtensionProperties(layer_name);
35 if (layer_exts.result != vk::Result::eSuccess) {
36 return;
37 }
38 for (const auto& layer_ext : layer_exts.value) {
39 exts_[layer_name].insert(layer_ext.extensionName);
40 }
41 }
42
43 validations_enabled_ =
44 enable_validations && HasLayer("VK_LAYER_KHRONOS_validation");
45 if (enable_validations && !validations_enabled_) {
46 FML_LOG(ERROR)
47 << "Requested Impeller context creation with validations but the "
48 "validation layers could not be found. Expect no Vulkan validation "
49 "checks!";
50 if (fatal_missing_validations) {
51 FML_LOG(FATAL) << "Validation missing. Exiting.";
52 }
53 }
54 if (validations_enabled_) {
55 FML_LOG(INFO) << "Vulkan validations are enabled.";
56 }
57 is_valid_ = true;
58 }

References impeller::kInstanceLayer.

## ◆ ~CapabilitiesVK()

impeller::CapabilitiesVK::~CapabilitiesVK | ( |  | ) |
| default

## Member Function Documentation

## ◆ AreValidationsEnabled()

bool impeller::CapabilitiesVK::AreValidationsEnabled | ( |  | ) | const

Definition at line 66 of file capabilities_vk.cc.

66 {
67 return validations_enabled_;
68 }

Referenced by impeller::DebugReportVK::DebugReportVK(), and impeller::testing::TEST().

## ◆ GetDefaultColorFormat()

PixelFormat impeller::CapabilitiesVK::GetDefaultColorFormat | ( |  | ) | const
| override virtual

Returns a supported `PixelFormat` for textures that store 4-channel colors (red/green/blue/alpha).

Implements impeller::Capabilities.

Definition at line 620 of file capabilities_vk.cc.

620 {
621 return default_color_format_;
622 }

Referenced by impeller::testing::TEST().

## ◆ GetDefaultDepthStencilFormat()

PixelFormat impeller::CapabilitiesVK::GetDefaultDepthStencilFormat | ( |  | ) | const
| override virtual

Returns a supported `PixelFormat` for textures that store both a stencil and depth component. This will never return a depth-only or stencil-only texture. Returns `PixelFormat::kUnknown` if no suitable depth+stencil format was found.

Implements impeller::Capabilities.

Definition at line 630 of file capabilities_vk.cc.

630 {
631 return default_depth_stencil_format_;
632 }

Referenced by impeller::testing::TEST().

## ◆ GetDefaultGlyphAtlasFormat()

PixelFormat impeller::CapabilitiesVK::GetDefaultGlyphAtlasFormat | ( |  | ) | const
| override virtual

Returns the default pixel format for the alpha bitmap glyph atlas.

       Some backends may use Red channel while others use grey. This
       should not have any impact

Implements impeller::Capabilities.

Definition at line 639 of file capabilities_vk.cc.

639 {
640 return PixelFormat::kR8UNormInt;
641 }

References impeller::kR8UNormInt.

## ◆ GetDefaultStencilFormat()

PixelFormat impeller::CapabilitiesVK::GetDefaultStencilFormat | ( |  | ) | const
| override virtual

Returns a supported `PixelFormat` for textures that store stencil information. May include a depth channel if a stencil-only format is not available.

Implements impeller::Capabilities.

Definition at line 625 of file capabilities_vk.cc.

625 {
626 return default_stencil_format_;
627 }

Referenced by impeller::testing::TEST().

## ◆ GetEnabledDeviceExtensions()

std::optional< std::vector< std::string > > impeller::CapabilitiesVK::GetEnabledDeviceExtensions | ( | const vk::PhysicalDevice & | physical_device | ) | const

Definition at line 240 of file capabilities_vk.cc.

241 {
242 auto exts = GetSupportedDeviceExtensions(physical_device);
243
244 if (!exts.has_value()) {
245 return std::nullopt;
246 }
247
248 std::vector<std::string> enabled;
249
250 auto for_each_common_extension = [&](RequiredCommonDeviceExtensionVK ext) {
251 auto name = GetExtensionName(ext);
252 if (exts->find(name) == exts->end()) {
253 VALIDATION_LOG << "Device does not support required extension: " << name;
254 return false;
255 }
256 enabled.push_back(name);
257 return true;
258 };
259
260 auto for_each_android_extension = [&](RequiredAndroidDeviceExtensionVK ext) {
261 #ifdef FML_OS_ANDROID
262 auto name = GetExtensionName(ext);
263 if (exts->find(name) == exts->end()) {
264 VALIDATION_LOG << "Device does not support required Android extension: "
265 << name;
266 return false;
267 }
268 enabled.push_back(name);
269 #endif // FML_OS_ANDROID
270 return true;
271 };
272
273 auto for_each_optional_extension = [&](OptionalDeviceExtensionVK ext) {
274 auto name = GetExtensionName(ext);
275 if (exts->find(name) != exts->end()) {
276 enabled.push_back(name);
277 }
278 return true;
279 };
280
281 const auto iterate_extensions =
282 IterateExtensions<RequiredCommonDeviceExtensionVK>(
283 for_each_common_extension) &&
284 IterateExtensions<RequiredAndroidDeviceExtensionVK>(
285 for_each_android_extension) &&
286 IterateExtensions<OptionalDeviceExtensionVK>(for_each_optional_extension);
287
288 if (!iterate_extensions) {
289 VALIDATION_LOG << "Device not suitable since required extensions are not "
290 "supported.";
291 return std::nullopt;
292 }
293
294 return enabled;
295 }

References impeller::GetExtensionName(), impeller::GetSupportedDeviceExtensions(), and VALIDATION_LOG.

Referenced by GetEnabledDeviceFeatures().

## ◆ GetEnabledDeviceFeatures()

std::optional< CapabilitiesVK::PhysicalDeviceFeatures > impeller::CapabilitiesVK::GetEnabledDeviceFeatures | ( | const vk::PhysicalDevice & | physical_device | ) | const

Definition at line 353 of file capabilities_vk.cc.

354 {
355 if (!PhysicalDeviceSupportsRequiredFormats(device)) {
356 VALIDATION_LOG << "Device doesn't support the required formats.";
357 return std::nullopt;
358 }
359
360 if (!HasRequiredProperties(device)) {
361 VALIDATION_LOG << "Device doesn't support the required properties.";
362 return std::nullopt;
363 }
364
365 if (!HasRequiredQueues(device)) {
366 VALIDATION_LOG << "Device doesn't support the required queues.";
367 return std::nullopt;
368 }
369
370 const auto enabled_extensions = GetEnabledDeviceExtensions(device);
371 if (!enabled_extensions.has_value()) {
372 VALIDATION_LOG << "Device doesn't support the required queues.";
373 return std::nullopt;
374 }
375
376 PhysicalDeviceFeatures supported_chain;
377
378 // Swiftshader seems to be fussy about just this structure even being in the
379 // chain. Just unlink it if its not supported. We already perform an
380 // extensions check on the other side when reading.
381 if (!IsExtensionInList(
382 enabled_extensions.value(),
383 OptionalDeviceExtensionVK::kEXTImageCompressionControl)) {
384 supported_chain
385 .unlink<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
386 }
387
388 device.getFeatures2(&supported_chain.get());
389
390 PhysicalDeviceFeatures required_chain;
391
392 // Base features.
393 {
394 auto& required = required_chain.get().features;
395 const auto& supported = supported_chain.get().features;
396
397 // We require this for enabling wireframes in the playground. But its not
398 // necessarily a big deal if we don't have this feature.
399 required.fillModeNonSolid = supported.fillModeNonSolid;
400 }
401 // VK_KHR_sampler_ycbcr_conversion features.
402 if (IsExtensionInList(
403 enabled_extensions.value(),
404 RequiredAndroidDeviceExtensionVK::kKHRSamplerYcbcrConversion)) {
405 auto& required =
406 required_chain
407 .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
408 const auto& supported =
409 supported_chain
410 .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
411
412 required.samplerYcbcrConversion = supported.samplerYcbcrConversion;
413 }
414
415 // VK_EXT_image_compression_control
416 if (IsExtensionInList(
417 enabled_extensions.value(),
418 OptionalDeviceExtensionVK::kEXTImageCompressionControl)) {
419 auto& required =
420 required_chain
421 .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
422 const auto& supported =
423 supported_chain
424 .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
425
426 required.imageCompressionControl = supported.imageCompressionControl;
427 } else {
428 required_chain
429 .unlink<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
430 }
431
432 // Vulkan 1.1
433 {
434 auto& required =
435 required_chain.get<vk::PhysicalDevice16BitStorageFeatures>();
436 const auto& supported =
437 supported_chain.get<vk::PhysicalDevice16BitStorageFeatures>();
438
439 required.uniformAndStorageBuffer16BitAccess =
440 supported.uniformAndStorageBuffer16BitAccess;
441 }
442
443 return required_chain;
444 }

References GetEnabledDeviceExtensions(), impeller::HasRequiredProperties(), impeller::HasRequiredQueues(), impeller::IsExtensionInList(), impeller::kEXTImageCompressionControl, impeller::kKHRSamplerYcbcrConversion, impeller::PhysicalDeviceSupportsRequiredFormats(), and VALIDATION_LOG.

Referenced by impeller::PickPhysicalDevice().

## ◆ GetEnabledInstanceExtensions()

std::optional< std::vector< std::string > > impeller::CapabilitiesVK::GetEnabledInstanceExtensions | ( |  | ) | const

Definition at line 83 of file capabilities_vk.cc.

83 {
84 std::vector<std::string> required;
85
86 if (!HasExtension("VK_KHR_surface")) {
87 // Swapchain support is required and this is a dependency of
88 // VK_KHR_swapchain.
89 VALIDATION_LOG << "Could not find the surface extension.";
90 return std::nullopt;
91 }
92 required.push_back("VK_KHR_surface");
93
94 auto has_wsi = false;
95 if (HasExtension("VK_MVK_macos_surface")) {
96 required.push_back("VK_MVK_macos_surface");
97 has_wsi = true;
98 }
99
100 if (HasExtension("VK_EXT_metal_surface")) {
101 required.push_back("VK_EXT_metal_surface");
102 has_wsi = true;
103 }
104
105 if (HasExtension("VK_KHR_portability_enumeration")) {
106 required.push_back("VK_KHR_portability_enumeration");
107 has_wsi = true;
108 }
109
110 if (HasExtension("VK_KHR_win32_surface")) {
111 required.push_back("VK_KHR_win32_surface");
112 has_wsi = true;
113 }
114
115 if (HasExtension("VK_KHR_android_surface")) {
116 required.push_back("VK_KHR_android_surface");
117 has_wsi = true;
118 }
119
120 if (HasExtension("VK_KHR_xcb_surface")) {
121 required.push_back("VK_KHR_xcb_surface");
122 has_wsi = true;
123 }
124
125 if (HasExtension("VK_KHR_xlib_surface")) {
126 required.push_back("VK_KHR_xlib_surface");
127 has_wsi = true;
128 }
129
130 if (HasExtension("VK_KHR_wayland_surface")) {
131 required.push_back("VK_KHR_wayland_surface");
132 has_wsi = true;
133 }
134
135 if (!has_wsi) {
136 // Don't really care which WSI extension there is as long there is at least
137 // one.
138 VALIDATION_LOG << "Could not find a WSI extension.";
139 return std::nullopt;
140 }
141
142 if (validations_enabled_) {
143 if (!HasExtension("VK_EXT_debug_utils")) {
144 VALIDATION_LOG << "Requested validations but could not find the "
145 "VK_EXT_debug_utils extension.";
146 return std::nullopt;
147 }
148 required.push_back("VK_EXT_debug_utils");
149
150 if (HasExtension("VK_EXT_validation_features")) {
151 // It's valid to not have `VK_EXT_validation_features` available. That's
152 // the case when using AGI as a frame debugger.
153 required.push_back("VK_EXT_validation_features");
154 }
155 }
156
157 return required;
158 }

References HasExtension(), and VALIDATION_LOG.

## ◆ GetEnabledLayers()

std::optional< std::vector< std::string > > impeller::CapabilitiesVK::GetEnabledLayers | ( |  | ) | const

Definition at line 70 of file capabilities_vk.cc.

71 {
72 std::vector<std::string> required;
73
74 if (validations_enabled_) {
75 // The presence of this layer is already checked in the ctor.
76 required.push_back("VK_LAYER_KHRONOS_validation");
77 }
78
79 return required;
80 }

## ◆ GetMaximumRenderPassAttachmentSize()

ISize impeller::CapabilitiesVK::GetMaximumRenderPassAttachmentSize | ( |  | ) | const
| override virtual

Return the maximum size of a render pass attachment.

Note that this may be smaller than the maximum allocatable texture size.

Implements impeller::Capabilities.

Definition at line 719 of file capabilities_vk.cc.

719 {
720 return max_render_pass_attachment_size_;
721 }

## ◆ GetPhysicalDeviceProperties()

const vk::PhysicalDeviceProperties & impeller::CapabilitiesVK::GetPhysicalDeviceProperties | ( |  | ) | const

Definition at line 635 of file capabilities_vk.cc.

635 {
636 return device_properties_;
637 }

## ◆ GetSupportedFRCRate()

std::optional< vk::ImageCompressionFixedRateFlagBitsEXT > impeller::CapabilitiesVK::GetSupportedFRCRate | ( | CompressionType | compression_type,
|  | const FRCFormatDescriptor & | desc
| ) |  | const

Get the fixed compression rate supported by the context for the given format and usage.

Parameters

  [in] | compression_type | The compression type.
  [in] | desc | The format and usage of the image.

Returns
  The supported fixed compression rate.

Definition at line 663 of file capabilities_vk.cc.

664 {
665 if (compression_type != CompressionType::kLossy) {
666 return std::nullopt;
667 }
668 if (!supports_texture_fixed_rate_compression_) {
669 return std::nullopt;
670 }
671 // There are opportunities to hash and cache the FRCFormatDescriptor if
672 // needed.
673 vk::StructureChain<vk::PhysicalDeviceImageFormatInfo2,
674 vk::ImageCompressionControlEXT>
675 format_chain;
676
677 auto& format_info = format_chain.get();
678
679 format_info.format = desc.format;
680 format_info.type = desc.type;
681 format_info.tiling = desc.tiling;
682 format_info.usage = desc.usage;
683 format_info.flags = desc.flags;
684
685 const auto kIdealFRCRate = vk::ImageCompressionFixedRateFlagBitsEXT::e4Bpc;
686
687 std::array<vk::ImageCompressionFixedRateFlagsEXT, 1u> rates = {kIdealFRCRate};
688
689 auto& compression = format_chain.get<vk::ImageCompressionControlEXT>();
690 compression.flags = vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit;
691 compression.compressionControlPlaneCount = rates.size();
692 compression.pFixedRateFlags = rates.data();
693
694 const auto [result, supported] = physical_device_.getImageFormatProperties2<
695 vk::ImageFormatProperties2, vk::ImageCompressionPropertiesEXT>(
696 format_chain.get());
697
698 if (result != vk::Result::eSuccess ||
699 !supported.isLinked<vk::ImageCompressionPropertiesEXT>()) {
700 return std::nullopt;
701 }
702
703 const auto& compression_props =
704 supported.get<vk::ImageCompressionPropertiesEXT>();
705
706 if ((compression_props.imageCompressionFlags &
707 vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit) &&
708 (compression_props.imageCompressionFixedRateFlags & kIdealFRCRate)) {
709 return kIdealFRCRate;
710 }
711
712 return std::nullopt;
713 }

References impeller::FRCFormatDescriptor::flags, impeller::FRCFormatDescriptor::format, impeller::kLossy, impeller::FRCFormatDescriptor::tiling, impeller::FRCFormatDescriptor::type, and impeller::FRCFormatDescriptor::usage.

## ◆ HasExtension() [1/3]

bool impeller::CapabilitiesVK::HasExtension | ( | OptionalDeviceExtensionVK | ext | ) | const

Definition at line 653 of file capabilities_vk.cc.

653 {
654 return optional_device_extensions_.find(ext) !=
655 optional_device_extensions_.end();
656 }

## ◆ HasExtension() [2/3]

bool impeller::CapabilitiesVK::HasExtension | ( | RequiredAndroidDeviceExtensionVK | ext | ) | const

Definition at line 648 of file capabilities_vk.cc.

648 {
649 return required_android_device_extensions_.find(ext) !=
650 required_android_device_extensions_.end();
651 }

## ◆ HasExtension() [3/3]

bool impeller::CapabilitiesVK::HasExtension | ( | RequiredCommonDeviceExtensionVK | ext | ) | const

Definition at line 643 of file capabilities_vk.cc.

643 {
644 return required_common_device_extensions_.find(ext) !=
645 required_common_device_extensions_.end();
646 }

Referenced by GetEnabledInstanceExtensions().

## ◆ IsValid()

bool impeller::CapabilitiesVK::IsValid | ( |  | ) | const

Definition at line 62 of file capabilities_vk.cc.

62 {
63 return is_valid_;
64 }

## ◆ SetOffscreenFormat()

void impeller::CapabilitiesVK::SetOffscreenFormat | ( | PixelFormat | pixel_format | ) | const

Definition at line 464 of file capabilities_vk.cc.

464 {
465 default_color_format_ = pixel_format;
466 }

Referenced by impeller::ContextVK::SetOffscreenFormat().

## ◆ SetPhysicalDevice()

bool impeller::CapabilitiesVK::SetPhysicalDevice | ( | const vk::PhysicalDevice & | physical_device,
|  | const PhysicalDeviceFeatures & | enabled_features
| ) |  |

Definition at line 468 of file capabilities_vk.cc.

470 {
471 if (HasSuitableColorFormat(device, vk::Format::eR8G8B8A8Unorm)) {
472 default_color_format_ = PixelFormat::kR8G8B8A8UNormInt;
473 } else {
474 default_color_format_ = PixelFormat::kUnknown;
475 }
476
477 if (HasSuitableDepthStencilFormat(device, vk::Format::eD32SfloatS8Uint)) {
478 default_depth_stencil_format_ = PixelFormat::kD32FloatS8UInt;
479 } else if (HasSuitableDepthStencilFormat(device,
480 vk::Format::eD24UnormS8Uint)) {
481 default_depth_stencil_format_ = PixelFormat::kD24UnormS8Uint;
482 } else {
483 default_depth_stencil_format_ = PixelFormat::kUnknown;
484 }
485
486 if (HasSuitableDepthStencilFormat(device, vk::Format::eS8Uint)) {
487 default_stencil_format_ = PixelFormat::kS8UInt;
488 } else if (default_depth_stencil_format_ != PixelFormat::kUnknown) {
489 default_stencil_format_ = default_depth_stencil_format_;
490 }
491
492 physical_device_ = device;
493 device_properties_ = device.getProperties();
494
495 auto physical_properties_2 =
496 device.getProperties2<vk::PhysicalDeviceProperties2,
497 vk::PhysicalDeviceSubgroupProperties>();
498
499 // Currently shaders only want access to arithmetic subgroup features.
500 // If that changes this needs to get updated, and so does Metal (which right
501 // now assumes it from compile time flags based on the MSL target version).
502
503 supports_compute_subgroups_ =
504 !!(physical_properties_2.get<vk::PhysicalDeviceSubgroupProperties>()
505 .supportedOperations &
506 vk::SubgroupFeatureFlagBits::eArithmetic);
507
508 {
509 // Query texture support.
510 // TODO(129784): Add a capability check for expected memory types.
511 vk::PhysicalDeviceMemoryProperties memory_properties;
512 device.getMemoryProperties(&memory_properties);
513
514 for (auto i = 0u; i < memory_properties.memoryTypeCount; i++) {
515 if (memory_properties.memoryTypes[i].propertyFlags &
516 vk::MemoryPropertyFlagBits::eLazilyAllocated) {
517 supports_device_transient_textures_ = true;
518 }
519 }
520 }
521
522 // Determine the optional device extensions this physical device supports.
523 {
524 required_common_device_extensions_.clear();
525 required_android_device_extensions_.clear();
526 optional_device_extensions_.clear();
527 auto exts = GetSupportedDeviceExtensions(device);
528 if (!exts.has_value()) {
529 return false;
530 }
531 IterateExtensions<RequiredCommonDeviceExtensionVK>([&](auto ext) -> bool {
532 auto ext_name = GetExtensionName(ext);
533 if (exts->find(ext_name) != exts->end()) {
534 required_common_device_extensions_.insert(ext);
535 }
536 return true;
537 });
538 IterateExtensions<RequiredAndroidDeviceExtensionVK>([&](auto ext) -> bool {
539 auto ext_name = GetExtensionName(ext);
540 if (exts->find(ext_name) != exts->end()) {
541 required_android_device_extensions_.insert(ext);
542 }
543 return true;
544 });
545 IterateExtensions<OptionalDeviceExtensionVK>([&](auto ext) -> bool {
546 auto ext_name = GetExtensionName(ext);
547 if (exts->find(ext_name) != exts->end()) {
548 optional_device_extensions_.insert(ext);
549 }
550 return true;
551 });
552 }
553
554 supports_texture_fixed_rate_compression_ =
555 enabled_features
556 .isLinked<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>() &&
557 enabled_features
558 .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>()
559 .imageCompressionControl;
560
561 max_render_pass_attachment_size_ =
562 ISize{device_properties_.limits.maxFramebufferWidth,
563 device_properties_.limits.maxFramebufferHeight};
564
565 return true;
566 }

References impeller::GetExtensionName(), impeller::GetSupportedDeviceExtensions(), impeller::HasSuitableColorFormat(), impeller::HasSuitableDepthStencilFormat(), impeller::kD24UnormS8Uint, impeller::kD32FloatS8UInt, impeller::kR8G8B8A8UNormInt, impeller::kS8UInt, and impeller::kUnknown.

## ◆ SupportsCompute()

bool impeller::CapabilitiesVK::SupportsCompute | ( |  | ) | const
| override virtual

Whether the context backend supports `ComputePass`.

Implements impeller::Capabilities.

Definition at line 594 of file capabilities_vk.cc.

594 {
595 // Vulkan 1.1 requires support for compute.
596 return true;
597 }

## ◆ SupportsComputeSubgroups()

bool impeller::CapabilitiesVK::SupportsComputeSubgroups | ( |  | ) | const
| override virtual

Whether the context backend supports configuring `ComputePass` command subgroups.

Implements impeller::Capabilities.

Definition at line 600 of file capabilities_vk.cc.

600 {
601 // Set by |SetPhysicalDevice|.
602 return supports_compute_subgroups_;
603 }

## ◆ SupportsDecalSamplerAddressMode()

bool impeller::CapabilitiesVK::SupportsDecalSamplerAddressMode | ( |  | ) | const
| override virtual

Whether the context backend supports `SamplerAddressMode::Decal`.

Implements impeller::Capabilities.

Definition at line 610 of file capabilities_vk.cc.

610 {
611 return true;
612 }

## ◆ SupportsDeviceTransientTextures()

bool impeller::CapabilitiesVK::SupportsDeviceTransientTextures | ( |  | ) | const
| override virtual

Whether the context backend supports allocating `StorageMode::kDeviceTransient` (aka "memoryless") textures, which are temporary textures kept in tile memory for the duration of the `RenderPass` it's attached to.

This feature is especially useful for MSAA and stencils.

Implements impeller::Capabilities.

Definition at line 615 of file capabilities_vk.cc.

615 {
616 return supports_device_transient_textures_;
617 }

## ◆ SupportsFramebufferFetch()

bool impeller::CapabilitiesVK::SupportsFramebufferFetch | ( |  | ) | const
| override virtual

Whether the context backend is able to support pipelines with shaders that read from the framebuffer (i.e. pixels that have been written by previous draw calls in the current render pass).

Example of reading from the first color attachment in a GLSL shader: ``` uniform subpassInput subpass_input;

out vec4 frag_color;

void main() { vec4 color = subpassLoad(subpass_input); // Invert the colors drawn to the framebuffer. frag_color = vec4(vec3(1) - color.rgb, color.a); } ```

Implements impeller::Capabilities.

Definition at line 589 of file capabilities_vk.cc.

589 {
590 return true;
591 }

## ◆ SupportsImplicitResolvingMSAA()

bool impeller::CapabilitiesVK::SupportsImplicitResolvingMSAA | ( |  | ) | const
| override virtual

Whether the context backend supports multisampled rendering to the on-screen surface without requiring an explicit resolve of the MSAA color attachment.

Implements impeller::Capabilities.

Definition at line 574 of file capabilities_vk.cc.

574 {
575 return false;
576 }

## ◆ SupportsOffscreenMSAA()

bool impeller::CapabilitiesVK::SupportsOffscreenMSAA | ( |  | ) | const
| override virtual

Whether the context backend supports attaching offscreen MSAA color/stencil textures.

Implements impeller::Capabilities.

Definition at line 569 of file capabilities_vk.cc.

569 {
570 return true;
571 }

## ◆ SupportsReadFromResolve()

bool impeller::CapabilitiesVK::SupportsReadFromResolve | ( |  | ) | const
| override virtual

Whether the context backend supports binding the current `RenderPass` attachments. This is supported if the backend can guarantee that attachment textures will not be mutated until the render pass has fully completed.

This is possible because many mobile graphics cards track `RenderPass` attachment state in intermediary tile memory prior to Storing the pass in the heap allocated attachments on DRAM. Metal's hazard tracking and Vulkan's barriers are granular enough to allow for safely accessing attachment textures prior to storage in the same `RenderPass`.

Implements impeller::Capabilities.

Definition at line 606 of file capabilities_vk.cc.

606 {
607 return false;
608 }

## ◆ SupportsSSBO()

bool impeller::CapabilitiesVK::SupportsSSBO | ( |  | ) | const
| override virtual

Whether the context backend supports binding Shader Storage Buffer Objects (SSBOs) to pipelines.

Implements impeller::Capabilities.

Definition at line 579 of file capabilities_vk.cc.

579 {
580 return true;
581 }

## ◆ SupportsTextureFixedRateCompression()

bool impeller::CapabilitiesVK::SupportsTextureFixedRateCompression | ( |  | ) | const

Returns
  If fixed-rate compression for non-onscreen surfaces is supported.

Definition at line 658 of file capabilities_vk.cc.

658 {
659 return supports_texture_fixed_rate_compression_;
660 }

## ◆ SupportsTextureToTextureBlits()

bool impeller::CapabilitiesVK::SupportsTextureToTextureBlits | ( |  | ) | const
| override virtual

Whether the context backend supports blitting from one texture region to another texture region (via the relevant `BlitPass::AddCopy` overloads).

Implements impeller::Capabilities.

Definition at line 584 of file capabilities_vk.cc.

584 {
585 return true;
586 }

## ◆ SupportsTriangleFan()

bool impeller::CapabilitiesVK::SupportsTriangleFan | ( |  | ) | const
| override virtual

Whether the primitive type TriangleFan is supported by the backend.

Implements impeller::Capabilities.

Definition at line 715 of file capabilities_vk.cc.

715 {
716 return true;
717 }

The documentation for this class was generated from the following files:

- impeller/renderer/backend/vulkan/capabilities_vk.h
- impeller/renderer/backend/vulkan/capabilities_vk.cc

impeller::OptionalDeviceExtensionVK
OptionalDeviceExtensionVK
A device extension enabled if available. Subsystems cannot assume availability and must check if thes...
Definition: capabilities_vk.h:120
impeller::HasRequiredProperties
static bool HasRequiredProperties(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:322
impeller::ISize
ISize64 ISize
Definition: size.h:140
impeller::PixelFormat::kS8UInt
@ kS8UInt
impeller::kInstanceLayer
static constexpr const char * kInstanceLayer
Definition: capabilities_vk.cc:16
impeller::PixelFormat::kR8UNormInt
@ kR8UNormInt
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::HasSuitableDepthStencilFormat
static bool HasSuitableDepthStencilFormat(const vk::PhysicalDevice &device, vk::Format format)
Definition: capabilities_vk.cc:305
impeller::HasRequiredQueues
static bool HasRequiredQueues(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:331
impeller::GetExtensionName
static const char * GetExtensionName(RequiredCommonDeviceExtensionVK ext)
Definition: capabilities_vk.cc:160
impeller::RequiredCommonDeviceExtensionVK
RequiredCommonDeviceExtensionVK
A device extension available on all platforms. Without the presence of these extensions,...
Definition: capabilities_vk.h:28
impeller::PixelFormat::kD32FloatS8UInt
@ kD32FloatS8UInt
impeller::PhysicalDeviceSupportsRequiredFormats
static bool PhysicalDeviceSupportsRequiredFormats(const vk::PhysicalDevice &device)
Definition: capabilities_vk.cc:312
impeller::CapabilitiesVK::HasExtension
bool HasExtension(RequiredCommonDeviceExtensionVK ext) const
Definition: capabilities_vk.cc:643
impeller::GetSupportedDeviceExtensions
static std::optional< std::set< std::string > > GetSupportedDeviceExtensions(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:224
impeller::RequiredAndroidDeviceExtensionVK::kKHRSamplerYcbcrConversion
@ kKHRSamplerYcbcrConversion
impeller::PixelFormat::kD24UnormS8Uint
@ kD24UnormS8Uint
impeller::CapabilitiesVK::PhysicalDeviceFeatures
vk::StructureChain< vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR, vk::PhysicalDevice16BitStorageFeatures, vk::PhysicalDeviceImageCompressionControlFeaturesEXT > PhysicalDeviceFeatures
Definition: capabilities_vk.h:198
impeller::CompressionType::kLossy
@ kLossy
impeller::PixelFormat::kUnknown
@ kUnknown
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91
impeller::HasSuitableColorFormat
static bool HasSuitableColorFormat(const vk::PhysicalDevice &device, vk::Format format)
Definition: capabilities_vk.cc:297
impeller::IsExtensionInList
static bool IsExtensionInList(const std::vector< std::string > &list, ExtensionEnum ext)
Definition: capabilities_vk.cc:346
impeller::RequiredAndroidDeviceExtensionVK
RequiredAndroidDeviceExtensionVK
A device extension available on all Android platforms. Without the presence of these extensions on An...
Definition: capabilities_vk.h:47
impeller::CapabilitiesVK::GetEnabledDeviceExtensions
std::optional< std::vector< std::string > > GetEnabledDeviceExtensions(const vk::PhysicalDevice &physical_device) const
Definition: capabilities_vk.cc:240
impeller::OptionalDeviceExtensionVK::kEXTImageCompressionControl
@ kEXTImageCompressionControl