More DX12 initialization code,
This commit is contained in:
parent
22d5bdd053
commit
5434627172
|
|
@ -431,7 +431,7 @@ static HWND create_main_window(int width, int height, qboolean fullscreen)
|
|||
return hwnd;
|
||||
}
|
||||
|
||||
static HWND create_twin_window(int width, int height)
|
||||
static HWND create_twin_window(int width, int height, bool dx_window)
|
||||
{
|
||||
//
|
||||
// register the window class if necessary
|
||||
|
|
@ -502,7 +502,7 @@ static HWND create_twin_window(int width, int height)
|
|||
// If r_renderAPI = 0 (OpenGL) then twin window uses Vulkan API.
|
||||
// If r_renderAPI = 1 (Vulkan) then twin window uses OpenGL API.
|
||||
char window_name[1024];
|
||||
sprintf(window_name, "%s [%s]", MAIN_WINDOW_CLASS_NAME, r_renderAPI->integer == 0 ? "Vulkan" : "OpenGL");
|
||||
sprintf(window_name, "%s [%s]", MAIN_WINDOW_CLASS_NAME, dx_window ? "DX12" : (r_renderAPI->integer == 0 ? "Vulkan" : "OpenGL"));
|
||||
|
||||
HWND hwnd = CreateWindowEx(
|
||||
0,
|
||||
|
|
@ -726,7 +726,7 @@ void GLimp_Init( void )
|
|||
SetFocus(g_wv.hWnd);
|
||||
WG_CheckHardwareGamma();
|
||||
} else {
|
||||
g_wv.hWnd_opengl = create_twin_window(glConfig.vidWidth, glConfig.vidHeight);
|
||||
g_wv.hWnd_opengl = create_twin_window(glConfig.vidWidth, glConfig.vidHeight, false);
|
||||
}
|
||||
|
||||
if (!GLW_InitDriver(g_wv.hWnd_opengl)) {
|
||||
|
|
@ -837,8 +837,10 @@ void vk_imp_init() {
|
|||
SetForegroundWindow(g_wv.hWnd);
|
||||
SetFocus(g_wv.hWnd);
|
||||
WG_CheckHardwareGamma();
|
||||
|
||||
g_wv.hWnd_dx = create_twin_window(glConfig.vidWidth, glConfig.vidHeight, true);
|
||||
} else {
|
||||
g_wv.hWnd_vulkan = create_twin_window(glConfig.vidWidth, glConfig.vidHeight);
|
||||
g_wv.hWnd_vulkan = create_twin_window(glConfig.vidWidth, glConfig.vidHeight, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -862,6 +864,16 @@ void vk_imp_shutdown() {
|
|||
}
|
||||
vkGetInstanceProcAddr = nullptr;
|
||||
|
||||
if (g_wv.hWnd_dx) {
|
||||
ri.Printf(PRINT_ALL, "...destroying DX12 window\n");
|
||||
DestroyWindow(g_wv.hWnd_dx);
|
||||
|
||||
if (g_wv.hWnd == g_wv.hWnd_dx) {
|
||||
g_wv.hWnd_dx = NULL;
|
||||
}
|
||||
g_wv.hWnd_dx = NULL;
|
||||
}
|
||||
|
||||
// For vulkan mode we still have qgl pointers initialized with placeholder values.
|
||||
// Reset them the same way as we do in opengl mode.
|
||||
QGL_Shutdown();
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
*/
|
||||
// win_local.h: Win32-specific Quake3 header file
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined (_MSC_VER) && (_MSC_VER >= 1200)
|
||||
#pragma warning(disable : 4201)
|
||||
#pragma warning( push )
|
||||
|
|
@ -77,6 +79,7 @@ typedef struct
|
|||
|
||||
HWND hWnd_opengl;
|
||||
HWND hWnd_vulkan;
|
||||
HWND hWnd_dx;
|
||||
|
||||
HINSTANCE hInstance;
|
||||
qboolean activeApp;
|
||||
|
|
|
|||
2540
src/engine/renderer/d3dx12.h
Normal file
2540
src/engine/renderer/d3dx12.h
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -201,6 +201,7 @@ static void InitRenderAPI( void )
|
|||
if (r_renderAPI->integer != 0 || r_twinMode->integer) {
|
||||
vk_imp_init();
|
||||
vk_initialize();
|
||||
dx_initialize();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1117,6 +1118,8 @@ void RE_Shutdown( qboolean destroyWindow ) {
|
|||
if (vk.active) {
|
||||
vk_release_resources();
|
||||
if (destroyWindow) {
|
||||
dx_shutdown();
|
||||
|
||||
vk_shutdown();
|
||||
vk_imp_shutdown();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -822,7 +822,7 @@ void get_hardware_adapter(IDXGIFactory4* p_factory, IDXGIAdapter1** pp_adapter)
|
|||
*pp_adapter = adapter.Detach();
|
||||
}
|
||||
|
||||
void vk_initialize() {
|
||||
void dx_initialize() {
|
||||
#if defined(_DEBUG)
|
||||
// Enable the D3D12 debug layer
|
||||
{
|
||||
|
|
@ -840,6 +840,66 @@ void vk_initialize() {
|
|||
get_hardware_adapter(factory.Get(), &hardware_adapter);
|
||||
DX_CHECK(D3D12CreateDevice(hardware_adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&vk.dx_device)));
|
||||
|
||||
// Describe and create the command queue.
|
||||
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
||||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
|
||||
DX_CHECK(vk.dx_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&vk.dx_command_queue)));
|
||||
|
||||
// Describe and create the swap chain.
|
||||
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
|
||||
swapChainDesc.BufferCount = D3D_FRAME_COUNT;
|
||||
swapChainDesc.Width = glConfig.vidWidth;
|
||||
swapChainDesc.Height = glConfig.vidHeight;
|
||||
swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
swapChainDesc.SampleDesc.Count = 1;
|
||||
|
||||
ComPtr<IDXGISwapChain1> swapchain;
|
||||
DX_CHECK(factory->CreateSwapChainForHwnd(
|
||||
vk.dx_command_queue, // Swap chain needs the queue so that it can force a flush on it.
|
||||
g_wv.hWnd_dx,
|
||||
&swapChainDesc,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&swapchain
|
||||
));
|
||||
|
||||
// This sample does not support fullscreen transitions.
|
||||
DX_CHECK(factory->MakeWindowAssociation(g_wv.hWnd_dx, DXGI_MWA_NO_ALT_ENTER));
|
||||
DX_CHECK(swapchain.As(&vk.dx_swapchain));
|
||||
|
||||
// Create descriptor heaps.
|
||||
{
|
||||
// Describe and create a render target view (RTV) descriptor heap.
|
||||
D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
|
||||
rtvHeapDesc.NumDescriptors = D3D_FRAME_COUNT;
|
||||
rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||
rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||
DX_CHECK(vk.dx_device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&vk.dx_rtv_heap)));
|
||||
|
||||
vk.dx_rtv_descriptor_size = vk.dx_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||
}
|
||||
|
||||
// Create frame resources.
|
||||
{
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE rtv_handle(vk.dx_rtv_heap->GetCPUDescriptorHandleForHeapStart());
|
||||
|
||||
// Create a RTV for each frame.
|
||||
for (UINT n = 0; n < D3D_FRAME_COUNT; n++)
|
||||
{
|
||||
DX_CHECK(vk.dx_swapchain->GetBuffer(n, IID_PPV_ARGS(&vk.render_targets[n])));
|
||||
vk.dx_device->CreateRenderTargetView(vk.render_targets[n].Get(), nullptr, rtv_handle);
|
||||
rtv_handle.Offset(1, vk.dx_rtv_descriptor_size);
|
||||
}
|
||||
}
|
||||
|
||||
DX_CHECK(vk.dx_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&vk.dx_command_allocator)));
|
||||
}
|
||||
|
||||
void vk_initialize() {
|
||||
init_vulkan_library();
|
||||
|
||||
VkPhysicalDeviceFeatures features;
|
||||
|
|
@ -1319,6 +1379,26 @@ void vk_initialize() {
|
|||
vk.active = true;
|
||||
}
|
||||
|
||||
void dx_shutdown() {
|
||||
vk.dx_swapchain.Reset();
|
||||
|
||||
vk.dx_command_allocator->Release();
|
||||
vk.dx_command_allocator = nullptr;
|
||||
|
||||
for (int i = 0; i < D3D_FRAME_COUNT; i++) {
|
||||
vk.render_targets[i].Reset();
|
||||
}
|
||||
|
||||
vk.dx_rtv_heap->Release();
|
||||
vk.dx_rtv_heap = nullptr;
|
||||
|
||||
vk.dx_command_queue->Release();
|
||||
vk.dx_command_queue = nullptr;
|
||||
|
||||
vk.dx_device->Release();
|
||||
vk.dx_device = nullptr;
|
||||
}
|
||||
|
||||
void vk_shutdown() {
|
||||
vkDestroyImage(vk.device, vk.depth_image, nullptr);
|
||||
vkFreeMemory(vk.device, vk.depth_image_memory, nullptr);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
#include "D3d12SDKLayers.h"
|
||||
#include "DXGI1_4.h"
|
||||
#include "wrl.h"
|
||||
#include "d3dx12.h"
|
||||
#include "../../engine/platform/win_local.h"
|
||||
|
||||
using Microsoft::WRL::ComPtr;
|
||||
|
||||
|
|
@ -23,6 +25,8 @@ const int MAX_VK_IMAGES = 2048; // should be the same as MAX_DRAWIMAGES
|
|||
const int IMAGE_CHUNK_SIZE = 32 * 1024 * 1024;
|
||||
const int MAX_IMAGE_CHUNKS = 16;
|
||||
|
||||
const int D3D_FRAME_COUNT = 2;
|
||||
|
||||
#define VK_CHECK(function_call) { \
|
||||
VkResult result = function_call; \
|
||||
if (result < 0) \
|
||||
|
|
@ -89,9 +93,13 @@ struct Vk_Image {
|
|||
// After calling this function we get fully functional vulkan subsystem.
|
||||
void vk_initialize();
|
||||
|
||||
void dx_initialize();
|
||||
|
||||
// Shutdown vulkan subsystem by releasing resources acquired by Vk_Instance.
|
||||
void vk_shutdown();
|
||||
|
||||
void dx_shutdown();
|
||||
|
||||
// Releases vulkan resources allocated during program execution.
|
||||
// This effectively puts vulkan subsystem into initial state (the state we have after vk_initialize call).
|
||||
void vk_release_resources();
|
||||
|
|
@ -121,7 +129,13 @@ void vk_read_pixels(byte* buffer); // screenshots
|
|||
struct Vk_Instance {
|
||||
bool active = false;
|
||||
|
||||
ComPtr<ID3D12Device> dx_device;
|
||||
ID3D12Device* dx_device = nullptr;
|
||||
ID3D12CommandQueue* dx_command_queue = nullptr;
|
||||
ComPtr<IDXGISwapChain3> dx_swapchain;
|
||||
ID3D12DescriptorHeap* dx_rtv_heap = nullptr;
|
||||
UINT dx_rtv_descriptor_size = 0;
|
||||
ComPtr<ID3D12Resource> render_targets[D3D_FRAME_COUNT];
|
||||
ID3D12CommandAllocator* dx_command_allocator = nullptr;
|
||||
|
||||
VkInstance instance = VK_NULL_HANDLE;
|
||||
VkPhysicalDevice physical_device = VK_NULL_HANDLE;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user