renderer_vulkan: Isolate surface creation to vk_platform.cpp
* Also cleanup the init code somewhat
This commit is contained in:
@ -14,7 +14,7 @@ namespace Frontend {
|
||||
|
||||
/// Information for the Graphics Backends signifying what type of screen pointer is in
|
||||
/// WindowInformation
|
||||
enum class WindowSystemType {
|
||||
enum class WindowSystemType : u8 {
|
||||
Headless,
|
||||
Windows,
|
||||
X11,
|
||||
|
@ -93,6 +93,7 @@ add_library(video_core STATIC
|
||||
renderer_vulkan/vk_instance.h
|
||||
renderer_vulkan/vk_pipeline_cache.cpp
|
||||
renderer_vulkan/vk_pipeline_cache.h
|
||||
renderer_vulkan/vk_platform.cpp
|
||||
renderer_vulkan/vk_platform.h
|
||||
renderer_vulkan/vk_renderpass_cache.cpp
|
||||
renderer_vulkan/vk_renderpass_cache.h
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
||||
#include <span>
|
||||
#include <array>
|
||||
#include "common/assert.h"
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "video_core/renderer_vulkan/vk_platform.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
|
||||
@ -45,9 +45,7 @@ Instance::Instance(Frontend::EmuWindow& window) {
|
||||
.ppEnabledExtensionNames = extensions.data()
|
||||
};
|
||||
|
||||
// Create VkInstance
|
||||
instance = vk::createInstance(instance_info);
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(instance);
|
||||
surface = CreateSurface(instance, window);
|
||||
|
||||
// TODO: GPU select dialog
|
||||
@ -55,8 +53,7 @@ Instance::Instance(Frontend::EmuWindow& window) {
|
||||
physical_device = physical_devices[0];
|
||||
device_properties = physical_device.getProperties();
|
||||
|
||||
// Create logical device
|
||||
CreateDevice(false);
|
||||
CreateDevice();
|
||||
}
|
||||
|
||||
Instance::~Instance() {
|
||||
@ -114,45 +111,16 @@ vk::Format Instance::GetFormatAlternative(vk::Format format) const {
|
||||
}
|
||||
}
|
||||
|
||||
bool Instance::CreateDevice(bool validation_enabled) {
|
||||
// Determine required extensions and features
|
||||
bool Instance::CreateDevice() {
|
||||
auto feature_chain = physical_device.getFeatures2<vk::PhysicalDeviceFeatures2,
|
||||
vk::PhysicalDeviceDynamicRenderingFeaturesKHR,
|
||||
vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT,
|
||||
vk::PhysicalDeviceExtendedDynamicState2FeaturesEXT>();
|
||||
vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
|
||||
|
||||
// Not having geometry shaders or wide lines will cause issues with rendering.
|
||||
// Not having geometry shaders will cause issues with accelerated rendering.
|
||||
const vk::PhysicalDeviceFeatures available = feature_chain.get().features;
|
||||
if (!available.geometryShader && !available.wideLines) {
|
||||
if (!available.geometryShader) {
|
||||
LOG_WARNING(Render_Vulkan, "Geometry shaders not availabe! Accelerated rendering not possible!");
|
||||
}
|
||||
|
||||
// Enable some common features other emulators like Dolphin use
|
||||
const vk::PhysicalDeviceFeatures2 features = {
|
||||
.features = {
|
||||
.robustBufferAccess = available.robustBufferAccess,
|
||||
.geometryShader = available.geometryShader,
|
||||
.sampleRateShading = available.sampleRateShading,
|
||||
.dualSrcBlend = available.dualSrcBlend,
|
||||
.logicOp = available.logicOp,
|
||||
.depthClamp = available.depthClamp,
|
||||
.largePoints = available.largePoints,
|
||||
.samplerAnisotropy = available.samplerAnisotropy,
|
||||
.occlusionQueryPrecise = available.occlusionQueryPrecise,
|
||||
.fragmentStoresAndAtomics = available.fragmentStoresAndAtomics,
|
||||
.shaderStorageImageMultisample = available.shaderStorageImageMultisample,
|
||||
.shaderClipDistance = available.shaderClipDistance
|
||||
}
|
||||
};
|
||||
|
||||
// Enable newer Vulkan features
|
||||
auto enabled_features = vk::StructureChain{
|
||||
features,
|
||||
//feature_chain.get<vk::PhysicalDeviceDynamicRenderingFeaturesKHR>(),
|
||||
//feature_chain.get<vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>(),
|
||||
//feature_chain.get<vk::PhysicalDeviceExtendedDynamicState2FeaturesEXT>()
|
||||
};
|
||||
|
||||
auto extension_list = physical_device.enumerateDeviceExtensionProperties();
|
||||
if (extension_list.empty()) {
|
||||
LOG_CRITICAL(Render_Vulkan, "No extensions supported by device.");
|
||||
@ -163,7 +131,7 @@ bool Instance::CreateDevice(bool validation_enabled) {
|
||||
std::array<const char*, 6> enabled_extensions;
|
||||
u32 enabled_extension_count = 0;
|
||||
|
||||
auto AddExtension = [&](std::string_view name, bool required) -> bool {
|
||||
auto AddExtension = [&](std::string_view name) -> bool {
|
||||
auto result = std::find_if(extension_list.begin(), extension_list.end(), [&](const auto& prop) {
|
||||
return name.compare(prop.extensionName.data());
|
||||
});
|
||||
@ -174,20 +142,13 @@ bool Instance::CreateDevice(bool validation_enabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (required) {
|
||||
LOG_ERROR(Render_Vulkan, "Unable to find required extension {}.", name);
|
||||
}
|
||||
|
||||
LOG_WARNING(Render_Vulkan, "Extension {} unavailable.", name);
|
||||
return false;
|
||||
};
|
||||
|
||||
// Add required extensions
|
||||
AddExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME, true);
|
||||
|
||||
// Check for optional features
|
||||
//dynamic_rendering = AddExtension(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, false);
|
||||
//extended_dynamic_state = AddExtension(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false);
|
||||
//push_descriptors = AddExtension(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, false);
|
||||
extended_dynamic_state = AddExtension(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
|
||||
push_descriptors = AddExtension(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
|
||||
AddExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
||||
|
||||
// Search queue families for graphics and present queues
|
||||
auto family_properties = physical_device.getQueueFamilyProperties();
|
||||
@ -236,39 +197,50 @@ bool Instance::CreateDevice(bool validation_enabled) {
|
||||
}
|
||||
};
|
||||
|
||||
vk::DeviceCreateInfo device_info = {
|
||||
.pNext = &features, // TODO: Change this
|
||||
.queueCreateInfoCount = 1,
|
||||
const u32 queue_count = graphics_queue_family_index != present_queue_family_index ? 2u : 1u;
|
||||
const vk::StructureChain device_chain = {
|
||||
vk::DeviceCreateInfo{
|
||||
.queueCreateInfoCount = queue_count,
|
||||
.pQueueCreateInfos = queue_infos.data(),
|
||||
.enabledExtensionCount = enabled_extension_count,
|
||||
.ppEnabledExtensionNames = enabled_extensions.data(),
|
||||
},
|
||||
vk::PhysicalDeviceFeatures2{
|
||||
.features = {
|
||||
.robustBufferAccess = available.robustBufferAccess,
|
||||
.geometryShader = available.geometryShader,
|
||||
.dualSrcBlend = available.dualSrcBlend,
|
||||
.logicOp = available.logicOp,
|
||||
.depthClamp = available.depthClamp,
|
||||
.largePoints = available.largePoints,
|
||||
.samplerAnisotropy = available.samplerAnisotropy,
|
||||
.fragmentStoresAndAtomics = available.fragmentStoresAndAtomics,
|
||||
.shaderStorageImageMultisample = available.shaderStorageImageMultisample,
|
||||
.shaderClipDistance = available.shaderClipDistance
|
||||
}
|
||||
},
|
||||
feature_chain.get<vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>(),
|
||||
};
|
||||
|
||||
if (graphics_queue_family_index != present_queue_family_index) {
|
||||
device_info.queueCreateInfoCount = 2;
|
||||
}
|
||||
|
||||
// Create logical device
|
||||
device = physical_device.createDevice(device_info);
|
||||
device = physical_device.createDevice(device_chain.get());
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(device);
|
||||
|
||||
// Grab the graphics and present queues.
|
||||
graphics_queue = device.getQueue(graphics_queue_family_index, 0);
|
||||
present_queue = device.getQueue(present_queue_family_index, 0);
|
||||
|
||||
// Create the VMA allocator
|
||||
CreateAllocator();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Instance::CreateAllocator() {
|
||||
VmaVulkanFunctions functions = {
|
||||
const VmaVulkanFunctions functions = {
|
||||
.vkGetInstanceProcAddr = VULKAN_HPP_DEFAULT_DISPATCHER.vkGetInstanceProcAddr,
|
||||
.vkGetDeviceProcAddr = VULKAN_HPP_DEFAULT_DISPATCHER.vkGetDeviceProcAddr
|
||||
};
|
||||
|
||||
VmaAllocatorCreateInfo allocator_info = {
|
||||
const VmaAllocatorCreateInfo allocator_info = {
|
||||
.physicalDevice = physical_device,
|
||||
.device = device,
|
||||
.pVulkanFunctions = &functions,
|
||||
@ -276,7 +248,7 @@ void Instance::CreateAllocator() {
|
||||
.vulkanApiVersion = VK_API_VERSION_1_1
|
||||
};
|
||||
|
||||
if (auto result = vmaCreateAllocator(&allocator_info, &allocator); result != VK_SUCCESS) {
|
||||
if (VkResult result = vmaCreateAllocator(&allocator_info, &allocator); result != VK_SUCCESS) {
|
||||
LOG_CRITICAL(Render_Vulkan, "Failed to initialize VMA with error {}", result);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -68,10 +68,6 @@ public:
|
||||
}
|
||||
|
||||
/// Feature support
|
||||
bool IsDynamicRenderingSupported() const {
|
||||
return dynamic_rendering;
|
||||
}
|
||||
|
||||
bool IsExtendedDynamicStateSupported() const {
|
||||
// TODO: Enable this when the pipeline builder is confirmed functional
|
||||
return false;
|
||||
@ -102,27 +98,25 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
bool CreateDevice(bool validation_enabled);
|
||||
/// Creates the logical device opportunistically enabling extensions
|
||||
bool CreateDevice();
|
||||
|
||||
/// Creates the VMA allocator handle
|
||||
void CreateAllocator();
|
||||
|
||||
private:
|
||||
// Queue family indexes
|
||||
u32 present_queue_family_index = 0;
|
||||
u32 graphics_queue_family_index = 0;
|
||||
vk::Queue present_queue, graphics_queue;
|
||||
|
||||
// Core vulkan objects
|
||||
vk::Device device;
|
||||
vk::PhysicalDevice physical_device;
|
||||
vk::Instance instance;
|
||||
vk::SurfaceKHR surface;
|
||||
vk::PhysicalDeviceProperties device_properties;
|
||||
VmaAllocator allocator;
|
||||
|
||||
// Features per vulkan version
|
||||
bool dynamic_rendering = false;
|
||||
vk::Queue present_queue;
|
||||
vk::Queue graphics_queue;
|
||||
u32 present_queue_family_index = 0;
|
||||
u32 graphics_queue_family_index = 0;
|
||||
bool extended_dynamic_state = false;
|
||||
bool push_descriptors = false;
|
||||
};
|
||||
|
||||
} // namespace VideoCore::Vulkan
|
||||
} // namespace Vulkan
|
||||
|
134
src/video_core/renderer_vulkan/vk_platform.cpp
Normal file
134
src/video_core/renderer_vulkan/vk_platform.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
// Copyright 2022 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// Include the vulkan platform specific header
|
||||
#if defined(ANDROID) || defined (__ANDROID__)
|
||||
#define VK_USE_PLATFORM_ANDROID_KHR
|
||||
#elif defined(_WIN32)
|
||||
#define VK_USE_PLATFORM_WIN32_KHR
|
||||
#elif defined(__APPLE__)
|
||||
#define VK_USE_PLATFORM_MACOS_MVK
|
||||
#define VK_USE_PLATFORM_METAL_EXT
|
||||
#else
|
||||
#ifdef WAYLAND_DISPLAY
|
||||
#define VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#else // wayland
|
||||
#define VK_USE_PLATFORM_XLIB_KHR
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "video_core/renderer_vulkan/vk_platform.h"
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::EmuWindow& emu_window) {
|
||||
const auto& window_info = emu_window.GetWindowInfo();
|
||||
vk::SurfaceKHR surface{};
|
||||
|
||||
// Perform instance function loading here, to also load window system functions
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(instance);
|
||||
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
if (window_info.type == Frontend::WindowSystemType::Windows) {
|
||||
const vk::Win32SurfaceCreateInfoKHR win32_ci = {
|
||||
.hinstance = nullptr,
|
||||
.hwnd = static_cast<HWND>(window_info.render_surface)
|
||||
};
|
||||
|
||||
if (instance.createWin32SurfaceKHR(&win32_ci, nullptr, &surface) != vk::Result::eSuccess) {
|
||||
LOG_CRITICAL(Render_Vulkan, "Failed to initialize Win32 surface");
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
#elif defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
if (window_info.type == Frontend::WindowSystemType::X11) {
|
||||
const vk::XlibSurfaceCreateInfoKHR xlib_ci = {
|
||||
.dpy = static_cast<Display*>(window_info.display_connection),
|
||||
.window = reinterpret_cast<Window>(window_info.render_surface)
|
||||
};
|
||||
|
||||
if (instance.createXlibSurfaceKHR(&xlib_ci, nullptr, &surface) != vk::Result::eSuccess) {
|
||||
LOG_ERROR(Render_Vulkan, "Failed to initialize Xlib surface");
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
if (window_info.type == Frontend::WindowSystemType::Wayland) {
|
||||
const vk::WaylandSurfaceCreateInfoKHR wayland_ci{{},
|
||||
static_cast<wl_display*>(window_info.display_connection),
|
||||
static_cast<wl_surface*>(window_info.render_surface)};
|
||||
if (instance.createWaylandSurfaceKHR(&wayland_ci, nullptr, &surface) != vk::Result::eSuccess) {
|
||||
LOG_ERROR(Render_Vulkan, "Failed to initialize Wayland surface");
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!surface) {
|
||||
LOG_CRITICAL(Render_Vulkan, "Presentation not supported on this platform");
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
std::vector<const char*> GetInstanceExtensions(Frontend::WindowSystemType window_type, bool enable_debug_utils) {
|
||||
const auto properties = vk::enumerateInstanceExtensionProperties();
|
||||
if (properties.empty()) {
|
||||
LOG_ERROR(Render_Vulkan, "Failed to query extension properties");
|
||||
return std::vector<const char*>{};
|
||||
}
|
||||
|
||||
// Add the windowing system specific extension
|
||||
std::vector<const char*> extensions;
|
||||
extensions.reserve(6);
|
||||
|
||||
switch (window_type) {
|
||||
case Frontend::WindowSystemType::Headless:
|
||||
break;
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
case Frontend::WindowSystemType::Windows:
|
||||
extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#elif defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
case Frontend::WindowSystemType::X11:
|
||||
extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
case Frontend::WindowSystemType::Wayland:
|
||||
extensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
LOG_ERROR(Render_Vulkan, "Presentation not supported on this platform");
|
||||
break;
|
||||
}
|
||||
|
||||
if (window_type != Frontend::WindowSystemType::Headless) {
|
||||
extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
if (enable_debug_utils) {
|
||||
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
for (const char* extension : extensions) {
|
||||
const auto iter = std::ranges::find_if(properties, [extension](const auto& prop) {
|
||||
return std::strcmp(extension, prop.extensionName) == 0;
|
||||
});
|
||||
|
||||
if (iter == properties.end()) {
|
||||
LOG_ERROR(Render_Vulkan, "Required instance extension {} is not available", extension);
|
||||
return std::vector<const char*>{};
|
||||
}
|
||||
}
|
||||
|
||||
return extensions;
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
@ -4,131 +4,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// Include the vulkan platform specific header
|
||||
#if defined(ANDROID) || defined (__ANDROID__)
|
||||
#define VK_USE_PLATFORM_ANDROID_KHR 1
|
||||
#elif defined(_WIN32)
|
||||
#define VK_USE_PLATFORM_WIN32_KHR 1
|
||||
#elif defined(__APPLE__)
|
||||
#define VK_USE_PLATFORM_MACOS_MVK 1
|
||||
#define VK_USE_PLATFORM_METAL_EXT 1
|
||||
#else
|
||||
#ifdef WAYLAND_DISPLAY
|
||||
#define VK_USE_PLATFORM_WAYLAND_KHR 1
|
||||
#else // wayland
|
||||
#define VK_USE_PLATFORM_XLIB_KHR 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define VULKAN_HPP_NO_CONSTRUCTORS
|
||||
#include <vector>
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "common/common_types.h"
|
||||
#include "video_core/renderer_vulkan/vk_common.h"
|
||||
|
||||
namespace Frontend {
|
||||
class EmuWindow;
|
||||
enum class WindowSystemType : u8;
|
||||
}
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
inline vk::SurfaceKHR CreateSurface(const vk::Instance& instance, const Frontend::EmuWindow& emu_window) {
|
||||
const auto& window_info = emu_window.GetWindowInfo();
|
||||
vk::SurfaceKHR surface;
|
||||
std::vector<const char*> GetInstanceExtensions(Frontend::WindowSystemType window_type, bool enable_debug_utils);
|
||||
|
||||
#if VK_USE_PLATFORM_WIN32_KHR
|
||||
if (window_info.type == Frontend::WindowSystemType::Windows) {
|
||||
const vk::Win32SurfaceCreateInfoKHR win32_ci = {
|
||||
.hinstance = nullptr,
|
||||
.hwnd = static_cast<HWND>(window_info.render_surface)
|
||||
};
|
||||
|
||||
if (instance.createWin32SurfaceKHR(&win32_ci, nullptr, &surface) != vk::Result::eSuccess) {
|
||||
LOG_CRITICAL(Render_Vulkan, "Failed to initialize Win32 surface");
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
#elif VK_USE_PLATFORM_XLIB_KHR
|
||||
if (window_info.type == Frontend::WindowSystemType::X11) {
|
||||
const vk::XlibSurfaceCreateInfoKHR xlib_ci = {
|
||||
.dpy = static_cast<Display*>(window_info.display_connection),
|
||||
.window = reinterpret_cast<Window>(window_info.render_surface)
|
||||
};
|
||||
|
||||
if (instance.createXlibSurfaceKHR(&xlib_ci, nullptr, &surface) != vk::Result::eSuccess) {
|
||||
LOG_ERROR(Render_Vulkan, "Failed to initialize Xlib surface");
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
#elif VK_USE_PLATFORM_WAYLAND_KHR
|
||||
if (window_info.type == Frontend::WindowSystemType::Wayland) {
|
||||
const vk::WaylandSurfaceCreateInfoKHR wayland_ci{{},
|
||||
static_cast<wl_display*>(window_info.display_connection),
|
||||
static_cast<wl_surface*>(window_info.render_surface)};
|
||||
if (instance.createWaylandSurfaceKHR(&wayland_ci, nullptr, &surface) != vk::Result::eSuccess) {
|
||||
LOG_ERROR(Render_Vulkan, "Failed to initialize Wayland surface");
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!surface) {
|
||||
LOG_CRITICAL(Render_Vulkan, "Presentation not supported on this platform");
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
inline auto GetInstanceExtensions(Frontend::WindowSystemType window_type, bool enable_debug_utils) {
|
||||
const auto properties = vk::enumerateInstanceExtensionProperties();
|
||||
if (properties.empty()) {
|
||||
LOG_ERROR(Render_Vulkan, "Failed to query extension properties");
|
||||
return std::vector<const char*>{};
|
||||
}
|
||||
|
||||
// Add the windowing system specific extension
|
||||
std::vector<const char*> extensions;
|
||||
extensions.reserve(6);
|
||||
|
||||
switch (window_type) {
|
||||
case Frontend::WindowSystemType::Headless:
|
||||
break;
|
||||
#if VK_USE_PLATFORM_WIN32_KHR
|
||||
case Frontend::WindowSystemType::Windows:
|
||||
extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#elif VK_USE_PLATFORM_XLIB_KHR
|
||||
case Frontend::WindowSystemType::X11:
|
||||
extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#elif VK_USE_PLATFORM_WAYLAND_KHR
|
||||
case Frontend::WindowSystemType::Wayland:
|
||||
extensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
LOG_ERROR(Render_Vulkan, "Presentation not supported on this platform");
|
||||
break;
|
||||
}
|
||||
|
||||
if (window_type != Frontend::WindowSystemType::Headless) {
|
||||
extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
if (enable_debug_utils) {
|
||||
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
for (const char* extension : extensions) {
|
||||
const auto iter = std::ranges::find_if(properties, [extension](const auto& prop) {
|
||||
return std::strcmp(extension, prop.extensionName) == 0;
|
||||
});
|
||||
|
||||
if (iter == properties.end()) {
|
||||
LOG_ERROR(Render_Vulkan, "Required instance extension {} is not available", extension);
|
||||
return std::vector<const char*>{};
|
||||
}
|
||||
}
|
||||
|
||||
return extensions;
|
||||
}
|
||||
vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::EmuWindow& emu_window);
|
||||
|
||||
} // namespace Vulkan
|
||||
|
Reference in New Issue
Block a user