[Vulkan v2] Physical device, [D3D12] Small cleanup
This commit is contained in:
parent
40471dff32
commit
2334e475de
|
@ -244,12 +244,14 @@ solution("xenia")
|
||||||
include("src/xenia/debug/ui")
|
include("src/xenia/debug/ui")
|
||||||
include("src/xenia/gpu")
|
include("src/xenia/gpu")
|
||||||
include("src/xenia/gpu/null")
|
include("src/xenia/gpu/null")
|
||||||
|
include("src/xenia/gpu/vk")
|
||||||
include("src/xenia/gpu/vulkan")
|
include("src/xenia/gpu/vulkan")
|
||||||
include("src/xenia/hid")
|
include("src/xenia/hid")
|
||||||
include("src/xenia/hid/nop")
|
include("src/xenia/hid/nop")
|
||||||
include("src/xenia/kernel")
|
include("src/xenia/kernel")
|
||||||
include("src/xenia/ui")
|
include("src/xenia/ui")
|
||||||
include("src/xenia/ui/spirv")
|
include("src/xenia/ui/spirv")
|
||||||
|
include("src/xenia/ui/vk")
|
||||||
include("src/xenia/ui/vulkan")
|
include("src/xenia/ui/vulkan")
|
||||||
include("src/xenia/vfs")
|
include("src/xenia/vfs")
|
||||||
|
|
||||||
|
|
|
@ -31,12 +31,14 @@ project("xenia-app")
|
||||||
"xenia-debug-ui",
|
"xenia-debug-ui",
|
||||||
"xenia-gpu",
|
"xenia-gpu",
|
||||||
"xenia-gpu-null",
|
"xenia-gpu-null",
|
||||||
|
"xenia-gpu-vk",
|
||||||
"xenia-gpu-vulkan",
|
"xenia-gpu-vulkan",
|
||||||
"xenia-hid",
|
"xenia-hid",
|
||||||
"xenia-hid-nop",
|
"xenia-hid-nop",
|
||||||
"xenia-kernel",
|
"xenia-kernel",
|
||||||
"xenia-ui",
|
"xenia-ui",
|
||||||
"xenia-ui-spirv",
|
"xenia-ui-spirv",
|
||||||
|
"xenia-ui-vk",
|
||||||
"xenia-ui-vulkan",
|
"xenia-ui-vulkan",
|
||||||
"xenia-vfs",
|
"xenia-vfs",
|
||||||
"xxhash",
|
"xxhash",
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
// Available graphics systems:
|
// Available graphics systems:
|
||||||
#include "xenia/gpu/null/null_graphics_system.h"
|
#include "xenia/gpu/null/null_graphics_system.h"
|
||||||
|
#include "xenia/gpu/vk/vulkan_graphics_system.h"
|
||||||
#include "xenia/gpu/vulkan/vulkan_graphics_system.h"
|
#include "xenia/gpu/vulkan/vulkan_graphics_system.h"
|
||||||
#if XE_PLATFORM_WIN32
|
#if XE_PLATFORM_WIN32
|
||||||
#include "xenia/gpu/d3d12/d3d12_graphics_system.h"
|
#include "xenia/gpu/d3d12/d3d12_graphics_system.h"
|
||||||
|
@ -44,8 +45,8 @@
|
||||||
#include "third_party/xbyak/xbyak/xbyak_util.h"
|
#include "third_party/xbyak/xbyak/xbyak_util.h"
|
||||||
|
|
||||||
DEFINE_string(apu, "any", "Audio system. Use: [any, nop, xaudio2]", "APU");
|
DEFINE_string(apu, "any", "Audio system. Use: [any, nop, xaudio2]", "APU");
|
||||||
DEFINE_string(gpu, "any", "Graphics system. Use: [any, d3d12, vulkan, null]",
|
DEFINE_string(gpu, "any",
|
||||||
"GPU");
|
"Graphics system. Use: [any, d3d12, vulkan, vk, null]", "GPU");
|
||||||
DEFINE_string(hid, "any", "Input system. Use: [any, nop, winkey, xinput]",
|
DEFINE_string(hid, "any", "Input system. Use: [any, nop, winkey, xinput]",
|
||||||
"HID");
|
"HID");
|
||||||
|
|
||||||
|
@ -156,7 +157,12 @@ std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() {
|
||||||
#if XE_PLATFORM_WIN32
|
#if XE_PLATFORM_WIN32
|
||||||
factory.Add<gpu::d3d12::D3D12GraphicsSystem>("d3d12");
|
factory.Add<gpu::d3d12::D3D12GraphicsSystem>("d3d12");
|
||||||
#endif // XE_PLATFORM_WIN32
|
#endif // XE_PLATFORM_WIN32
|
||||||
|
// Abandoned Vulkan graphics system.
|
||||||
factory.Add<gpu::vulkan::VulkanGraphicsSystem>("vulkan");
|
factory.Add<gpu::vulkan::VulkanGraphicsSystem>("vulkan");
|
||||||
|
// New Vulkan graphics system.
|
||||||
|
// TODO(Triang3l): Move this higher when it's more ready, then drop the old
|
||||||
|
// Vulkan graphics system.
|
||||||
|
factory.Add<gpu::vk::VulkanGraphicsSystem>("vk");
|
||||||
factory.Add<gpu::null::NullGraphicsSystem>("null");
|
factory.Add<gpu::null::NullGraphicsSystem>("null");
|
||||||
return factory.Create(cvars::gpu);
|
return factory.Create(cvars::gpu);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,11 +50,12 @@ class D3D12GraphicsSystem : public GraphicsSystem {
|
||||||
D3D12_GPU_DESCRIPTOR_HANDLE* gamma_ramp_handle, float gamma_ramp_inv_size,
|
D3D12_GPU_DESCRIPTOR_HANDLE* gamma_ramp_handle, float gamma_ramp_inv_size,
|
||||||
DeferredCommandList& command_list);
|
DeferredCommandList& command_list);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
std::unique_ptr<CommandProcessor> CreateCommandProcessor() override;
|
std::unique_ptr<CommandProcessor> CreateCommandProcessor() override;
|
||||||
|
|
||||||
void Swap(xe::ui::UIEvent* e) override;
|
void Swap(xe::ui::UIEvent* e) override;
|
||||||
|
|
||||||
|
private:
|
||||||
ui::d3d12::D3D12Context* display_context_ = nullptr;
|
ui::d3d12::D3D12Context* display_context_ = nullptr;
|
||||||
|
|
||||||
ID3D12RootSignature* stretch_root_signature_ = nullptr;
|
ID3D12RootSignature* stretch_root_signature_ = nullptr;
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
project_root = "../../../.."
|
||||||
|
include(project_root.."/tools/build")
|
||||||
|
|
||||||
|
group("src")
|
||||||
|
project("xenia-gpu-vk")
|
||||||
|
uuid("66c9afbb-798a-405d-80a1-7bda473e700d")
|
||||||
|
kind("StaticLib")
|
||||||
|
language("C++")
|
||||||
|
links({
|
||||||
|
"xenia-base",
|
||||||
|
"xenia-gpu",
|
||||||
|
"xenia-ui",
|
||||||
|
"xenia-ui-vk",
|
||||||
|
"xxhash",
|
||||||
|
})
|
||||||
|
local_platform_files()
|
||||||
|
files({
|
||||||
|
"shaders/bin/*.h",
|
||||||
|
})
|
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xenia/gpu/vk/vulkan_command_processor.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace gpu {
|
||||||
|
namespace vk {
|
||||||
|
|
||||||
|
VulkanCommandProcessor::VulkanCommandProcessor(
|
||||||
|
VulkanGraphicsSystem* graphics_system, kernel::KernelState* kernel_state)
|
||||||
|
: CommandProcessor(graphics_system, kernel_state) {}
|
||||||
|
VulkanCommandProcessor::~VulkanCommandProcessor() = default;
|
||||||
|
|
||||||
|
bool VulkanCommandProcessor::SetupContext() { return true; }
|
||||||
|
|
||||||
|
void VulkanCommandProcessor::ShutdownContext() {}
|
||||||
|
|
||||||
|
void VulkanCommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
||||||
|
uint32_t frontbuffer_width,
|
||||||
|
uint32_t frontbuffer_height) {}
|
||||||
|
|
||||||
|
Shader* VulkanCommandProcessor::LoadShader(ShaderType shader_type,
|
||||||
|
uint32_t guest_address,
|
||||||
|
const uint32_t* host_address,
|
||||||
|
uint32_t dword_count) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VulkanCommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
||||||
|
uint32_t index_count,
|
||||||
|
IndexBufferInfo* index_buffer_info) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VulkanCommandProcessor::IssueCopy() { return true; }
|
||||||
|
|
||||||
|
} // namespace vk
|
||||||
|
} // namespace gpu
|
||||||
|
} // namespace xe
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_GPU_VK_VULKAN_COMMAND_PROCESSOR_H_
|
||||||
|
#define XENIA_GPU_VK_VULKAN_COMMAND_PROCESSOR_H_
|
||||||
|
|
||||||
|
#include "xenia/gpu/command_processor.h"
|
||||||
|
#include "xenia/gpu/vk/vulkan_graphics_system.h"
|
||||||
|
#include "xenia/kernel/kernel_state.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace gpu {
|
||||||
|
namespace vk {
|
||||||
|
|
||||||
|
class VulkanCommandProcessor : public CommandProcessor {
|
||||||
|
public:
|
||||||
|
explicit VulkanCommandProcessor(VulkanGraphicsSystem* graphics_system,
|
||||||
|
kernel::KernelState* kernel_state);
|
||||||
|
~VulkanCommandProcessor();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool SetupContext() override;
|
||||||
|
void ShutdownContext() override;
|
||||||
|
|
||||||
|
void PerformSwap(uint32_t frontbuffer_ptr, uint32_t frontbuffer_width,
|
||||||
|
uint32_t frontbuffer_height) override;
|
||||||
|
|
||||||
|
Shader* LoadShader(ShaderType shader_type, uint32_t guest_address,
|
||||||
|
const uint32_t* host_address,
|
||||||
|
uint32_t dword_count) override;
|
||||||
|
|
||||||
|
bool IssueDraw(PrimitiveType primitive_type, uint32_t index_count,
|
||||||
|
IndexBufferInfo* index_buffer_info) override;
|
||||||
|
bool IssueCopy() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace vk
|
||||||
|
} // namespace gpu
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
#endif // XENIA_GPU_VK_VULKAN_COMMAND_PROCESSOR_H_
|
|
@ -0,0 +1,54 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xenia/gpu/vk/vulkan_graphics_system.h"
|
||||||
|
|
||||||
|
#include "xenia/gpu/vk/vulkan_command_processor.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace gpu {
|
||||||
|
namespace vk {
|
||||||
|
|
||||||
|
VulkanGraphicsSystem::VulkanGraphicsSystem() {}
|
||||||
|
|
||||||
|
VulkanGraphicsSystem::~VulkanGraphicsSystem() {}
|
||||||
|
|
||||||
|
std::wstring VulkanGraphicsSystem::name() const { return L"Vulkan Prototype"; }
|
||||||
|
|
||||||
|
X_STATUS VulkanGraphicsSystem::Setup(cpu::Processor* processor,
|
||||||
|
kernel::KernelState* kernel_state,
|
||||||
|
ui::Window* target_window) {
|
||||||
|
provider_ = xe::ui::vk::VulkanProvider::Create(target_window);
|
||||||
|
|
||||||
|
auto result = GraphicsSystem::Setup(processor, kernel_state, target_window);
|
||||||
|
if (result != X_STATUS_SUCCESS) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_window) {
|
||||||
|
display_context_ =
|
||||||
|
reinterpret_cast<xe::ui::vk::VulkanContext*>(target_window->context());
|
||||||
|
}
|
||||||
|
|
||||||
|
return X_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanGraphicsSystem::Shutdown() { GraphicsSystem::Shutdown(); }
|
||||||
|
|
||||||
|
std::unique_ptr<CommandProcessor>
|
||||||
|
VulkanGraphicsSystem::CreateCommandProcessor() {
|
||||||
|
return std::unique_ptr<CommandProcessor>(
|
||||||
|
new VulkanCommandProcessor(this, kernel_state_));
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanGraphicsSystem::Swap(xe::ui::UIEvent* e) {}
|
||||||
|
|
||||||
|
} // namespace vk
|
||||||
|
} // namespace gpu
|
||||||
|
} // namespace xe
|
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_GPU_VK_VULKAN_GRAPHICS_SYSTEM_H_
|
||||||
|
#define XENIA_GPU_VK_VULKAN_GRAPHICS_SYSTEM_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "xenia/gpu/command_processor.h"
|
||||||
|
#include "xenia/gpu/graphics_system.h"
|
||||||
|
#include "xenia/ui/vk/vulkan_context.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace gpu {
|
||||||
|
namespace vk {
|
||||||
|
|
||||||
|
class VulkanGraphicsSystem : public GraphicsSystem {
|
||||||
|
public:
|
||||||
|
VulkanGraphicsSystem();
|
||||||
|
~VulkanGraphicsSystem() override;
|
||||||
|
|
||||||
|
static bool IsAvailable() { return true; }
|
||||||
|
|
||||||
|
std::wstring name() const override;
|
||||||
|
|
||||||
|
X_STATUS Setup(cpu::Processor* processor, kernel::KernelState* kernel_state,
|
||||||
|
ui::Window* target_window) override;
|
||||||
|
void Shutdown() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<CommandProcessor> CreateCommandProcessor() override;
|
||||||
|
|
||||||
|
void Swap(xe::ui::UIEvent* e) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ui::vk::VulkanContext* display_context_ = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace vk
|
||||||
|
} // namespace gpu
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
#endif // XENIA_GPU_VK_VULKAN_GRAPHICS_SYSTEM_H_
|
|
@ -309,24 +309,12 @@ void D3D12ImmediateDrawer::Shutdown() {
|
||||||
texture_descriptor_pool_.reset();
|
texture_descriptor_pool_.reset();
|
||||||
vertex_buffer_pool_.reset();
|
vertex_buffer_pool_.reset();
|
||||||
|
|
||||||
if (sampler_heap_ != nullptr) {
|
util::ReleaseAndNull(sampler_heap_);
|
||||||
sampler_heap_->Release();
|
|
||||||
sampler_heap_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pipeline_line_ != nullptr) {
|
util::ReleaseAndNull(pipeline_line_);
|
||||||
pipeline_line_->Release();
|
util::ReleaseAndNull(pipeline_triangle_);
|
||||||
pipeline_line_ = nullptr;
|
|
||||||
}
|
|
||||||
if (pipeline_triangle_ != nullptr) {
|
|
||||||
pipeline_triangle_->Release();
|
|
||||||
pipeline_triangle_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (root_signature_ != nullptr) {
|
util::ReleaseAndNull(root_signature_);
|
||||||
root_signature_->Release();
|
|
||||||
root_signature_ = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ImmediateTexture> D3D12ImmediateDrawer::CreateTexture(
|
std::unique_ptr<ImmediateTexture> D3D12ImmediateDrawer::CreateTexture(
|
||||||
|
|
|
@ -43,7 +43,7 @@ class D3D12ImmediateDrawer : public ImmediateDrawer {
|
||||||
void BeginDrawBatch(const ImmediateDrawBatch& batch) override;
|
void BeginDrawBatch(const ImmediateDrawBatch& batch) override;
|
||||||
void Draw(const ImmediateDraw& draw) override;
|
void Draw(const ImmediateDraw& draw) override;
|
||||||
void EndDrawBatch() override;
|
void EndDrawBatch() override;
|
||||||
void End();
|
void End() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
D3D12Context* context_ = nullptr;
|
D3D12Context* context_ = nullptr;
|
||||||
|
|
|
@ -38,18 +38,15 @@ bool D3D12Provider::IsD3D12APIAvailable() {
|
||||||
|
|
||||||
std::unique_ptr<D3D12Provider> D3D12Provider::Create(Window* main_window) {
|
std::unique_ptr<D3D12Provider> D3D12Provider::Create(Window* main_window) {
|
||||||
std::unique_ptr<D3D12Provider> provider(new D3D12Provider(main_window));
|
std::unique_ptr<D3D12Provider> provider(new D3D12Provider(main_window));
|
||||||
InitializationResult result = provider->Initialize();
|
if (!provider->Initialize()) {
|
||||||
if (result != InitializationResult::kSucceeded) {
|
|
||||||
if (result != InitializationResult::kLibraryLoadFailed) {
|
|
||||||
xe::FatalError(
|
xe::FatalError(
|
||||||
"Unable to initialize Direct3D 12 graphics subsystem.\n"
|
"Unable to initialize Direct3D 12 graphics subsystem.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Ensure that you have the latest drivers for your GPU and it "
|
"Ensure that you have the latest drivers for your GPU and it supports "
|
||||||
"supports Direct3D 12 feature level 11_0.\n"
|
"Direct3D 12 feature level 11_0.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"See https://xenia.jp/faq/ for more information and a list of "
|
"See https://xenia.jp/faq/ for more information and a list of "
|
||||||
"supported GPUs.");
|
"supported GPUs.");
|
||||||
}
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return provider;
|
return provider;
|
||||||
|
@ -83,7 +80,7 @@ D3D12Provider::~D3D12Provider() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D12Provider::InitializationResult D3D12Provider::Initialize() {
|
bool D3D12Provider::Initialize() {
|
||||||
// Load the libraries.
|
// Load the libraries.
|
||||||
library_dxgi_ = LoadLibrary(L"dxgi.dll");
|
library_dxgi_ = LoadLibrary(L"dxgi.dll");
|
||||||
library_d3d12_ = LoadLibrary(L"D3D12.dll");
|
library_d3d12_ = LoadLibrary(L"D3D12.dll");
|
||||||
|
@ -91,7 +88,7 @@ D3D12Provider::InitializationResult D3D12Provider::Initialize() {
|
||||||
if (library_dxgi_ == nullptr || library_d3d12_ == nullptr ||
|
if (library_dxgi_ == nullptr || library_d3d12_ == nullptr ||
|
||||||
library_d3dcompiler_ == nullptr) {
|
library_d3dcompiler_ == nullptr) {
|
||||||
XELOGE("Failed to load dxgi.dll, D3D12.dll and D3DCompiler_47.dll.");
|
XELOGE("Failed to load dxgi.dll, D3D12.dll and D3DCompiler_47.dll.");
|
||||||
return InitializationResult::kLibraryLoadFailed;
|
return false;
|
||||||
}
|
}
|
||||||
bool libraries_loaded = true;
|
bool libraries_loaded = true;
|
||||||
libraries_loaded &=
|
libraries_loaded &=
|
||||||
|
@ -114,7 +111,7 @@ D3D12Provider::InitializationResult D3D12Provider::Initialize() {
|
||||||
libraries_loaded &= (pfn_d3d_disassemble_ = pD3DDisassemble(GetProcAddress(
|
libraries_loaded &= (pfn_d3d_disassemble_ = pD3DDisassemble(GetProcAddress(
|
||||||
library_d3dcompiler_, "D3DDisassemble"))) != nullptr;
|
library_d3dcompiler_, "D3DDisassemble"))) != nullptr;
|
||||||
if (!libraries_loaded) {
|
if (!libraries_loaded) {
|
||||||
return InitializationResult::kLibraryLoadFailed;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable the debug layer.
|
// Enable the debug layer.
|
||||||
|
@ -136,7 +133,7 @@ D3D12Provider::InitializationResult D3D12Provider::Initialize() {
|
||||||
if (FAILED(pfn_create_dxgi_factory2_(debug ? DXGI_CREATE_FACTORY_DEBUG : 0,
|
if (FAILED(pfn_create_dxgi_factory2_(debug ? DXGI_CREATE_FACTORY_DEBUG : 0,
|
||||||
IID_PPV_ARGS(&dxgi_factory)))) {
|
IID_PPV_ARGS(&dxgi_factory)))) {
|
||||||
XELOGE("Failed to create a DXGI factory");
|
XELOGE("Failed to create a DXGI factory");
|
||||||
return InitializationResult::kDeviceInitializationFailed;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choose the adapter.
|
// Choose the adapter.
|
||||||
|
@ -169,14 +166,14 @@ D3D12Provider::InitializationResult D3D12Provider::Initialize() {
|
||||||
if (adapter == nullptr) {
|
if (adapter == nullptr) {
|
||||||
XELOGE("Failed to get an adapter supporting Direct3D feature level 11_0.");
|
XELOGE("Failed to get an adapter supporting Direct3D feature level 11_0.");
|
||||||
dxgi_factory->Release();
|
dxgi_factory->Release();
|
||||||
return InitializationResult::kDeviceInitializationFailed;
|
return false;
|
||||||
}
|
}
|
||||||
DXGI_ADAPTER_DESC adapter_desc;
|
DXGI_ADAPTER_DESC adapter_desc;
|
||||||
if (FAILED(adapter->GetDesc(&adapter_desc))) {
|
if (FAILED(adapter->GetDesc(&adapter_desc))) {
|
||||||
XELOGE("Failed to get the DXGI adapter description.");
|
XELOGE("Failed to get the DXGI adapter description.");
|
||||||
adapter->Release();
|
adapter->Release();
|
||||||
dxgi_factory->Release();
|
dxgi_factory->Release();
|
||||||
return InitializationResult::kDeviceInitializationFailed;
|
return false;
|
||||||
}
|
}
|
||||||
adapter_vendor_id_ = adapter_desc.VendorId;
|
adapter_vendor_id_ = adapter_desc.VendorId;
|
||||||
int adapter_name_mb_size = WideCharToMultiByte(
|
int adapter_name_mb_size = WideCharToMultiByte(
|
||||||
|
@ -199,7 +196,7 @@ D3D12Provider::InitializationResult D3D12Provider::Initialize() {
|
||||||
XELOGE("Failed to create a Direct3D 12 feature level 11_0 device.");
|
XELOGE("Failed to create a Direct3D 12 feature level 11_0 device.");
|
||||||
adapter->Release();
|
adapter->Release();
|
||||||
dxgi_factory->Release();
|
dxgi_factory->Release();
|
||||||
return InitializationResult::kDeviceInitializationFailed;
|
return false;
|
||||||
}
|
}
|
||||||
adapter->Release();
|
adapter->Release();
|
||||||
|
|
||||||
|
@ -268,7 +265,7 @@ D3D12Provider::InitializationResult D3D12Provider::Initialize() {
|
||||||
// attached.
|
// attached.
|
||||||
pfn_dxgi_get_debug_interface1_(0, IID_PPV_ARGS(&graphics_analysis_));
|
pfn_dxgi_get_debug_interface1_(0, IID_PPV_ARGS(&graphics_analysis_));
|
||||||
|
|
||||||
return InitializationResult::kSucceeded;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<GraphicsContext> D3D12Provider::CreateContext(
|
std::unique_ptr<GraphicsContext> D3D12Provider::CreateContext(
|
||||||
|
|
|
@ -97,13 +97,7 @@ class D3D12Provider : public GraphicsProvider {
|
||||||
private:
|
private:
|
||||||
explicit D3D12Provider(Window* main_window);
|
explicit D3D12Provider(Window* main_window);
|
||||||
|
|
||||||
enum InitializationResult : uint32_t {
|
bool Initialize();
|
||||||
kSucceeded,
|
|
||||||
kDeviceInitializationFailed,
|
|
||||||
kLibraryLoadFailed,
|
|
||||||
};
|
|
||||||
|
|
||||||
InitializationResult Initialize();
|
|
||||||
|
|
||||||
HMODULE library_dxgi_ = nullptr;
|
HMODULE library_dxgi_ = nullptr;
|
||||||
HMODULE library_d3d12_ = nullptr;
|
HMODULE library_d3d12_ = nullptr;
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
project_root = "../../../.."
|
||||||
|
include(project_root.."/tools/build")
|
||||||
|
|
||||||
|
group("src")
|
||||||
|
project("xenia-ui-vk")
|
||||||
|
uuid("758e31de-c91b-44ce-acef-27752939d37f")
|
||||||
|
kind("StaticLib")
|
||||||
|
language("C++")
|
||||||
|
links({
|
||||||
|
"volk",
|
||||||
|
"xenia-base",
|
||||||
|
"xenia-ui",
|
||||||
|
})
|
||||||
|
local_platform_files()
|
||||||
|
files({
|
||||||
|
"shaders/bin/*.h",
|
||||||
|
})
|
|
@ -0,0 +1,65 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xenia/ui/vk/vulkan_context.h"
|
||||||
|
|
||||||
|
#include "xenia/ui/vk/vulkan_immediate_drawer.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace vk {
|
||||||
|
|
||||||
|
VulkanContext::VulkanContext(VulkanProvider* provider, Window* target_window)
|
||||||
|
: GraphicsContext(provider, target_window) {}
|
||||||
|
|
||||||
|
VulkanContext::~VulkanContext() { Shutdown(); }
|
||||||
|
|
||||||
|
bool VulkanContext::Initialize() {
|
||||||
|
context_lost_ = false;
|
||||||
|
|
||||||
|
if (target_window_) {
|
||||||
|
// Initialize the immediate mode drawer if not offscreen.
|
||||||
|
immediate_drawer_ = std::make_unique<VulkanImmediateDrawer>(this);
|
||||||
|
if (!immediate_drawer_->Initialize()) {
|
||||||
|
Shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanContext::Shutdown() {
|
||||||
|
initialized_fully_ = false;
|
||||||
|
|
||||||
|
immediate_drawer_.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImmediateDrawer* VulkanContext::immediate_drawer() {
|
||||||
|
return immediate_drawer_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VulkanContext::is_current() { return false; }
|
||||||
|
|
||||||
|
bool VulkanContext::MakeCurrent() { return true; }
|
||||||
|
|
||||||
|
void VulkanContext::ClearCurrent() {}
|
||||||
|
|
||||||
|
void VulkanContext::BeginSwap() {}
|
||||||
|
|
||||||
|
void VulkanContext::EndSwap() {}
|
||||||
|
|
||||||
|
std::unique_ptr<RawImage> VulkanContext::Capture() {
|
||||||
|
// TODO(Triang3l): Read back swap chain front buffer.
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace vk
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_UI_VK_VULKAN_CONTEXT_H_
|
||||||
|
#define XENIA_UI_VK_VULKAN_CONTEXT_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "xenia/ui/graphics_context.h"
|
||||||
|
#include "xenia/ui/vk/vulkan_provider.h"
|
||||||
|
|
||||||
|
#define FINE_GRAINED_DRAW_SCOPES 1
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace vk {
|
||||||
|
|
||||||
|
class VulkanImmediateDrawer;
|
||||||
|
|
||||||
|
class VulkanContext : public GraphicsContext {
|
||||||
|
public:
|
||||||
|
~VulkanContext() override;
|
||||||
|
|
||||||
|
ImmediateDrawer* immediate_drawer() override;
|
||||||
|
|
||||||
|
bool is_current() override;
|
||||||
|
bool MakeCurrent() override;
|
||||||
|
void ClearCurrent() override;
|
||||||
|
|
||||||
|
bool WasLost() override { return context_lost_; }
|
||||||
|
|
||||||
|
void BeginSwap() override;
|
||||||
|
void EndSwap() override;
|
||||||
|
|
||||||
|
std::unique_ptr<RawImage> Capture() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class VulkanProvider;
|
||||||
|
|
||||||
|
explicit VulkanContext(VulkanProvider* provider, Window* target_window);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool Initialize();
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
bool initialized_fully_ = false;
|
||||||
|
|
||||||
|
bool context_lost_ = false;
|
||||||
|
|
||||||
|
std::unique_ptr<VulkanImmediateDrawer> immediate_drawer_ = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace vk
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
#endif // XENIA_UI_VK_VULKAN_CONTEXT_H_
|
|
@ -0,0 +1,68 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xenia/ui/vk/vulkan_immediate_drawer.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace vk {
|
||||||
|
|
||||||
|
class VulkanImmediateTexture : public ImmediateTexture {
|
||||||
|
public:
|
||||||
|
VulkanImmediateTexture(uint32_t width, uint32_t height,
|
||||||
|
ImmediateTextureFilter filter, bool repeat);
|
||||||
|
~VulkanImmediateTexture() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
VulkanImmediateTexture::VulkanImmediateTexture(uint32_t width, uint32_t height,
|
||||||
|
ImmediateTextureFilter filter,
|
||||||
|
bool repeat)
|
||||||
|
: ImmediateTexture(width, height) {
|
||||||
|
handle = reinterpret_cast<uintptr_t>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
VulkanImmediateTexture::~VulkanImmediateTexture() {}
|
||||||
|
|
||||||
|
VulkanImmediateDrawer::VulkanImmediateDrawer(VulkanContext* graphics_context)
|
||||||
|
: ImmediateDrawer(graphics_context), context_(graphics_context) {}
|
||||||
|
|
||||||
|
VulkanImmediateDrawer::~VulkanImmediateDrawer() { Shutdown(); }
|
||||||
|
|
||||||
|
bool VulkanImmediateDrawer::Initialize() { return true; }
|
||||||
|
|
||||||
|
void VulkanImmediateDrawer::Shutdown() {}
|
||||||
|
|
||||||
|
std::unique_ptr<ImmediateTexture> VulkanImmediateDrawer::CreateTexture(
|
||||||
|
uint32_t width, uint32_t height, ImmediateTextureFilter filter, bool repeat,
|
||||||
|
const uint8_t* data) {
|
||||||
|
auto texture =
|
||||||
|
std::make_unique<VulkanImmediateTexture>(width, height, filter, repeat);
|
||||||
|
if (data != nullptr) {
|
||||||
|
UpdateTexture(texture.get(), data);
|
||||||
|
}
|
||||||
|
return std::unique_ptr<ImmediateTexture>(texture.release());
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanImmediateDrawer::UpdateTexture(ImmediateTexture* texture,
|
||||||
|
const uint8_t* data) {}
|
||||||
|
|
||||||
|
void VulkanImmediateDrawer::Begin(int render_target_width,
|
||||||
|
int render_target_height) {}
|
||||||
|
|
||||||
|
void VulkanImmediateDrawer::BeginDrawBatch(const ImmediateDrawBatch& batch) {}
|
||||||
|
|
||||||
|
void VulkanImmediateDrawer::Draw(const ImmediateDraw& draw) {}
|
||||||
|
|
||||||
|
void VulkanImmediateDrawer::EndDrawBatch() {}
|
||||||
|
|
||||||
|
void VulkanImmediateDrawer::End() {}
|
||||||
|
|
||||||
|
} // namespace vk
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_UI_VK_VULKAN_IMMEDIATE_DRAWER_H_
|
||||||
|
#define XENIA_UI_VK_VULKAN_IMMEDIATE_DRAWER_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "xenia/ui/immediate_drawer.h"
|
||||||
|
#include "xenia/ui/vk/vulkan_context.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace vk {
|
||||||
|
|
||||||
|
class VulkanImmediateDrawer : public ImmediateDrawer {
|
||||||
|
public:
|
||||||
|
VulkanImmediateDrawer(VulkanContext* graphics_context);
|
||||||
|
~VulkanImmediateDrawer() override;
|
||||||
|
|
||||||
|
bool Initialize();
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
std::unique_ptr<ImmediateTexture> CreateTexture(uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
ImmediateTextureFilter filter,
|
||||||
|
bool repeat,
|
||||||
|
const uint8_t* data) override;
|
||||||
|
void UpdateTexture(ImmediateTexture* texture, const uint8_t* data) override;
|
||||||
|
|
||||||
|
void Begin(int render_target_width, int render_target_height) override;
|
||||||
|
void BeginDrawBatch(const ImmediateDrawBatch& batch) override;
|
||||||
|
void Draw(const ImmediateDraw& draw) override;
|
||||||
|
void EndDrawBatch() override;
|
||||||
|
void End() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
VulkanContext* context_ = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace vk
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
#endif // XENIA_UI_VK_VULKAN_IMMEDIATE_DRAWER_H_
|
|
@ -0,0 +1,230 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xenia/ui/vk/vulkan_provider.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
|
#include "xenia/base/logging.h"
|
||||||
|
#include "xenia/ui/vk/vulkan_context.h"
|
||||||
|
#include "xenia/ui/vk/vulkan_util.h"
|
||||||
|
|
||||||
|
DEFINE_bool(vk_validation, false, "Enable Vulkan validation layers.", "Vulkan");
|
||||||
|
DEFINE_int32(vk_device, -1,
|
||||||
|
"Index of the Vulkan physical device to use. -1 to use any "
|
||||||
|
"compatible.",
|
||||||
|
"Vulkan");
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace vk {
|
||||||
|
|
||||||
|
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 1.1 graphics subsystem.\n"
|
||||||
|
"\n"
|
||||||
|
"Ensure you have the latest drivers for your GPU and that it supports "
|
||||||
|
"Vulkan, and install the latest Vulkan runtime from "
|
||||||
|
"https://vulkan.lunarg.com/sdk/home.\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() {
|
||||||
|
if (device_ != VK_NULL_HANDLE) {
|
||||||
|
vkDestroyDevice(device_, nullptr);
|
||||||
|
}
|
||||||
|
if (instance_ != VK_NULL_HANDLE) {
|
||||||
|
vkDestroyInstance(instance_, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VulkanProvider::Initialize() {
|
||||||
|
if (volkInitialize() != VK_SUCCESS) {
|
||||||
|
XELOGE("Failed to initialize the Vulkan loader volk.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t api_version = VK_MAKE_VERSION(1, 1, 0);
|
||||||
|
|
||||||
|
// Create the instance.
|
||||||
|
VkApplicationInfo application_info;
|
||||||
|
application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||||
|
application_info.pNext = nullptr;
|
||||||
|
application_info.pApplicationName = "Xenia";
|
||||||
|
application_info.applicationVersion = 1;
|
||||||
|
application_info.pEngineName = "Xenia";
|
||||||
|
application_info.engineVersion = 1;
|
||||||
|
application_info.apiVersion = api_version;
|
||||||
|
const char* const validation_layers[] = {
|
||||||
|
"VK_LAYER_LUNARG_standard_validation",
|
||||||
|
};
|
||||||
|
const char* const instance_extensions[] = {
|
||||||
|
"VK_KHR_surface",
|
||||||
|
#if XE_PLATFORM_WIN32
|
||||||
|
"VK_KHR_win32_surface",
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
VkInstanceCreateInfo instance_create_info;
|
||||||
|
instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
|
instance_create_info.pNext = nullptr;
|
||||||
|
instance_create_info.flags = 0;
|
||||||
|
instance_create_info.pApplicationInfo = &application_info;
|
||||||
|
if (cvars::vk_validation) {
|
||||||
|
instance_create_info.enabledLayerCount =
|
||||||
|
uint32_t(xe::countof(validation_layers));
|
||||||
|
instance_create_info.ppEnabledLayerNames = validation_layers;
|
||||||
|
} else {
|
||||||
|
instance_create_info.enabledLayerCount = 0;
|
||||||
|
instance_create_info.ppEnabledLayerNames = nullptr;
|
||||||
|
}
|
||||||
|
instance_create_info.enabledExtensionCount =
|
||||||
|
uint32_t(xe::countof(instance_extensions));
|
||||||
|
instance_create_info.ppEnabledExtensionNames = instance_extensions;
|
||||||
|
if (vkCreateInstance(&instance_create_info, nullptr, &instance_) !=
|
||||||
|
VK_SUCCESS) {
|
||||||
|
XELOGE("Failed to create a Vulkan instance.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
volkLoadInstance(instance_);
|
||||||
|
|
||||||
|
// Get a supported physical device.
|
||||||
|
physical_device_ = nullptr;
|
||||||
|
std::vector<VkPhysicalDevice> physical_devices;
|
||||||
|
uint32_t physical_device_count;
|
||||||
|
if (vkEnumeratePhysicalDevices(instance_, &physical_device_count, nullptr) !=
|
||||||
|
VK_SUCCESS) {
|
||||||
|
XELOGE("Failed to get Vulkan physical device count.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
physical_devices.resize(physical_device_count);
|
||||||
|
if (vkEnumeratePhysicalDevices(instance_, &physical_device_count,
|
||||||
|
physical_devices.data()) != VK_SUCCESS) {
|
||||||
|
XELOGE("Failed to get Vulkan physical devices.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
physical_devices.resize(physical_device_count);
|
||||||
|
uint32_t physical_device_index, physical_device_index_end;
|
||||||
|
if (cvars::vk_device >= 0) {
|
||||||
|
physical_device_index = uint32_t(cvars::vk_device);
|
||||||
|
physical_device_index_end =
|
||||||
|
std::min(physical_device_index + 1, physical_device_count);
|
||||||
|
} else {
|
||||||
|
physical_device_index = 0;
|
||||||
|
physical_device_index_end = physical_device_count;
|
||||||
|
}
|
||||||
|
VkPhysicalDeviceFeatures physical_device_features;
|
||||||
|
std::vector<VkQueueFamilyProperties> queue_families;
|
||||||
|
uint32_t queue_family = UINT32_MAX;
|
||||||
|
bool sparse_residency_buffer = false;
|
||||||
|
for (; physical_device_index < physical_device_index_end;
|
||||||
|
++physical_device_index) {
|
||||||
|
VkPhysicalDevice physical_device = physical_devices[physical_device_index];
|
||||||
|
vkGetPhysicalDeviceFeatures(physical_device, &physical_device_features);
|
||||||
|
sparse_residency_buffer = physical_device_features.sparseBinding &&
|
||||||
|
physical_device_features.sparseResidencyBuffer;
|
||||||
|
// Get a queue supporting graphics, compute and transfer, and if available,
|
||||||
|
// also sparse memory management.
|
||||||
|
queue_family = UINT32_MAX;
|
||||||
|
uint32_t queue_family_count;
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(physical_device,
|
||||||
|
&queue_family_count, nullptr);
|
||||||
|
queue_families.resize(queue_family_count);
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(
|
||||||
|
physical_device, &queue_family_count, queue_families.data());
|
||||||
|
const uint32_t queue_flags_required =
|
||||||
|
VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT;
|
||||||
|
for (uint32_t i = 0; i < queue_family_count; ++i) {
|
||||||
|
const VkQueueFamilyProperties& queue_family_properties =
|
||||||
|
queue_families[i];
|
||||||
|
// Arbitrary copying done when loading textures.
|
||||||
|
if (queue_family_properties.minImageTransferGranularity.width > 1 ||
|
||||||
|
queue_family_properties.minImageTransferGranularity.height > 1 ||
|
||||||
|
queue_family_properties.minImageTransferGranularity.depth > 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((queue_family_properties.queueFlags & queue_flags_required) !=
|
||||||
|
queue_flags_required) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
queue_family = i;
|
||||||
|
if (!sparse_residency_buffer ||
|
||||||
|
(queue_family_properties.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT)) {
|
||||||
|
// Found a fully compatible queue family, stop searching for a family
|
||||||
|
// that support both graphics/compute/transfer and sparse binding.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (queue_family == UINT32_MAX) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!(queue_families[queue_family].queueFlags &
|
||||||
|
VK_QUEUE_SPARSE_BINDING_BIT)) {
|
||||||
|
sparse_residency_buffer = false;
|
||||||
|
}
|
||||||
|
physical_device_ = physical_device;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (physical_device_ == VK_NULL_HANDLE) {
|
||||||
|
XELOGE("Failed to get a supported Vulkan physical device.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
supports_sparse_residency_buffer_ = sparse_residency_buffer;
|
||||||
|
supports_texture_compression_bc_ =
|
||||||
|
physical_device_features.textureCompressionBC != VK_FALSE;
|
||||||
|
// TODO(Triang3l): Check if VK_EXT_fragment_shader_interlock and
|
||||||
|
// fragmentShaderSampleInterlock are supported.
|
||||||
|
|
||||||
|
// Log physical device properties.
|
||||||
|
VkPhysicalDeviceProperties physical_device_properties;
|
||||||
|
vkGetPhysicalDeviceProperties(physical_device_, &physical_device_properties);
|
||||||
|
XELOGVK("Vulkan physical device: %s (vendor %.4X, device %.4X)",
|
||||||
|
physical_device_properties.deviceName,
|
||||||
|
physical_device_properties.vendorID,
|
||||||
|
physical_device_properties.deviceID);
|
||||||
|
XELOGVK("* Sparse buffer residency: %s",
|
||||||
|
supports_sparse_residency_buffer_ ? "yes" : "no");
|
||||||
|
XELOGVK("* BC texture compression: %s",
|
||||||
|
supports_texture_compression_bc_ ? "yes" : "no");
|
||||||
|
|
||||||
|
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 vk
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
|
@ -0,0 +1,54 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_UI_VK_VULKAN_PROVIDER_H_
|
||||||
|
#define XENIA_UI_VK_VULKAN_PROVIDER_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "third_party/volk/volk.h"
|
||||||
|
|
||||||
|
#define XELOGVK XELOGI
|
||||||
|
|
||||||
|
#include "xenia/ui/graphics_provider.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace vk {
|
||||||
|
|
||||||
|
class VulkanImmediateDrawer;
|
||||||
|
|
||||||
|
class VulkanProvider : public GraphicsProvider {
|
||||||
|
public:
|
||||||
|
~VulkanProvider() override;
|
||||||
|
|
||||||
|
static std::unique_ptr<VulkanProvider> Create(Window* main_window);
|
||||||
|
|
||||||
|
std::unique_ptr<GraphicsContext> CreateContext(
|
||||||
|
Window* target_window) override;
|
||||||
|
std::unique_ptr<GraphicsContext> CreateOffscreenContext() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit VulkanProvider(Window* main_window);
|
||||||
|
|
||||||
|
bool Initialize();
|
||||||
|
|
||||||
|
VkInstance instance_ = VK_NULL_HANDLE;
|
||||||
|
VkPhysicalDevice physical_device_ = VK_NULL_HANDLE;
|
||||||
|
bool supports_sparse_residency_buffer_ = false;
|
||||||
|
bool supports_texture_compression_bc_ = false;
|
||||||
|
VkDevice device_ = VK_NULL_HANDLE;
|
||||||
|
VkQueue graphics_queue_ = VK_NULL_HANDLE;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace vk
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
#endif // XENIA_UI_VK_VULKAN_PROVIDER_H_
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2019 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_UI_VK_VULKAN_UTIL_H_
|
||||||
|
#define XENIA_UI_VK_VULKAN_UTIL_H_
|
||||||
|
|
||||||
|
#include "xenia/ui/vk/vulkan_provider.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace vk {
|
||||||
|
namespace util {
|
||||||
|
|
||||||
|
template <typename F, typename T>
|
||||||
|
inline bool DestroyAndNullHandle(F* destroy_function, T& handle) {
|
||||||
|
if (handle != VK_NULL_HANDLE) {
|
||||||
|
destroy_function(handle, nullptr);
|
||||||
|
handle = VK_NULL_HANDLE;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace util
|
||||||
|
} // namespace vk
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
#endif // XENIA_UI_VK_VULKAN_UTIL_H_
|
Loading…
Reference in New Issue