blob: d02602104e328be6fb2fef0f3e2e642e2037b385 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/vulkan/vulkan_utilities.h"
#include "flutter/fml/build_config.h"
#include <algorithm>
#include <unordered_set>
namespace vulkan {
bool IsDebuggingEnabled() {
#ifndef NDEBUG
return true;
#elif defined(VULKAN_VALIDATION_LAYERS_ENABLED)
return true;
#else
return false;
#endif
}
// Whether to show Vulkan validation layer info messages in addition
// to the error messages.
bool ValidationLayerInfoMessagesEnabled() {
return false;
}
bool ValidationErrorsFatal() {
#if OS_FUCHSIA
return false;
#endif
return true;
}
static std::vector<std::string> InstanceOrDeviceLayersToEnable(
const VulkanProcTable& vk,
VkPhysicalDevice physical_device) {
if (!IsDebuggingEnabled()) {
return {};
}
// NOTE: The loader is sensitive to the ordering here. Please do not rearrange
// this list.
#if OS_FUCHSIA
// Fuchsia uses the updated Vulkan loader and validation layers which no
// longer includes the image validation layer.
const std::vector<std::string> candidates = {
"VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation",
"VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation",
"VK_LAYER_LUNARG_device_limits", "VK_LAYER_LUNARG_swapchain",
"VK_LAYER_GOOGLE_unique_objects"};
#else
const std::vector<std::string> candidates = {
"VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation",
"VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation",
"VK_LAYER_LUNARG_device_limits", "VK_LAYER_LUNARG_image",
"VK_LAYER_LUNARG_swapchain", "VK_LAYER_GOOGLE_unique_objects"};
#endif
uint32_t count = 0;
if (physical_device == VK_NULL_HANDLE) {
if (VK_CALL_LOG_ERROR(vk.EnumerateInstanceLayerProperties(
&count, nullptr)) != VK_SUCCESS) {
return {};
}
} else {
if (VK_CALL_LOG_ERROR(vk.EnumerateDeviceLayerProperties(
physical_device, &count, nullptr)) != VK_SUCCESS) {
return {};
}
}
std::vector<VkLayerProperties> properties;
properties.resize(count);
if (physical_device == VK_NULL_HANDLE) {
if (VK_CALL_LOG_ERROR(vk.EnumerateInstanceLayerProperties(
&count, properties.data())) != VK_SUCCESS) {
return {};
}
} else {
if (VK_CALL_LOG_ERROR(vk.EnumerateDeviceLayerProperties(
physical_device, &count, properties.data())) != VK_SUCCESS) {
return {};
}
}
std::unordered_set<std::string> available_extensions;
for (size_t i = 0; i < count; i++) {
available_extensions.emplace(properties[i].layerName);
}
std::vector<std::string> available_candidates;
for (const auto& candidate : candidates) {
auto found = available_extensions.find(candidate);
if (found != available_extensions.end()) {
available_candidates.emplace_back(candidate);
}
}
return available_candidates;
}
std::vector<std::string> InstanceLayersToEnable(const VulkanProcTable& vk) {
return InstanceOrDeviceLayersToEnable(vk, VK_NULL_HANDLE);
}
std::vector<std::string> DeviceLayersToEnable(
const VulkanProcTable& vk,
const VulkanHandle<VkPhysicalDevice>& physical_device) {
if (!physical_device) {
return {};
}
return InstanceOrDeviceLayersToEnable(vk, physical_device);
}
} // namespace vulkan