| 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, bool use_embedder_extensions=false, std::vector< std::string > instance_extensions={}, std::vector< std::string > device_extensions={})
| ~CapabilitiesVK ()
bool | IsValid () const
bool | AreValidationsEnabled () const
bool | HasExtension (RequiredCommonDeviceExtensionVK ext) const
bool | HasExtension (RequiredAndroidDeviceExtensionVK ext) const
bool | HasExtension (OptionalDeviceExtensionVK ext) const
bool | HasExtension (OptionalAndroidDeviceExtensionVK 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...
bool | SupportsPrimitiveRestart () const override
| Whether primitive restart is supported. More...
bool | SupportsExtendedRangeFormats () const override
| Whether the XR formats are supported on this device. 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...
size_t | GetMinimumUniformAlignment () const override
| The minimum alignment of uniform value offsets in bytes. More...
bool | SupportsTextureFixedRateCompression () const
bool | SupportsExternalSemaphoreExtensions () 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...
void | ApplyWorkarounds (const WorkaroundsVK &workarounds)
| Update capabilities for the given set of workarounds. 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 180 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 210 of file capabilities_vk.h.

## Constructor & Destructor Documentation

## ◆ CapabilitiesVK()

impeller::CapabilitiesVK::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 = `{}`
| ) |  |
| explicit

Definition at line 19 of file capabilities_vk.cc.

24 : use_embedder_extensions_(use_embedder_extensions),
25 embedder_instance_extensions_(std::move(instance_extensions)),
26 embedder_device_extensions_(std::move(device_extensions)) {
27 if (!use_embedder_extensions_) {
28 auto extensions = vk::enumerateInstanceExtensionProperties();
29 auto layers = vk::enumerateInstanceLayerProperties();
30
31 if (extensions.result != vk::Result::eSuccess ||
32 layers.result != vk::Result::eSuccess) {
33 return;
34 }
35
36 for (const auto& ext : extensions.value) {
37 exts_[kInstanceLayer].insert(ext.extensionName);
38 }
39
40 for (const auto& layer : layers.value) {
41 const std::string layer_name = layer.layerName;
42 auto layer_exts = vk::enumerateInstanceExtensionProperties(layer_name);
43 if (layer_exts.result != vk::Result::eSuccess) {
44 return;
45 }
46 for (const auto& layer_ext : layer_exts.value) {
47 exts_[layer_name].insert(layer_ext.extensionName);
48 }
49 }
50 } else {
51 for (const auto& ext : embedder_instance_extensions_) {
52 exts_[kInstanceLayer].insert(ext);
53 }
54 }
55
56 validations_enabled_ =
57 enable_validations && HasLayer("VK_LAYER_KHRONOS_validation");
58 if (enable_validations && !validations_enabled_) {
59 FML_LOG(ERROR)
60 << "Requested Impeller context creation with validations but the "
61 "validation layers could not be found. Expect no Vulkan validation "
62 "checks!";
63 if (fatal_missing_validations) {
64 FML_LOG(FATAL) << "Validation missing. Exiting.";
65 }
66 }
67 if (validations_enabled_) {
68 FML_LOG(INFO) << "Vulkan validations are enabled.";
69 }
70 is_valid_ = true;
71 }
impeller::kInstanceLayer
static constexpr const char * kInstanceLayer
Definition: capabilities_vk.cc:17

References impeller::kInstanceLayer.

## ◆ ~CapabilitiesVK()

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

## Member Function Documentation

## ◆ ApplyWorkarounds()

void impeller::CapabilitiesVK::ApplyWorkarounds | ( | const WorkaroundsVK & | workarounds | ) |

Update capabilities for the given set of workarounds.

Definition at line 815 of file capabilities_vk.cc.

815 {
816 has_primitive_restart_ = !workarounds.slow_primitive_restart_performance;
817 has_framebuffer_fetch_ = !workarounds.input_attachment_self_dependency_broken;
818 }

References impeller::WorkaroundsVK::input_attachment_self_dependency_broken, and impeller::WorkaroundsVK::slow_primitive_restart_performance.

## ◆ AreValidationsEnabled()

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

Definition at line 79 of file capabilities_vk.cc.

79 {
80 return validations_enabled_;
81 }

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 703 of file capabilities_vk.cc.

703 {
704 return default_color_format_;
705 }

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 713 of file capabilities_vk.cc.

713 {
714 return default_depth_stencil_format_;
715 }

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 722 of file capabilities_vk.cc.

722 {
723 return PixelFormat::kR8UNormInt;
724 }
impeller::PixelFormat::kR8UNormInt
@ kR8UNormInt

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 708 of file capabilities_vk.cc.

708 {
709 return default_stencil_format_;
710 }

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

## ◆ GetEnabledDeviceExtensions()

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

Definition at line 260 of file capabilities_vk.cc.

261 {
262 std::set<std::string> exts;
263
264 if (!use_embedder_extensions_) {
265 auto maybe_exts = GetSupportedDeviceExtensions(physical_device);
266
267 if (!maybe_exts.has_value()) {
268 return std::nullopt;
269 }
270 exts = maybe_exts.value();
271 } else {
272 for (const auto& ext : embedder_device_extensions_) {
273 exts.insert(ext);
274 }
275 }
276
277 std::vector<std::string> enabled;
278
279 auto for_each_common_extension = [&](RequiredCommonDeviceExtensionVK ext) {
280 auto name = GetExtensionName(ext);
281 if (exts.find(name) == exts.end()) {
282 VALIDATION_LOG << "Device does not support required extension: " << name;
283 return false;
284 }
285 enabled.push_back(name);
286 return true;
287 };
288
289 auto for_each_android_extension = [&](RequiredAndroidDeviceExtensionVK ext) {
290 #ifdef FML_OS_ANDROID
291 auto name = GetExtensionName(ext);
292 if (exts.find(name) == exts.end()) {
293 VALIDATION_LOG << "Device does not support required Android extension: "
294 << name;
295 return false;
296 }
297 enabled.push_back(name);
298 #endif // FML_OS_ANDROID
299 return true;
300 };
301
302 auto for_each_optional_android_extension =
303 [&](OptionalAndroidDeviceExtensionVK ext) {
304 #ifdef FML_OS_ANDROID
305 auto name = GetExtensionName(ext);
306 if (exts.find(name) != exts.end()) {
307 enabled.push_back(name);
308 }
309 #endif // FML_OS_ANDROID
310 return true;
311 };
312
313 auto for_each_optional_extension = [&](OptionalDeviceExtensionVK ext) {
314 auto name = GetExtensionName(ext);
315 if (exts.find(name) != exts.end()) {
316 enabled.push_back(name);
317 }
318 return true;
319 };
320
321 const auto iterate_extensions =
322 IterateExtensions<RequiredCommonDeviceExtensionVK>(
323 for_each_common_extension) &&
324 IterateExtensions<RequiredAndroidDeviceExtensionVK>(
325 for_each_android_extension) &&
326 IterateExtensions<OptionalDeviceExtensionVK>(
327 for_each_optional_extension) &&
328 IterateExtensions<OptionalAndroidDeviceExtensionVK>(
329 for_each_optional_android_extension);
330
331 if (!iterate_extensions) {
332 VALIDATION_LOG << "Device not suitable since required extensions are not "
333 "supported.";
334 return std::nullopt;
335 }
336
337 return enabled;
338 }
impeller::GetSupportedDeviceExtensions
static std::optional< std::set< std::string > > GetSupportedDeviceExtensions(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:244
impeller::RequiredAndroidDeviceExtensionVK
RequiredAndroidDeviceExtensionVK
A device extension available on all Android platforms. Without the presence of these extensions on An...
Definition: capabilities_vk.h:48
impeller::RequiredCommonDeviceExtensionVK
RequiredCommonDeviceExtensionVK
A device extension available on all platforms. Without the presence of these extensions,...
Definition: capabilities_vk.h:29
impeller::OptionalAndroidDeviceExtensionVK
OptionalAndroidDeviceExtensionVK
A device extension available on some Android platforms.
Definition: capabilities_vk.h:93
impeller::GetExtensionName
static const char * GetExtensionName(RequiredCommonDeviceExtensionVK ext)
Definition: capabilities_vk.cc:173
impeller::OptionalDeviceExtensionVK
OptionalDeviceExtensionVK
A device extension enabled if available. Subsystems cannot assume availability and must check if thes...
Definition: capabilities_vk.h:131
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91

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 396 of file capabilities_vk.cc.

397 {
398 if (!PhysicalDeviceSupportsRequiredFormats(device)) {
399 VALIDATION_LOG << "Device doesn't support the required formats.";
400 return std::nullopt;
401 }
402
403 if (!HasRequiredProperties(device)) {
404 VALIDATION_LOG << "Device doesn't support the required properties.";
405 return std::nullopt;
406 }
407
408 if (!HasRequiredQueues(device)) {
409 VALIDATION_LOG << "Device doesn't support the required queues.";
410 return std::nullopt;
411 }
412
413 const auto enabled_extensions = GetEnabledDeviceExtensions(device);
414 if (!enabled_extensions.has_value()) {
415 VALIDATION_LOG << "Device doesn't support the required queues.";
416 return std::nullopt;
417 }
418
419 PhysicalDeviceFeatures supported_chain;
420
421 // Swiftshader seems to be fussy about just this structure even being in the
422 // chain. Just unlink it if its not supported. We already perform an
423 // extensions check on the other side when reading.
424 if (!IsExtensionInList(
425 enabled_extensions.value(),
426 OptionalDeviceExtensionVK::kEXTImageCompressionControl)) {
427 supported_chain
428 .unlink<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
429 }
430
431 device.getFeatures2(&supported_chain.get());
432
433 PhysicalDeviceFeatures required_chain;
434
435 // Base features.
436 {
437 auto& required = required_chain.get().features;
438 const auto& supported = supported_chain.get().features;
439
440 // We require this for enabling wireframes in the playground. But its not
441 // necessarily a big deal if we don't have this feature.
442 required.fillModeNonSolid = supported.fillModeNonSolid;
443 }
444 // VK_KHR_sampler_ycbcr_conversion features.
445 if (IsExtensionInList(
446 enabled_extensions.value(),
447 RequiredAndroidDeviceExtensionVK::kKHRSamplerYcbcrConversion)) {
448 auto& required =
449 required_chain
450 .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
451 const auto& supported =
452 supported_chain
453 .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
454
455 required.samplerYcbcrConversion = supported.samplerYcbcrConversion;
456 }
457
458 // VK_EXT_image_compression_control
459 if (IsExtensionInList(
460 enabled_extensions.value(),
461 OptionalDeviceExtensionVK::kEXTImageCompressionControl)) {
462 auto& required =
463 required_chain
464 .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
465 const auto& supported =
466 supported_chain
467 .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
468
469 required.imageCompressionControl = supported.imageCompressionControl;
470 } else {
471 required_chain
472 .unlink<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
473 }
474
475 // Vulkan 1.1
476 {
477 auto& required =
478 required_chain.get<vk::PhysicalDevice16BitStorageFeatures>();
479 const auto& supported =
480 supported_chain.get<vk::PhysicalDevice16BitStorageFeatures>();
481
482 required.uniformAndStorageBuffer16BitAccess =
483 supported.uniformAndStorageBuffer16BitAccess;
484 }
485
486 return required_chain;
487 }
impeller::CapabilitiesVK::PhysicalDeviceFeatures
vk::StructureChain< vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR, vk::PhysicalDevice16BitStorageFeatures, vk::PhysicalDeviceImageCompressionControlFeaturesEXT > PhysicalDeviceFeatures
Definition: capabilities_vk.h:214
impeller::CapabilitiesVK::GetEnabledDeviceExtensions
std::optional< std::vector< std::string > > GetEnabledDeviceExtensions(const vk::PhysicalDevice &physical_device) const
Definition: capabilities_vk.cc:260
impeller::PhysicalDeviceSupportsRequiredFormats
static bool PhysicalDeviceSupportsRequiredFormats(const vk::PhysicalDevice &device)
Definition: capabilities_vk.cc:355
impeller::HasRequiredProperties
static bool HasRequiredProperties(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:365
impeller::IsExtensionInList
static bool IsExtensionInList(const std::vector< std::string > &list, ExtensionEnum ext)
Definition: capabilities_vk.cc:389
impeller::RequiredAndroidDeviceExtensionVK::kKHRSamplerYcbcrConversion
@ kKHRSamplerYcbcrConversion
impeller::OptionalDeviceExtensionVK::kEXTImageCompressionControl
@ kEXTImageCompressionControl
impeller::HasRequiredQueues
static bool HasRequiredQueues(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:374

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 96 of file capabilities_vk.cc.

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

References HasExtension(), and VALIDATION_LOG.

## ◆ GetEnabledLayers()

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

Definition at line 83 of file capabilities_vk.cc.

84 {
85 std::vector<std::string> required;
86
87 if (validations_enabled_) {
88 // The presence of this layer is already checked in the ctor.
89 required.push_back("VK_LAYER_KHRONOS_validation");
90 }
91
92 return required;
93 }

## ◆ 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 811 of file capabilities_vk.cc.

811 {
812 return max_render_pass_attachment_size_;
813 }

## ◆ GetMinimumUniformAlignment()

size_t impeller::CapabilitiesVK::GetMinimumUniformAlignment | ( |  | ) | const
| override virtual

The minimum alignment of uniform value offsets in bytes.

Implements impeller::Capabilities.

Definition at line 726 of file capabilities_vk.cc.

726 {
727 return minimum_uniform_alignment_;
728 }

## ◆ GetPhysicalDeviceProperties()

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

Definition at line 718 of file capabilities_vk.cc.

718 {
719 return device_properties_;
720 }

## ◆ 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 755 of file capabilities_vk.cc.

756 {
757 if (compression_type != CompressionType::kLossy) {
758 return std::nullopt;
759 }
760 if (!supports_texture_fixed_rate_compression_) {
761 return std::nullopt;
762 }
763 // There are opportunities to hash and cache the FRCFormatDescriptor if
764 // needed.
765 vk::StructureChain<vk::PhysicalDeviceImageFormatInfo2,
766 vk::ImageCompressionControlEXT>
767 format_chain;
768
769 auto& format_info = format_chain.get();
770
771 format_info.format = desc.format;
772 format_info.type = desc.type;
773 format_info.tiling = desc.tiling;
774 format_info.usage = desc.usage;
775 format_info.flags = desc.flags;
776
777 const auto kIdealFRCRate = vk::ImageCompressionFixedRateFlagBitsEXT::e4Bpc;
778
779 std::array<vk::ImageCompressionFixedRateFlagsEXT, 1u> rates = {kIdealFRCRate};
780
781 auto& compression = format_chain.get<vk::ImageCompressionControlEXT>();
782 compression.flags = vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit;
783 compression.compressionControlPlaneCount = rates.size();
784 compression.pFixedRateFlags = rates.data();
785
786 const auto [result, supported] = physical_device_.getImageFormatProperties2<
787 vk::ImageFormatProperties2, vk::ImageCompressionPropertiesEXT>(
788 format_chain.get());
789
790 if (result != vk::Result::eSuccess ||
791 !supported.isLinked<vk::ImageCompressionPropertiesEXT>()) {
792 return std::nullopt;
793 }
794
795 const auto& compression_props =
796 supported.get<vk::ImageCompressionPropertiesEXT>();
797
798 if ((compression_props.imageCompressionFlags &
799 vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit) &&
800 (compression_props.imageCompressionFixedRateFlags & kIdealFRCRate)) {
801 return kIdealFRCRate;
802 }
803
804 return std::nullopt;
805 }
impeller::CompressionType::kLossy
@ kLossy

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

## ◆ HasExtension() [1/4]

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

Definition at line 745 of file capabilities_vk.cc.

745 {
746 return optional_android_device_extensions_.find(ext) !=
747 optional_android_device_extensions_.end();
748 }

## ◆ HasExtension() [2/4]

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

Definition at line 740 of file capabilities_vk.cc.

740 {
741 return optional_device_extensions_.find(ext) !=
742 optional_device_extensions_.end();
743 }

## ◆ HasExtension() [3/4]

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

Definition at line 735 of file capabilities_vk.cc.

735 {
736 return required_android_device_extensions_.find(ext) !=
737 required_android_device_extensions_.end();
738 }

## ◆ HasExtension() [4/4]

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

Definition at line 730 of file capabilities_vk.cc.

730 {
731 return required_common_device_extensions_.find(ext) !=
732 required_common_device_extensions_.end();
733 }

Referenced by GetEnabledInstanceExtensions(), and SetPhysicalDevice().

## ◆ IsValid()

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

Definition at line 75 of file capabilities_vk.cc.

75 {
76 return is_valid_;
77 }

## ◆ SetOffscreenFormat()

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

Definition at line 511 of file capabilities_vk.cc.

511 {
512 default_color_format_ = pixel_format;
513 }

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

## ◆ SetPhysicalDevice()

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

Definition at line 515 of file capabilities_vk.cc.

517 {
518 if (HasSuitableColorFormat(device, vk::Format::eR8G8B8A8Unorm)) {
519 default_color_format_ = PixelFormat::kR8G8B8A8UNormInt;
520 } else {
521 default_color_format_ = PixelFormat::kUnknown;
522 }
523
524 if (HasSuitableDepthStencilFormat(device, vk::Format::eD24UnormS8Uint)) {
525 default_depth_stencil_format_ = PixelFormat::kD24UnormS8Uint;
526 } else if (HasSuitableDepthStencilFormat(device,
527 vk::Format::eD32SfloatS8Uint)) {
528 default_depth_stencil_format_ = PixelFormat::kD32FloatS8UInt;
529 } else {
530 default_depth_stencil_format_ = PixelFormat::kUnknown;
531 }
532
533 if (HasSuitableDepthStencilFormat(device, vk::Format::eS8Uint)) {
534 default_stencil_format_ = PixelFormat::kS8UInt;
535 } else if (default_depth_stencil_format_ != PixelFormat::kUnknown) {
536 default_stencil_format_ = default_depth_stencil_format_;
537 }
538
539 physical_device_ = device;
540 device_properties_ = device.getProperties();
541
542 auto physical_properties_2 =
543 device.getProperties2<vk::PhysicalDeviceProperties2,
544 vk::PhysicalDeviceSubgroupProperties>();
545
546 // Currently shaders only want access to arithmetic subgroup features.
547 // If that changes this needs to get updated, and so does Metal (which right
548 // now assumes it from compile time flags based on the MSL target version).
549
550 supports_compute_subgroups_ =
551 !!(physical_properties_2.get<vk::PhysicalDeviceSubgroupProperties>()
552 .supportedOperations &
553 vk::SubgroupFeatureFlagBits::eArithmetic);
554
555 {
556 // Query texture support.
557 // TODO(129784): Add a capability check for expected memory types.
558 vk::PhysicalDeviceMemoryProperties memory_properties;
559 device.getMemoryProperties(&memory_properties);
560
561 for (auto i = 0u; i < memory_properties.memoryTypeCount; i++) {
562 if (memory_properties.memoryTypes[i].propertyFlags &
563 vk::MemoryPropertyFlagBits::eLazilyAllocated) {
564 supports_device_transient_textures_ = true;
565 }
566 }
567 }
568
569 // Determine the optional device extensions this physical device supports.
570 {
571 required_common_device_extensions_.clear();
572 required_android_device_extensions_.clear();
573 optional_device_extensions_.clear();
574 optional_android_device_extensions_.clear();
575
576 std::set<std::string> exts;
577 if (!use_embedder_extensions_) {
578 auto maybe_exts = GetSupportedDeviceExtensions(device);
579 if (!maybe_exts.has_value()) {
580 return false;
581 }
582 exts = maybe_exts.value();
583 } else {
584 for (const auto& ext : embedder_device_extensions_) {
585 exts.insert(ext);
586 }
587 }
588
589 IterateExtensions<RequiredCommonDeviceExtensionVK>([&](auto ext) -> bool {
590 auto ext_name = GetExtensionName(ext);
591 if (exts.find(ext_name) != exts.end()) {
592 required_common_device_extensions_.insert(ext);
593 }
594 return true;
595 });
596 IterateExtensions<RequiredAndroidDeviceExtensionVK>([&](auto ext) -> bool {
597 auto ext_name = GetExtensionName(ext);
598 if (exts.find(ext_name) != exts.end()) {
599 required_android_device_extensions_.insert(ext);
600 }
601 return true;
602 });
603 IterateExtensions<OptionalDeviceExtensionVK>([&](auto ext) -> bool {
604 auto ext_name = GetExtensionName(ext);
605 if (exts.find(ext_name) != exts.end()) {
606 optional_device_extensions_.insert(ext);
607 }
608 return true;
609 });
610 IterateExtensions<OptionalAndroidDeviceExtensionVK>(
611 [&](OptionalAndroidDeviceExtensionVK ext) {
612 auto name = GetExtensionName(ext);
613 if (exts.find(name) != exts.end()) {
614 optional_android_device_extensions_.insert(ext);
615 }
616 return true;
617 });
618 }
619
620 supports_texture_fixed_rate_compression_ =
621 enabled_features
622 .isLinked<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>() &&
623 enabled_features
624 .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>()
625 .imageCompressionControl;
626
627 max_render_pass_attachment_size_ =
628 ISize{device_properties_.limits.maxFramebufferWidth,
629 device_properties_.limits.maxFramebufferHeight};
630
631 // Molten, Vulkan on Metal, cannot support triangle fans because Metal doesn't
632 // support triangle fans.
633 // See VUID-VkPipelineInputAssemblyStateCreateInfo-triangleFans-04452.
634 has_triangle_fans_ =
635 !HasExtension(OptionalDeviceExtensionVK::kVKKHRPortabilitySubset);
636
637 // External Fence/Semaphore for AHB swapchain
638 if (HasExtension(OptionalAndroidDeviceExtensionVK::kKHRExternalFenceFd) &&
639 HasExtension(OptionalAndroidDeviceExtensionVK::kKHRExternalFence) &&
640 HasExtension(OptionalAndroidDeviceExtensionVK::kKHRExternalSemaphore) &&
641 HasExtension(OptionalAndroidDeviceExtensionVK::kKHRExternalSemaphoreFd)) {
642 supports_external_fence_and_semaphore_ = true;
643 }
644
645 minimum_uniform_alignment_ =
646 device_properties_.limits.minUniformBufferOffsetAlignment;
647
648 return true;
649 }
impeller::HasSuitableColorFormat
static bool HasSuitableColorFormat(const vk::PhysicalDevice &device, vk::Format format)
Definition: capabilities_vk.cc:340
impeller::PixelFormat::kD24UnormS8Uint
@ kD24UnormS8Uint
impeller::PixelFormat::kUnknown
@ kUnknown
impeller::PixelFormat::kS8UInt
@ kS8UInt
impeller::PixelFormat::kD32FloatS8UInt
@ kD32FloatS8UInt
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::HasSuitableDepthStencilFormat
static bool HasSuitableDepthStencilFormat(const vk::PhysicalDevice &device, vk::Format format)
Definition: capabilities_vk.cc:348
impeller::OptionalAndroidDeviceExtensionVK::kKHRExternalFenceFd
@ kKHRExternalFenceFd
impeller::OptionalAndroidDeviceExtensionVK::kKHRExternalSemaphore
@ kKHRExternalSemaphore
impeller::OptionalAndroidDeviceExtensionVK::kKHRExternalFence
@ kKHRExternalFence
impeller::OptionalAndroidDeviceExtensionVK::kKHRExternalSemaphoreFd
@ kKHRExternalSemaphoreFd
impeller::ISize
ISize64 ISize
Definition: size.h:162
impeller::OptionalDeviceExtensionVK::kVKKHRPortabilitySubset
@ kVKKHRPortabilitySubset

References impeller::GetExtensionName(), impeller::GetSupportedDeviceExtensions(), HasExtension(), impeller::HasSuitableColorFormat(), impeller::HasSuitableDepthStencilFormat(), impeller::kD24UnormS8Uint, impeller::kD32FloatS8UInt, impeller::kKHRExternalFence, impeller::kKHRExternalFenceFd, impeller::kKHRExternalSemaphore, impeller::kKHRExternalSemaphoreFd, impeller::kR8G8B8A8UNormInt, impeller::kS8UInt, impeller::kUnknown, and impeller::kVKKHRPortabilitySubset.

## ◆ SupportsCompute()

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

Whether the context backend supports `ComputePass`.

Implements impeller::Capabilities.

Definition at line 677 of file capabilities_vk.cc.

677 {
678 // Vulkan 1.1 requires support for compute.
679 return true;
680 }

## ◆ SupportsComputeSubgroups()

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

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

Implements impeller::Capabilities.

Definition at line 683 of file capabilities_vk.cc.

683 {
684 // Set by |SetPhysicalDevice|.
685 return supports_compute_subgroups_;
686 }

## ◆ SupportsDecalSamplerAddressMode()

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

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

Implements impeller::Capabilities.

Definition at line 693 of file capabilities_vk.cc.

693 {
694 return true;
695 }

## ◆ 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 698 of file capabilities_vk.cc.

698 {
699 return supports_device_transient_textures_;
700 }

## ◆ SupportsExtendedRangeFormats()

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

Whether the XR formats are supported on this device.

This is only ever true for iOS and macOS devices. We may need to revisit this API when approaching wide gamut rendering for Vulkan and GLES.

Implements impeller::Capabilities.

Definition at line 824 of file capabilities_vk.cc.

824 {
825 return false;
826 }

## ◆ SupportsExternalSemaphoreExtensions()

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

Whether the external fence and semaphore extensions used for AHB support are available.

Definition at line 820 of file capabilities_vk.cc.

820 {
821 return supports_external_fence_and_semaphore_;
822 }

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

## ◆ 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 672 of file capabilities_vk.cc.

672 {
673 return has_framebuffer_fetch_;
674 }

## ◆ 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 657 of file capabilities_vk.cc.

657 {
658 return false;
659 }

## ◆ 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 652 of file capabilities_vk.cc.

652 {
653 return true;
654 }

## ◆ SupportsPrimitiveRestart()

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

Whether primitive restart is supported.

Implements impeller::Capabilities.

Definition at line 507 of file capabilities_vk.cc.

507 {
508 return has_primitive_restart_;
509 }

## ◆ 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 689 of file capabilities_vk.cc.

689 {
690 return false;
691 }

## ◆ 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 662 of file capabilities_vk.cc.

662 {
663 return true;
664 }

## ◆ SupportsTextureFixedRateCompression()

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

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

Definition at line 750 of file capabilities_vk.cc.

750 {
751 return supports_texture_fixed_rate_compression_;
752 }

## ◆ 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 667 of file capabilities_vk.cc.

667 {
668 return true;
669 }

## ◆ SupportsTriangleFan()

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

Whether the primitive type TriangleFan is supported by the backend.

Implements impeller::Capabilities.

Definition at line 807 of file capabilities_vk.cc.

807 {
808 return has_triangle_fans_;
809 }

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