diff --git a/src/engine/renderer/vk.cpp b/src/engine/renderer/vk.cpp index b71e020..a99c813 100644 --- a/src/engine/renderer/vk.cpp +++ b/src/engine/renderer/vk.cpp @@ -797,7 +797,49 @@ static void deinit_vulkan_library() { VkPipeline create_pipeline(const Vk_Pipeline_Def&); +// Helper function for acquiring the first available hardware adapter that supports Direct3D 12. +// If no such adapter can be found, *ppAdapter will be set to nullptr. +void get_hardware_adapter(IDXGIFactory4* p_factory, IDXGIAdapter1** pp_adapter) { + ComPtr adapter; + *pp_adapter = nullptr; + + for (UINT adapter_index = 0; DXGI_ERROR_NOT_FOUND != p_factory->EnumAdapters1(adapter_index, &adapter); ++adapter_index) { + DXGI_ADAPTER_DESC1 desc; + adapter->GetDesc1(&desc); + + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { + // Don't select the Basic Render Driver adapter. + // If you want a software adapter, pass in "/warp" on the command line. + continue; + } + + // Check to see if the adapter supports Direct3D 12, but don't create the + // actual device yet. + if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) { + break; + } + } + *pp_adapter = adapter.Detach(); +} + void vk_initialize() { +#if defined(_DEBUG) + // Enable the D3D12 debug layer + { + ComPtr debug_controller; + if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debug_controller)))) { + debug_controller->EnableDebugLayer(); + } + } +#endif + + ComPtr factory; + DX_CHECK(CreateDXGIFactory1(IID_PPV_ARGS(&factory))); + + ComPtr hardware_adapter; + get_hardware_adapter(factory.Get(), &hardware_adapter); + DX_CHECK(D3D12CreateDevice(hardware_adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&vk.dx_device))); + init_vulkan_library(); VkPhysicalDeviceFeatures features; diff --git a/src/engine/renderer/vk.h b/src/engine/renderer/vk.h index ebc2d13..b71017e 100644 --- a/src/engine/renderer/vk.h +++ b/src/engine/renderer/vk.h @@ -8,6 +8,13 @@ #define VK_NO_PROTOTYPES #include "vulkan/vulkan.h" +#include "D3d12.h" +#include "D3d12SDKLayers.h" +#include "DXGI1_4.h" +#include "wrl.h" + +using Microsoft::WRL::ComPtr; + const int MAX_SWAPCHAIN_IMAGES = 8; const int MAX_VK_SAMPLERS = 32; const int MAX_VK_PIPELINES = 1024; @@ -22,6 +29,12 @@ const int MAX_IMAGE_CHUNKS = 16; ri.Error(ERR_FATAL, "Vulkan: error code %d returned by %s", result, #function_call); \ } +#define DX_CHECK(function_call) { \ + HRESULT hr = function_call; \ + if (FAILED(hr)) \ + ri.Error(ERR_FATAL, "Direct3D: error returned by %s", #function_call); \ +} + enum class Vk_Shader_Type { single_texture, multi_texture_mul, @@ -107,6 +120,9 @@ void vk_read_pixels(byte* buffer); // screenshots // This structure is initialized/deinitialized by vk_initialize/vk_shutdown functions correspondingly. struct Vk_Instance { bool active = false; + + ComPtr dx_device; + VkInstance instance = VK_NULL_HANDLE; VkPhysicalDevice physical_device = VK_NULL_HANDLE; VkSurfaceKHR surface = VK_NULL_HANDLE; diff --git a/visual-studio/quake3.vcxproj b/visual-studio/quake3.vcxproj index 1c08b83..7f3d389 100644 --- a/visual-studio/quake3.vcxproj +++ b/visual-studio/quake3.vcxproj @@ -79,7 +79,7 @@ 0x0409 - winmm.lib;wsock32.lib;%(AdditionalDependencies) + winmm.lib;wsock32.lib;D3d12.lib;DXGI.lib;%(AdditionalDependencies) true true Windows @@ -120,7 +120,7 @@ 0x0409 - winmm.lib;wsock32.lib;%(AdditionalDependencies) + winmm.lib;wsock32.lib;D3d12.lib;DXGI.lib;%(AdditionalDependencies) true Windows 8388608