| 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
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...
PixelFormat | GetDefaultColorFormat () const override
| Returns a supported `PixelFormat` for textures that store 4-channel colors (red/green/blue/alpha). More...
PixelFormat | GetDefaultStencilFormat () const override
| Returns a supported `PixelFormat` for textures that store stencil information. May include a depth channel if a stencil-only format is not available. More...
PixelFormat | GetDefaultDepthStencilFormat () const override
| Returns a supported `PixelFormat` for textures that store both a stencil and depth component. This will never return a depth-only or stencil-only texture. Returns `PixelFormat::kUnknown` if no suitable depth+stencil format was found. More...
PixelFormat | GetDefaultGlyphAtlasFormat () const override
| Returns the default pixel format for the alpha bitmap glyph atlas. More...
ISize | GetMaximumRenderPassAttachmentSize () const override
| Return the maximum size of a render pass attachment. More...
bool | SupportsTextureFixedRateCompression () const
std::optional< vk::ImageCompressionFixedRateFlagBitsEXT > | GetSupportedFRCRate (CompressionType compression_type, const FRCFormatDescriptor &desc) const
| Get the fixed compression rate supported by the context for the given format and usage. More...
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 170 of file capabilities_vk.h.

## Member Typedef Documentation

## ◆ PhysicalDeviceFeatures

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

Definition at line 198 of file capabilities_vk.h.

## Constructor & Destructor Documentation

## ◆ CapabilitiesVK()

impeller::CapabilitiesVK::CapabilitiesVK | ( | bool | enable_validations,
|  | bool | fatal_missing_validations = `false`,
|  | 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 763 of file capabilities_vk.cc.

763 {
764 has_primitive_restart_ = !workarounds.slow_primitive_restart_performance;
765 has_framebuffer_fetch_ = !workarounds.input_attachment_self_dependency_broken;
766 }

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

660 {
661 return default_color_format_;
662 }

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

670 {
671 return default_depth_stencil_format_;
672 }

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

679 {
680 return PixelFormat::kR8UNormInt;
681 }
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 665 of file capabilities_vk.cc.

665 {
666 return default_stencil_format_;
667 }

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

## ◆ GetEnabledDeviceExtensions()

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

Definition at line 253 of file capabilities_vk.cc.

254 {
255 std::set<std::string> exts;
256
257 if (!use_embedder_extensions_) {
258 auto maybe_exts = GetSupportedDeviceExtensions(physical_device);
259
260 if (!maybe_exts.has_value()) {
261 return std::nullopt;
262 }
263 exts = maybe_exts.value();
264 } else {
265 exts = std::set(embedder_device_extensions_.begin(),
266 embedder_device_extensions_.end());
267 }
268
269 std::vector<std::string> enabled;
270
271 auto for_each_common_extension = [&](RequiredCommonDeviceExtensionVK ext) {
272 auto name = GetExtensionName(ext);
273 if (exts.find(name) == exts.end()) {
274 VALIDATION_LOG << "Device does not support required extension: " << name;
275 return false;
276 }
277 enabled.push_back(name);
278 return true;
279 };
280
281 auto for_each_android_extension = [&](RequiredAndroidDeviceExtensionVK ext) {
282 #ifdef FML_OS_ANDROID
283 auto name = GetExtensionName(ext);
284 if (exts.find(name) == exts.end()) {
285 VALIDATION_LOG << "Device does not support required Android extension: "
286 << name;
287 return false;
288 }
289 enabled.push_back(name);
290 #endif // FML_OS_ANDROID
291 return true;
292 };
293
294 auto for_each_optional_extension = [&](OptionalDeviceExtensionVK ext) {
295 auto name = GetExtensionName(ext);
296 if (exts.find(name) != exts.end()) {
297 enabled.push_back(name);
298 }
299 return true;
300 };
301
302 const auto iterate_extensions =
303 IterateExtensions<RequiredCommonDeviceExtensionVK>(
304 for_each_common_extension) &&
305 IterateExtensions<RequiredAndroidDeviceExtensionVK>(
306 for_each_android_extension) &&
307 IterateExtensions<OptionalDeviceExtensionVK>(for_each_optional_extension);
308
309 if (!iterate_extensions) {
310 VALIDATION_LOG << "Device not suitable since required extensions are not "
311 "supported.";
312 return std::nullopt;
313 }
314
315 return enabled;
316 }
impeller::GetSupportedDeviceExtensions
static std::optional< std::set< std::string > > GetSupportedDeviceExtensions(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:237
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::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:121
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 374 of file capabilities_vk.cc.

375 {
376 if (!PhysicalDeviceSupportsRequiredFormats(device)) {
377 VALIDATION_LOG << "Device doesn't support the required formats.";
378 return std::nullopt;
379 }
380
381 if (!HasRequiredProperties(device)) {
382 VALIDATION_LOG << "Device doesn't support the required properties.";
383 return std::nullopt;
384 }
385
386 if (!HasRequiredQueues(device)) {
387 VALIDATION_LOG << "Device doesn't support the required queues.";
388 return std::nullopt;
389 }
390
391 const auto enabled_extensions = GetEnabledDeviceExtensions(device);
392 if (!enabled_extensions.has_value()) {
393 VALIDATION_LOG << "Device doesn't support the required queues.";
394 return std::nullopt;
395 }
396
397 PhysicalDeviceFeatures supported_chain;
398
399 // Swiftshader seems to be fussy about just this structure even being in the
400 // chain. Just unlink it if its not supported. We already perform an
401 // extensions check on the other side when reading.
402 if (!IsExtensionInList(
403 enabled_extensions.value(),
404 OptionalDeviceExtensionVK::kEXTImageCompressionControl)) {
405 supported_chain
406 .unlink<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
407 }
408
409 device.getFeatures2(&supported_chain.get());
410
411 PhysicalDeviceFeatures required_chain;
412
413 // Base features.
414 {
415 auto& required = required_chain.get().features;
416 const auto& supported = supported_chain.get().features;
417
418 // We require this for enabling wireframes in the playground. But its not
419 // necessarily a big deal if we don't have this feature.
420 required.fillModeNonSolid = supported.fillModeNonSolid;
421 }
422 // VK_KHR_sampler_ycbcr_conversion features.
423 if (IsExtensionInList(
424 enabled_extensions.value(),
425 RequiredAndroidDeviceExtensionVK::kKHRSamplerYcbcrConversion)) {
426 auto& required =
427 required_chain
428 .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
429 const auto& supported =
430 supported_chain
431 .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
432
433 required.samplerYcbcrConversion = supported.samplerYcbcrConversion;
434 }
435
436 // VK_EXT_image_compression_control
437 if (IsExtensionInList(
438 enabled_extensions.value(),
439 OptionalDeviceExtensionVK::kEXTImageCompressionControl)) {
440 auto& required =
441 required_chain
442 .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
443 const auto& supported =
444 supported_chain
445 .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
446
447 required.imageCompressionControl = supported.imageCompressionControl;
448 } else {
449 required_chain
450 .unlink<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
451 }
452
453 // Vulkan 1.1
454 {
455 auto& required =
456 required_chain.get<vk::PhysicalDevice16BitStorageFeatures>();
457 const auto& supported =
458 supported_chain.get<vk::PhysicalDevice16BitStorageFeatures>();
459
460 required.uniformAndStorageBuffer16BitAccess =
461 supported.uniformAndStorageBuffer16BitAccess;
462 }
463
464 return required_chain;
465 }
impeller::CapabilitiesVK::PhysicalDeviceFeatures
vk::StructureChain< vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR, vk::PhysicalDevice16BitStorageFeatures, vk::PhysicalDeviceImageCompressionControlFeaturesEXT > PhysicalDeviceFeatures
Definition: capabilities_vk.h:202
impeller::CapabilitiesVK::GetEnabledDeviceExtensions
std::optional< std::vector< std::string > > GetEnabledDeviceExtensions(const vk::PhysicalDevice &physical_device) const
Definition: capabilities_vk.cc:253
impeller::PhysicalDeviceSupportsRequiredFormats
static bool PhysicalDeviceSupportsRequiredFormats(const vk::PhysicalDevice &device)
Definition: capabilities_vk.cc:333
impeller::HasRequiredProperties
static bool HasRequiredProperties(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:343
impeller::IsExtensionInList
static bool IsExtensionInList(const std::vector< std::string > &list, ExtensionEnum ext)
Definition: capabilities_vk.cc:367
impeller::RequiredAndroidDeviceExtensionVK::kKHRSamplerYcbcrConversion
@ kKHRSamplerYcbcrConversion
impeller::OptionalDeviceExtensionVK::kEXTImageCompressionControl
@ kEXTImageCompressionControl
impeller::HasRequiredQueues
static bool HasRequiredQueues(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:352

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

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

759 {
760 return max_render_pass_attachment_size_;
761 }

## ◆ GetPhysicalDeviceProperties()

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

Definition at line 675 of file capabilities_vk.cc.

675 {
676 return device_properties_;
677 }

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

704 {
705 if (compression_type != CompressionType::kLossy) {
706 return std::nullopt;
707 }
708 if (!supports_texture_fixed_rate_compression_) {
709 return std::nullopt;
710 }
711 // There are opportunities to hash and cache the FRCFormatDescriptor if
712 // needed.
713 vk::StructureChain<vk::PhysicalDeviceImageFormatInfo2,
714 vk::ImageCompressionControlEXT>
715 format_chain;
716
717 auto& format_info = format_chain.get();
718
719 format_info.format = desc.format;
720 format_info.type = desc.type;
721 format_info.tiling = desc.tiling;
722 format_info.usage = desc.usage;
723 format_info.flags = desc.flags;
724
725 const auto kIdealFRCRate = vk::ImageCompressionFixedRateFlagBitsEXT::e4Bpc;
726
727 std::array<vk::ImageCompressionFixedRateFlagsEXT, 1u> rates = {kIdealFRCRate};
728
729 auto& compression = format_chain.get<vk::ImageCompressionControlEXT>();
730 compression.flags = vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit;
731 compression.compressionControlPlaneCount = rates.size();
732 compression.pFixedRateFlags = rates.data();
733
734 const auto [result, supported] = physical_device_.getImageFormatProperties2<
735 vk::ImageFormatProperties2, vk::ImageCompressionPropertiesEXT>(
736 format_chain.get());
737
738 if (result != vk::Result::eSuccess ||
739 !supported.isLinked<vk::ImageCompressionPropertiesEXT>()) {
740 return std::nullopt;
741 }
742
743 const auto& compression_props =
744 supported.get<vk::ImageCompressionPropertiesEXT>();
745
746 if ((compression_props.imageCompressionFlags &
747 vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit) &&
748 (compression_props.imageCompressionFixedRateFlags & kIdealFRCRate)) {
749 return kIdealFRCRate;
750 }
751
752 return std::nullopt;
753 }
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/3]

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

Definition at line 693 of file capabilities_vk.cc.

693 {
694 return optional_device_extensions_.find(ext) !=
695 optional_device_extensions_.end();
696 }

## ◆ HasExtension() [2/3]

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

Definition at line 688 of file capabilities_vk.cc.

688 {
689 return required_android_device_extensions_.find(ext) !=
690 required_android_device_extensions_.end();
691 }

## ◆ HasExtension() [3/3]

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

Definition at line 683 of file capabilities_vk.cc.

683 {
684 return required_common_device_extensions_.find(ext) !=
685 required_common_device_extensions_.end();
686 }

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

489 {
490 default_color_format_ = pixel_format;
491 }

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

## ◆ SetPhysicalDevice()

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

Definition at line 493 of file capabilities_vk.cc.

495 {
496 if (HasSuitableColorFormat(device, vk::Format::eR8G8B8A8Unorm)) {
497 default_color_format_ = PixelFormat::kR8G8B8A8UNormInt;
498 } else {
499 default_color_format_ = PixelFormat::kUnknown;
500 }
501
502 if (HasSuitableDepthStencilFormat(device, vk::Format::eD32SfloatS8Uint)) {
503 default_depth_stencil_format_ = PixelFormat::kD32FloatS8UInt;
504 } else if (HasSuitableDepthStencilFormat(device,
505 vk::Format::eD24UnormS8Uint)) {
506 default_depth_stencil_format_ = PixelFormat::kD24UnormS8Uint;
507 } else {
508 default_depth_stencil_format_ = PixelFormat::kUnknown;
509 }
510
511 if (HasSuitableDepthStencilFormat(device, vk::Format::eS8Uint)) {
512 default_stencil_format_ = PixelFormat::kS8UInt;
513 } else if (default_depth_stencil_format_ != PixelFormat::kUnknown) {
514 default_stencil_format_ = default_depth_stencil_format_;
515 }
516
517 physical_device_ = device;
518 device_properties_ = device.getProperties();
519
520 auto physical_properties_2 =
521 device.getProperties2<vk::PhysicalDeviceProperties2,
522 vk::PhysicalDeviceSubgroupProperties>();
523
524 // Currently shaders only want access to arithmetic subgroup features.
525 // If that changes this needs to get updated, and so does Metal (which right
526 // now assumes it from compile time flags based on the MSL target version).
527
528 supports_compute_subgroups_ =
529 !!(physical_properties_2.get<vk::PhysicalDeviceSubgroupProperties>()
530 .supportedOperations &
531 vk::SubgroupFeatureFlagBits::eArithmetic);
532
533 {
534 // Query texture support.
535 // TODO(129784): Add a capability check for expected memory types.
536 vk::PhysicalDeviceMemoryProperties memory_properties;
537 device.getMemoryProperties(&memory_properties);
538
539 for (auto i = 0u; i < memory_properties.memoryTypeCount; i++) {
540 if (memory_properties.memoryTypes[i].propertyFlags &
541 vk::MemoryPropertyFlagBits::eLazilyAllocated) {
542 supports_device_transient_textures_ = true;
543 }
544 }
545 }
546
547 // Determine the optional device extensions this physical device supports.
548 {
549 required_common_device_extensions_.clear();
550 required_android_device_extensions_.clear();
551 optional_device_extensions_.clear();
552
553 std::set<std::string> exts;
554 if (!use_embedder_extensions_) {
555 auto maybe_exts = GetSupportedDeviceExtensions(device);
556 if (!maybe_exts.has_value()) {
557 return false;
558 }
559 exts = maybe_exts.value();
560 } else {
561 exts = std::set(embedder_device_extensions_.begin(),
562 embedder_device_extensions_.end());
563 }
564
565 IterateExtensions<RequiredCommonDeviceExtensionVK>([&](auto ext) -> bool {
566 auto ext_name = GetExtensionName(ext);
567 if (exts.find(ext_name) != exts.end()) {
568 required_common_device_extensions_.insert(ext);
569 }
570 return true;
571 });
572 IterateExtensions<RequiredAndroidDeviceExtensionVK>([&](auto ext) -> bool {
573 auto ext_name = GetExtensionName(ext);
574 if (exts.find(ext_name) != exts.end()) {
575 required_android_device_extensions_.insert(ext);
576 }
577 return true;
578 });
579 IterateExtensions<OptionalDeviceExtensionVK>([&](auto ext) -> bool {
580 auto ext_name = GetExtensionName(ext);
581 if (exts.find(ext_name) != exts.end()) {
582 optional_device_extensions_.insert(ext);
583 }
584 return true;
585 });
586 }
587
588 supports_texture_fixed_rate_compression_ =
589 enabled_features
590 .isLinked<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>() &&
591 enabled_features
592 .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>()
593 .imageCompressionControl;
594
595 max_render_pass_attachment_size_ =
596 ISize{device_properties_.limits.maxFramebufferWidth,
597 device_properties_.limits.maxFramebufferHeight};
598
599 // Molten, Vulkan on Metal, cannot support triangle fans because Metal doesn't
600 // support triangle fans.
601 // See VUID-VkPipelineInputAssemblyStateCreateInfo-triangleFans-04452.
602 has_triangle_fans_ =
603 !HasExtension(OptionalDeviceExtensionVK::kVKKHRPortabilitySubset);
604
605 return true;
606 }
impeller::HasSuitableColorFormat
static bool HasSuitableColorFormat(const vk::PhysicalDevice &device, vk::Format format)
Definition: capabilities_vk.cc:318
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:326
impeller::ISize
ISize64 ISize
Definition: size.h:174
impeller::OptionalDeviceExtensionVK::kVKKHRPortabilitySubset
@ kVKKHRPortabilitySubset

References impeller::GetExtensionName(), impeller::GetSupportedDeviceExtensions(), HasExtension(), impeller::HasSuitableColorFormat(), impeller::HasSuitableDepthStencilFormat(), impeller::kD24UnormS8Uint, impeller::kD32FloatS8UInt, 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 634 of file capabilities_vk.cc.

634 {
635 // Vulkan 1.1 requires support for compute.
636 return true;
637 }

## ◆ SupportsComputeSubgroups()

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

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

Implements impeller::Capabilities.

Definition at line 640 of file capabilities_vk.cc.

640 {
641 // Set by |SetPhysicalDevice|.
642 return supports_compute_subgroups_;
643 }

## ◆ SupportsDecalSamplerAddressMode()

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

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

Implements impeller::Capabilities.

Definition at line 650 of file capabilities_vk.cc.

650 {
651 return true;
652 }

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

655 {
656 return supports_device_transient_textures_;
657 }

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

629 {
630 return has_framebuffer_fetch_;
631 }

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

614 {
615 return false;
616 }

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

609 {
610 return true;
611 }

## ◆ SupportsPrimitiveRestart()

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

Whether primitive restart is supported.

Implements impeller::Capabilities.

Definition at line 485 of file capabilities_vk.cc.

485 {
486 return has_primitive_restart_;
487 }

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

646 {
647 return false;
648 }

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

619 {
620 return true;
621 }

## ◆ SupportsTextureFixedRateCompression()

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

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

Definition at line 698 of file capabilities_vk.cc.

698 {
699 return supports_texture_fixed_rate_compression_;
700 }

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

624 {
625 return true;
626 }

## ◆ SupportsTriangleFan()

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

Whether the primitive type TriangleFan is supported by the backend.

Implements impeller::Capabilities.

Definition at line 755 of file capabilities_vk.cc.

755 {
756 return has_triangle_fans_;
757 }

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