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, vk::PhysicalDeviceTextureCompressionASTCHDRFeatures >
 

Public Member Functions

 CapabilitiesVK (bool enable_validations, bool fatal_missing_validations=false, bool use_embedder_extensions=false, std::vector< std::string > instance_extensions={}, std::vector< std::string > device_extensions={})
 
 ~CapabilitiesVK ()
 
bool IsValid () const
 
bool AreValidationsEnabled () const
 
bool HasExtension (RequiredCommonDeviceExtensionVK ext) const
 
bool HasExtension (RequiredAndroidDeviceExtensionVK ext) const
 
bool HasExtension (OptionalDeviceExtensionVK ext) const
 
bool HasExtension (OptionalAndroidDeviceExtensionVK ext) const
 
std::optional< std::vector< std::string > > GetEnabledLayers () const
 
std::optional< std::vector< std::string > > GetEnabledInstanceExtensions () const
 
std::optional< std::vector< std::string > > GetEnabledDeviceExtensions (const vk::PhysicalDevice &physical_device) const
 
std::optional< PhysicalDeviceFeatures > GetEnabledDeviceFeatures (const vk::PhysicalDevice &physical_device) const
 
bool SetPhysicalDevice (const vk::PhysicalDevice &physical_device, const PhysicalDeviceFeatures &enabled_features)
 
const vk::PhysicalDeviceProperties & GetPhysicalDeviceProperties () const
 
void SetOffscreenFormat (PixelFormat pixel_format) const
 
bool SupportsOffscreenMSAA () const override
 Whether the context backend supports attaching offscreen MSAA color/stencil textures. More...
 
bool SupportsImplicitResolvingMSAA () const override
 Whether the context backend supports multisampled rendering to the on-screen surface without requiring an explicit resolve of the MSAA color attachment. More...
 
bool SupportsSSBO () const override
 Whether the context backend supports binding Shader Storage Buffer Objects (SSBOs) to pipelines. More...
 
bool SupportsTextureToTextureBlits () const override
 Whether the context backend supports blitting from one texture region to another texture region (via the relevant BlitPass::AddCopy overloads). More...
 
bool SupportsFramebufferFetch () const override
 Whether the context backend is able to support pipelines with shaders that read from the framebuffer (i.e. pixels that have been written by previous draw calls in the current render pass). More...
 
bool SupportsCompute () const override
 Whether the context backend supports ComputePass. More...
 
bool SupportsComputeSubgroups () const override
 Whether the context backend supports configuring ComputePass command subgroups. More...
 
bool SupportsReadFromResolve () const override
 Whether the context backend supports binding the current RenderPass attachments. This is supported if the backend can guarantee that attachment textures will not be mutated until the render pass has fully completed. More...
 
bool SupportsDecalSamplerAddressMode () const override
 Whether the context backend supports SamplerAddressMode::Decal. More...
 
bool SupportsDeviceTransientTextures () const override
 Whether the context backend supports allocating StorageMode::kDeviceTransient (aka "memoryless") textures, which are temporary textures kept in tile memory for the duration of the RenderPass it's attached to. More...
 
bool SupportsTriangleFan () const override
 Whether the primitive type TriangleFan is supported by the backend. More...
 
bool SupportsPrimitiveRestart () const override
 Whether primitive restart is supported. More...
 
bool Supports32BitPrimitiveIndices () const override
 Whether 32-bit values are supported in index buffers used to draw primitives. More...
 
bool SupportsManuallyMippedTextures () const override
 Whether a texture whose mip levels were uploaded by hand (rather than produced by BlitPass::GenerateMipmap) samples with correct per-level selection. True everywhere except OpenGL ES 2.0 without GL_APPLE_texture_max_level, where the sampled mip range cannot be bounded to the levels the texture declares. More...
 
bool SupportsExtendedRangeFormats () const override
 Whether the XR formats are supported on this device. More...
 
bool SupportsTextureCompression (CompressedTextureFamily family) const override
 Whether the given family of block-compressed texture formats is supported by this device. Compressed formats are sample-only and their support varies by hardware, so callers must check this before allocating a compressed texture. More...
 
bool SupportsFramebufferRenderMipmap () const override
 Whether a non-zero mip level of a texture can be attached as a render target. Rendering into a cube map face or array layer is always supported. Metal and Vulkan support this; the GLES backend does not yet, so it returns false there. 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...
 
uint32_t GetMaxSamplerAnisotropy () const override
 The maximum anisotropy clamp supported by device samplers. More...
 
size_t GetMinimumUniformAlignment () const override
 The minimum alignment of uniform value offsets in bytes. More...
 
size_t GetMinimumStorageBufferAlignment () const override
 The minimum alignment of storage buffer value offsets in bytes. More...
 
bool NeedsPartitionedHostBuffer () const override
 Whether the host buffer should use separate device buffers for indexes from other data. More...
 
bool SupportsTextureFixedRateCompression () const
 
bool SupportsExternalSemaphoreExtensions () const
 
std::optional< vk::ImageCompressionFixedRateFlagBitsEXT > GetSupportedFRCRate (CompressionType compression_type, const FRCFormatDescriptor &desc) const
 Get the fixed compression rate supported by the context for the given format and usage. More...
 
void ApplyWorkarounds (const WorkaroundsVK &workarounds)
 Update capabilities for the given set of workarounds. More...
 
- Public Member Functions inherited from impeller::Capabilities
virtual ~Capabilities ()
 

Additional Inherited Members

- Static Public Member Functions inherited from impeller::BackendCast< CapabilitiesVK, Capabilities >
static CapabilitiesVK & Cast (Capabilities &base)
 
static const CapabilitiesVK & Cast (const Capabilities &base)
 
static CapabilitiesVK * Cast (Capabilities *base)
 
static const CapabilitiesVK * Cast (const Capabilities *base)
 
- Protected Member Functions inherited from impeller::Capabilities
 Capabilities ()
 
 Capabilities (const Capabilities &)=delete
 
Capabilities & operator= (const Capabilities &)=delete
 

Detailed Description

The Vulkan layers and extensions wrangler.

Definition at line 188 of file capabilities_vk.h.

Member Typedef Documentation

◆ PhysicalDeviceFeatures

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

Definition at line 218 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 893 of file capabilities_vk.cc.

893  {
894  has_primitive_restart_ = !workarounds.slow_primitive_restart_performance;
895  has_framebuffer_fetch_ = !workarounds.input_attachment_self_dependency_broken;
896 }

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

769  {
770  return default_color_format_;
771 }

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

779  {
780  return default_depth_stencil_format_;
781 }

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

788  {
790 }

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

774  {
775  return default_stencil_format_;
776 }

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

◆ GetEnabledDeviceExtensions()

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

Definition at line 265 of file capabilities_vk.cc.

266  {
267  std::set<std::string> exts;
268 
269  if (!use_embedder_extensions_) {
270  auto maybe_exts = GetSupportedDeviceExtensions(physical_device);
271 
272  if (!maybe_exts.has_value()) {
273  return std::nullopt;
274  }
275  exts = maybe_exts.value();
276  } else {
277  for (const auto& ext : embedder_device_extensions_) {
278  exts.insert(ext);
279  }
280  }
281 
282  std::vector<std::string> enabled;
283 
284  auto for_each_common_extension = [&](RequiredCommonDeviceExtensionVK ext) {
285  auto name = GetExtensionName(ext);
286  if (exts.find(name) == exts.end()) {
287  VALIDATION_LOG << "Device does not support required extension: " << name;
288  return false;
289  }
290  enabled.push_back(name);
291  return true;
292  };
293 
294  auto for_each_android_extension = [&](RequiredAndroidDeviceExtensionVK ext) {
295 #ifdef FML_OS_ANDROID
296  auto name = GetExtensionName(ext);
297  if (exts.find(name) == exts.end()) {
298  VALIDATION_LOG << "Device does not support required Android extension: "
299  << name;
300  return false;
301  }
302  enabled.push_back(name);
303 #endif // FML_OS_ANDROID
304  return true;
305  };
306 
307  auto for_each_optional_android_extension =
309 #ifdef FML_OS_ANDROID
310  auto name = GetExtensionName(ext);
311  if (exts.find(name) != exts.end()) {
312  enabled.push_back(name);
313  }
314 #endif // FML_OS_ANDROID
315  return true;
316  };
317 
318  auto for_each_optional_extension = [&](OptionalDeviceExtensionVK ext) {
319  auto name = GetExtensionName(ext);
320  if (exts.find(name) != exts.end()) {
321  enabled.push_back(name);
322  }
323  return true;
324  };
325 
326  const auto iterate_extensions =
327  IterateExtensions<RequiredCommonDeviceExtensionVK>(
328  for_each_common_extension) &&
329  IterateExtensions<RequiredAndroidDeviceExtensionVK>(
330  for_each_android_extension) &&
331  IterateExtensions<OptionalDeviceExtensionVK>(
332  for_each_optional_extension) &&
333  IterateExtensions<OptionalAndroidDeviceExtensionVK>(
334  for_each_optional_android_extension);
335 
336  if (!iterate_extensions) {
337  VALIDATION_LOG << "Device not suitable since required extensions are not "
338  "supported.";
339  return std::nullopt;
340  }
341 
342  return enabled;
343 }
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 401 of file capabilities_vk.cc.

402  {
404  VALIDATION_LOG << "Device doesn't support the required formats.";
405  return std::nullopt;
406  }
407 
408  if (!HasRequiredProperties(device)) {
409  VALIDATION_LOG << "Device doesn't support the required properties.";
410  return std::nullopt;
411  }
412 
413  if (!HasRequiredQueues(device)) {
414  VALIDATION_LOG << "Device doesn't support the required queues.";
415  return std::nullopt;
416  }
417 
418  const auto enabled_extensions = GetEnabledDeviceExtensions(device);
419  if (!enabled_extensions.has_value()) {
420  VALIDATION_LOG << "Device doesn't support the required queues.";
421  return std::nullopt;
422  }
423 
424  PhysicalDeviceFeatures supported_chain;
425 
426  // Swiftshader seems to be fussy about just this structure even being in the
427  // chain. Just unlink it if its not supported. We already perform an
428  // extensions check on the other side when reading.
429  if (!IsExtensionInList(
430  enabled_extensions.value(),
432  supported_chain
433  .unlink<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
434  }
435  if (!IsExtensionInList(
436  enabled_extensions.value(),
438  supported_chain
439  .unlink<vk::PhysicalDeviceTextureCompressionASTCHDRFeatures>();
440  }
441 
442  device.getFeatures2(&supported_chain.get());
443 
444  PhysicalDeviceFeatures required_chain;
445 
446  // Base features.
447  {
448  auto& required = required_chain.get().features;
449  const auto& supported = supported_chain.get().features;
450 
451  // We require this for enabling wireframes in the playground. But its not
452  // necessarily a big deal if we don't have this feature.
453  required.fillModeNonSolid = supported.fillModeNonSolid;
454 
455  // Enable anisotropic filtering when available. Samplers with
456  // `max_anisotropy` greater than 1 may only be created when this feature
457  // is enabled.
458  required.samplerAnisotropy = supported.samplerAnisotropy;
459  }
460  // VK_KHR_sampler_ycbcr_conversion features.
461  if (IsExtensionInList(
462  enabled_extensions.value(),
464  auto& required =
465  required_chain
466  .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
467  const auto& supported =
468  supported_chain
469  .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
470 
471  required.samplerYcbcrConversion = supported.samplerYcbcrConversion;
472  }
473 
474  // VK_EXT_image_compression_control
475  if (IsExtensionInList(
476  enabled_extensions.value(),
478  auto& required =
479  required_chain
480  .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
481  const auto& supported =
482  supported_chain
483  .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
484 
485  required.imageCompressionControl = supported.imageCompressionControl;
486  } else {
487  required_chain
488  .unlink<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
489  }
490 
491  // VK_EXT_texture_compression_astc_hdr
492  if (IsExtensionInList(
493  enabled_extensions.value(),
495  auto& required =
496  required_chain
497  .get<vk::PhysicalDeviceTextureCompressionASTCHDRFeatures>();
498  const auto& supported =
499  supported_chain
500  .get<vk::PhysicalDeviceTextureCompressionASTCHDRFeatures>();
501 
502  required.textureCompressionASTC_HDR = supported.textureCompressionASTC_HDR;
503  } else {
504  required_chain
505  .unlink<vk::PhysicalDeviceTextureCompressionASTCHDRFeatures>();
506  }
507 
508  // Vulkan 1.1
509  {
510  auto& required =
511  required_chain.get<vk::PhysicalDevice16BitStorageFeatures>();
512  const auto& supported =
513  supported_chain.get<vk::PhysicalDevice16BitStorageFeatures>();
514 
515  required.uniformAndStorageBuffer16BitAccess =
516  supported.uniformAndStorageBuffer16BitAccess;
517  }
518 
519  return required_chain;
520 }
std::optional< std::vector< std::string > > GetEnabledDeviceExtensions(const vk::PhysicalDevice &physical_device) const
vk::StructureChain< vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR, vk::PhysicalDevice16BitStorageFeatures, vk::PhysicalDeviceImageCompressionControlFeaturesEXT, vk::PhysicalDeviceTextureCompressionASTCHDRFeatures > PhysicalDeviceFeatures
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::kEXTTextureCompressionAstcHdr, 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 885 of file capabilities_vk.cc.

885  {
886  return max_render_pass_attachment_size_;
887 }

◆ GetMaxSamplerAnisotropy()

uint32_t impeller::CapabilitiesVK::GetMaxSamplerAnisotropy ( ) const
overridevirtual

The maximum anisotropy clamp supported by device samplers.

   A value of 1 means anisotropic filtering is not supported.
   Sampler descriptors with `max_anisotropy` greater than this value
   are clamped to it. 

Implements impeller::Capabilities.

Definition at line 889 of file capabilities_vk.cc.

889  {
890  return max_sampler_anisotropy_;
891 }

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

796  {
797  return minimum_storage_alignment_;
798 }

◆ GetMinimumUniformAlignment()

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

The minimum alignment of uniform value offsets in bytes.

Implements impeller::Capabilities.

Definition at line 792 of file capabilities_vk.cc.

792  {
793  return minimum_uniform_alignment_;
794 }

◆ GetPhysicalDeviceProperties()

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

Definition at line 784 of file capabilities_vk.cc.

784  {
785  return device_properties_;
786 }

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

830  {
831  if (compression_type != CompressionType::kLossy) {
832  return std::nullopt;
833  }
834  if (!supports_texture_fixed_rate_compression_) {
835  return std::nullopt;
836  }
837  // There are opportunities to hash and cache the FRCFormatDescriptor if
838  // needed.
839  vk::StructureChain<vk::PhysicalDeviceImageFormatInfo2,
840  vk::ImageCompressionControlEXT>
841  format_chain;
842 
843  auto& format_info = format_chain.get();
844 
845  format_info.format = desc.format;
846  format_info.type = desc.type;
847  format_info.tiling = desc.tiling;
848  format_info.usage = desc.usage;
849  format_info.flags = desc.flags;
850 
851  const auto kIdealFRCRate = vk::ImageCompressionFixedRateFlagBitsEXT::e4Bpc;
852 
853  std::array<vk::ImageCompressionFixedRateFlagsEXT, 1u> rates = {kIdealFRCRate};
854 
855  auto& compression = format_chain.get<vk::ImageCompressionControlEXT>();
856  compression.flags = vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit;
857  compression.compressionControlPlaneCount = rates.size();
858  compression.pFixedRateFlags = rates.data();
859 
860  const auto [result, supported] = physical_device_.getImageFormatProperties2<
861  vk::ImageFormatProperties2, vk::ImageCompressionPropertiesEXT>(
862  format_chain.get());
863 
864  if (result != vk::Result::eSuccess ||
865  !supported.isLinked<vk::ImageCompressionPropertiesEXT>()) {
866  return std::nullopt;
867  }
868 
869  const auto& compression_props =
870  supported.get<vk::ImageCompressionPropertiesEXT>();
871 
872  if ((compression_props.imageCompressionFlags &
873  vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit) &&
874  (compression_props.imageCompressionFixedRateFlags & kIdealFRCRate)) {
875  return kIdealFRCRate;
876  }
877 
878  return std::nullopt;
879 }

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

819  {
820  return optional_android_device_extensions_.find(ext) !=
821  optional_android_device_extensions_.end();
822 }

◆ HasExtension() [2/4]

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

Definition at line 814 of file capabilities_vk.cc.

814  {
815  return optional_device_extensions_.find(ext) !=
816  optional_device_extensions_.end();
817 }

◆ HasExtension() [3/4]

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

Definition at line 809 of file capabilities_vk.cc.

809  {
810  return required_android_device_extensions_.find(ext) !=
811  required_android_device_extensions_.end();
812 }

◆ HasExtension() [4/4]

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

Definition at line 804 of file capabilities_vk.cc.

804  {
805  return required_common_device_extensions_.find(ext) !=
806  required_common_device_extensions_.end();
807 }

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

800  {
801  return false;
802 }

◆ SetOffscreenFormat()

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

Definition at line 552 of file capabilities_vk.cc.

552  {
553  default_color_format_ = pixel_format;
554 }

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

◆ SetPhysicalDevice()

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

Definition at line 556 of file capabilities_vk.cc.

558  {
559  if (HasSuitableColorFormat(device, vk::Format::eR8G8B8A8Unorm)) {
560  default_color_format_ = PixelFormat::kR8G8B8A8UNormInt;
561  } else {
562  default_color_format_ = PixelFormat::kUnknown;
563  }
564 
565  if (HasSuitableDepthStencilFormat(device, vk::Format::eD24UnormS8Uint)) {
566  default_depth_stencil_format_ = PixelFormat::kD24UnormS8Uint;
567  } else if (HasSuitableDepthStencilFormat(device,
568  vk::Format::eD32SfloatS8Uint)) {
569  default_depth_stencil_format_ = PixelFormat::kD32FloatS8UInt;
570  } else {
571  default_depth_stencil_format_ = PixelFormat::kUnknown;
572  }
573 
574  if (HasSuitableDepthStencilFormat(device, vk::Format::eS8Uint)) {
575  default_stencil_format_ = PixelFormat::kS8UInt;
576  } else if (default_depth_stencil_format_ != PixelFormat::kUnknown) {
577  default_stencil_format_ = default_depth_stencil_format_;
578  }
579 
580  physical_device_ = device;
581  device_properties_ = device.getProperties();
582 
583  auto physical_properties_2 =
584  device.getProperties2<vk::PhysicalDeviceProperties2,
585  vk::PhysicalDeviceSubgroupProperties>();
586 
587  // Currently shaders only want access to arithmetic subgroup features.
588  // If that changes this needs to get updated, and so does Metal (which right
589  // now assumes it from compile time flags based on the MSL target version).
590 
591  supports_compute_subgroups_ =
592  !!(physical_properties_2.get<vk::PhysicalDeviceSubgroupProperties>()
593  .supportedOperations &
594  vk::SubgroupFeatureFlagBits::eArithmetic);
595 
596  {
597  // Query texture support.
598  // TODO(129784): Add a capability check for expected memory types.
599  vk::PhysicalDeviceMemoryProperties memory_properties;
600  device.getMemoryProperties(&memory_properties);
601 
602  for (auto i = 0u; i < memory_properties.memoryTypeCount; i++) {
603  if (memory_properties.memoryTypes[i].propertyFlags &
604  vk::MemoryPropertyFlagBits::eLazilyAllocated) {
605  supports_device_transient_textures_ = true;
606  }
607  }
608  }
609 
610  // Determine the optional device extensions this physical device supports.
611  {
612  required_common_device_extensions_.clear();
613  required_android_device_extensions_.clear();
614  optional_device_extensions_.clear();
615  optional_android_device_extensions_.clear();
616 
617  std::set<std::string> exts;
618  if (!use_embedder_extensions_) {
619  auto maybe_exts = GetSupportedDeviceExtensions(device);
620  if (!maybe_exts.has_value()) {
621  return false;
622  }
623  exts = maybe_exts.value();
624  } else {
625  for (const auto& ext : embedder_device_extensions_) {
626  exts.insert(ext);
627  }
628  }
629 
630  IterateExtensions<RequiredCommonDeviceExtensionVK>([&](auto ext) -> bool {
631  auto ext_name = GetExtensionName(ext);
632  if (exts.find(ext_name) != exts.end()) {
633  required_common_device_extensions_.insert(ext);
634  }
635  return true;
636  });
637  IterateExtensions<RequiredAndroidDeviceExtensionVK>([&](auto ext) -> bool {
638  auto ext_name = GetExtensionName(ext);
639  if (exts.find(ext_name) != exts.end()) {
640  required_android_device_extensions_.insert(ext);
641  }
642  return true;
643  });
644  IterateExtensions<OptionalDeviceExtensionVK>([&](auto ext) -> bool {
645  auto ext_name = GetExtensionName(ext);
646  if (exts.find(ext_name) != exts.end()) {
647  optional_device_extensions_.insert(ext);
648  }
649  return true;
650  });
651  IterateExtensions<OptionalAndroidDeviceExtensionVK>(
653  auto name = GetExtensionName(ext);
654  if (exts.find(name) != exts.end()) {
655  optional_android_device_extensions_.insert(ext);
656  }
657  return true;
658  });
659  }
660 
661  supports_texture_fixed_rate_compression_ =
662  enabled_features
663  .isLinked<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>() &&
664  enabled_features
665  .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>()
666  .imageCompressionControl;
667 
668  {
669  const auto& features = enabled_features.get().features;
670  supports_texture_compression_bc_ = features.textureCompressionBC;
671  supports_texture_compression_etc2_ = features.textureCompressionETC2;
672  supports_texture_compression_astc_ = features.textureCompressionASTC_LDR;
673  }
674 
675  supports_texture_compression_astc_hdr_ =
676  enabled_features
677  .isLinked<vk::PhysicalDeviceTextureCompressionASTCHDRFeatures>() &&
678  enabled_features
679  .get<vk::PhysicalDeviceTextureCompressionASTCHDRFeatures>()
680  .textureCompressionASTC_HDR;
681 
682  max_render_pass_attachment_size_ =
683  ISize{device_properties_.limits.maxFramebufferWidth,
684  device_properties_.limits.maxFramebufferHeight};
685 
686  // Anisotropic filtering is gated on the samplerAnisotropy feature. When the
687  // feature is unavailable, report a maximum of 1 (disabled). The device limit
688  // is a float but is always an integer in practice, so floor it.
689  max_sampler_anisotropy_ =
690  enabled_features.get().features.samplerAnisotropy
691  ? static_cast<uint32_t>(
692  device_properties_.limits.maxSamplerAnisotropy)
693  : 1u;
694 
695  // Molten, Vulkan on Metal, cannot support triangle fans because Metal doesn't
696  // support triangle fans.
697  // See VUID-VkPipelineInputAssemblyStateCreateInfo-triangleFans-04452.
698  has_triangle_fans_ =
700 
701  // External Fence/Semaphore for AHB swapchain
706  supports_external_fence_and_semaphore_ = true;
707  }
708 
709  minimum_uniform_alignment_ =
710  device_properties_.limits.minUniformBufferOffsetAlignment;
711  minimum_storage_alignment_ =
712  device_properties_.limits.minStorageBufferOffsetAlignment;
713 
714  return true;
715 }
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.

◆ Supports32BitPrimitiveIndices()

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

Whether 32-bit values are supported in index buffers used to draw primitives.

Implements impeller::Capabilities.

Definition at line 544 of file capabilities_vk.cc.

544  {
545  return true;
546 }

◆ SupportsCompute()

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

Whether the context backend supports ComputePass.

Implements impeller::Capabilities.

Definition at line 743 of file capabilities_vk.cc.

743  {
744  // Vulkan 1.1 requires support for compute.
745  return true;
746 }

◆ SupportsComputeSubgroups()

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

Whether the context backend supports configuring ComputePass command subgroups.

Implements impeller::Capabilities.

Definition at line 749 of file capabilities_vk.cc.

749  {
750  // Set by |SetPhysicalDevice|.
751  return supports_compute_subgroups_;
752 }

◆ SupportsDecalSamplerAddressMode()

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

Whether the context backend supports SamplerAddressMode::Decal.

Implements impeller::Capabilities.

Definition at line 759 of file capabilities_vk.cc.

759  {
760  return true;
761 }

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

764  {
765  return supports_device_transient_textures_;
766 }

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

902  {
903  return false;
904 }

◆ SupportsExternalSemaphoreExtensions()

bool impeller::CapabilitiesVK::SupportsExternalSemaphoreExtensions ( ) const

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

Definition at line 898 of file capabilities_vk.cc.

898  {
899  return supports_external_fence_and_semaphore_;
900 }

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

738  {
739  return has_framebuffer_fetch_;
740 }

◆ SupportsFramebufferRenderMipmap()

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

Whether a non-zero mip level of a texture can be attached as a render target. Rendering into a cube map face or array layer is always supported. Metal and Vulkan support this; the GLES backend does not yet, so it returns false there.

Implements impeller::Capabilities.

Definition at line 906 of file capabilities_vk.cc.

906  {
907  return true;
908 }

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

723  {
724  return false;
725 }

◆ SupportsManuallyMippedTextures()

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

Whether a texture whose mip levels were uploaded by hand (rather than produced by BlitPass::GenerateMipmap) samples with correct per-level selection. True everywhere except OpenGL ES 2.0 without GL_APPLE_texture_max_level, where the sampled mip range cannot be bounded to the levels the texture declares.

Implements impeller::Capabilities.

Definition at line 548 of file capabilities_vk.cc.

548  {
549  return true;
550 }

◆ SupportsOffscreenMSAA()

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

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

Implements impeller::Capabilities.

Definition at line 718 of file capabilities_vk.cc.

718  {
719  return true;
720 }

◆ SupportsPrimitiveRestart()

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

Whether primitive restart is supported.

Implements impeller::Capabilities.

Definition at line 540 of file capabilities_vk.cc.

540  {
541  return has_primitive_restart_;
542 }

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

755  {
756  return false;
757 }

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

728  {
729  return true;
730 }

◆ SupportsTextureCompression()

bool impeller::CapabilitiesVK::SupportsTextureCompression ( CompressedTextureFamily  family) const
overridevirtual

Whether the given family of block-compressed texture formats is supported by this device. Compressed formats are sample-only and their support varies by hardware, so callers must check this before allocating a compressed texture.

Implements impeller::Capabilities.

Definition at line 910 of file capabilities_vk.cc.

911  {
912  switch (family) {
914  return supports_texture_compression_bc_;
916  return supports_texture_compression_etc2_;
918  return supports_texture_compression_astc_;
920  return supports_texture_compression_astc_hdr_;
921  }
922  return false;
923 }
@ kASTCHDR
ASTC HDR. A separate device feature from ASTC LDR.
@ kBC
S3TC, RGTC, and BPTC (BC1 through BC7). Desktop GPUs.
@ kETC2
ETC2 and EAC. Mobile, OpenGL ES 3.0, and WebGL2.
@ kASTC
ASTC LDR. Modern mobile and some desktop.

References impeller::kASTC, impeller::kASTCHDR, impeller::kBC, and impeller::kETC2.

◆ SupportsTextureFixedRateCompression()

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

Definition at line 824 of file capabilities_vk.cc.

824  {
825  return supports_texture_fixed_rate_compression_;
826 }

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

733  {
734  return true;
735 }

◆ SupportsTriangleFan()

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

Whether the primitive type TriangleFan is supported by the backend.

Implements impeller::Capabilities.

Definition at line 881 of file capabilities_vk.cc.

881  {
882  return has_triangle_fans_;
883 }

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