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

Member Typedef Documentation

◆ PhysicalDeviceFeatures

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

Definition at line 198 of file capabilities_vk.h.

Constructor & Destructor Documentation

◆ CapabilitiesVK()

impeller::CapabilitiesVK::CapabilitiesVK ( bool  enable_validations,
bool  fatal_missing_validations = false 
)
explicit

Definition at line 18 of file capabilities_vk.cc.

19  {
20  auto extensions = vk::enumerateInstanceExtensionProperties();
21  auto layers = vk::enumerateInstanceLayerProperties();
22 
23  if (extensions.result != vk::Result::eSuccess ||
24  layers.result != vk::Result::eSuccess) {
25  return;
26  }
27 
28  for (const auto& ext : extensions.value) {
29  exts_[kInstanceLayer].insert(ext.extensionName);
30  }
31 
32  for (const auto& layer : layers.value) {
33  const std::string layer_name = layer.layerName;
34  auto layer_exts = vk::enumerateInstanceExtensionProperties(layer_name);
35  if (layer_exts.result != vk::Result::eSuccess) {
36  return;
37  }
38  for (const auto& layer_ext : layer_exts.value) {
39  exts_[layer_name].insert(layer_ext.extensionName);
40  }
41  }
42 
43  validations_enabled_ =
44  enable_validations && HasLayer("VK_LAYER_KHRONOS_validation");
45  if (enable_validations && !validations_enabled_) {
46  FML_LOG(ERROR)
47  << "Requested Impeller context creation with validations but the "
48  "validation layers could not be found. Expect no Vulkan validation "
49  "checks!";
50  if (fatal_missing_validations) {
51  FML_LOG(FATAL) << "Validation missing. Exiting.";
52  }
53  }
54  if (validations_enabled_) {
55  FML_LOG(INFO) << "Vulkan validations are enabled.";
56  }
57  is_valid_ = true;
58 }

References impeller::kInstanceLayer.

◆ ~CapabilitiesVK()

impeller::CapabilitiesVK::~CapabilitiesVK ( )
default

Member Function Documentation

◆ AreValidationsEnabled()

bool impeller::CapabilitiesVK::AreValidationsEnabled ( ) const

Definition at line 66 of file capabilities_vk.cc.

66  {
67  return validations_enabled_;
68 }

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

620  {
621  return default_color_format_;
622 }

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

630  {
631  return default_depth_stencil_format_;
632 }

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

639  {
641 }

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

625  {
626  return default_stencil_format_;
627 }

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

◆ GetEnabledDeviceExtensions()

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

Definition at line 240 of file capabilities_vk.cc.

241  {
242  auto exts = GetSupportedDeviceExtensions(physical_device);
243 
244  if (!exts.has_value()) {
245  return std::nullopt;
246  }
247 
248  std::vector<std::string> enabled;
249 
250  auto for_each_common_extension = [&](RequiredCommonDeviceExtensionVK ext) {
251  auto name = GetExtensionName(ext);
252  if (exts->find(name) == exts->end()) {
253  VALIDATION_LOG << "Device does not support required extension: " << name;
254  return false;
255  }
256  enabled.push_back(name);
257  return true;
258  };
259 
260  auto for_each_android_extension = [&](RequiredAndroidDeviceExtensionVK ext) {
261 #ifdef FML_OS_ANDROID
262  auto name = GetExtensionName(ext);
263  if (exts->find(name) == exts->end()) {
264  VALIDATION_LOG << "Device does not support required Android extension: "
265  << name;
266  return false;
267  }
268  enabled.push_back(name);
269 #endif // FML_OS_ANDROID
270  return true;
271  };
272 
273  auto for_each_optional_extension = [&](OptionalDeviceExtensionVK ext) {
274  auto name = GetExtensionName(ext);
275  if (exts->find(name) != exts->end()) {
276  enabled.push_back(name);
277  }
278  return true;
279  };
280 
281  const auto iterate_extensions =
282  IterateExtensions<RequiredCommonDeviceExtensionVK>(
283  for_each_common_extension) &&
284  IterateExtensions<RequiredAndroidDeviceExtensionVK>(
285  for_each_android_extension) &&
286  IterateExtensions<OptionalDeviceExtensionVK>(for_each_optional_extension);
287 
288  if (!iterate_extensions) {
289  VALIDATION_LOG << "Device not suitable since required extensions are not "
290  "supported.";
291  return std::nullopt;
292  }
293 
294  return enabled;
295 }

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

354  {
356  VALIDATION_LOG << "Device doesn't support the required formats.";
357  return std::nullopt;
358  }
359 
360  if (!HasRequiredProperties(device)) {
361  VALIDATION_LOG << "Device doesn't support the required properties.";
362  return std::nullopt;
363  }
364 
365  if (!HasRequiredQueues(device)) {
366  VALIDATION_LOG << "Device doesn't support the required queues.";
367  return std::nullopt;
368  }
369 
370  const auto enabled_extensions = GetEnabledDeviceExtensions(device);
371  if (!enabled_extensions.has_value()) {
372  VALIDATION_LOG << "Device doesn't support the required queues.";
373  return std::nullopt;
374  }
375 
376  PhysicalDeviceFeatures supported_chain;
377 
378  // Swiftshader seems to be fussy about just this structure even being in the
379  // chain. Just unlink it if its not supported. We already perform an
380  // extensions check on the other side when reading.
381  if (!IsExtensionInList(
382  enabled_extensions.value(),
384  supported_chain
385  .unlink<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
386  }
387 
388  device.getFeatures2(&supported_chain.get());
389 
390  PhysicalDeviceFeatures required_chain;
391 
392  // Base features.
393  {
394  auto& required = required_chain.get().features;
395  const auto& supported = supported_chain.get().features;
396 
397  // We require this for enabling wireframes in the playground. But its not
398  // necessarily a big deal if we don't have this feature.
399  required.fillModeNonSolid = supported.fillModeNonSolid;
400  }
401  // VK_KHR_sampler_ycbcr_conversion features.
402  if (IsExtensionInList(
403  enabled_extensions.value(),
405  auto& required =
406  required_chain
407  .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
408  const auto& supported =
409  supported_chain
410  .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
411 
412  required.samplerYcbcrConversion = supported.samplerYcbcrConversion;
413  }
414 
415  // VK_EXT_image_compression_control
416  if (IsExtensionInList(
417  enabled_extensions.value(),
419  auto& required =
420  required_chain
421  .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
422  const auto& supported =
423  supported_chain
424  .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
425 
426  required.imageCompressionControl = supported.imageCompressionControl;
427  } else {
428  required_chain
429  .unlink<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
430  }
431 
432  // Vulkan 1.1
433  {
434  auto& required =
435  required_chain.get<vk::PhysicalDevice16BitStorageFeatures>();
436  const auto& supported =
437  supported_chain.get<vk::PhysicalDevice16BitStorageFeatures>();
438 
439  required.uniformAndStorageBuffer16BitAccess =
440  supported.uniformAndStorageBuffer16BitAccess;
441  }
442 
443  return required_chain;
444 }

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

83  {
84  std::vector<std::string> required;
85 
86  if (!HasExtension("VK_KHR_surface")) {
87  // Swapchain support is required and this is a dependency of
88  // VK_KHR_swapchain.
89  VALIDATION_LOG << "Could not find the surface extension.";
90  return std::nullopt;
91  }
92  required.push_back("VK_KHR_surface");
93 
94  auto has_wsi = false;
95  if (HasExtension("VK_MVK_macos_surface")) {
96  required.push_back("VK_MVK_macos_surface");
97  has_wsi = true;
98  }
99 
100  if (HasExtension("VK_EXT_metal_surface")) {
101  required.push_back("VK_EXT_metal_surface");
102  has_wsi = true;
103  }
104 
105  if (HasExtension("VK_KHR_portability_enumeration")) {
106  required.push_back("VK_KHR_portability_enumeration");
107  has_wsi = true;
108  }
109 
110  if (HasExtension("VK_KHR_win32_surface")) {
111  required.push_back("VK_KHR_win32_surface");
112  has_wsi = true;
113  }
114 
115  if (HasExtension("VK_KHR_android_surface")) {
116  required.push_back("VK_KHR_android_surface");
117  has_wsi = true;
118  }
119 
120  if (HasExtension("VK_KHR_xcb_surface")) {
121  required.push_back("VK_KHR_xcb_surface");
122  has_wsi = true;
123  }
124 
125  if (HasExtension("VK_KHR_xlib_surface")) {
126  required.push_back("VK_KHR_xlib_surface");
127  has_wsi = true;
128  }
129 
130  if (HasExtension("VK_KHR_wayland_surface")) {
131  required.push_back("VK_KHR_wayland_surface");
132  has_wsi = true;
133  }
134 
135  if (!has_wsi) {
136  // Don't really care which WSI extension there is as long there is at least
137  // one.
138  VALIDATION_LOG << "Could not find a WSI extension.";
139  return std::nullopt;
140  }
141 
142  if (validations_enabled_) {
143  if (!HasExtension("VK_EXT_debug_utils")) {
144  VALIDATION_LOG << "Requested validations but could not find the "
145  "VK_EXT_debug_utils extension.";
146  return std::nullopt;
147  }
148  required.push_back("VK_EXT_debug_utils");
149 
150  if (HasExtension("VK_EXT_validation_features")) {
151  // It's valid to not have `VK_EXT_validation_features` available. That's
152  // the case when using AGI as a frame debugger.
153  required.push_back("VK_EXT_validation_features");
154  }
155  }
156 
157  return required;
158 }

References HasExtension(), and VALIDATION_LOG.

◆ GetEnabledLayers()

std::optional< std::vector< std::string > > impeller::CapabilitiesVK::GetEnabledLayers ( ) const

Definition at line 70 of file capabilities_vk.cc.

71  {
72  std::vector<std::string> required;
73 
74  if (validations_enabled_) {
75  // The presence of this layer is already checked in the ctor.
76  required.push_back("VK_LAYER_KHRONOS_validation");
77  }
78 
79  return required;
80 }

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

719  {
720  return max_render_pass_attachment_size_;
721 }

◆ GetPhysicalDeviceProperties()

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

Definition at line 635 of file capabilities_vk.cc.

635  {
636  return device_properties_;
637 }

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

664  {
665  if (compression_type != CompressionType::kLossy) {
666  return std::nullopt;
667  }
668  if (!supports_texture_fixed_rate_compression_) {
669  return std::nullopt;
670  }
671  // There are opportunities to hash and cache the FRCFormatDescriptor if
672  // needed.
673  vk::StructureChain<vk::PhysicalDeviceImageFormatInfo2,
674  vk::ImageCompressionControlEXT>
675  format_chain;
676 
677  auto& format_info = format_chain.get();
678 
679  format_info.format = desc.format;
680  format_info.type = desc.type;
681  format_info.tiling = desc.tiling;
682  format_info.usage = desc.usage;
683  format_info.flags = desc.flags;
684 
685  const auto kIdealFRCRate = vk::ImageCompressionFixedRateFlagBitsEXT::e4Bpc;
686 
687  std::array<vk::ImageCompressionFixedRateFlagsEXT, 1u> rates = {kIdealFRCRate};
688 
689  auto& compression = format_chain.get<vk::ImageCompressionControlEXT>();
690  compression.flags = vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit;
691  compression.compressionControlPlaneCount = rates.size();
692  compression.pFixedRateFlags = rates.data();
693 
694  const auto [result, supported] = physical_device_.getImageFormatProperties2<
695  vk::ImageFormatProperties2, vk::ImageCompressionPropertiesEXT>(
696  format_chain.get());
697 
698  if (result != vk::Result::eSuccess ||
699  !supported.isLinked<vk::ImageCompressionPropertiesEXT>()) {
700  return std::nullopt;
701  }
702 
703  const auto& compression_props =
704  supported.get<vk::ImageCompressionPropertiesEXT>();
705 
706  if ((compression_props.imageCompressionFlags &
707  vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit) &&
708  (compression_props.imageCompressionFixedRateFlags & kIdealFRCRate)) {
709  return kIdealFRCRate;
710  }
711 
712  return std::nullopt;
713 }

References impeller::FRCFormatDescriptor::flags, impeller::FRCFormatDescriptor::format, impeller::kLossy, impeller::FRCFormatDescriptor::tiling, impeller::FRCFormatDescriptor::type, and impeller::FRCFormatDescriptor::usage.

◆ HasExtension() [1/3]

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

Definition at line 653 of file capabilities_vk.cc.

653  {
654  return optional_device_extensions_.find(ext) !=
655  optional_device_extensions_.end();
656 }

◆ HasExtension() [2/3]

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

Definition at line 648 of file capabilities_vk.cc.

648  {
649  return required_android_device_extensions_.find(ext) !=
650  required_android_device_extensions_.end();
651 }

◆ HasExtension() [3/3]

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

Definition at line 643 of file capabilities_vk.cc.

643  {
644  return required_common_device_extensions_.find(ext) !=
645  required_common_device_extensions_.end();
646 }

Referenced by GetEnabledInstanceExtensions().

◆ IsValid()

bool impeller::CapabilitiesVK::IsValid ( ) const

Definition at line 62 of file capabilities_vk.cc.

62  {
63  return is_valid_;
64 }

◆ SetOffscreenFormat()

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

Definition at line 464 of file capabilities_vk.cc.

464  {
465  default_color_format_ = pixel_format;
466 }

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

◆ SetPhysicalDevice()

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

Definition at line 468 of file capabilities_vk.cc.

470  {
471  if (HasSuitableColorFormat(device, vk::Format::eR8G8B8A8Unorm)) {
472  default_color_format_ = PixelFormat::kR8G8B8A8UNormInt;
473  } else {
474  default_color_format_ = PixelFormat::kUnknown;
475  }
476 
477  if (HasSuitableDepthStencilFormat(device, vk::Format::eD32SfloatS8Uint)) {
478  default_depth_stencil_format_ = PixelFormat::kD32FloatS8UInt;
479  } else if (HasSuitableDepthStencilFormat(device,
480  vk::Format::eD24UnormS8Uint)) {
481  default_depth_stencil_format_ = PixelFormat::kD24UnormS8Uint;
482  } else {
483  default_depth_stencil_format_ = PixelFormat::kUnknown;
484  }
485 
486  if (HasSuitableDepthStencilFormat(device, vk::Format::eS8Uint)) {
487  default_stencil_format_ = PixelFormat::kS8UInt;
488  } else if (default_depth_stencil_format_ != PixelFormat::kUnknown) {
489  default_stencil_format_ = default_depth_stencil_format_;
490  }
491 
492  physical_device_ = device;
493  device_properties_ = device.getProperties();
494 
495  auto physical_properties_2 =
496  device.getProperties2<vk::PhysicalDeviceProperties2,
497  vk::PhysicalDeviceSubgroupProperties>();
498 
499  // Currently shaders only want access to arithmetic subgroup features.
500  // If that changes this needs to get updated, and so does Metal (which right
501  // now assumes it from compile time flags based on the MSL target version).
502 
503  supports_compute_subgroups_ =
504  !!(physical_properties_2.get<vk::PhysicalDeviceSubgroupProperties>()
505  .supportedOperations &
506  vk::SubgroupFeatureFlagBits::eArithmetic);
507 
508  {
509  // Query texture support.
510  // TODO(129784): Add a capability check for expected memory types.
511  vk::PhysicalDeviceMemoryProperties memory_properties;
512  device.getMemoryProperties(&memory_properties);
513 
514  for (auto i = 0u; i < memory_properties.memoryTypeCount; i++) {
515  if (memory_properties.memoryTypes[i].propertyFlags &
516  vk::MemoryPropertyFlagBits::eLazilyAllocated) {
517  supports_device_transient_textures_ = true;
518  }
519  }
520  }
521 
522  // Determine the optional device extensions this physical device supports.
523  {
524  required_common_device_extensions_.clear();
525  required_android_device_extensions_.clear();
526  optional_device_extensions_.clear();
527  auto exts = GetSupportedDeviceExtensions(device);
528  if (!exts.has_value()) {
529  return false;
530  }
531  IterateExtensions<RequiredCommonDeviceExtensionVK>([&](auto ext) -> bool {
532  auto ext_name = GetExtensionName(ext);
533  if (exts->find(ext_name) != exts->end()) {
534  required_common_device_extensions_.insert(ext);
535  }
536  return true;
537  });
538  IterateExtensions<RequiredAndroidDeviceExtensionVK>([&](auto ext) -> bool {
539  auto ext_name = GetExtensionName(ext);
540  if (exts->find(ext_name) != exts->end()) {
541  required_android_device_extensions_.insert(ext);
542  }
543  return true;
544  });
545  IterateExtensions<OptionalDeviceExtensionVK>([&](auto ext) -> bool {
546  auto ext_name = GetExtensionName(ext);
547  if (exts->find(ext_name) != exts->end()) {
548  optional_device_extensions_.insert(ext);
549  }
550  return true;
551  });
552  }
553 
554  supports_texture_fixed_rate_compression_ =
555  enabled_features
556  .isLinked<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>() &&
557  enabled_features
558  .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>()
559  .imageCompressionControl;
560 
561  max_render_pass_attachment_size_ =
562  ISize{device_properties_.limits.maxFramebufferWidth,
563  device_properties_.limits.maxFramebufferHeight};
564 
565  return true;
566 }

References impeller::GetExtensionName(), impeller::GetSupportedDeviceExtensions(), impeller::HasSuitableColorFormat(), impeller::HasSuitableDepthStencilFormat(), impeller::kD24UnormS8Uint, impeller::kD32FloatS8UInt, impeller::kR8G8B8A8UNormInt, impeller::kS8UInt, and impeller::kUnknown.

◆ SupportsCompute()

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

Whether the context backend supports ComputePass.

Implements impeller::Capabilities.

Definition at line 594 of file capabilities_vk.cc.

594  {
595  // Vulkan 1.1 requires support for compute.
596  return true;
597 }

◆ SupportsComputeSubgroups()

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

Whether the context backend supports configuring ComputePass command subgroups.

Implements impeller::Capabilities.

Definition at line 600 of file capabilities_vk.cc.

600  {
601  // Set by |SetPhysicalDevice|.
602  return supports_compute_subgroups_;
603 }

◆ SupportsDecalSamplerAddressMode()

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

Whether the context backend supports SamplerAddressMode::Decal.

Implements impeller::Capabilities.

Definition at line 610 of file capabilities_vk.cc.

610  {
611  return true;
612 }

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

615  {
616  return supports_device_transient_textures_;
617 }

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

589  {
590  return true;
591 }

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

574  {
575  return false;
576 }

◆ SupportsOffscreenMSAA()

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

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

Implements impeller::Capabilities.

Definition at line 569 of file capabilities_vk.cc.

569  {
570  return true;
571 }

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

606  {
607  return false;
608 }

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

579  {
580  return true;
581 }

◆ SupportsTextureFixedRateCompression()

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

Definition at line 658 of file capabilities_vk.cc.

658  {
659  return supports_texture_fixed_rate_compression_;
660 }

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

584  {
585  return true;
586 }

◆ SupportsTriangleFan()

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

Whether the primitive type TriangleFan is supported by the backend.

Implements impeller::Capabilities.

Definition at line 715 of file capabilities_vk.cc.

715  {
716  return true;
717 }

The documentation for this class was generated from the following files:
impeller::OptionalDeviceExtensionVK
OptionalDeviceExtensionVK
A device extension enabled if available. Subsystems cannot assume availability and must check if thes...
Definition: capabilities_vk.h:120
impeller::HasRequiredProperties
static bool HasRequiredProperties(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:322
impeller::ISize
ISize64 ISize
Definition: size.h:140
impeller::PixelFormat::kS8UInt
@ kS8UInt
impeller::kInstanceLayer
static constexpr const char * kInstanceLayer
Definition: capabilities_vk.cc:16
impeller::PixelFormat::kR8UNormInt
@ kR8UNormInt
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::HasSuitableDepthStencilFormat
static bool HasSuitableDepthStencilFormat(const vk::PhysicalDevice &device, vk::Format format)
Definition: capabilities_vk.cc:305
impeller::HasRequiredQueues
static bool HasRequiredQueues(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:331
impeller::GetExtensionName
static const char * GetExtensionName(RequiredCommonDeviceExtensionVK ext)
Definition: capabilities_vk.cc:160
impeller::RequiredCommonDeviceExtensionVK
RequiredCommonDeviceExtensionVK
A device extension available on all platforms. Without the presence of these extensions,...
Definition: capabilities_vk.h:28
impeller::PixelFormat::kD32FloatS8UInt
@ kD32FloatS8UInt
impeller::PhysicalDeviceSupportsRequiredFormats
static bool PhysicalDeviceSupportsRequiredFormats(const vk::PhysicalDevice &device)
Definition: capabilities_vk.cc:312
impeller::CapabilitiesVK::HasExtension
bool HasExtension(RequiredCommonDeviceExtensionVK ext) const
Definition: capabilities_vk.cc:643
impeller::GetSupportedDeviceExtensions
static std::optional< std::set< std::string > > GetSupportedDeviceExtensions(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:224
impeller::RequiredAndroidDeviceExtensionVK::kKHRSamplerYcbcrConversion
@ kKHRSamplerYcbcrConversion
impeller::PixelFormat::kD24UnormS8Uint
@ kD24UnormS8Uint
impeller::CapabilitiesVK::PhysicalDeviceFeatures
vk::StructureChain< vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR, vk::PhysicalDevice16BitStorageFeatures, vk::PhysicalDeviceImageCompressionControlFeaturesEXT > PhysicalDeviceFeatures
Definition: capabilities_vk.h:198
impeller::CompressionType::kLossy
@ kLossy
impeller::PixelFormat::kUnknown
@ kUnknown
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91
impeller::HasSuitableColorFormat
static bool HasSuitableColorFormat(const vk::PhysicalDevice &device, vk::Format format)
Definition: capabilities_vk.cc:297
impeller::IsExtensionInList
static bool IsExtensionInList(const std::vector< std::string > &list, ExtensionEnum ext)
Definition: capabilities_vk.cc:346
impeller::RequiredAndroidDeviceExtensionVK
RequiredAndroidDeviceExtensionVK
A device extension available on all Android platforms. Without the presence of these extensions on An...
Definition: capabilities_vk.h:47
impeller::CapabilitiesVK::GetEnabledDeviceExtensions
std::optional< std::vector< std::string > > GetEnabledDeviceExtensions(const vk::PhysicalDevice &physical_device) const
Definition: capabilities_vk.cc:240
impeller::OptionalDeviceExtensionVK::kEXTImageCompressionControl
@ kEXTImageCompressionControl