Flutter Impeller
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. 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...
 
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 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 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 }
static constexpr const char * kInstanceLayer

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

806  {
807  has_primitive_restart_ = !workarounds.slow_primitive_restart_performance;
808  has_framebuffer_fetch_ = !workarounds.input_attachment_self_dependency_broken;
809 }

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
overridevirtual

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

Implements impeller::Capabilities.

Definition at line 698 of file capabilities_vk.cc.

698  {
699  return default_color_format_;
700 }

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

708  {
709  return default_depth_stencil_format_;
710 }

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

717  {
719 }

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

703  {
704  return default_stencil_format_;
705 }

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

◆ GetEnabledDeviceExtensions()

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

Definition at line 260 of file capabilities_vk.cc.

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

Referenced by GetEnabledDeviceFeatures().

◆ GetEnabledDeviceFeatures()

std::optional< CapabilitiesVK::PhysicalDeviceFeatures > impeller::CapabilitiesVK::GetEnabledDeviceFeatures ( const vk::PhysicalDevice &  physical_device) const

Definition at line 395 of file capabilities_vk.cc.

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

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

802  {
803  return max_render_pass_attachment_size_;
804 }

◆ GetPhysicalDeviceProperties()

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

Definition at line 713 of file capabilities_vk.cc.

713  {
714  return device_properties_;
715 }

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

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

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

736  {
737  return optional_android_device_extensions_.find(ext) !=
738  optional_android_device_extensions_.end();
739 }

◆ HasExtension() [2/4]

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

Definition at line 731 of file capabilities_vk.cc.

731  {
732  return optional_device_extensions_.find(ext) !=
733  optional_device_extensions_.end();
734 }

◆ HasExtension() [3/4]

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

Definition at line 726 of file capabilities_vk.cc.

726  {
727  return required_android_device_extensions_.find(ext) !=
728  required_android_device_extensions_.end();
729 }

◆ HasExtension() [4/4]

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

Definition at line 721 of file capabilities_vk.cc.

721  {
722  return required_common_device_extensions_.find(ext) !=
723  required_common_device_extensions_.end();
724 }

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

510  {
511  default_color_format_ = pixel_format;
512 }

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

◆ SetPhysicalDevice()

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

Definition at line 514 of file capabilities_vk.cc.

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

Whether the context backend supports ComputePass.

Implements impeller::Capabilities.

Definition at line 672 of file capabilities_vk.cc.

672  {
673  // Vulkan 1.1 requires support for compute.
674  return true;
675 }

◆ SupportsComputeSubgroups()

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

Whether the context backend supports configuring ComputePass command subgroups.

Implements impeller::Capabilities.

Definition at line 678 of file capabilities_vk.cc.

678  {
679  // Set by |SetPhysicalDevice|.
680  return supports_compute_subgroups_;
681 }

◆ SupportsDecalSamplerAddressMode()

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

Whether the context backend supports SamplerAddressMode::Decal.

Implements impeller::Capabilities.

Definition at line 688 of file capabilities_vk.cc.

688  {
689  return true;
690 }

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

693  {
694  return supports_device_transient_textures_;
695 }

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

815  {
816  return false;
817 }

◆ SupportsExternalSemaphoreExtensions()

bool impeller::CapabilitiesVK::SupportsExternalSemaphoreExtensions ( ) const

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

Definition at line 811 of file capabilities_vk.cc.

811  {
812  return supports_external_fence_and_semaphore_;
813 }

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

667  {
668  return has_framebuffer_fetch_;
669 }

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

652  {
653  return false;
654 }

◆ SupportsOffscreenMSAA()

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

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

Implements impeller::Capabilities.

Definition at line 647 of file capabilities_vk.cc.

647  {
648  return true;
649 }

◆ SupportsPrimitiveRestart()

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

Whether primitive restart is supported.

Implements impeller::Capabilities.

Definition at line 506 of file capabilities_vk.cc.

506  {
507  return has_primitive_restart_;
508 }

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

684  {
685  return false;
686 }

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

657  {
658  return true;
659 }

◆ SupportsTextureFixedRateCompression()

bool impeller::CapabilitiesVK::SupportsTextureFixedRateCompression ( ) const
Returns
If fixed-rate compression for non-onscreen surfaces is supported.

Definition at line 741 of file capabilities_vk.cc.

741  {
742  return supports_texture_fixed_rate_compression_;
743 }

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

662  {
663  return true;
664 }

◆ SupportsTriangleFan()

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

Whether the primitive type TriangleFan is supported by the backend.

Implements impeller::Capabilities.

Definition at line 798 of file capabilities_vk.cc.

798  {
799  return has_triangle_fans_;
800 }

The documentation for this class was generated from the following files: