|
|
|
@ -20,18 +20,12 @@ |
|
|
|
namespace Vulkan { |
|
|
|
namespace { |
|
|
|
|
|
|
|
[[nodiscard]] bool AreExtensionsSupported(const vk::InstanceDispatch& dld, |
|
|
|
std::span<const char* const> extensions) { |
|
|
|
const std::optional properties = vk::EnumerateInstanceExtensionProperties(dld); |
|
|
|
if (!properties) { |
|
|
|
LOG_ERROR(Render_Vulkan, "Failed to query extension properties"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
[[nodiscard]] bool AreExtensionsSupported(const vk::InstanceDispatch& dld, std::vector<VkExtensionProperties> const& properties, std::span<const char* const> extensions) { |
|
|
|
for (const char* extension : extensions) { |
|
|
|
const auto it = std::ranges::find_if(*properties, [extension](const auto& prop) { |
|
|
|
const auto it = std::ranges::find_if(properties, [extension](const auto& prop) { |
|
|
|
return std::strcmp(extension, prop.extensionName) == 0; |
|
|
|
}); |
|
|
|
if (it == properties->end()) { |
|
|
|
if (it == properties.end()) { |
|
|
|
LOG_ERROR(Render_Vulkan, "Required instance extension {} is not available", extension); |
|
|
|
return false; |
|
|
|
} |
|
|
|
@ -78,14 +72,16 @@ namespace { |
|
|
|
if (window_type != Core::Frontend::WindowSystemType::Headless) { |
|
|
|
extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); |
|
|
|
} |
|
|
|
if (auto const properties = vk::EnumerateInstanceExtensionProperties(dld); properties) { |
|
|
|
#ifdef __APPLE__
|
|
|
|
if (AreExtensionsSupported(dld, std::array{VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME})) { |
|
|
|
extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); |
|
|
|
} |
|
|
|
if (AreExtensionsSupported(dld, *properties, std::array{VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME})) |
|
|
|
extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); |
|
|
|
#endif
|
|
|
|
if (enable_validation && |
|
|
|
AreExtensionsSupported(dld, std::array{VK_EXT_DEBUG_UTILS_EXTENSION_NAME})) { |
|
|
|
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); |
|
|
|
if (enable_validation && AreExtensionsSupported(dld, *properties, std::array{VK_EXT_DEBUG_UTILS_EXTENSION_NAME})) |
|
|
|
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); |
|
|
|
// VK_EXT_surface_maintenance1 is required for VK_EXT_swapchain_maintenance1
|
|
|
|
if (window_type != Core::Frontend::WindowSystemType::Headless && AreExtensionsSupported(dld, *properties, std::array{VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME})) |
|
|
|
extensions.push_back(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME); |
|
|
|
} |
|
|
|
return extensions; |
|
|
|
} |
|
|
|
@ -133,11 +129,10 @@ vk::Instance CreateInstance(const Common::DynamicLibrary& library, vk::InstanceD |
|
|
|
LOG_ERROR(Render_Vulkan, "Failed to load Vulkan function pointers"); |
|
|
|
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); |
|
|
|
} |
|
|
|
const std::vector<const char*> extensions = |
|
|
|
RequiredExtensions(dld, window_type, enable_validation); |
|
|
|
if (!AreExtensionsSupported(dld, extensions)) { |
|
|
|
std::vector<const char*> const extensions = RequiredExtensions(dld, window_type, enable_validation); |
|
|
|
auto const properties = vk::EnumerateInstanceExtensionProperties(dld); |
|
|
|
if (!properties || !AreExtensionsSupported(dld, *properties, extensions)) |
|
|
|
throw vk::Exception(VK_ERROR_EXTENSION_NOT_PRESENT); |
|
|
|
} |
|
|
|
std::vector<const char*> layers = Layers(enable_validation); |
|
|
|
RemoveUnavailableLayers(dld, layers); |
|
|
|
|
|
|
|
|