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

828 {
829 has_primitive_restart_ = !workarounds.slow_primitive_restart_performance;
830 has_framebuffer_fetch_ = !workarounds.input_attachment_self_dependency_broken;
831 }

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
| override virtual

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

Implements impeller::Capabilities.

Definition at line 708 of file capabilities_vk.cc.

708 {
709 return default_color_format_;
710 }

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

718 {
719 return default_depth_stencil_format_;
720 }

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

727 {
728 return PixelFormat::kR8UNormInt;
729 }
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 713 of file capabilities_vk.cc.

713 {
714 return default_stencil_format_;
715 }

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:743

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

824 {
825 return max_render_pass_attachment_size_;
826 }

## ◆ GetMinimumStorageBufferAlignment()

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

The minimum alignment of storage buffer value offsets in bytes.

Reimplemented from impeller::Capabilities.

Definition at line 735 of file capabilities_vk.cc.

735 {
736 return minimum_storage_alignment_;
737 }

## ◆ GetMinimumUniformAlignment()

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

The minimum alignment of uniform value offsets in bytes.

Implements impeller::Capabilities.

Definition at line 731 of file capabilities_vk.cc.

731 {
732 return minimum_uniform_alignment_;
733 }

## ◆ GetPhysicalDeviceProperties()

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

Definition at line 723 of file capabilities_vk.cc.

723 {
724 return device_properties_;
725 }

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

769 {
770 if (compression_type != CompressionType::kLossy) {
771 return std::nullopt;
772 }
773 if (!supports_texture_fixed_rate_compression_) {
774 return std::nullopt;
775 }
776 // There are opportunities to hash and cache the FRCFormatDescriptor if
777 // needed.
778 vk::StructureChain<vk::PhysicalDeviceImageFormatInfo2,
779 vk::ImageCompressionControlEXT>
780 format_chain;
781
782 auto& format_info = format_chain.get();
783
784 format_info.format = desc.format;
785 format_info.type = desc.type;
786 format_info.tiling = desc.tiling;
787 format_info.usage = desc.usage;
788 format_info.flags = desc.flags;
789
790 const auto kIdealFRCRate = vk::ImageCompressionFixedRateFlagBitsEXT::e4Bpc;
791
792 std::array<vk::ImageCompressionFixedRateFlagsEXT, 1u> rates = {kIdealFRCRate};
793
794 auto& compression = format_chain.get<vk::ImageCompressionControlEXT>();
795 compression.flags = vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit;
796 compression.compressionControlPlaneCount = rates.size();
797 compression.pFixedRateFlags = rates.data();
798
799 const auto [result, supported] = physical_device_.getImageFormatProperties2<
800 vk::ImageFormatProperties2, vk::ImageCompressionPropertiesEXT>(
801 format_chain.get());
802
803 if (result != vk::Result::eSuccess ||
804 !supported.isLinked<vk::ImageCompressionPropertiesEXT>()) {
805 return std::nullopt;
806 }
807
808 const auto& compression_props =
809 supported.get<vk::ImageCompressionPropertiesEXT>();
810
811 if ((compression_props.imageCompressionFlags &
812 vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit) &&
813 (compression_props.imageCompressionFixedRateFlags & kIdealFRCRate)) {
814 return kIdealFRCRate;
815 }
816
817 return std::nullopt;
818 }
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 758 of file capabilities_vk.cc.

758 {
759 return optional_android_device_extensions_.find(ext) !=
760 optional_android_device_extensions_.end();
761 }

## ◆ HasExtension() [2/4]

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

Definition at line 753 of file capabilities_vk.cc.

753 {
754 return optional_device_extensions_.find(ext) !=
755 optional_device_extensions_.end();
756 }

## ◆ HasExtension() [3/4]

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

Definition at line 748 of file capabilities_vk.cc.

748 {
749 return required_android_device_extensions_.find(ext) !=
750 required_android_device_extensions_.end();
751 }

## ◆ HasExtension() [4/4]

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

Definition at line 743 of file capabilities_vk.cc.

743 {
744 return required_common_device_extensions_.find(ext) !=
745 required_common_device_extensions_.end();
746 }

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
| override virtual

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

Implements impeller::Capabilities.

Definition at line 739 of file capabilities_vk.cc.

739 {
740 return false;
741 }

## ◆ SetOffscreenFormat()

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

Definition at line 514 of file capabilities_vk.cc.

514 {
515 default_color_format_ = pixel_format;
516 }

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

## ◆ SetPhysicalDevice()

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

Definition at line 518 of file capabilities_vk.cc.

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

## ◆ SupportsCompute()

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

Whether the context backend supports `ComputePass`.

Implements impeller::Capabilities.

Definition at line 682 of file capabilities_vk.cc.

682 {
683 // Vulkan 1.1 requires support for compute.
684 return true;
685 }

## ◆ SupportsComputeSubgroups()

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

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

Implements impeller::Capabilities.

Definition at line 688 of file capabilities_vk.cc.

688 {
689 // Set by |SetPhysicalDevice|.
690 return supports_compute_subgroups_;
691 }

## ◆ SupportsDecalSamplerAddressMode()

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

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

Implements impeller::Capabilities.

Definition at line 698 of file capabilities_vk.cc.

698 {
699 return true;
700 }

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

703 {
704 return supports_device_transient_textures_;
705 }

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

837 {
838 return false;
839 }

## ◆ SupportsExternalSemaphoreExtensions()

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

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

Definition at line 833 of file capabilities_vk.cc.

833 {
834 return supports_external_fence_and_semaphore_;
835 }

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

677 {
678 return has_framebuffer_fetch_;
679 }

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

662 {
663 return false;
664 }

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

657 {
658 return true;
659 }

## ◆ SupportsPrimitiveRestart()

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

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

694 {
695 return false;
696 }

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

667 {
668 return true;
669 }

## ◆ SupportsTextureFixedRateCompression()

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

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

Definition at line 763 of file capabilities_vk.cc.

763 {
764 return supports_texture_fixed_rate_compression_;
765 }

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

672 {
673 return true;
674 }

## ◆ SupportsTriangleFan()

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

Whether the primitive type TriangleFan is supported by the backend.

Implements impeller::Capabilities.

Definition at line 820 of file capabilities_vk.cc.

820 {
821 return has_triangle_fans_;
822 }

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