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
 
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...
 
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...
 
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 170 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,
bool  use_embedder_extensions = false,
std::vector< std::string >  instance_extensions = {},
std::vector< std::string >  device_extensions = {} 
)
explicit

Definition at line 19 of file capabilities_vk.cc.

24  : use_embedder_extensions_(use_embedder_extensions),
25  embedder_instance_extensions_(std::move(instance_extensions)),
26  embedder_device_extensions_(std::move(device_extensions)) {
27  if (!use_embedder_extensions_) {
28  auto extensions = vk::enumerateInstanceExtensionProperties();
29  auto layers = vk::enumerateInstanceLayerProperties();
30 
31  if (extensions.result != vk::Result::eSuccess ||
32  layers.result != vk::Result::eSuccess) {
33  return;
34  }
35 
36  for (const auto& ext : extensions.value) {
37  exts_[kInstanceLayer].insert(ext.extensionName);
38  }
39 
40  for (const auto& layer : layers.value) {
41  const std::string layer_name = layer.layerName;
42  auto layer_exts = vk::enumerateInstanceExtensionProperties(layer_name);
43  if (layer_exts.result != vk::Result::eSuccess) {
44  return;
45  }
46  for (const auto& layer_ext : layer_exts.value) {
47  exts_[layer_name].insert(layer_ext.extensionName);
48  }
49  }
50  } else {
51  for (const auto& ext : embedder_instance_extensions_) {
52  exts_[kInstanceLayer].insert(ext);
53  }
54  }
55 
56  validations_enabled_ =
57  enable_validations && HasLayer("VK_LAYER_KHRONOS_validation");
58  if (enable_validations && !validations_enabled_) {
59  FML_LOG(ERROR)
60  << "Requested Impeller context creation with validations but the "
61  "validation layers could not be found. Expect no Vulkan validation "
62  "checks!";
63  if (fatal_missing_validations) {
64  FML_LOG(FATAL) << "Validation missing. Exiting.";
65  }
66  }
67  if (validations_enabled_) {
68  FML_LOG(INFO) << "Vulkan validations are enabled.";
69  }
70  is_valid_ = true;
71 }
static constexpr const char * kInstanceLayer

References impeller::kInstanceLayer.

◆ ~CapabilitiesVK()

impeller::CapabilitiesVK::~CapabilitiesVK ( )
default

Member Function Documentation

◆ ApplyWorkarounds()

void impeller::CapabilitiesVK::ApplyWorkarounds ( const WorkaroundsVK workarounds)

Update capabilities for the given set of workarounds.

Definition at line 763 of file capabilities_vk.cc.

763  {
764  has_primitive_restart_ = !workarounds.slow_primitive_restart_performance;
765  has_framebuffer_fetch_ = !workarounds.input_attachment_self_dependency_broken;
766 }

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

◆ AreValidationsEnabled()

bool impeller::CapabilitiesVK::AreValidationsEnabled ( ) const

Definition at line 79 of file capabilities_vk.cc.

79  {
80  return validations_enabled_;
81 }

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

◆ GetDefaultColorFormat()

PixelFormat impeller::CapabilitiesVK::GetDefaultColorFormat ( ) const
overridevirtual

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

Implements impeller::Capabilities.

Definition at line 660 of file capabilities_vk.cc.

660  {
661  return default_color_format_;
662 }

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

670  {
671  return default_depth_stencil_format_;
672 }

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

679  {
681 }

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

665  {
666  return default_stencil_format_;
667 }

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

◆ GetEnabledDeviceExtensions()

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

Definition at line 253 of file capabilities_vk.cc.

254  {
255  std::set<std::string> exts;
256 
257  if (!use_embedder_extensions_) {
258  auto maybe_exts = GetSupportedDeviceExtensions(physical_device);
259 
260  if (!maybe_exts.has_value()) {
261  return std::nullopt;
262  }
263  exts = maybe_exts.value();
264  } else {
265  exts = std::set(embedder_device_extensions_.begin(),
266  embedder_device_extensions_.end());
267  }
268 
269  std::vector<std::string> enabled;
270 
271  auto for_each_common_extension = [&](RequiredCommonDeviceExtensionVK ext) {
272  auto name = GetExtensionName(ext);
273  if (exts.find(name) == exts.end()) {
274  VALIDATION_LOG << "Device does not support required extension: " << name;
275  return false;
276  }
277  enabled.push_back(name);
278  return true;
279  };
280 
281  auto for_each_android_extension = [&](RequiredAndroidDeviceExtensionVK ext) {
282 #ifdef FML_OS_ANDROID
283  auto name = GetExtensionName(ext);
284  if (exts.find(name) == exts.end()) {
285  VALIDATION_LOG << "Device does not support required Android extension: "
286  << name;
287  return false;
288  }
289  enabled.push_back(name);
290 #endif // FML_OS_ANDROID
291  return true;
292  };
293 
294  auto for_each_optional_extension = [&](OptionalDeviceExtensionVK ext) {
295  auto name = GetExtensionName(ext);
296  if (exts.find(name) != exts.end()) {
297  enabled.push_back(name);
298  }
299  return true;
300  };
301 
302  const auto iterate_extensions =
303  IterateExtensions<RequiredCommonDeviceExtensionVK>(
304  for_each_common_extension) &&
305  IterateExtensions<RequiredAndroidDeviceExtensionVK>(
306  for_each_android_extension) &&
307  IterateExtensions<OptionalDeviceExtensionVK>(for_each_optional_extension);
308 
309  if (!iterate_extensions) {
310  VALIDATION_LOG << "Device not suitable since required extensions are not "
311  "supported.";
312  return std::nullopt;
313  }
314 
315  return enabled;
316 }
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,...
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 374 of file capabilities_vk.cc.

375  {
377  VALIDATION_LOG << "Device doesn't support the required formats.";
378  return std::nullopt;
379  }
380 
381  if (!HasRequiredProperties(device)) {
382  VALIDATION_LOG << "Device doesn't support the required properties.";
383  return std::nullopt;
384  }
385 
386  if (!HasRequiredQueues(device)) {
387  VALIDATION_LOG << "Device doesn't support the required queues.";
388  return std::nullopt;
389  }
390 
391  const auto enabled_extensions = GetEnabledDeviceExtensions(device);
392  if (!enabled_extensions.has_value()) {
393  VALIDATION_LOG << "Device doesn't support the required queues.";
394  return std::nullopt;
395  }
396 
397  PhysicalDeviceFeatures supported_chain;
398 
399  // Swiftshader seems to be fussy about just this structure even being in the
400  // chain. Just unlink it if its not supported. We already perform an
401  // extensions check on the other side when reading.
402  if (!IsExtensionInList(
403  enabled_extensions.value(),
405  supported_chain
406  .unlink<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
407  }
408 
409  device.getFeatures2(&supported_chain.get());
410 
411  PhysicalDeviceFeatures required_chain;
412 
413  // Base features.
414  {
415  auto& required = required_chain.get().features;
416  const auto& supported = supported_chain.get().features;
417 
418  // We require this for enabling wireframes in the playground. But its not
419  // necessarily a big deal if we don't have this feature.
420  required.fillModeNonSolid = supported.fillModeNonSolid;
421  }
422  // VK_KHR_sampler_ycbcr_conversion features.
423  if (IsExtensionInList(
424  enabled_extensions.value(),
426  auto& required =
427  required_chain
428  .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
429  const auto& supported =
430  supported_chain
431  .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
432 
433  required.samplerYcbcrConversion = supported.samplerYcbcrConversion;
434  }
435 
436  // VK_EXT_image_compression_control
437  if (IsExtensionInList(
438  enabled_extensions.value(),
440  auto& required =
441  required_chain
442  .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
443  const auto& supported =
444  supported_chain
445  .get<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
446 
447  required.imageCompressionControl = supported.imageCompressionControl;
448  } else {
449  required_chain
450  .unlink<vk::PhysicalDeviceImageCompressionControlFeaturesEXT>();
451  }
452 
453  // Vulkan 1.1
454  {
455  auto& required =
456  required_chain.get<vk::PhysicalDevice16BitStorageFeatures>();
457  const auto& supported =
458  supported_chain.get<vk::PhysicalDevice16BitStorageFeatures>();
459 
460  required.uniformAndStorageBuffer16BitAccess =
461  supported.uniformAndStorageBuffer16BitAccess;
462  }
463 
464  return required_chain;
465 }
vk::StructureChain< vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR, vk::PhysicalDevice16BitStorageFeatures, vk::PhysicalDeviceImageCompressionControlFeaturesEXT > PhysicalDeviceFeatures
std::optional< std::vector< std::string > > GetEnabledDeviceExtensions(const vk::PhysicalDevice &physical_device) const
static bool PhysicalDeviceSupportsRequiredFormats(const vk::PhysicalDevice &device)
static bool HasRequiredProperties(const vk::PhysicalDevice &physical_device)
static bool IsExtensionInList(const std::vector< std::string > &list, ExtensionEnum ext)
static bool HasRequiredQueues(const vk::PhysicalDevice &physical_device)

References GetEnabledDeviceExtensions(), impeller::HasRequiredProperties(), impeller::HasRequiredQueues(), impeller::IsExtensionInList(), impeller::kEXTImageCompressionControl, impeller::kKHRSamplerYcbcrConversion, impeller::PhysicalDeviceSupportsRequiredFormats(), and VALIDATION_LOG.

Referenced by impeller::PickPhysicalDevice().

◆ GetEnabledInstanceExtensions()

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

Definition at line 96 of file capabilities_vk.cc.

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

References HasExtension(), and VALIDATION_LOG.

◆ GetEnabledLayers()

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

Definition at line 83 of file capabilities_vk.cc.

84  {
85  std::vector<std::string> required;
86 
87  if (validations_enabled_) {
88  // The presence of this layer is already checked in the ctor.
89  required.push_back("VK_LAYER_KHRONOS_validation");
90  }
91 
92  return required;
93 }

◆ GetMaximumRenderPassAttachmentSize()

ISize impeller::CapabilitiesVK::GetMaximumRenderPassAttachmentSize ( ) const
overridevirtual

Return the maximum size of a render pass attachment.

Note that this may be smaller than the maximum allocatable texture size.

Implements impeller::Capabilities.

Definition at line 759 of file capabilities_vk.cc.

759  {
760  return max_render_pass_attachment_size_;
761 }

◆ GetPhysicalDeviceProperties()

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

Definition at line 675 of file capabilities_vk.cc.

675  {
676  return device_properties_;
677 }

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

704  {
705  if (compression_type != CompressionType::kLossy) {
706  return std::nullopt;
707  }
708  if (!supports_texture_fixed_rate_compression_) {
709  return std::nullopt;
710  }
711  // There are opportunities to hash and cache the FRCFormatDescriptor if
712  // needed.
713  vk::StructureChain<vk::PhysicalDeviceImageFormatInfo2,
714  vk::ImageCompressionControlEXT>
715  format_chain;
716 
717  auto& format_info = format_chain.get();
718 
719  format_info.format = desc.format;
720  format_info.type = desc.type;
721  format_info.tiling = desc.tiling;
722  format_info.usage = desc.usage;
723  format_info.flags = desc.flags;
724 
725  const auto kIdealFRCRate = vk::ImageCompressionFixedRateFlagBitsEXT::e4Bpc;
726 
727  std::array<vk::ImageCompressionFixedRateFlagsEXT, 1u> rates = {kIdealFRCRate};
728 
729  auto& compression = format_chain.get<vk::ImageCompressionControlEXT>();
730  compression.flags = vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit;
731  compression.compressionControlPlaneCount = rates.size();
732  compression.pFixedRateFlags = rates.data();
733 
734  const auto [result, supported] = physical_device_.getImageFormatProperties2<
735  vk::ImageFormatProperties2, vk::ImageCompressionPropertiesEXT>(
736  format_chain.get());
737 
738  if (result != vk::Result::eSuccess ||
739  !supported.isLinked<vk::ImageCompressionPropertiesEXT>()) {
740  return std::nullopt;
741  }
742 
743  const auto& compression_props =
744  supported.get<vk::ImageCompressionPropertiesEXT>();
745 
746  if ((compression_props.imageCompressionFlags &
747  vk::ImageCompressionFlagBitsEXT::eFixedRateExplicit) &&
748  (compression_props.imageCompressionFixedRateFlags & kIdealFRCRate)) {
749  return kIdealFRCRate;
750  }
751 
752  return std::nullopt;
753 }

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

693  {
694  return optional_device_extensions_.find(ext) !=
695  optional_device_extensions_.end();
696 }

◆ HasExtension() [2/3]

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

Definition at line 688 of file capabilities_vk.cc.

688  {
689  return required_android_device_extensions_.find(ext) !=
690  required_android_device_extensions_.end();
691 }

◆ HasExtension() [3/3]

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

Definition at line 683 of file capabilities_vk.cc.

683  {
684  return required_common_device_extensions_.find(ext) !=
685  required_common_device_extensions_.end();
686 }

Referenced by GetEnabledInstanceExtensions(), and SetPhysicalDevice().

◆ IsValid()

bool impeller::CapabilitiesVK::IsValid ( ) const

Definition at line 75 of file capabilities_vk.cc.

75  {
76  return is_valid_;
77 }

◆ SetOffscreenFormat()

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

Definition at line 489 of file capabilities_vk.cc.

489  {
490  default_color_format_ = pixel_format;
491 }

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

◆ SetPhysicalDevice()

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

Definition at line 493 of file capabilities_vk.cc.

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

References impeller::GetExtensionName(), impeller::GetSupportedDeviceExtensions(), HasExtension(), impeller::HasSuitableColorFormat(), impeller::HasSuitableDepthStencilFormat(), impeller::kD24UnormS8Uint, impeller::kD32FloatS8UInt, 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 634 of file capabilities_vk.cc.

634  {
635  // Vulkan 1.1 requires support for compute.
636  return true;
637 }

◆ SupportsComputeSubgroups()

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

Whether the context backend supports configuring ComputePass command subgroups.

Implements impeller::Capabilities.

Definition at line 640 of file capabilities_vk.cc.

640  {
641  // Set by |SetPhysicalDevice|.
642  return supports_compute_subgroups_;
643 }

◆ SupportsDecalSamplerAddressMode()

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

Whether the context backend supports SamplerAddressMode::Decal.

Implements impeller::Capabilities.

Definition at line 650 of file capabilities_vk.cc.

650  {
651  return true;
652 }

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

655  {
656  return supports_device_transient_textures_;
657 }

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

629  {
630  return has_framebuffer_fetch_;
631 }

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

614  {
615  return false;
616 }

◆ SupportsOffscreenMSAA()

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

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

Implements impeller::Capabilities.

Definition at line 609 of file capabilities_vk.cc.

609  {
610  return true;
611 }

◆ SupportsPrimitiveRestart()

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

Whether primitive restart is supported.

Implements impeller::Capabilities.

Definition at line 485 of file capabilities_vk.cc.

485  {
486  return has_primitive_restart_;
487 }

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

646  {
647  return false;
648 }

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

619  {
620  return true;
621 }

◆ SupportsTextureFixedRateCompression()

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

Definition at line 698 of file capabilities_vk.cc.

698  {
699  return supports_texture_fixed_rate_compression_;
700 }

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

624  {
625  return true;
626 }

◆ SupportsTriangleFan()

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

Whether the primitive type TriangleFan is supported by the backend.

Implements impeller::Capabilities.

Definition at line 755 of file capabilities_vk.cc.

755  {
756  return has_triangle_fans_;
757 }

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