18 bool fatal_missing_validations) {
19 auto extensions = vk::enumerateInstanceExtensionProperties();
20 auto layers = vk::enumerateInstanceLayerProperties();
22 if (
extensions.result != vk::Result::eSuccess ||
23 layers.result != vk::Result::eSuccess) {
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) {
37 for (
const auto& layer_ext : layer_exts.value) {
38 exts_[layer_name].insert(layer_ext.extensionName);
42 validations_enabled_ =
43 enable_validations && HasLayer(
"VK_LAYER_KHRONOS_validation");
44 if (enable_validations && !validations_enabled_) {
46 <<
"Requested Impeller context creation with validations but the "
47 "validation layers could not be found. Expect no Vulkan validation "
49 if (fatal_missing_validations) {
53 if (validations_enabled_) {
54 FML_LOG(INFO) <<
"Vulkan validations are enabled.";
66 return validations_enabled_;
71 std::vector<std::string> required;
73 if (validations_enabled_) {
75 required.push_back(
"VK_LAYER_KHRONOS_validation");
81std::optional<std::vector<std::string>>
83 std::vector<std::string> required;
91 required.push_back(
"VK_KHR_surface");
95 required.push_back(
"VK_MVK_macos_surface");
100 required.push_back(
"VK_EXT_metal_surface");
105 required.push_back(
"VK_KHR_portability_enumeration");
110 required.push_back(
"VK_KHR_win32_surface");
115 required.push_back(
"VK_KHR_android_surface");
120 required.push_back(
"VK_KHR_xcb_surface");
125 required.push_back(
"VK_KHR_xlib_surface");
130 required.push_back(
"VK_KHR_wayland_surface");
141 if (validations_enabled_) {
144 "VK_EXT_debug_utils extension.";
147 required.push_back(
"VK_EXT_debug_utils");
152 required.push_back(
"VK_EXT_validation_features");
173 return "VK_ANDROID_external_memory_android_hardware_buffer";
201 return "VK_KHR_portability_subset";
213 for (
size_t i = 0; i < static_cast<uint32_t>(T::kLast);
i++) {
214 if (!it(
static_cast<T>(
i))) {
223 auto device_extensions =
physical_device.enumerateDeviceExtensionProperties();
224 if (device_extensions.result != vk::Result::eSuccess) {
228 std::set<std::string> exts;
229 for (
const auto& device_extension : device_extensions.value) {
230 exts.insert(device_extension.extensionName);
236std::optional<std::vector<std::string>>
241 if (!exts.has_value()) {
245 std::vector<std::string> enabled;
249 if (exts->find(
name) == exts->end()) {
253 enabled.push_back(
name);
260 if (exts->find(
name) == exts->end()) {
261 VALIDATION_LOG <<
"Device does not support required Android extension: "
265 enabled.push_back(
name);
272 if (exts->find(
name) != exts->end()) {
273 enabled.push_back(
name);
278 const auto iterate_extensions =
279 IterateExtensions<RequiredCommonDeviceExtensionVK>(
280 for_each_common_extension) &&
281 IterateExtensions<RequiredAndroidDeviceExtensionVK>(
282 for_each_android_extension) &&
283 IterateExtensions<OptionalDeviceExtensionVK>(for_each_optional_extension);
285 if (!iterate_extensions) {
286 VALIDATION_LOG <<
"Device not suitable since required extensions are not "
298 return !!(props.optimalTilingFeatures &
299 vk::FormatFeatureFlagBits::eColorAttachment);
305 return !!(props.optimalTilingFeatures &
306 vk::FormatFeatureFlagBits::eDepthStencilAttachment);
310 const vk::PhysicalDevice&
device) {
311 const auto has_color_format =
313 const auto has_stencil_format =
316 return has_color_format && has_stencil_format;
321 if (!(properties.limits.framebufferColorSampleCounts &
329 auto queue_flags = vk::QueueFlags{};
331 if (
queue.queueCount == 0) {
334 queue_flags |=
queue.queueFlags;
337 (vk::QueueFlagBits::eGraphics |
338 vk::QueueFlagBits::eCompute |
339 vk::QueueFlagBits::eTransfer));
342template <
class ExtensionEnum>
346 return std::find(list.begin(), list.end(),
name) != list.end();
349std::optional<CapabilitiesVK::PhysicalDeviceFeatures>
351 const vk::PhysicalDevice&
device)
const {
358 VALIDATION_LOG <<
"Device doesn't support the required properties.";
368 if (!enabled_extensions.has_value()) {
374 device.getFeatures2(&supported_chain.get());
380 auto& required = required_chain.get().features;
381 const auto& supported = supported_chain.get().features;
385 required.fillModeNonSolid = supported.fillModeNonSolid;
389 enabled_extensions.value(),
393 .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
394 const auto& supported =
396 .get<vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR>();
398 required.samplerYcbcrConversion = supported.samplerYcbcrConversion;
404 required_chain.get<vk::PhysicalDevice16BitStorageFeatures>();
405 const auto& supported =
406 supported_chain.get<vk::PhysicalDevice16BitStorageFeatures>();
408 required.uniformAndStorageBuffer16BitAccess =
409 supported.uniformAndStorageBuffer16BitAccess;
412 return required_chain;
415bool CapabilitiesVK::HasLayer(
const std::string& layer)
const {
416 for (
const auto& [found_layer, exts] : exts_) {
417 if (found_layer == layer) {
425 for (
const auto& [layer, exts] : exts_) {
426 if (exts.find(
ext) != exts.end()) {
434 default_color_format_ = pixel_format;
447 vk::Format::eD24UnormS8Uint)) {
456 default_stencil_format_ = default_depth_stencil_format_;
459 device_properties_ =
device.getProperties();
461 auto physical_properties_2 =
462 device.getProperties2<vk::PhysicalDeviceProperties2,
463 vk::PhysicalDeviceSubgroupProperties>();
469 supports_compute_subgroups_ =
470 !!(physical_properties_2.get<vk::PhysicalDeviceSubgroupProperties>()
471 .supportedOperations &
472 vk::SubgroupFeatureFlagBits::eArithmetic);
478 vk::PhysicalDeviceMemoryProperties memory_properties;
479 device.getMemoryProperties(&memory_properties);
481 for (
auto i = 0u;
i < memory_properties.memoryTypeCount;
i++) {
482 if (memory_properties.memoryTypes[
i].propertyFlags &
483 vk::MemoryPropertyFlagBits::eLazilyAllocated) {
484 supports_device_transient_textures_ =
true;
491 required_common_device_extensions_.clear();
492 required_android_device_extensions_.clear();
493 optional_device_extensions_.clear();
495 if (!exts.has_value()) {
498 IterateExtensions<RequiredCommonDeviceExtensionVK>([&](
auto ext) ->
bool {
500 if (exts->find(ext_name) != exts->end()) {
501 required_common_device_extensions_.insert(
ext);
505 IterateExtensions<RequiredAndroidDeviceExtensionVK>([&](
auto ext) ->
bool {
507 if (exts->find(ext_name) != exts->end()) {
508 required_android_device_extensions_.insert(
ext);
512 IterateExtensions<OptionalDeviceExtensionVK>([&](
auto ext) ->
bool {
514 if (exts->find(ext_name) != exts->end()) {
515 optional_device_extensions_.insert(
ext);
558 return supports_compute_subgroups_;
572 return supports_device_transient_textures_;
577 return default_color_format_;
582 return default_stencil_format_;
587 return default_depth_stencil_format_;
590const vk::PhysicalDeviceProperties&
592 return device_properties_;
600 return required_common_device_extensions_.find(
ext) !=
601 required_common_device_extensions_.end();
605 return required_android_device_extensions_.find(
ext) !=
606 required_android_device_extensions_.end();
610 return optional_device_extensions_.find(
ext) !=
611 optional_device_extensions_.end();
int find(T *array, int N, T item)
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 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 ...
CapabilitiesVK(bool enable_validations, bool fatal_missing_validations=false)
vk::StructureChain< vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceSamplerYcbcrConversionFeaturesKHR, vk::PhysicalDevice16BitStorageFeatures > PhysicalDeviceFeatures
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
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...
bool SetPhysicalDevice(const vk::PhysicalDevice &physical_device)
bool SupportsComputeSubgroups() const override
Whether the context backend supports configuring ComputePass command subgroups.
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 ...
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.
std::optional< std::vector< std::string > > GetEnabledLayers() const
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 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
VkPhysicalDevice physical_device
uint32_t uint32_t * format
#define FML_LOG(severity)
#define FML_UNREACHABLE()
Dart_NativeFunction function
DEF_SWITCHES_START aot vmservice shared library name
static bool IterateExtensions(const std::function< bool(T)> &it)
static const char * GetExtensionName(RequiredCommonDeviceExtensionVK ext)
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 HasSuitableColorFormat(const vk::PhysicalDevice &device, vk::Format format)
RequiredAndroidDeviceExtensionVK
A device extension available on all Android platforms. Without the presence of these extensions on An...
@ kKHRSamplerYcbcrConversion
@ kKHRDedicatedAllocation
@ kKHRExternalSemaphoreFd
@ kANDROIDExternalMemoryAndroidHardwareBuffer
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
static std::optional< std::set< std::string > > GetSupportedDeviceExtensions(const vk::PhysicalDevice &physical_device)
static bool HasSuitableDepthStencilFormat(const vk::PhysicalDevice &device, vk::Format format)
RequiredCommonDeviceExtensionVK
A device extension available on all platforms. Without the presence of these extensions,...
static constexpr const char * kInstanceLayer
OptionalDeviceExtensionVK
A device extension enabled if available. Subsystems cannot assume availability and must check if thes...
@ kVKKHRPortabilitySubset
@ kEXTPipelineCreationFeedback
static bool HasRequiredQueues(const vk::PhysicalDevice &physical_device)
def Format(template, **parameters)
#define VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME
#define VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME
#define VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME
#define VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME
#define VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME
#define VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME
#define VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME
#define VK_KHR_SWAPCHAIN_EXTENSION_NAME
#define VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME
#define VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME