| 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 | Supports32BitPrimitiveIndices () const override
| Whether 32-bit values are supported in index buffers used to draw primitives. 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...
size_t | GetMinimumStorageBufferAlignment () const override
| The minimum alignment of storage buffer value offsets in bytes. More...
bool | NeedsPartitionedHostBuffer () const override
| Whether the host buffer should use separate device buffers for indexes from other data. 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 22 of file capabilities_vk.cc.

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 }
impeller::kInstanceLayer
static constexpr const char * kInstanceLayer
Definition: capabilities_vk.cc:20

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

832 {
833 has_primitive_restart_ = !workarounds.slow_primitive_restart_performance;
834 has_framebuffer_fetch_ = !workarounds.input_attachment_self_dependency_broken;
835 }

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

## ◆ AreValidationsEnabled()

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

Definition at line 82 of file capabilities_vk.cc.

82 {
83 return validations_enabled_;
84 }

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

## ◆ GetDefaultColorFormat()

PixelFormat impeller::CapabilitiesVK::GetDefaultColorFormat | ( |  | ) | const
| overridevirtual

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

Implements impeller::Capabilities.

Definition at line 712 of file capabilities_vk.cc.

712 {
713 return default_color_format_;
714 }

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

## ◆ GetDefaultDepthStencilFormat()

PixelFormat impeller::CapabilitiesVK::GetDefaultDepthStencilFormat | ( |  | ) | const
| overridevirtual

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

722 {
723 return default_depth_stencil_format_;
724 }

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

## ◆ GetDefaultGlyphAtlasFormat()

PixelFormat impeller::CapabilitiesVK::GetDefaultGlyphAtlasFormat | ( |  | ) | const
| overridevirtual

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

731 {
732 return PixelFormat::kR8UNormInt;
733 }
impeller::PixelFormat::kR8UNormInt
@ kR8UNormInt

References impeller::kR8UNormInt.

## ◆ GetDefaultStencilFormat()

PixelFormat impeller::CapabilitiesVK::GetDefaultStencilFormat | ( |  | ) | const
| overridevirtual

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

717 {
718 return default_stencil_format_;
719 }

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

## ◆ GetEnabledDeviceExtensions()

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

Definition at line 263 of file capabilities_vk.cc.

264 {
265 std::set<std::string> exts;
266
267 if (!use_embedder_extensions_) {
268 auto maybe_exts = GetSupportedDeviceExtensions(physical_device);
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 =
306 [&](OptionalAndroidDeviceExtensionVK ext) {
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 }
impeller::GetSupportedDeviceExtensions
static std::optional< std::set< std::string > > GetSupportedDeviceExtensions(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:247
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:176
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 399 of file capabilities_vk.cc.

400 {
401 if (!PhysicalDeviceSupportsRequiredFormats(device)) {
402 VALIDATION_LOG << "Device doesn't support the required formats.";
403 return std::nullopt;
404 }
405
406 if (!HasRequiredProperties(device)) {
407 VALIDATION_LOG << "Device doesn't support the required properties.";
408 return std::nullopt;
409 }
410
411 if (!HasRequiredQueues(device)) {
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.
427 if (!IsExtensionInList(
428 enabled_extensions.value(),
429 OptionalDeviceExtensionVK::kEXTImageCompressionControl)) {
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.
448 if (IsExtensionInList(
449 enabled_extensions.value(),
450 RequiredAndroidDeviceExtensionVK::kKHRSamplerYcbcrConversion)) {
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
462 if (IsExtensionInList(
463 enabled_extensions.value(),
464 OptionalDeviceExtensionVK::kEXTImageCompressionControl)) {
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 }
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:263
impeller::PhysicalDeviceSupportsRequiredFormats
static bool PhysicalDeviceSupportsRequiredFormats(const vk::PhysicalDevice &device)
Definition: capabilities_vk.cc:358
impeller::HasRequiredProperties
static bool HasRequiredProperties(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:368
impeller::IsExtensionInList
static bool IsExtensionInList(const std::vector< std::string > &list, ExtensionEnum ext)
Definition: capabilities_vk.cc:392
impeller::RequiredAndroidDeviceExtensionVK::kKHRSamplerYcbcrConversion
@ kKHRSamplerYcbcrConversion
impeller::OptionalDeviceExtensionVK::kEXTImageCompressionControl
@ kEXTImageCompressionControl
impeller::HasRequiredQueues
static bool HasRequiredQueues(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:377

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

99 {
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 }
impeller::CapabilitiesVK::HasExtension
bool HasExtension(RequiredCommonDeviceExtensionVK ext) const
Definition: capabilities_vk.cc:747

References HasExtension(), and VALIDATION_LOG.

## ◆ GetEnabledLayers()

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

Definition at line 86 of file capabilities_vk.cc.

87 {
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 }

## ◆ GetMaximumRenderPassAttachmentSize()

ISize impeller::CapabilitiesVK::GetMaximumRenderPassAttachmentSize | ( |  | ) | const
| overridevirtual

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

828 {
829 return max_render_pass_attachment_size_;
830 }

## ◆ GetMinimumStorageBufferAlignment()

size_t impeller::CapabilitiesVK::GetMinimumStorageBufferAlignment | ( |  | ) | const
| overridevirtual

The minimum alignment of storage buffer value offsets in bytes.

Reimplemented from impeller::Capabilities.

Definition at line 739 of file capabilities_vk.cc.

739 {
740 return minimum_storage_alignment_;
741 }

## ◆ GetMinimumUniformAlignment()

size_t impeller::CapabilitiesVK::GetMinimumUniformAlignment | ( |  | ) | const
| overridevirtual

The minimum alignment of uniform value offsets in bytes.

Implements impeller::Capabilities.

Definition at line 735 of file capabilities_vk.cc.

735 {
736 return minimum_uniform_alignment_;
737 }

## ◆ GetPhysicalDeviceProperties()

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

Definition at line 727 of file capabilities_vk.cc.

727 {
728 return device_properties_;
729 }

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

773 {
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 }
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 762 of file capabilities_vk.cc.

762 {
763 return optional_android_device_extensions_.find(ext) !=
764 optional_android_device_extensions_.end();
765 }

## ◆ HasExtension() [2/4]

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

Definition at line 757 of file capabilities_vk.cc.

757 {
758 return optional_device_extensions_.find(ext) !=
759 optional_device_extensions_.end();
760 }

## ◆ HasExtension() [3/4]

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

Definition at line 752 of file capabilities_vk.cc.

752 {
753 return required_android_device_extensions_.find(ext) !=
754 required_android_device_extensions_.end();
755 }

## ◆ HasExtension() [4/4]

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

Definition at line 747 of file capabilities_vk.cc.

747 {
748 return required_common_device_extensions_.find(ext) !=
749 required_common_device_extensions_.end();
750 }

Referenced by GetEnabledInstanceExtensions(), and SetPhysicalDevice().

## ◆ IsValid()

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

Definition at line 78 of file capabilities_vk.cc.

78 {
79 return is_valid_;
80 }

## ◆ NeedsPartitionedHostBuffer()

bool impeller::CapabilitiesVK::NeedsPartitionedHostBuffer | ( |  | ) | const
| overridevirtual

Whether the host buffer should use separate device buffers for indexes from other data.

Implements impeller::Capabilities.

Definition at line 743 of file capabilities_vk.cc.

743 {
744 return false;
745 }

## ◆ SetOffscreenFormat()

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

Definition at line 518 of file capabilities_vk.cc.

518 {
519 default_color_format_ = pixel_format;
520 }

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

## ◆ SetPhysicalDevice()

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

Definition at line 522 of file capabilities_vk.cc.

524 {
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;
533 } else if (HasSuitableDepthStencilFormat(device,
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>(
618 [&](OptionalAndroidDeviceExtensionVK ext) {
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_ =
642 !HasExtension(OptionalDeviceExtensionVK::kVKKHRPortabilitySubset);
643
644 // External Fence/Semaphore for AHB swapchain
645 if (HasExtension(OptionalAndroidDeviceExtensionVK::kKHRExternalFenceFd) &&
646 HasExtension(OptionalAndroidDeviceExtensionVK::kKHRExternalFence) &&
647 HasExtension(OptionalAndroidDeviceExtensionVK::kKHRExternalSemaphore) &&
648 HasExtension(OptionalAndroidDeviceExtensionVK::kKHRExternalSemaphoreFd)) {
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 }
impeller::HasSuitableColorFormat
static bool HasSuitableColorFormat(const vk::PhysicalDevice &device, vk::Format format)
Definition: capabilities_vk.cc:343
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:351
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.

## ◆ Supports32BitPrimitiveIndices()

bool impeller::CapabilitiesVK::Supports32BitPrimitiveIndices | ( |  | ) | const
| overridevirtual

Whether 32-bit values are supported in index buffers used to draw primitives.

Implements impeller::Capabilities.

Definition at line 514 of file capabilities_vk.cc.

514 {
515 return true;
516 }

## ◆ SupportsCompute()

bool impeller::CapabilitiesVK::SupportsCompute | ( |  | ) | const
| overridevirtual

Whether the context backend supports `ComputePass`.

Implements impeller::Capabilities.

Definition at line 686 of file capabilities_vk.cc.

686 {
687 // Vulkan 1.1 requires support for compute.
688 return true;
689 }

## ◆ SupportsComputeSubgroups()

bool impeller::CapabilitiesVK::SupportsComputeSubgroups | ( |  | ) | const
| overridevirtual

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

Implements impeller::Capabilities.

Definition at line 692 of file capabilities_vk.cc.

692 {
693 // Set by |SetPhysicalDevice|.
694 return supports_compute_subgroups_;
695 }

## ◆ SupportsDecalSamplerAddressMode()

bool impeller::CapabilitiesVK::SupportsDecalSamplerAddressMode | ( |  | ) | const
| overridevirtual

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

Implements impeller::Capabilities.

Definition at line 702 of file capabilities_vk.cc.

702 {
703 return true;
704 }

## ◆ SupportsDeviceTransientTextures()

bool impeller::CapabilitiesVK::SupportsDeviceTransientTextures | ( |  | ) | const
| overridevirtual

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

707 {
708 return supports_device_transient_textures_;
709 }

## ◆ SupportsExtendedRangeFormats()

bool impeller::CapabilitiesVK::SupportsExtendedRangeFormats | ( |  | ) | const
| overridevirtual

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

841 {
842 return false;
843 }

## ◆ SupportsExternalSemaphoreExtensions()

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

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

Definition at line 837 of file capabilities_vk.cc.

837 {
838 return supports_external_fence_and_semaphore_;
839 }

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

## ◆ SupportsFramebufferFetch()

bool impeller::CapabilitiesVK::SupportsFramebufferFetch | ( |  | ) | const
| overridevirtual

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

681 {
682 return has_framebuffer_fetch_;
683 }

## ◆ SupportsImplicitResolvingMSAA()

bool impeller::CapabilitiesVK::SupportsImplicitResolvingMSAA | ( |  | ) | const
| overridevirtual

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

666 {
667 return false;
668 }

## ◆ SupportsOffscreenMSAA()

bool impeller::CapabilitiesVK::SupportsOffscreenMSAA | ( |  | ) | const
| overridevirtual

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

Implements impeller::Capabilities.

Definition at line 661 of file capabilities_vk.cc.

661 {
662 return true;
663 }

## ◆ SupportsPrimitiveRestart()

bool impeller::CapabilitiesVK::SupportsPrimitiveRestart | ( |  | ) | const
| overridevirtual

Whether primitive restart is supported.

Implements impeller::Capabilities.

Definition at line 510 of file capabilities_vk.cc.

510 {
511 return has_primitive_restart_;
512 }

## ◆ SupportsReadFromResolve()

bool impeller::CapabilitiesVK::SupportsReadFromResolve | ( |  | ) | const
| overridevirtual

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

698 {
699 return false;
700 }

## ◆ SupportsSSBO()

bool impeller::CapabilitiesVK::SupportsSSBO | ( |  | ) | const
| overridevirtual

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

Implements impeller::Capabilities.

Definition at line 671 of file capabilities_vk.cc.

671 {
672 return true;
673 }

## ◆ SupportsTextureFixedRateCompression()

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

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

Definition at line 767 of file capabilities_vk.cc.

767 {
768 return supports_texture_fixed_rate_compression_;
769 }

## ◆ SupportsTextureToTextureBlits()

bool impeller::CapabilitiesVK::SupportsTextureToTextureBlits | ( |  | ) | const
| overridevirtual

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

676 {
677 return true;
678 }

## ◆ SupportsTriangleFan()

bool impeller::CapabilitiesVK::SupportsTriangleFan | ( |  | ) | const
| overridevirtual

Whether the primitive type TriangleFan is supported by the backend.

Implements impeller::Capabilities.

Definition at line 824 of file capabilities_vk.cc.

824 {
825 return has_triangle_fans_;
826 }

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