Flutter Engine
 
Loading...
Searching...
No Matches
impeller::CapabilitiesVK Class Referencefinal

The Vulkan layers and extensions wrangler. More...

#include <capabilities_vk.h>

Inheritance diagram for impeller::CapabilitiesVK:
impeller::Capabilities impeller::BackendCast< CapabilitiesVK, Capabilities >

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< PhysicalDeviceFeaturesGetEnabledDeviceFeatures (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.
 
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.
 
bool SupportsSSBO () const override
 Whether the context backend supports binding Shader Storage Buffer Objects (SSBOs) to pipelines.
 
bool SupportsTextureToTextureBlits () const override
 Whether the context backend supports blitting from one texture region to another texture region (via the relevant BlitPass::AddCopy overloads).
 
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).
 
bool SupportsCompute () const override
 Whether the context backend supports ComputePass.
 
bool SupportsComputeSubgroups () const override
 Whether the context backend supports configuring ComputePass command subgroups.
 
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.
 
bool SupportsDecalSamplerAddressMode () const override
 Whether the context backend supports SamplerAddressMode::Decal.
 
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.
 
bool SupportsTriangleFan () const override
 Whether the primitive type TriangleFan is supported by the backend.
 
bool SupportsPrimitiveRestart () const override
 Whether primitive restart is supported.
 
bool SupportsExtendedRangeFormats () const override
 Whether the XR formats are supported on this device.
 
PixelFormat GetDefaultColorFormat () const override
 Returns a supported PixelFormat for textures that store 4-channel colors (red/green/blue/alpha).
 
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.
 
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.
 
PixelFormat GetDefaultGlyphAtlasFormat () const override
 Returns the default pixel format for the alpha bitmap glyph atlas.
 
ISize GetMaximumRenderPassAttachmentSize () const override
 Return the maximum size of a render pass attachment.
 
size_t GetMinimumUniformAlignment () const override
 The minimum alignment of uniform value offsets in bytes.
 
size_t GetMinimumStorageBufferAlignment () const override
 The minimum alignment of storage buffer value offsets in bytes.
 
bool NeedsPartitionedHostBuffer () const override
 Whether the host buffer should use separate device buffers for indexes from other data.
 
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.
 
void ApplyWorkarounds (const WorkaroundsVK &workarounds)
 Update capabilities for the given set of workarounds.
 
- Public Member Functions inherited from impeller::Capabilities
virtual ~Capabilities ()
 

Additional Inherited Members

- Static Public Member Functions inherited from impeller::BackendCast< CapabilitiesVK, Capabilities >
static CapabilitiesVKCast (Capabilities &base)
 
static const CapabilitiesVKCast (const Capabilities &base)
 
static CapabilitiesVKCast (Capabilities *base)
 
static const CapabilitiesVKCast (const Capabilities *base)
 
- Protected Member Functions inherited from impeller::Capabilities
 Capabilities ()
 
 Capabilities (const Capabilities &)=delete
 
Capabilitiesoperator= (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}
int32_t value
const FlutterLayer ** layers
#define FML_LOG(severity)
Definition logging.h:101
static constexpr const char * kInstanceLayer

References FML_LOG, impeller::kInstanceLayer, and layers.

◆ ~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 flutter::CreateImpellerContext(), impeller::DebugReportVK::DebugReportVK(), impeller::testing::TEST(), 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 708 of file capabilities_vk.cc.

708 {
709 return default_color_format_;
710}

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

727 {
729}

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 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_) {
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 =
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}
VkPhysicalDevice physical_device
Definition main.cc:67
const char * name
Definition fuchsia.cc:49
static const char * GetExtensionName(RequiredCommonDeviceExtensionVK ext)
RequiredAndroidDeviceExtensionVK
A device extension available on all Android platforms. Without the presence of these extensions on An...
static std::optional< std::set< std::string > > GetSupportedDeviceExtensions(const vk::PhysicalDevice &physical_device)
RequiredCommonDeviceExtensionVK
A device extension available on all platforms. Without the presence of these extensions,...
OptionalAndroidDeviceExtensionVK
A device extension available on some Android platforms.
OptionalDeviceExtensionVK
A device extension enabled if available. Subsystems cannot assume availability and must check if thes...
#define VALIDATION_LOG
Definition validation.h:91

References impeller::GetExtensionName(), impeller::GetSupportedDeviceExtensions(), name, physical_device, 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 {
402 VALIDATION_LOG << "Device doesn't support the required formats.";
403 return std::nullopt;
404 }
405
407 VALIDATION_LOG << "Device doesn't support the required properties.";
408 return std::nullopt;
409 }
410
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.
428 enabled_extensions.value(),
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.
449 enabled_extensions.value(),
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
463 enabled_extensions.value(),
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}
vk::StructureChain< vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR, vk::PhysicalDevice16BitStorageFeatures, vk::PhysicalDeviceImageCompressionControlFeaturesEXT > PhysicalDeviceFeatures
std::optional< std::vector< std::string > > GetEnabledDeviceExtensions(const vk::PhysicalDevice &physical_device) const
VkDevice device
Definition main.cc:69
static bool PhysicalDeviceSupportsRequiredFormats(const vk::PhysicalDevice &device)
static bool HasRequiredProperties(const vk::PhysicalDevice &physical_device)
static bool IsExtensionInList(const std::vector< std::string > &list, ExtensionEnum ext)
static bool HasRequiredQueues(const vk::PhysicalDevice &physical_device)

References device, 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}
bool HasExtension(RequiredCommonDeviceExtensionVK ext) const

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

824 {
825 return max_render_pass_attachment_size_;
826}

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

735 {
736 return minimum_storage_alignment_;
737}

◆ GetMinimumUniformAlignment()

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

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_typeThe compression type.
[in]descThe 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}

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
overridevirtual

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;
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>(
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_ =
639
640 // External Fence/Semaphore for AHB swapchain
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}
static bool HasSuitableColorFormat(const vk::PhysicalDevice &device, vk::Format format)
static bool HasSuitableDepthStencilFormat(const vk::PhysicalDevice &device, vk::Format format)
ISize64 ISize
Definition size.h:162

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

◆ SupportsCompute()

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

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
overridevirtual

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
overridevirtual

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

703 {
704 return supports_device_transient_textures_;
705}

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

677 {
678 return has_framebuffer_fetch_;
679}

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

662 {
663 return false;
664}

◆ SupportsOffscreenMSAA()

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

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

694 {
695 return false;
696}

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

672 {
673 return true;
674}

◆ SupportsTriangleFan()

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

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: