[Vulkan v2] VkSurface
This commit is contained in:
parent
30ba2619f3
commit
af93986c8f
|
@ -10,8 +10,10 @@
|
||||||
#include "xenia/ui/vk/vulkan_context.h"
|
#include "xenia/ui/vk/vulkan_context.h"
|
||||||
|
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
|
#include "xenia/base/platform.h"
|
||||||
#include "xenia/ui/vk/vulkan_immediate_drawer.h"
|
#include "xenia/ui/vk/vulkan_immediate_drawer.h"
|
||||||
#include "xenia/ui/vk/vulkan_util.h"
|
#include "xenia/ui/vk/vulkan_util.h"
|
||||||
|
#include "xenia/ui/window.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
@ -23,7 +25,9 @@ VulkanContext::VulkanContext(VulkanProvider* provider, Window* target_window)
|
||||||
VulkanContext::~VulkanContext() { Shutdown(); }
|
VulkanContext::~VulkanContext() { Shutdown(); }
|
||||||
|
|
||||||
bool VulkanContext::Initialize() {
|
bool VulkanContext::Initialize() {
|
||||||
auto device = GetVulkanProvider()->GetDevice();
|
auto provider = GetVulkanProvider();
|
||||||
|
auto instance = provider->GetInstance();
|
||||||
|
auto device = provider->GetDevice();
|
||||||
|
|
||||||
context_lost_ = false;
|
context_lost_ = false;
|
||||||
|
|
||||||
|
@ -49,6 +53,43 @@ bool VulkanContext::Initialize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_window_) {
|
if (target_window_) {
|
||||||
|
// Create the surface.
|
||||||
|
VkResult surface_create_result;
|
||||||
|
#if XE_PLATFORM_WIN32
|
||||||
|
VkWin32SurfaceCreateInfoKHR surface_create_info;
|
||||||
|
surface_create_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
||||||
|
surface_create_info.pNext = nullptr;
|
||||||
|
surface_create_info.flags = 0;
|
||||||
|
surface_create_info.hinstance =
|
||||||
|
static_cast<HINSTANCE>(target_window_->native_platform_handle());
|
||||||
|
surface_create_info.hwnd =
|
||||||
|
static_cast<HWND>(target_window_->native_handle());
|
||||||
|
surface_create_result = vkCreateWin32SurfaceKHR(
|
||||||
|
instance, &surface_create_info, nullptr, &surface_);
|
||||||
|
#else
|
||||||
|
#error No Vulkan surface creation for the platform implemented yet.
|
||||||
|
#endif
|
||||||
|
if (surface_create_result != VK_SUCCESS) {
|
||||||
|
XELOGE("Failed to create a Vulkan surface");
|
||||||
|
Shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the graphics queue can present to the surface.
|
||||||
|
// FIXME(Triang3l): Separate present queue not supported - would require
|
||||||
|
// deferring VkDevice creation because vkCreateDevice needs all used queues.
|
||||||
|
VkBool32 surface_supported = VK_FALSE;
|
||||||
|
vkGetPhysicalDeviceSurfaceSupportKHR(provider->GetPhysicalDevice(),
|
||||||
|
provider->GetGraphicsQueueFamily(),
|
||||||
|
surface_, &surface_supported);
|
||||||
|
if (!surface_supported) {
|
||||||
|
XELOGE(
|
||||||
|
"Surface not supported by the graphics queue of the Vulkan physical "
|
||||||
|
"device");
|
||||||
|
Shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize the immediate mode drawer if not offscreen.
|
// Initialize the immediate mode drawer if not offscreen.
|
||||||
immediate_drawer_ = std::make_unique<VulkanImmediateDrawer>(this);
|
immediate_drawer_ = std::make_unique<VulkanImmediateDrawer>(this);
|
||||||
if (!immediate_drawer_->Initialize()) {
|
if (!immediate_drawer_->Initialize()) {
|
||||||
|
@ -61,7 +102,9 @@ bool VulkanContext::Initialize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanContext::Shutdown() {
|
void VulkanContext::Shutdown() {
|
||||||
auto device = GetVulkanProvider()->GetDevice();
|
auto provider = GetVulkanProvider();
|
||||||
|
auto instance = provider->GetInstance();
|
||||||
|
auto device = provider->GetDevice();
|
||||||
|
|
||||||
if (initialized_fully_ && !context_lost_) {
|
if (initialized_fully_ && !context_lost_) {
|
||||||
AwaitAllFramesCompletion();
|
AwaitAllFramesCompletion();
|
||||||
|
@ -71,6 +114,8 @@ void VulkanContext::Shutdown() {
|
||||||
|
|
||||||
immediate_drawer_.reset();
|
immediate_drawer_.reset();
|
||||||
|
|
||||||
|
util::DestroyAndNullHandle(vkDestroySurfaceKHR, instance, surface_);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < kQueuedFrames; ++i) {
|
for (uint32_t i = 0; i < kQueuedFrames; ++i) {
|
||||||
util::DestroyAndNullHandle(vkDestroyFence, device, fences_[i]);
|
util::DestroyAndNullHandle(vkDestroyFence, device, fences_[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,8 @@ class VulkanContext : public GraphicsContext {
|
||||||
uint32_t current_queue_frame_ = 1;
|
uint32_t current_queue_frame_ = 1;
|
||||||
VkFence fences_[kQueuedFrames] = {};
|
VkFence fences_[kQueuedFrames] = {};
|
||||||
|
|
||||||
|
VkSurfaceKHR surface_ = VK_NULL_HANDLE;
|
||||||
|
|
||||||
std::unique_ptr<VulkanImmediateDrawer> immediate_drawer_ = nullptr;
|
std::unique_ptr<VulkanImmediateDrawer> immediate_drawer_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,8 @@
|
||||||
#include "xenia/base/platform.h"
|
#include "xenia/base/platform.h"
|
||||||
#include "xenia/ui/graphics_provider.h"
|
#include "xenia/ui/graphics_provider.h"
|
||||||
|
|
||||||
#ifndef VK_NO_PROTOTYPES
|
#if XE_PLATFORM_WIN32 && !defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||||
#define VK_NO_PROTOTYPES
|
#define VK_USE_PLATFORM_WIN32_KHR 1
|
||||||
#endif
|
|
||||||
#include "third_party/vulkan/vulkan.h"
|
|
||||||
#if XE_PLATFORM_WIN32
|
|
||||||
#include "third_party/vulkan/vulkan_win32.h"
|
|
||||||
#include "xenia/base/platform_win.h"
|
|
||||||
#endif
|
#endif
|
||||||
#include "third_party/volk/volk.h"
|
#include "third_party/volk/volk.h"
|
||||||
|
|
||||||
|
@ -44,6 +39,8 @@ class VulkanProvider : public GraphicsProvider {
|
||||||
Window* target_window) override;
|
Window* target_window) override;
|
||||||
std::unique_ptr<GraphicsContext> CreateOffscreenContext() override;
|
std::unique_ptr<GraphicsContext> CreateOffscreenContext() override;
|
||||||
|
|
||||||
|
VkInstance GetInstance() const { return instance_; }
|
||||||
|
VkPhysicalDevice GetPhysicalDevice() const { return physical_device_; }
|
||||||
const VkPhysicalDeviceFeatures& GetPhysicalDeviceFeatures() const {
|
const VkPhysicalDeviceFeatures& GetPhysicalDeviceFeatures() const {
|
||||||
return physical_device_features_;
|
return physical_device_features_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,11 +27,10 @@ inline bool DestroyAndNullHandle(F* destroy_function, T& handle) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F, typename T>
|
template <typename F, typename P, typename T>
|
||||||
inline bool DestroyAndNullHandle(F* destroy_function, VkDevice device,
|
inline bool DestroyAndNullHandle(F* destroy_function, P parent, T& handle) {
|
||||||
T& handle) {
|
|
||||||
if (handle != VK_NULL_HANDLE) {
|
if (handle != VK_NULL_HANDLE) {
|
||||||
destroy_function(device, handle, nullptr);
|
destroy_function(parent, handle, nullptr);
|
||||||
handle = VK_NULL_HANDLE;
|
handle = VK_NULL_HANDLE;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue