| Flutter Impeller |

capabilities_vk.cc
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 #include "impeller/renderer/backend/vulkan/capabilities_vk.h"
6
7 #include <algorithm>
8
9 #include "impeller/base/validation.h"
10 #include "impeller/core/formats.h"
11 #include "impeller/renderer/backend/vulkan/vk.h"
12 #include "vulkan/vulkan_core.h"
13
14 namespace impeller {
15
16 static constexpr const char* kInstanceLayer = "ImpellerInstance";
17
18 CapabilitiesVK::CapabilitiesVK(bool enable_validations) {
19 auto extensions = vk::enumerateInstanceExtensionProperties();
20 auto layers = vk::enumerateInstanceLayerProperties();
21
22 if (extensions.result != vk::Result::eSuccess ||
23 layers.result != vk::Result::eSuccess) {
24 return;
25 }
26
27 for (const auto& ext : extensions.value) {
28 exts_[kInstanceLayer].insert(ext.extensionName);
29 }
30
31 for (const auto& layer : layers.value) {
32 const std::string layer_name = layer.layerName;
33 auto layer_exts = vk::enumerateInstanceExtensionProperties(layer_name);
34 if (layer_exts.result != vk::Result::eSuccess) {
35 return;
36 }
37 for (const auto& layer_ext : layer_exts.value) {
38 exts_[layer_name].insert(layer_ext.extensionName);
39 }
40 }
41
42 validations_enabled_ =
43 enable_validations && HasLayer("VK_LAYER_KHRONOS_validation");
44 if (enable_validations && !validations_enabled_) {
45 FML_LOG(ERROR)
46 << "Requested Impeller context creation with validations but the "
47 "validation layers could not be found. Expect no Vulkan validation "
48 "checks!";
49 }
50 if (validations_enabled_) {
51 FML_LOG(INFO) << "Vulkan validations are enabled.";
52 }
53 is_valid_ = true;
54 }
55
56 CapabilitiesVK::~CapabilitiesVK() = default;
57
58 bool CapabilitiesVK::IsValid() const {
59 return is_valid_;
60 }
61
62 bool CapabilitiesVK::AreValidationsEnabled() const {
63 return validations_enabled_;
64 }
65
66 std::optional<std::vector<std::string>> CapabilitiesVK::GetEnabledLayers()
67 const {
68 std::vector<std::string> required;
69
70 if (validations_enabled_) {
71 // The presence of this layer is already checked in the ctor.
72 required.push_back("VK_LAYER_KHRONOS_validation");
73 }
74
75 return required;
76 }
77
78 std::optional<std::vector<std::string>>
79 CapabilitiesVK::GetEnabledInstanceExtensions() const {
80 std::vector<std::string> required;
81
82 if (!HasExtension("VK_KHR_surface")) {
83 // Swapchain support is required and this is a dependency of
84 // VK_KHR_swapchain.
85 VALIDATION_LOG << "Could not find the surface extension.";
86 return std::nullopt;
87 }
88 required.push_back("VK_KHR_surface");
89
90 auto has_wsi = false;
91 if (HasExtension("VK_MVK_macos_surface")) {
92 required.push_back("VK_MVK_macos_surface");
93 has_wsi = true;
94 }
95
96 if (HasExtension("VK_EXT_metal_surface")) {
97 required.push_back("VK_EXT_metal_surface");
98 has_wsi = true;
99 }
100
101 if (HasExtension("VK_KHR_portability_enumeration")) {
102 required.push_back("VK_KHR_portability_enumeration");
103 has_wsi = true;
104 }
105
106 if (HasExtension("VK_KHR_win32_surface")) {
107 required.push_back("VK_KHR_win32_surface");
108 has_wsi = true;
109 }
110
111 if (HasExtension("VK_KHR_android_surface")) {
112 required.push_back("VK_KHR_android_surface");
113 has_wsi = true;
114 }
115
116 if (HasExtension("VK_KHR_xcb_surface")) {
117 required.push_back("VK_KHR_xcb_surface");
118 has_wsi = true;
119 }
120
121 if (HasExtension("VK_KHR_xlib_surface")) {
122 required.push_back("VK_KHR_xlib_surface");
123 has_wsi = true;
124 }
125
126 if (HasExtension("VK_KHR_wayland_surface")) {
127 required.push_back("VK_KHR_wayland_surface");
128 has_wsi = true;
129 }
130
131 if (!has_wsi) {
132 // Don't really care which WSI extension there is as long there is at least
133 // one.
134 VALIDATION_LOG << "Could not find a WSI extension.";
135 return std::nullopt;
136 }
137
138 if (validations_enabled_) {
139 if (!HasExtension("VK_EXT_debug_utils")) {
140 VALIDATION_LOG << "Requested validations but could not find the "
141 "VK_EXT_debug_utils extension.";
142 return std::nullopt;
143 }
144 required.push_back("VK_EXT_debug_utils");
145
146 if (HasExtension("VK_EXT_validation_features")) {
147 // It's valid to not have `VK_EXT_validation_features` available. That's
148 // the case when using AGI as a frame debugger.
149 required.push_back("VK_EXT_validation_features");
150 }
151 }
152
153 return required;
154 }
155
156 static const char* GetDeviceExtensionName(OptionalDeviceExtensionVK ext) {
157 switch (ext) {
158 case OptionalDeviceExtensionVK::kEXTPipelineCreationFeedback:
159 return VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME;
160 case OptionalDeviceExtensionVK::kARMRasterizationOrderAttachmentAccess:
161 return VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME;
162 case OptionalDeviceExtensionVK::kEXTRasterizationOrderAttachmentAccess:
163 return VK_EXT_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME;
164 case OptionalDeviceExtensionVK::kLast:
165 return "Unknown";
166 }
167 return "Unknown";
168 }
169
170 static void IterateOptionalDeviceExtensions(
171 const std::function<void(OptionalDeviceExtensionVK)>& it) {
172 if (!it) {
173 return;
174 }
175 for (size_t i = 0;
176 i < static_cast<uint32_t>(OptionalDeviceExtensionVK::kLast); i++) {
177 it(static_cast<OptionalDeviceExtensionVK>(i));
178 }
179 }
180
181 static std::optional<std::set<std::string>> GetSupportedDeviceExtensions(
182 const vk::PhysicalDevice& physical_device) {
183 auto device_extensions = physical_device.enumerateDeviceExtensionProperties();
184 if (device_extensions.result != vk::Result::eSuccess) {
185 return std::nullopt;
186 }
187
188 std::set<std::string> exts;
189 for (const auto& device_extension : device_extensions.value) {
190 exts.insert(device_extension.extensionName);
191 };
192
193 return exts;
194 }
195
196 std::optional<std::vector<std::string>>
197 CapabilitiesVK::GetEnabledDeviceExtensions(
198 const vk::PhysicalDevice& physical_device) const {
199 auto exts = GetSupportedDeviceExtensions(physical_device);
200
201 if (!exts.has_value()) {
202 return std::nullopt;
203 }
204
205 std::vector<std::string> enabled;
206
207 if (exts->find("VK_KHR_swapchain") == exts->end()) {
208 VALIDATION_LOG << "Device does not support the swapchain extension.";
209 return std::nullopt;
210 }
211 enabled.push_back("VK_KHR_swapchain");
212
213 // Required for non-conformant implementations like MoltenVK.
214 if (exts->find("VK_KHR_portability_subset") != exts->end()) {
215 enabled.push_back("VK_KHR_portability_subset");
216 }
217
218 #ifdef FML_OS_ANDROID
219 if (exts->find("VK_ANDROID_external_memory_android_hardware_buffer") ==
220 exts->end()) {
221 VALIDATION_LOG
222 << "Device does not support "
223 "VK_ANDROID_external_memory_android_hardware_buffer extension.";
224 return std::nullopt;
225 }
226 enabled.push_back("VK_ANDROID_external_memory_android_hardware_buffer");
227 enabled.push_back("VK_EXT_queue_family_foreign");
228 #endif
229
230 // Enable all optional extensions if the device supports it.
231 IterateOptionalDeviceExtensions([&](auto ext) {
232 auto ext_name = GetDeviceExtensionName(ext);
233 if (exts->find(ext_name) != exts->end()) {
234 enabled.push_back(ext_name);
235 }
236 });
237
238 return enabled;
239 }
240
241 static bool HasSuitableColorFormat(const vk::PhysicalDevice& device,
242 vk::Format format) {
243 const auto props = device.getFormatProperties(format);
244 // This needs to be more comprehensive.
245 return !!(props.optimalTilingFeatures &
246 vk::FormatFeatureFlagBits::eColorAttachment);
247 }
248
249 static bool HasSuitableDepthStencilFormat(const vk::PhysicalDevice& device,
250 vk::Format format) {
251 const auto props = device.getFormatProperties(format);
252 return !!(props.optimalTilingFeatures &
253 vk::FormatFeatureFlagBits::eDepthStencilAttachment);
254 }
255
256 static bool PhysicalDeviceSupportsRequiredFormats(
257 const vk::PhysicalDevice& device) {
258 const auto has_color_format =
259 HasSuitableColorFormat(device, vk::Format::eB8G8R8A8Unorm);
260 const auto has_stencil_format =
261 HasSuitableDepthStencilFormat(device, vk::Format::eS8Uint) ||
262 HasSuitableDepthStencilFormat(device, vk::Format::eD32SfloatS8Uint) ||
263 HasSuitableDepthStencilFormat(device, vk::Format::eD24UnormS8Uint);
264 return has_color_format && has_stencil_format;
265 }
266
267 static bool HasRequiredProperties(const vk::PhysicalDevice& physical_device) {
268 auto properties = physical_device.getProperties();
269 if (!(properties.limits.framebufferColorSampleCounts &
270 (vk::SampleCountFlagBits::e1 | vk::SampleCountFlagBits::e4))) {
271 return false;
272 }
273 return true;
274 }
275
276 static bool HasRequiredQueues(const vk::PhysicalDevice& physical_device) {
277 auto queue_flags = vk::QueueFlags{};
278 for (const auto& queue : physical_device.getQueueFamilyProperties()) {
279 if (queue.queueCount == 0) {
280 continue;
281 }
282 queue_flags |= queue.queueFlags;
283 }
284 return static_cast<VkQueueFlags>(queue_flags &
285 (vk::QueueFlagBits::eGraphics |
286 vk::QueueFlagBits::eCompute |
287 vk::QueueFlagBits::eTransfer));
288 }
289
290 std::optional<vk::PhysicalDeviceFeatures>
291 CapabilitiesVK::GetEnabledDeviceFeatures(
292 const vk::PhysicalDevice& device) const {
293 if (!PhysicalDeviceSupportsRequiredFormats(device)) {
294 VALIDATION_LOG << "Device doesn't support the required formats.";
295 return std::nullopt;
296 }
297
298 if (!HasRequiredProperties(device)) {
299 VALIDATION_LOG << "Device doesn't support the required properties.";
300 return std::nullopt;
301 }
302
303 if (!HasRequiredQueues(device)) {
304 VALIDATION_LOG << "Device doesn't support the required queues.";
305 return std::nullopt;
306 }
307
308 if (!GetEnabledDeviceExtensions(device).has_value()) {
309 VALIDATION_LOG << "Device doesn't support the required queues.";
310 return std::nullopt;
311 }
312
313 const auto device_features = device.getFeatures();
314
315 vk::PhysicalDeviceFeatures required;
316
317 // We require this for enabling wireframes in the playground. But its not
318 // necessarily a big deal if we don't have this feature.
319 required.fillModeNonSolid = device_features.fillModeNonSolid;
320
321 return required;
322 }
323
324 bool CapabilitiesVK::HasLayer(const std::string& layer) const {
325 for (const auto& [found_layer, exts] : exts_) {
326 if (found_layer == layer) {
327 return true;
328 }
329 }
330 return false;
331 }
332
333 bool CapabilitiesVK::HasExtension(const std::string& ext) const {
334 for (const auto& [layer, exts] : exts_) {
335 if (exts.find(ext) != exts.end()) {
336 return true;
337 }
338 }
339 return false;
340 }
341
342 void CapabilitiesVK::SetOffscreenFormat(PixelFormat pixel_format) const {
343 default_color_format_ = pixel_format;
344 }
345
346 bool CapabilitiesVK::SetPhysicalDevice(const vk::PhysicalDevice& device) {
347 if (HasSuitableDepthStencilFormat(device, vk::Format::eD32SfloatS8Uint)) {
348 default_depth_stencil_format_ = PixelFormat::kD32FloatS8UInt;
349 } else if (HasSuitableDepthStencilFormat(device,
350 vk::Format::eD24UnormS8Uint)) {
351 default_depth_stencil_format_ = PixelFormat::kD24UnormS8Uint;
352 } else {
353 default_depth_stencil_format_ = PixelFormat::kUnknown;
354 }
355
356 if (HasSuitableDepthStencilFormat(device, vk::Format::eS8Uint)) {
357 default_stencil_format_ = PixelFormat::kS8UInt;
358 } else if (default_stencil_format_ != PixelFormat::kUnknown) {
359 default_stencil_format_ = default_depth_stencil_format_;
360 } else {
361 return false;
362 }
363
364 device_properties_ = device.getProperties();
365
366 auto physical_properties_2 =
367 device.getProperties2<vk::PhysicalDeviceProperties2,
368 vk::PhysicalDeviceSubgroupProperties>();
369
370 // Currently shaders only want access to arithmetic subgroup features.
371 // If that changes this needs to get updated, and so does Metal (which right
372 // now assumes it from compile time flags based on the MSL target version).
373
374 supports_compute_subgroups_ =
375 !!(physical_properties_2.get<vk::PhysicalDeviceSubgroupProperties>()
376 .supportedOperations &
377 vk::SubgroupFeatureFlagBits::eArithmetic);
378
379 {
380 // Query texture support.
381 // TODO(jonahwilliams):
382 // https://github.com/flutter/flutter/issues/129784
383 vk::PhysicalDeviceMemoryProperties memory_properties;
384 device.getMemoryProperties(&memory_properties);
385
386 for (auto i = 0u; i < memory_properties.memoryTypeCount; i++) {
387 if (memory_properties.memoryTypes[i].propertyFlags &
388 vk::MemoryPropertyFlagBits::eLazilyAllocated) {
389 supports_device_transient_textures_ = true;
390 }
391 }
392 }
393
394 // Determine the optional device extensions this physical device supports.
395 {
396 optional_device_extensions_.clear();
397 auto exts = GetSupportedDeviceExtensions(device);
398 if (!exts.has_value()) {
399 return false;
400 }
401 IterateOptionalDeviceExtensions([&](auto ext) {
402 auto ext_name = GetDeviceExtensionName(ext);
403 if (exts->find(ext_name) != exts->end()) {
404 optional_device_extensions_.insert(ext);
405 }
406 });
407 }
408
409 {
410 supports_framebuffer_fetch_ =
411 (optional_device_extensions_.find(
412 OptionalDeviceExtensionVK::
413 kARMRasterizationOrderAttachmentAccess) !=
414 optional_device_extensions_.end() ||
415 optional_device_extensions_.find(
416 OptionalDeviceExtensionVK::
417 kEXTRasterizationOrderAttachmentAccess) !=
418 optional_device_extensions_.end());
419 }
420
421 return true;
422 }
423
424 // |Capabilities|
425 bool CapabilitiesVK::SupportsOffscreenMSAA() const {
426 return true;
427 }
428
429 // |Capabilities|
430 bool CapabilitiesVK::SupportsImplicitResolvingMSAA() const {
431 return false;
432 }
433
434 // |Capabilities|
435 bool CapabilitiesVK::SupportsSSBO() const {
436 return true;
437 }
438
439 // |Capabilities|
440 bool CapabilitiesVK::SupportsBufferToTextureBlits() const {
441 return true;
442 }
443
444 // |Capabilities|
445 bool CapabilitiesVK::SupportsTextureToTextureBlits() const {
446 return true;
447 }
448
449 // |Capabilities|
450 bool CapabilitiesVK::SupportsFramebufferFetch() const {
451 return supports_framebuffer_fetch_;
452 }
453
454 // |Capabilities|
455 bool CapabilitiesVK::SupportsCompute() const {
456 // Vulkan 1.1 requires support for compute.
457 return true;
458 }
459
460 // |Capabilities|
461 bool CapabilitiesVK::SupportsComputeSubgroups() const {
462 // Set by |SetPhysicalDevice|.
463 return supports_compute_subgroups_;
464 }
465
466 // |Capabilities|
467 bool CapabilitiesVK::SupportsReadFromResolve() const {
468 return false;
469 }
470
471 bool CapabilitiesVK::SupportsDecalSamplerAddressMode() const {
472 return true;
473 }
474
475 // |Capabilities|
476 bool CapabilitiesVK::SupportsDeviceTransientTextures() const {
477 return supports_device_transient_textures_;
478 }
479
480 // |Capabilities|
481 PixelFormat CapabilitiesVK::GetDefaultColorFormat() const {
482 return default_color_format_;
483 }
484
485 // |Capabilities|
486 PixelFormat CapabilitiesVK::GetDefaultStencilFormat() const {
487 return default_stencil_format_;
488 }
489
490 // |Capabilities|
491 PixelFormat CapabilitiesVK::GetDefaultDepthStencilFormat() const {
492 return default_depth_stencil_format_;
493 }
494
495 const vk::PhysicalDeviceProperties&
496 CapabilitiesVK::GetPhysicalDeviceProperties() const {
497 return device_properties_;
498 }
499
500 bool CapabilitiesVK::HasOptionalDeviceExtension(
501 OptionalDeviceExtensionVK extension) const {
502 return optional_device_extensions_.find(extension) !=
503 optional_device_extensions_.end();
504 }
505
506 } // namespace impeller
impeller::OptionalDeviceExtensionVK
OptionalDeviceExtensionVK
Definition: capabilities_vk.h:22
impeller::HasRequiredProperties
static bool HasRequiredProperties(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:267
impeller::PixelFormat::kS8UInt
@ kS8UInt
impeller::CapabilitiesVK::SupportsDecalSamplerAddressMode
bool SupportsDecalSamplerAddressMode() const override
Whether the context backend supports SamplerAddressMode::Decal.
Definition: capabilities_vk.cc:471
impeller::CapabilitiesVK::SetOffscreenFormat
void SetOffscreenFormat(PixelFormat pixel_format) const
Definition: capabilities_vk.cc:342
impeller::CapabilitiesVK::GetEnabledInstanceExtensions
std::optional< std::vector< std::string > > GetEnabledInstanceExtensions() const
Definition: capabilities_vk.cc:79
impeller::kInstanceLayer
static constexpr const char * kInstanceLayer
Definition: capabilities_vk.cc:16
impeller::CapabilitiesVK::IsValid
bool IsValid() const
Definition: capabilities_vk.cc:58
impeller::CapabilitiesVK::SupportsOffscreenMSAA
bool SupportsOffscreenMSAA() const override
Whether the context backend supports attaching offscreen MSAA color/stencil textures.
Definition: capabilities_vk.cc:425
impeller::CapabilitiesVK::SupportsFramebufferFetch
bool SupportsFramebufferFetch() const override
Whether the context backend is able to support pipelines with shaders that read from the framebuffer ...
Definition: capabilities_vk.cc:450
impeller::OptionalDeviceExtensionVK::kLast
@ kLast
formats.h
impeller::HasSuitableDepthStencilFormat
static bool HasSuitableDepthStencilFormat(const vk::PhysicalDevice &device, vk::Format format)
Definition: capabilities_vk.cc:249
impeller::CapabilitiesVK::GetDefaultStencilFormat
PixelFormat GetDefaultStencilFormat() const override
Returns a supported PixelFormat for textures that store stencil information. May include a depth chan...
Definition: capabilities_vk.cc:486
impeller::CapabilitiesVK::GetEnabledLayers
std::optional< std::vector< std::string > > GetEnabledLayers() const
Definition: capabilities_vk.cc:66
impeller::OptionalDeviceExtensionVK::kEXTPipelineCreationFeedback
@ kEXTPipelineCreationFeedback
impeller::OptionalDeviceExtensionVK::kARMRasterizationOrderAttachmentAccess
@ kARMRasterizationOrderAttachmentAccess
impeller::CapabilitiesVK::SupportsTextureToTextureBlits
bool SupportsTextureToTextureBlits() const override
Whether the context backend supports blitting from one texture region to another texture region (via ...
Definition: capabilities_vk.cc:445
validation.h
impeller::HasRequiredQueues
static bool HasRequiredQueues(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:276
impeller::CapabilitiesVK::SupportsComputeSubgroups
bool SupportsComputeSubgroups() const override
Whether the context backend supports configuring ComputePass command subgroups.
Definition: capabilities_vk.cc:461
impeller::IterateOptionalDeviceExtensions
static void IterateOptionalDeviceExtensions(const std::function< void(OptionalDeviceExtensionVK)> &it)
Definition: capabilities_vk.cc:170
impeller::CapabilitiesVK::HasOptionalDeviceExtension
bool HasOptionalDeviceExtension(OptionalDeviceExtensionVK extension) const
Definition: capabilities_vk.cc:500
impeller::CapabilitiesVK::SupportsReadFromResolve
bool SupportsReadFromResolve() const override
Whether the context backend supports binding the current RenderPass attachments. This is supported if...
Definition: capabilities_vk.cc:467
vk.h
impeller::PixelFormat::kD32FloatS8UInt
@ kD32FloatS8UInt
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:94
impeller::PhysicalDeviceSupportsRequiredFormats
static bool PhysicalDeviceSupportsRequiredFormats(const vk::PhysicalDevice &device)
Definition: capabilities_vk.cc:256
impeller::CapabilitiesVK::SetPhysicalDevice
bool SetPhysicalDevice(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:346
capabilities_vk.h
impeller::CapabilitiesVK::~CapabilitiesVK
~CapabilitiesVK()
impeller::CapabilitiesVK::GetDefaultColorFormat
PixelFormat GetDefaultColorFormat() const override
Returns a supported PixelFormat for textures that store 4-channel colors (red/green/blue/alpha).
Definition: capabilities_vk.cc:481
impeller::OptionalDeviceExtensionVK::kEXTRasterizationOrderAttachmentAccess
@ kEXTRasterizationOrderAttachmentAccess
impeller::GetSupportedDeviceExtensions
static std::optional< std::set< std::string > > GetSupportedDeviceExtensions(const vk::PhysicalDevice &physical_device)
Definition: capabilities_vk.cc:181
impeller::CapabilitiesVK::GetEnabledDeviceFeatures
std::optional< vk::PhysicalDeviceFeatures > GetEnabledDeviceFeatures(const vk::PhysicalDevice &physical_device) const
Definition: capabilities_vk.cc:291
impeller::CapabilitiesVK::CapabilitiesVK
CapabilitiesVK(bool enable_validations)
Definition: capabilities_vk.cc:18
impeller::PixelFormat::kD24UnormS8Uint
@ kD24UnormS8Uint
impeller::CapabilitiesVK::GetDefaultDepthStencilFormat
PixelFormat GetDefaultDepthStencilFormat() const override
Returns a supported PixelFormat for textures that store both a stencil and depth component....
Definition: capabilities_vk.cc:491
impeller::GetDeviceExtensionName
static const char * GetDeviceExtensionName(OptionalDeviceExtensionVK ext)
Definition: capabilities_vk.cc:156
impeller::CapabilitiesVK::SupportsBufferToTextureBlits
bool SupportsBufferToTextureBlits() const override
Whether the context backend supports blitting from a given DeviceBuffer view to a texture region (via...
Definition: capabilities_vk.cc:440
impeller::CapabilitiesVK::SupportsCompute
bool SupportsCompute() const override
Whether the context backend supports ComputePass.
Definition: capabilities_vk.cc:455
impeller::PixelFormat::kUnknown
@ kUnknown
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:67
impeller::HasSuitableColorFormat
static bool HasSuitableColorFormat(const vk::PhysicalDevice &device, vk::Format format)
Definition: capabilities_vk.cc:241
impeller::CapabilitiesVK::SupportsDeviceTransientTextures
bool SupportsDeviceTransientTextures() const override
Whether the context backend supports allocating StorageMode::kDeviceTransient (aka "memoryless") text...
Definition: capabilities_vk.cc:476
impeller::CapabilitiesVK::GetPhysicalDeviceProperties
const vk::PhysicalDeviceProperties & GetPhysicalDeviceProperties() const
Definition: capabilities_vk.cc:496
impeller::CapabilitiesVK::SupportsSSBO
bool SupportsSSBO() const override
Whether the context backend supports binding Shader Storage Buffer Objects (SSBOs) to pipelines.
Definition: capabilities_vk.cc:435
impeller::CapabilitiesVK::AreValidationsEnabled
bool AreValidationsEnabled() const
Definition: capabilities_vk.cc:62
impeller::CapabilitiesVK::GetEnabledDeviceExtensions
std::optional< std::vector< std::string > > GetEnabledDeviceExtensions(const vk::PhysicalDevice &physical_device) const
Definition: capabilities_vk.cc:197
impeller::CapabilitiesVK::SupportsImplicitResolvingMSAA
bool SupportsImplicitResolvingMSAA() const override
Whether the context backend supports multisampled rendering to the on-screen surface without requirin...
Definition: capabilities_vk.cc:430
impeller
Definition: aiks_context.cc:10