mirror of
https://github.com/xenia-project/xenia.git
synced 2025-12-06 07:12:03 +01:00
117 lines
3.7 KiB
C++
117 lines
3.7 KiB
C++
/**
|
|
******************************************************************************
|
|
* Xenia : Xbox 360 Emulator Research Project *
|
|
******************************************************************************
|
|
* Copyright 2016 Ben Vanik. All rights reserved. *
|
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
******************************************************************************
|
|
*/
|
|
|
|
#include "xenia/ui/vulkan/vulkan_provider.h"
|
|
|
|
#include <algorithm>
|
|
|
|
#include "xenia/base/logging.h"
|
|
#include "xenia/ui/vulkan/vulkan_context.h"
|
|
#include "xenia/ui/vulkan/vulkan_device.h"
|
|
#include "xenia/ui/vulkan/vulkan_instance.h"
|
|
#include "xenia/ui/vulkan/vulkan_util.h"
|
|
|
|
DEFINE_uint64(vulkan_device_index, 0, "Index of the physical device to use.",
|
|
"Vulkan");
|
|
|
|
namespace xe {
|
|
namespace ui {
|
|
namespace vulkan {
|
|
|
|
std::unique_ptr<VulkanProvider> VulkanProvider::Create(Window* main_window) {
|
|
std::unique_ptr<VulkanProvider> provider(new VulkanProvider(main_window));
|
|
if (!provider->Initialize()) {
|
|
xe::FatalError(
|
|
"Unable to initialize Vulkan graphics subsystem.\n"
|
|
"\n"
|
|
"Ensure you have the latest drivers for your GPU and that it "
|
|
"supports Vulkan.\n"
|
|
"\n"
|
|
"See https://xenia.jp/faq/ for more information and a list of "
|
|
"supported GPUs.");
|
|
return nullptr;
|
|
}
|
|
return provider;
|
|
}
|
|
|
|
VulkanProvider::VulkanProvider(Window* main_window)
|
|
: GraphicsProvider(main_window) {}
|
|
|
|
VulkanProvider::~VulkanProvider() {
|
|
device_.reset();
|
|
instance_.reset();
|
|
}
|
|
|
|
bool VulkanProvider::Initialize() {
|
|
instance_ = std::make_unique<VulkanInstance>();
|
|
|
|
// Always enable the swapchain.
|
|
#if XE_PLATFORM_GNU_LINUX || XE_PLATFORM_WIN32
|
|
instance_->DeclareRequiredExtension("VK_KHR_surface", Version::Make(0, 0, 0),
|
|
false);
|
|
#if XE_PLATFORM_GNU_LINUX
|
|
instance_->DeclareRequiredExtension("VK_KHR_xcb_surface",
|
|
Version::Make(0, 0, 0), false);
|
|
#elif XE_PLATFORM_WIN32
|
|
instance_->DeclareRequiredExtension("VK_KHR_win32_surface",
|
|
Version::Make(0, 0, 0), false);
|
|
#endif
|
|
#endif
|
|
|
|
// Attempt initialization and device query.
|
|
if (!instance_->Initialize()) {
|
|
XELOGE("Failed to initialize vulkan instance");
|
|
return false;
|
|
}
|
|
|
|
// Pick the device to use.
|
|
auto available_devices = instance_->available_devices();
|
|
if (available_devices.empty()) {
|
|
XELOGE("No devices available for use");
|
|
return false;
|
|
}
|
|
size_t device_index =
|
|
std::min(available_devices.size(), cvars::vulkan_device_index);
|
|
auto& device_info = available_devices[device_index];
|
|
|
|
// Create the device.
|
|
device_ = std::make_unique<VulkanDevice>(instance_.get());
|
|
device_->DeclareRequiredExtension("VK_KHR_swapchain", Version::Make(0, 0, 0),
|
|
false);
|
|
if (!device_->Initialize(device_info)) {
|
|
XELOGE("Unable to initialize device");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
std::unique_ptr<GraphicsContext> VulkanProvider::CreateContext(
|
|
Window* target_window) {
|
|
auto new_context =
|
|
std::unique_ptr<VulkanContext>(new VulkanContext(this, target_window));
|
|
if (!new_context->Initialize()) {
|
|
return nullptr;
|
|
}
|
|
return std::unique_ptr<GraphicsContext>(new_context.release());
|
|
}
|
|
|
|
std::unique_ptr<GraphicsContext> VulkanProvider::CreateOffscreenContext() {
|
|
auto new_context =
|
|
std::unique_ptr<VulkanContext>(new VulkanContext(this, nullptr));
|
|
if (!new_context->Initialize()) {
|
|
return nullptr;
|
|
}
|
|
return std::unique_ptr<GraphicsContext>(new_context.release());
|
|
}
|
|
|
|
} // namespace vulkan
|
|
} // namespace ui
|
|
} // namespace xe
|