[Vulkan] Context, remove Volk
This commit is contained in:
@@ -9,9 +9,6 @@
|
||||
|
||||
#include "xenia/ui/d3d12/d3d12_context.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "xenia/base/cvar.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/ui/d3d12/d3d12_immediate_drawer.h"
|
||||
@@ -19,9 +16,6 @@
|
||||
#include "xenia/ui/d3d12/d3d12_util.h"
|
||||
#include "xenia/ui/window.h"
|
||||
|
||||
DEFINE_bool(d3d12_random_clear_color, false,
|
||||
"Randomize presentation back buffer clear color.", "D3D12");
|
||||
|
||||
namespace xe {
|
||||
namespace ui {
|
||||
namespace d3d12 {
|
||||
@@ -32,110 +26,112 @@ D3D12Context::D3D12Context(D3D12Provider* provider, Window* target_window)
|
||||
D3D12Context::~D3D12Context() { Shutdown(); }
|
||||
|
||||
bool D3D12Context::Initialize() {
|
||||
context_lost_ = false;
|
||||
|
||||
if (!target_window_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto& provider = GetD3D12Provider();
|
||||
auto dxgi_factory = provider.GetDXGIFactory();
|
||||
auto device = provider.GetDevice();
|
||||
auto direct_queue = provider.GetDirectQueue();
|
||||
|
||||
context_lost_ = false;
|
||||
swap_fence_current_value_ = 1;
|
||||
swap_fence_completed_value_ = 0;
|
||||
swap_fence_completion_event_ = CreateEvent(nullptr, false, false, nullptr);
|
||||
if (swap_fence_completion_event_ == nullptr) {
|
||||
XELOGE("Failed to create the composition fence completion event");
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
// Create a fence for transient resources of compositing.
|
||||
if (FAILED(device->CreateFence(0, D3D12_FENCE_FLAG_NONE,
|
||||
IID_PPV_ARGS(&swap_fence_)))) {
|
||||
XELOGE("Failed to create the composition fence");
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target_window_) {
|
||||
swap_fence_current_value_ = 1;
|
||||
swap_fence_completed_value_ = 0;
|
||||
swap_fence_completion_event_ = CreateEvent(nullptr, false, false, nullptr);
|
||||
if (swap_fence_completion_event_ == nullptr) {
|
||||
XELOGE("Failed to create the composition fence completion event");
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
// Create a fence for transient resources of compositing.
|
||||
if (FAILED(device->CreateFence(0, D3D12_FENCE_FLAG_NONE,
|
||||
IID_PPV_ARGS(&swap_fence_)))) {
|
||||
XELOGE("Failed to create the composition fence");
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the swap chain.
|
||||
swap_chain_width_ = target_window_->scaled_width();
|
||||
swap_chain_height_ = target_window_->scaled_height();
|
||||
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc;
|
||||
swap_chain_desc.Width = swap_chain_width_;
|
||||
swap_chain_desc.Height = swap_chain_height_;
|
||||
swap_chain_desc.Format = kSwapChainFormat;
|
||||
swap_chain_desc.Stereo = FALSE;
|
||||
swap_chain_desc.SampleDesc.Count = 1;
|
||||
swap_chain_desc.SampleDesc.Quality = 0;
|
||||
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swap_chain_desc.BufferCount = kSwapChainBufferCount;
|
||||
swap_chain_desc.Scaling = DXGI_SCALING_STRETCH;
|
||||
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
swap_chain_desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
|
||||
swap_chain_desc.Flags = 0;
|
||||
IDXGISwapChain1* swap_chain_1;
|
||||
if (FAILED(dxgi_factory->CreateSwapChainForHwnd(
|
||||
provider.GetDirectQueue(),
|
||||
static_cast<HWND>(target_window_->native_handle()),
|
||||
&swap_chain_desc, nullptr, nullptr, &swap_chain_1))) {
|
||||
XELOGE("Failed to create a DXGI swap chain");
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
if (FAILED(swap_chain_1->QueryInterface(IID_PPV_ARGS(&swap_chain_)))) {
|
||||
XELOGE("Failed to get version 3 of the DXGI swap chain interface");
|
||||
swap_chain_1->Release();
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
// Create the swap chain.
|
||||
swap_chain_width_ = target_window_->scaled_width();
|
||||
swap_chain_height_ = target_window_->scaled_height();
|
||||
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc;
|
||||
swap_chain_desc.Width = swap_chain_width_;
|
||||
swap_chain_desc.Height = swap_chain_height_;
|
||||
swap_chain_desc.Format = kSwapChainFormat;
|
||||
swap_chain_desc.Stereo = FALSE;
|
||||
swap_chain_desc.SampleDesc.Count = 1;
|
||||
swap_chain_desc.SampleDesc.Quality = 0;
|
||||
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swap_chain_desc.BufferCount = kSwapChainBufferCount;
|
||||
swap_chain_desc.Scaling = DXGI_SCALING_STRETCH;
|
||||
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
swap_chain_desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
|
||||
swap_chain_desc.Flags = 0;
|
||||
IDXGISwapChain1* swap_chain_1;
|
||||
if (FAILED(dxgi_factory->CreateSwapChainForHwnd(
|
||||
provider.GetDirectQueue(),
|
||||
reinterpret_cast<HWND>(target_window_->native_handle()),
|
||||
&swap_chain_desc, nullptr, nullptr, &swap_chain_1))) {
|
||||
XELOGE("Failed to create a DXGI swap chain");
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
if (FAILED(swap_chain_1->QueryInterface(IID_PPV_ARGS(&swap_chain_)))) {
|
||||
XELOGE("Failed to get version 3 of the DXGI swap chain interface");
|
||||
swap_chain_1->Release();
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
swap_chain_1->Release();
|
||||
|
||||
// Create a heap for RTV descriptors of swap chain buffers.
|
||||
D3D12_DESCRIPTOR_HEAP_DESC rtv_heap_desc;
|
||||
rtv_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||
rtv_heap_desc.NumDescriptors = kSwapChainBufferCount;
|
||||
rtv_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||
rtv_heap_desc.NodeMask = 0;
|
||||
if (FAILED(device->CreateDescriptorHeap(
|
||||
&rtv_heap_desc, IID_PPV_ARGS(&swap_chain_rtv_heap_)))) {
|
||||
XELOGE("Failed to create swap chain RTV descriptor heap");
|
||||
// Create a heap for RTV descriptors of swap chain buffers.
|
||||
D3D12_DESCRIPTOR_HEAP_DESC rtv_heap_desc;
|
||||
rtv_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||
rtv_heap_desc.NumDescriptors = kSwapChainBufferCount;
|
||||
rtv_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||
rtv_heap_desc.NodeMask = 0;
|
||||
if (FAILED(device->CreateDescriptorHeap(
|
||||
&rtv_heap_desc, IID_PPV_ARGS(&swap_chain_rtv_heap_)))) {
|
||||
XELOGE("Failed to create swap chain RTV descriptor heap");
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
swap_chain_rtv_heap_start_ =
|
||||
swap_chain_rtv_heap_->GetCPUDescriptorHandleForHeapStart();
|
||||
|
||||
// Get the buffers and create their RTV descriptors.
|
||||
if (!InitializeSwapChainBuffers()) {
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the command list for compositing.
|
||||
for (uint32_t i = 0; i < kSwapCommandAllocatorCount; ++i) {
|
||||
if (FAILED(device->CreateCommandAllocator(
|
||||
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
IID_PPV_ARGS(&swap_command_allocators_[i])))) {
|
||||
XELOGE("Failed to create a composition command allocator");
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
swap_chain_rtv_heap_start_ =
|
||||
swap_chain_rtv_heap_->GetCPUDescriptorHandleForHeapStart();
|
||||
}
|
||||
if (FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
swap_command_allocators_[0], nullptr,
|
||||
IID_PPV_ARGS(&swap_command_list_)))) {
|
||||
XELOGE("Failed to create the composition graphics command list");
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
// Initially in open state, wait until BeginSwap.
|
||||
swap_command_list_->Close();
|
||||
|
||||
// Get the buffers and create their RTV descriptors.
|
||||
if (!InitializeSwapChainBuffers()) {
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the command list for compositing.
|
||||
for (uint32_t i = 0; i < kSwapCommandAllocatorCount; ++i) {
|
||||
if (FAILED(device->CreateCommandAllocator(
|
||||
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
IID_PPV_ARGS(&swap_command_allocators_[i])))) {
|
||||
XELOGE("Failed to create a composition command allocator");
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
swap_command_allocators_[0], nullptr,
|
||||
IID_PPV_ARGS(&swap_command_list_)))) {
|
||||
XELOGE("Failed to create the composition graphics command list");
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
// Initially in open state, wait until BeginSwap.
|
||||
swap_command_list_->Close();
|
||||
|
||||
// Initialize the immediate mode drawer if not offscreen.
|
||||
immediate_drawer_ = std::make_unique<D3D12ImmediateDrawer>(*this);
|
||||
if (!immediate_drawer_->Initialize()) {
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
// Initialize the immediate mode drawer if not offscreen.
|
||||
immediate_drawer_ = std::make_unique<D3D12ImmediateDrawer>(*this);
|
||||
if (!immediate_drawer_->Initialize()) {
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -223,9 +219,11 @@ ImmediateDrawer* D3D12Context::immediate_drawer() {
|
||||
return immediate_drawer_.get();
|
||||
}
|
||||
|
||||
void D3D12Context::BeginSwap() {
|
||||
bool D3D12Context::WasLost() { return context_lost_; }
|
||||
|
||||
bool D3D12Context::BeginSwap() {
|
||||
if (!target_window_ || context_lost_) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Resize the swap chain if the window is resized.
|
||||
@@ -252,13 +250,13 @@ void D3D12Context::BeginSwap() {
|
||||
kSwapChainBufferCount, target_window_width, target_window_height,
|
||||
kSwapChainFormat, 0))) {
|
||||
context_lost_ = true;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
swap_chain_width_ = target_window_width;
|
||||
swap_chain_height_ = target_window_height;
|
||||
if (!InitializeSwapChainBuffers()) {
|
||||
context_lost_ = true;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,18 +293,11 @@ void D3D12Context::BeginSwap() {
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE back_buffer_rtv = GetSwapChainBackBufferRTV();
|
||||
swap_command_list_->OMSetRenderTargets(1, &back_buffer_rtv, TRUE, nullptr);
|
||||
float clear_color[4];
|
||||
if (cvars::d3d12_random_clear_color) {
|
||||
clear_color[0] = rand() / float(RAND_MAX); // NOLINT(runtime/threadsafe_fn)
|
||||
clear_color[1] = 1.0f;
|
||||
clear_color[2] = 0.0f;
|
||||
} else {
|
||||
clear_color[0] = 0.0f;
|
||||
clear_color[1] = 0.0f;
|
||||
clear_color[2] = 0.0f;
|
||||
}
|
||||
clear_color[3] = 1.0f;
|
||||
GetClearColor(clear_color);
|
||||
swap_command_list_->ClearRenderTargetView(back_buffer_rtv, clear_color, 0,
|
||||
nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void D3D12Context::EndSwap() {
|
||||
|
||||
@@ -28,9 +28,9 @@ class D3D12Context : public GraphicsContext {
|
||||
|
||||
ImmediateDrawer* immediate_drawer() override;
|
||||
|
||||
bool WasLost() override { return context_lost_; }
|
||||
bool WasLost() override;
|
||||
|
||||
void BeginSwap() override;
|
||||
bool BeginSwap() override;
|
||||
void EndSwap() override;
|
||||
|
||||
std::unique_ptr<RawImage> Capture() override;
|
||||
|
||||
Reference in New Issue
Block a user