Flutter Impeller
capabilities_vk.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_CAPABILITIES_VK_H_
6 #define FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_CAPABILITIES_VK_H_
7 
8 #include <cstdint>
9 #include <map>
10 #include <optional>
11 #include <set>
12 #include <string>
13 #include <vector>
14 
20 
21 namespace impeller {
22 
23 class ContextVK;
24 
25 //------------------------------------------------------------------------------
26 /// @brief A device extension available on all platforms. Without the
27 /// presence of these extensions, context creation will fail.
28 ///
29 enum class RequiredCommonDeviceExtensionVK : uint32_t {
30  //----------------------------------------------------------------------------
31  /// For displaying content in the window system.
32  ///
33  /// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_swapchain.html
34  ///
36 
37  kLast,
38 };
39 
40 //------------------------------------------------------------------------------
41 /// @brief A device extension available on all Android platforms. Without
42 /// the presence of these extensions on Android, context creation
43 /// will fail.
44 ///
45 /// Platform agnostic code can still check if these Android
46 /// extensions are present.
47 ///
48 enum class RequiredAndroidDeviceExtensionVK : uint32_t {
49  //----------------------------------------------------------------------------
50  /// For importing hardware buffers used in external texture composition.
51  ///
52  /// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_ANDROID_external_memory_android_hardware_buffer.html
53  ///
55 
56  //----------------------------------------------------------------------------
57  /// Dependency of kANDROIDExternalMemoryAndroidHardwareBuffer.
58  ///
59  /// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_sampler_ycbcr_conversion.html
60  ///
62 
63  //----------------------------------------------------------------------------
64  /// Dependency of kANDROIDExternalMemoryAndroidHardwareBuffer.
65  ///
66  /// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_external_memory.html
67  ///
69 
70  //----------------------------------------------------------------------------
71  /// Dependency of kANDROIDExternalMemoryAndroidHardwareBuffer.
72  ///
73  /// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_queue_family_foreign.html
74  ///
76 
77  //----------------------------------------------------------------------------
78  /// Dependency of kANDROIDExternalMemoryAndroidHardwareBuffer.
79  ///
80  /// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_dedicated_allocation.html
81  ///
83 
84  kLast,
85 };
86 
87 //------------------------------------------------------------------------------
88 /// @brief A device extension available on some Android platforms.
89 ///
90 /// Platform agnostic code can still check if these Android
91 /// extensions are present.
92 ///
93 enum class OptionalAndroidDeviceExtensionVK : uint32_t {
94  //----------------------------------------------------------------------------
95  /// For exporting file descriptors from fences to interact with platform APIs.
96  ///
97  /// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_external_fence_fd.html
98  ///
100 
101  //----------------------------------------------------------------------------
102  /// Dependency of kKHRExternalFenceFd.
103  ///
104  /// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_external_fence.html
105  ///
107 
108  //----------------------------------------------------------------------------
109  /// For importing sync file descriptors as semaphores so the GPU can wait for
110  /// semaphore to be signaled.
111  ///
112  /// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_external_semaphore_fd.html
114 
115  //----------------------------------------------------------------------------
116  /// Dependency of kKHRExternalSemaphoreFd
117  ///
118  /// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_external_semaphore.html
120 
121  kLast,
122 };
123 
124 //------------------------------------------------------------------------------
125 /// @brief A device extension enabled if available. Subsystems cannot
126 /// assume availability and must check if these extensions are
127 /// available.
128 ///
129 /// @see `CapabilitiesVK::HasExtension`.
130 ///
131 enum class OptionalDeviceExtensionVK : uint32_t {
132  //----------------------------------------------------------------------------
133  /// To instrument and profile PSO creation.
134  ///
135  /// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_pipeline_creation_feedback.html
136  ///
138 
139  //----------------------------------------------------------------------------
140  /// To enable context creation on MoltenVK. A non-conformant Vulkan
141  /// implementation.
142  ///
143  /// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_portability_subset.html
144  ///
146 
147  //----------------------------------------------------------------------------
148  /// For fixed-rate compression of images.
149  ///
150  /// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_image_compression_control.html
151  ///
153 
154  //----------------------------------------------------------------------------
155  /// For sampling ASTC HDR block-compressed textures. Promoted to core in
156  /// Vulkan 1.3, but gated here on the extension for broader device coverage.
157  ///
158  /// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_texture_compression_astc_hdr.html
159  ///
161 
162  kLast,
163 };
164 
165 //------------------------------------------------------------------------------
166 /// @brief A pixel format and usage that is sufficient to check if images
167 /// of that format and usage are suitable for use with fixed-rate
168 /// compression.
169 ///
171  vk::Format format = vk::Format::eUndefined;
172  vk::ImageType type = {};
173  vk::ImageTiling tiling = {};
174  vk::ImageUsageFlags usage = {};
175  vk::ImageCreateFlags flags = {};
176 
177  explicit FRCFormatDescriptor(const vk::ImageCreateInfo& image_info)
178  : format(image_info.format),
179  type(image_info.imageType),
180  tiling(image_info.tiling),
181  usage(image_info.usage),
182  flags(image_info.flags) {}
183 };
184 
185 //------------------------------------------------------------------------------
186 /// @brief The Vulkan layers and extensions wrangler.
187 ///
188 class CapabilitiesVK final : public Capabilities,
189  public BackendCast<CapabilitiesVK, Capabilities> {
190  public:
191  explicit CapabilitiesVK(bool enable_validations,
192  bool fatal_missing_validations = false,
193  bool use_embedder_extensions = false,
194  std::vector<std::string> instance_extensions = {},
195  std::vector<std::string> device_extensions = {});
196 
198 
199  bool IsValid() const;
200 
201  bool AreValidationsEnabled() const;
202 
204 
206 
207  bool HasExtension(OptionalDeviceExtensionVK ext) const;
208 
210 
211  std::optional<std::vector<std::string>> GetEnabledLayers() const;
212 
213  std::optional<std::vector<std::string>> GetEnabledInstanceExtensions() const;
214 
215  std::optional<std::vector<std::string>> GetEnabledDeviceExtensions(
216  const vk::PhysicalDevice& physical_device) const;
217 
219  vk::StructureChain<vk::PhysicalDeviceFeatures2,
220  vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR,
221  vk::PhysicalDevice16BitStorageFeatures,
222  vk::PhysicalDeviceImageCompressionControlFeaturesEXT,
223  vk::PhysicalDeviceTextureCompressionASTCHDRFeatures>;
224 
225  std::optional<PhysicalDeviceFeatures> GetEnabledDeviceFeatures(
226  const vk::PhysicalDevice& physical_device) const;
227 
228  [[nodiscard]] bool SetPhysicalDevice(
229  const vk::PhysicalDevice& physical_device,
230  const PhysicalDeviceFeatures& enabled_features);
231 
232  const vk::PhysicalDeviceProperties& GetPhysicalDeviceProperties() const;
233 
234  void SetOffscreenFormat(PixelFormat pixel_format) const;
235 
236  // |Capabilities|
237  bool SupportsOffscreenMSAA() const override;
238 
239  // |Capabilities|
240  bool SupportsImplicitResolvingMSAA() const override;
241 
242  // |Capabilities|
243  bool SupportsSSBO() const override;
244 
245  // |Capabilities|
246  bool SupportsTextureToTextureBlits() const override;
247 
248  // |Capabilities|
249  bool SupportsFramebufferFetch() const override;
250 
251  // |Capabilities|
252  bool SupportsCompute() const override;
253 
254  // |Capabilities|
255  bool SupportsComputeSubgroups() const override;
256 
257  // |Capabilities|
258  bool SupportsReadFromResolve() const override;
259 
260  // |Capabilities|
261  bool SupportsDecalSamplerAddressMode() const override;
262 
263  // |Capabilities|
264  bool SupportsDeviceTransientTextures() const override;
265 
266  // |Capabilities|
267  bool SupportsTriangleFan() const override;
268 
269  // |Capabilities|
270  bool SupportsPrimitiveRestart() const override;
271 
272  // |Capabilities|
273  bool Supports32BitPrimitiveIndices() const override;
274 
275  // |Capabilities|
276  bool SupportsManuallyMippedTextures() const override;
277 
278  // |Capabilities|
279  bool SupportsExtendedRangeFormats() const override;
280 
281  // |Capabilities|
283  CompressedTextureFamily family) const override;
284 
285  // |Capabilities|
286  bool SupportsFramebufferRenderMipmap() const override;
287 
288  // |Capabilities|
289  PixelFormat GetDefaultColorFormat() const override;
290 
291  // |Capabilities|
292  PixelFormat GetDefaultStencilFormat() const override;
293 
294  // |Capabilities|
295  PixelFormat GetDefaultDepthStencilFormat() const override;
296 
297  // |Capabilities|
298  PixelFormat GetDefaultGlyphAtlasFormat() const override;
299 
300  // |Capabilities|
301  ISize GetMaximumRenderPassAttachmentSize() const override;
302 
303  // |Capabilities|
304  uint32_t GetMaxSamplerAnisotropy() const override;
305 
306  // |Capabilities|
307  size_t GetMinimumUniformAlignment() const override;
308 
309  // |Capabilities|
310  size_t GetMinimumStorageBufferAlignment() const override;
311 
312  // |Capabilities|
313  bool NeedsPartitionedHostBuffer() const override;
314 
315  //----------------------------------------------------------------------------
316  /// @return If fixed-rate compression for non-onscreen surfaces is
317  /// supported.
318  ///
320 
321  /// Whether the external fence and semaphore extensions used for AHB support
322  /// are available.
324 
325  //----------------------------------------------------------------------------
326  /// @brief Get the fixed compression rate supported by the context for
327  /// the given format and usage.
328  ///
329  /// @param[in] compression_type The compression type.
330  /// @param[in] desc The format and usage of the image.
331  ///
332  /// @return The supported fixed compression rate.
333  ///
334  std::optional<vk::ImageCompressionFixedRateFlagBitsEXT> GetSupportedFRCRate(
335  CompressionType compression_type,
336  const FRCFormatDescriptor& desc) const;
337 
338  //----------------------------------------------------------------------------
339  /// @brief Update capabilities for the given set of workarounds.
340  void ApplyWorkarounds(const WorkaroundsVK& workarounds);
341 
342  private:
343  bool validations_enabled_ = false;
344  std::map<std::string, std::set<std::string>> exts_;
345  std::set<RequiredCommonDeviceExtensionVK> required_common_device_extensions_;
346  std::set<RequiredAndroidDeviceExtensionVK>
347  required_android_device_extensions_;
348  std::set<OptionalAndroidDeviceExtensionVK>
349  optional_android_device_extensions_;
350  std::set<OptionalDeviceExtensionVK> optional_device_extensions_;
351  mutable PixelFormat default_color_format_ = PixelFormat::kUnknown;
352  PixelFormat default_stencil_format_ = PixelFormat::kUnknown;
353  PixelFormat default_depth_stencil_format_ = PixelFormat::kUnknown;
354  vk::PhysicalDevice physical_device_;
355  vk::PhysicalDeviceProperties device_properties_;
356  size_t minimum_uniform_alignment_ = 256;
357  size_t minimum_storage_alignment_ = 256;
358  bool supports_compute_subgroups_ = false;
359  bool supports_device_transient_textures_ = false;
360  bool supports_texture_fixed_rate_compression_ = false;
361  ISize max_render_pass_attachment_size_ = ISize{0, 0};
362  uint32_t max_sampler_anisotropy_ = 1;
363  bool has_triangle_fans_ = true;
364  bool has_primitive_restart_ = true;
365  bool has_framebuffer_fetch_ = true;
366  bool supports_external_fence_and_semaphore_ = false;
367  bool supports_texture_compression_bc_ = false;
368  bool supports_texture_compression_etc2_ = false;
369  bool supports_texture_compression_astc_ = false;
370  bool supports_texture_compression_astc_hdr_ = false;
371  bool is_valid_ = false;
372 
373  // The embedder.h API is responsible for providing the instance and device
374  // extensions.
375  bool use_embedder_extensions_ = false;
376  std::vector<std::string> embedder_instance_extensions_;
377  std::vector<std::string> embedder_device_extensions_;
378 
379  bool HasExtension(const std::string& ext) const;
380 
381  bool HasLayer(const std::string& layer) const;
382 
383  CapabilitiesVK(const CapabilitiesVK&) = delete;
384 
385  CapabilitiesVK& operator=(const CapabilitiesVK&) = delete;
386 };
387 
388 } // namespace impeller
389 
390 #endif // FLUTTER_IMPELLER_RENDERER_BACKEND_VULKAN_CAPABILITIES_VK_H_
The Vulkan layers and extensions wrangler.
bool SupportsFramebufferRenderMipmap() const override
Whether a non-zero mip level of a texture can be attached as a render target. Rendering into a cube m...
bool SupportsTriangleFan() const override
Whether the primitive type TriangleFan is supported by the backend.
size_t GetMinimumUniformAlignment() const override
The minimum alignment of uniform value offsets in bytes.
bool SupportsDeviceTransientTextures() const override
Whether the context backend supports allocating StorageMode::kDeviceTransient (aka "memoryless") text...
std::optional< std::vector< std::string > > GetEnabledInstanceExtensions() const
bool AreValidationsEnabled() const
bool SetPhysicalDevice(const vk::PhysicalDevice &physical_device, const PhysicalDeviceFeatures &enabled_features)
ISize GetMaximumRenderPassAttachmentSize() const override
Return the maximum size of a render pass attachment.
bool SupportsSSBO() const override
Whether the context backend supports binding Shader Storage Buffer Objects (SSBOs) to pipelines.
bool SupportsFramebufferFetch() const override
Whether the context backend is able to support pipelines with shaders that read from the framebuffer ...
bool SupportsExternalSemaphoreExtensions() const
bool SupportsManuallyMippedTextures() const override
Whether a texture whose mip levels were uploaded by hand (rather than produced by BlitPass::GenerateM...
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={})
bool SupportsOffscreenMSAA() const override
Whether the context backend supports attaching offscreen MSAA color/stencil textures.
bool SupportsCompute() const override
Whether the context backend supports ComputePass.
bool HasExtension(RequiredCommonDeviceExtensionVK ext) 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.
void SetOffscreenFormat(PixelFormat pixel_format) const
PixelFormat GetDefaultStencilFormat() const override
Returns a supported PixelFormat for textures that store stencil information. May include a depth chan...
void ApplyWorkarounds(const WorkaroundsVK &workarounds)
Update capabilities for the given set of workarounds.
bool SupportsComputeSubgroups() const override
Whether the context backend supports configuring ComputePass command subgroups.
size_t GetMinimumStorageBufferAlignment() const override
The minimum alignment of storage buffer value offsets in bytes.
PixelFormat GetDefaultDepthStencilFormat() const override
Returns a supported PixelFormat for textures that store both a stencil and depth component....
bool SupportsTextureToTextureBlits() const override
Whether the context backend supports blitting from one texture region to another texture region (via ...
bool Supports32BitPrimitiveIndices() const override
Whether 32-bit values are supported in index buffers used to draw primitives.
std::optional< std::vector< std::string > > GetEnabledDeviceExtensions(const vk::PhysicalDevice &physical_device) const
bool SupportsReadFromResolve() const override
Whether the context backend supports binding the current RenderPass attachments. This is supported if...
bool SupportsDecalSamplerAddressMode() const override
Whether the context backend supports SamplerAddressMode::Decal.
bool SupportsPrimitiveRestart() const override
Whether primitive restart is supported.
std::optional< std::vector< std::string > > GetEnabledLayers() const
bool SupportsTextureFixedRateCompression() const
bool NeedsPartitionedHostBuffer() const override
Whether the host buffer should use separate device buffers for indexes from other data.
PixelFormat GetDefaultGlyphAtlasFormat() const override
Returns the default pixel format for the alpha bitmap glyph atlas.
PixelFormat GetDefaultColorFormat() const override
Returns a supported PixelFormat for textures that store 4-channel colors (red/green/blue/alpha).
const vk::PhysicalDeviceProperties & GetPhysicalDeviceProperties() const
bool SupportsExtendedRangeFormats() const override
Whether the XR formats are supported on this device.
uint32_t GetMaxSamplerAnisotropy() const override
The maximum anisotropy clamp supported by device samplers.
bool SupportsImplicitResolvingMSAA() const override
Whether the context backend supports multisampled rendering to the on-screen surface without requirin...
std::optional< PhysicalDeviceFeatures > GetEnabledDeviceFeatures(const vk::PhysicalDevice &physical_device) const
bool SupportsTextureCompression(CompressedTextureFamily family) const override
Whether the given family of block-compressed texture formats is supported by this device....
vk::StructureChain< vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR, vk::PhysicalDevice16BitStorageFeatures, vk::PhysicalDeviceImageCompressionControlFeaturesEXT, vk::PhysicalDeviceTextureCompressionASTCHDRFeatures > PhysicalDeviceFeatures
RequiredAndroidDeviceExtensionVK
A device extension available on all Android platforms. Without the presence of these extensions on An...
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
CompressedTextureFamily
The family of a block-compressed pixel format. GPUs support compressed formats on a per-family basis,...
Definition: formats.h:146
RequiredCommonDeviceExtensionVK
A device extension available on all platforms. Without the presence of these extensions,...
OptionalAndroidDeviceExtensionVK
A device extension available on some Android platforms.
CompressionType
Additional compression to apply to a texture. This value is ignored on platforms which do not support...
OptionalDeviceExtensionVK
A device extension enabled if available. Subsystems cannot assume availability and must check if thes...
A pixel format and usage that is sufficient to check if images of that format and usage are suitable ...
vk::ImageCreateFlags flags
FRCFormatDescriptor(const vk::ImageCreateInfo &image_info)
A non-exhaustive set of driver specific workarounds.