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...
 
size_t GetMinimumUniformAlignment () const override
 The minimum alignment of uniform value offsets in bytes. More...
 
size_t GetMinimumStorageBufferAlignment () const override
 The minimum alignment of storage buffer value offsets in bytes. More...
 
bool NeedsPartitionedHostBuffer () const override
 Whether the host buffer should use separate device buffers for indexes from other data. More...
 
bool SupportsTextureFixedRateCompression () const
 
bool SupportsExternalSemaphoreExtensions () const
 
std::optional< vk::ImageCompressionFixedRateFlagBitsEXT > GetSupportedFRCRate (CompressionType compression_type, const FRCFormatDescriptor &desc) const
 Get the fixed compression rate supported by the context for the given format and usage. More...
 
void ApplyWorkarounds (const WorkaroundsVK &workarounds)
 Update capabilities for the given set of workarounds. More...
 
- Public Member Functions inherited from impeller::Capabilities
virtual ~Capabilities ()
 

Additional Inherited Members

- Static Public Member Functions inherited from impeller::BackendCast< CapabilitiesVK, Capabilities >
static 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 }
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 828 of file capabilities_vk.cc.

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

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

◆ AreValidationsEnabled()

bool impeller::CapabilitiesVK::AreValidationsEnabled ( ) const

Definition at line 82 of file capabilities_vk.cc.

82  {
83  return validations_enabled_;
84 }

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

◆ GetDefaultColorFormat()

PixelFormat impeller::CapabilitiesVK::GetDefaultColorFormat ( ) const
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_) {
268  auto maybe_exts = GetSupportedDeviceExtensions(physical_device);
269 
270  if (!maybe_exts.has_value()) {
271  return std::nullopt;
272  }
273  exts = maybe_exts.value();
274  } else {
275  for (const auto& ext : embedder_device_extensions_) {
276  exts.insert(ext);
277  }
278  }
279 
280  std::vector<std::string> enabled;
281 
282  auto for_each_common_extension = [&](RequiredCommonDeviceExtensionVK ext) {
283  auto name = GetExtensionName(ext);
284  if (exts.find(name) == exts.end()) {
285  VALIDATION_LOG << "Device does not support required extension: " << name;
286  return false;
287  }
288  enabled.push_back(name);
289  return true;
290  };
291 
292  auto for_each_android_extension = [&](RequiredAndroidDeviceExtensionVK ext) {
293 #ifdef FML_OS_ANDROID
294  auto name = GetExtensionName(ext);
295  if (exts.find(name) == exts.end()) {
296  VALIDATION_LOG << "Device does not support required Android extension: "
297  << name;
298  return false;
299  }
300  enabled.push_back(name);
301 #endif // FML_OS_ANDROID
302  return true;
303  };
304 
305  auto for_each_optional_android_extension =
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 }
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 399 of file capabilities_vk.cc.

400  {
402  VALIDATION_LOG << "Device doesn't support the required formats.";
403  return std::nullopt;
404  }
405 
406  if (!HasRequiredProperties(device)) {
407  VALIDATION_LOG << "Device doesn't support the required properties.";
408  return std::nullopt;
409  }
410 
411  if (!HasRequiredQueues(device)) {
412  VALIDATION_LOG << "Device doesn't support the required queues.";
413  return std::nullopt;
414  }
415 
416  const auto enabled_extensions = GetEnabledDeviceExtensions(device);
417  if (!enabled_extensions.has_value()) {
418  VALIDATION_LOG << "Device doesn't support the required queues.";
419  return std::nullopt;
420  }
421 
422  PhysicalDeviceFeatures supported_chain;
423 
424  // Swiftshader seems to be fussy about just this structure even being in the
425  // chain. Just unlink it if its not supported. We already perform an
426  // extensions check on the other side when reading.
427  if (!IsExtensionInList(
428  enabled_extensions.value(),
430  supported_chain
431  .unlink<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
432  }
433 
434  device.getFeatures2(&supported_chain.get());
435 
436  PhysicalDeviceFeatures required_chain;
437 
438  // Base features.
439  {
440  auto& required = required_chain.get().features;
441  const auto& supported = supported_chain.get().features;
442 
443  // We require this for enabling wireframes in the playground. But its not
444  // necessarily a big deal if we don't have this feature.
445  required.fillModeNonSolid = supported.fillModeNonSolid;
446  }
447  // VK_KHR_sampler_ycbcr_conversion features.
448  if (IsExtensionInList(
449  enabled_extensions.value(),
451  auto& required =
452  required_chain
453  .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
454  const auto& supported =
455  supported_chain
456  .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
457 
458  required.samplerYcbcrConversion = supported.samplerYcbcrConversion;
459  }
460 
461  // VK_EXT_image_compression_control
462  if (IsExtensionInList(
463  enabled_extensions.value(),
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
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 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;
529  } else if (HasSuitableDepthStencilFormat(device,
530  vk::Format::eD32SfloatS8Uint)) {
531  default_depth_stencil_format_ = PixelFormat::kD32FloatS8UInt;
532  } else {
533  default_depth_stencil_format_ = PixelFormat::kUnknown;
534  }
535 
536  if (HasSuitableDepthStencilFormat(device, vk::Format::eS8Uint)) {
537  default_stencil_format_ = PixelFormat::kS8UInt;
538  } else if (default_depth_stencil_format_ != PixelFormat::kUnknown) {
539  default_stencil_format_ = default_depth_stencil_format_;
540  }
541 
542  physical_device_ = device;
543  device_properties_ = device.getProperties();
544 
545  auto physical_properties_2 =
546  device.getProperties2<vk::PhysicalDeviceProperties2,
547  vk::PhysicalDeviceSubgroupProperties>();
548 
549  // Currently shaders only want access to arithmetic subgroup features.
550  // If that changes this needs to get updated, and so does Metal (which right
551  // now assumes it from compile time flags based on the MSL target version).
552 
553  supports_compute_subgroups_ =
554  !!(physical_properties_2.get<vk::PhysicalDeviceSubgroupProperties>()
555  .supportedOperations &
556  vk::SubgroupFeatureFlagBits::eArithmetic);
557 
558  {
559  // Query texture support.
560  // TODO(129784): Add a capability check for expected memory types.
561  vk::PhysicalDeviceMemoryProperties memory_properties;
562  device.getMemoryProperties(&memory_properties);
563 
564  for (auto i = 0u; i < memory_properties.memoryTypeCount; i++) {
565  if (memory_properties.memoryTypes[i].propertyFlags &
566  vk::MemoryPropertyFlagBits::eLazilyAllocated) {
567  supports_device_transient_textures_ = true;
568  }
569  }
570  }
571 
572  // Determine the optional device extensions this physical device supports.
573  {
574  required_common_device_extensions_.clear();
575  required_android_device_extensions_.clear();
576  optional_device_extensions_.clear();
577  optional_android_device_extensions_.clear();
578 
579  std::set<std::string> exts;
580  if (!use_embedder_extensions_) {
581  auto maybe_exts = GetSupportedDeviceExtensions(device);
582  if (!maybe_exts.has_value()) {
583  return false;
584  }
585  exts = maybe_exts.value();
586  } else {
587  for (const auto& ext : embedder_device_extensions_) {
588  exts.insert(ext);
589  }
590  }
591 
592  IterateExtensions<RequiredCommonDeviceExtensionVK>([&](auto ext) -> bool {
593  auto ext_name = GetExtensionName(ext);
594  if (exts.find(ext_name) != exts.end()) {
595  required_common_device_extensions_.insert(ext);
596  }
597  return true;
598  });
599  IterateExtensions<RequiredAndroidDeviceExtensionVK>([&](auto ext) -> bool {
600  auto ext_name = GetExtensionName(ext);
601  if (exts.find(ext_name) != exts.end()) {
602  required_android_device_extensions_.insert(ext);
603  }
604  return true;
605  });
606  IterateExtensions<OptionalDeviceExtensionVK>([&](auto ext) -> bool {
607  auto ext_name = GetExtensionName(ext);
608  if (exts.find(ext_name) != exts.end()) {
609  optional_device_extensions_.insert(ext);
610  }
611  return true;
612  });
613  IterateExtensions<OptionalAndroidDeviceExtensionVK>(
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 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 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: