From 6569f9f0a4025ec66ccbf96c45af8a5c3c647dfe Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Wed, 7 Feb 2018 09:34:30 -0500 Subject: [PATCH] D3D12: Move initialization of the device in the backend --- src/backend/d3d12/D3D12Backend.cpp | 86 +++++++++++++++++++++++------ src/backend/d3d12/D3D12Backend.h | 13 ++--- src/backend/d3d12/d3d12_platform.h | 4 ++ src/utils/D3D12Binding.cpp | 87 ++---------------------------- 4 files changed, 85 insertions(+), 105 deletions(-) diff --git a/src/backend/d3d12/D3D12Backend.cpp b/src/backend/d3d12/D3D12Backend.cpp index fe23c58506..230d0a8280 100644 --- a/src/backend/d3d12/D3D12Backend.cpp +++ b/src/backend/d3d12/D3D12Backend.cpp @@ -43,13 +43,10 @@ namespace backend { namespace d3d12 { nxtProcTable GetNonValidatingProcs(); nxtProcTable GetValidatingProcs(); - void Init(ComPtr factory, - ComPtr d3d12Device, - nxtProcTable* procs, - nxtDevice* device) { + void Init(nxtProcTable* procs, nxtDevice* device) { *device = nullptr; *procs = GetValidatingProcs(); - *device = reinterpret_cast(new Device(factory, d3d12Device)); + *device = reinterpret_cast(new Device()); } nxtSwapChainImplementation CreateNativeSwapChainImpl(nxtDevice device, HWND window) { @@ -67,24 +64,83 @@ namespace backend { namespace d3d12 { ASSERT(SUCCEEDED(hr)); } - Device::Device(ComPtr factory, ComPtr d3d12Device) - : mFactory(factory), - mD3d12Device(d3d12Device), - mCommandAllocatorManager(new CommandAllocatorManager(this)), - mDescriptorHeapAllocator(new DescriptorHeapAllocator(this)), - mMapReadRequestTracker(new MapReadRequestTracker(this)), - mResourceAllocator(new ResourceAllocator(this)), - mResourceUploader(new ResourceUploader(this)) { + namespace { + ComPtr CreateFactory() { + ComPtr factory; + + uint32_t dxgiFactoryFlags = 0; +#if defined(NXT_ENABLE_ASSERTS) + // Enable the debug layer (requires the Graphics Tools "optional feature"). + { + ComPtr debugController; + if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) { + debugController->EnableDebugLayer(); + + // Enable additional debug layers. + dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG; + } + + ComPtr dxgiDebug; + if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(&dxgiDebug)))) { + dxgiDebug->ReportLiveObjects(DXGI_DEBUG_ALL, + DXGI_DEBUG_RLO_FLAGS(DXGI_DEBUG_RLO_ALL)); + } + } +#endif // defined(NXT_ENABLE_ASSERTS) + + ASSERT_SUCCESS(CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&factory))); + return factory; + } + + ComPtr GetHardwareAdapter(ComPtr factory) { + for (uint32_t adapterIndex = 0;; ++adapterIndex) { + IDXGIAdapter1* adapter = nullptr; + if (factory->EnumAdapters1(adapterIndex, &adapter) == DXGI_ERROR_NOT_FOUND) { + break; // No more adapters to enumerate. + } + + // Check to see if the adapter supports Direct3D 12, but don't create the actual + // device yet. + if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, + _uuidof(ID3D12Device), nullptr))) { + return adapter; + } + adapter->Release(); + } + return nullptr; + } + + } // anonymous namespace + + Device::Device() { + // Create the connection to DXGI and the D3D12 device + mFactory = CreateFactory(); + ASSERT(mFactory.Get() != nullptr); + + mHardwareAdapter = GetHardwareAdapter(mFactory); + ASSERT(mHardwareAdapter.Get() != nullptr); + + ASSERT_SUCCESS(D3D12CreateDevice(mHardwareAdapter.Get(), D3D_FEATURE_LEVEL_11_0, + IID_PPV_ARGS(&mD3d12Device))); + + // Create device-global objects D3D12_COMMAND_QUEUE_DESC queueDesc = {}; queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - ASSERT_SUCCESS(d3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue))); + ASSERT_SUCCESS(mD3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue))); ASSERT_SUCCESS( - d3d12Device->CreateFence(mSerial, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&mFence))); + mD3d12Device->CreateFence(mSerial, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&mFence))); mFenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); ASSERT(mFenceEvent != nullptr); + // Initialize backend services + mCommandAllocatorManager = new CommandAllocatorManager(this); + mDescriptorHeapAllocator = new DescriptorHeapAllocator(this); + mMapReadRequestTracker = new MapReadRequestTracker(this); + mResourceAllocator = new ResourceAllocator(this); + mResourceUploader = new ResourceUploader(this); + NextSerial(); } diff --git a/src/backend/d3d12/D3D12Backend.h b/src/backend/d3d12/D3D12Backend.h index 3332ef575f..22f0938a9d 100644 --- a/src/backend/d3d12/D3D12Backend.h +++ b/src/backend/d3d12/D3D12Backend.h @@ -86,7 +86,7 @@ namespace backend { namespace d3d12 { // Definition of backend types class Device : public DeviceBase { public: - Device(ComPtr factory, ComPtr d3d12Device); + Device(); ~Device(); BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override; @@ -135,14 +135,15 @@ namespace backend { namespace d3d12 { HANDLE mFenceEvent; ComPtr mFactory; + ComPtr mHardwareAdapter; ComPtr mD3d12Device; ComPtr mCommandQueue; - CommandAllocatorManager* mCommandAllocatorManager; - DescriptorHeapAllocator* mDescriptorHeapAllocator; - MapReadRequestTracker* mMapReadRequestTracker; - ResourceAllocator* mResourceAllocator; - ResourceUploader* mResourceUploader; + CommandAllocatorManager* mCommandAllocatorManager = nullptr; + DescriptorHeapAllocator* mDescriptorHeapAllocator = nullptr; + MapReadRequestTracker* mMapReadRequestTracker = nullptr; + ResourceAllocator* mResourceAllocator = nullptr; + ResourceUploader* mResourceUploader = nullptr; struct PendingCommandList { ComPtr commandList; diff --git a/src/backend/d3d12/d3d12_platform.h b/src/backend/d3d12/d3d12_platform.h index b37270d61d..e3f08008a9 100644 --- a/src/backend/d3d12/d3d12_platform.h +++ b/src/backend/d3d12/d3d12_platform.h @@ -19,6 +19,10 @@ #include #include +#if defined(NXT_ENABLE_ASSERTS) +# include +#endif // defined(NXT_ENABLE_ASSERTS) + using Microsoft::WRL::ComPtr; #endif // BACKEND_D3D12_D3D12PLATFORM_H_ diff --git a/src/utils/D3D12Binding.cpp b/src/utils/D3D12Binding.cpp index e33a14ae3c..a6538ac82f 100644 --- a/src/utils/D3D12Binding.cpp +++ b/src/utils/D3D12Binding.cpp @@ -17,67 +17,18 @@ #include "common/Assert.h" #include "nxt/nxt_wsi.h" -#define GLFW_EXPOSE_NATIVE_WIN32 #include "GLFW/glfw3.h" +#define GLFW_EXPOSE_NATIVE_WIN32 #include "GLFW/glfw3native.h" -#include -#include -#include -#include -#ifdef _DEBUG -#include -#endif - -using Microsoft::WRL::ComPtr; - namespace backend { namespace d3d12 { - void Init(ComPtr factory, - ComPtr d3d12Device, - nxtProcTable* procs, - nxtDevice* device); + void Init(nxtProcTable* procs, nxtDevice* device); nxtSwapChainImplementation CreateNativeSwapChainImpl(nxtDevice device, HWND window); nxtTextureFormat GetNativeSwapChainPreferredFormat(const nxtSwapChainImplementation* swapChain); }} // namespace backend::d3d12 namespace utils { - namespace { - void ASSERT_SUCCESS(HRESULT hr) { - ASSERT(SUCCEEDED(hr)); - } - - ComPtr CreateFactory() { - ComPtr factory; - - uint32_t dxgiFactoryFlags = 0; -#ifdef _DEBUG - // Enable the debug layer (requires the Graphics Tools "optional feature"). - // NOTE: Enabling the debug layer after device creation will invalidate the active - // device. - { - ComPtr debugController; - if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) { - debugController->EnableDebugLayer(); - - // Enable additional debug layers. - dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG; - } - - ComPtr dxgiDebug; - if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(&dxgiDebug)))) { - dxgiDebug->ReportLiveObjects(DXGI_DEBUG_ALL, - DXGI_DEBUG_RLO_FLAGS(DXGI_DEBUG_RLO_ALL)); - } - } -#endif - - ASSERT_SUCCESS(CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&factory))); - - return factory; - } - - } // namespace class D3D12Binding : public BackendBinding { public: @@ -86,14 +37,8 @@ namespace utils { } void GetProcAndDevice(nxtProcTable* procs, nxtDevice* device) override { - mFactory = CreateFactory(); - ASSERT(GetHardwareAdapter(mFactory.Get(), &mHardwareAdapter)); - ASSERT_SUCCESS(D3D12CreateDevice(mHardwareAdapter.Get(), D3D_FEATURE_LEVEL_11_0, - IID_PPV_ARGS(&mD3d12Device))); - - backend::d3d12::Init(mFactory, mD3d12Device, procs, device); + backend::d3d12::Init(procs, device); mBackendDevice = *device; - mProcTable = *procs; } uint64_t GetSwapChainImplementation() override { @@ -113,32 +58,6 @@ namespace utils { private: nxtDevice mBackendDevice = nullptr; nxtSwapChainImplementation mSwapchainImpl = {}; - nxtProcTable mProcTable = {}; - - // Initialization - ComPtr mFactory; - ComPtr mHardwareAdapter; - ComPtr mD3d12Device; - - static bool GetHardwareAdapter(IDXGIFactory4* factory, IDXGIAdapter1** hardwareAdapter) { - *hardwareAdapter = nullptr; - for (uint32_t adapterIndex = 0;; ++adapterIndex) { - IDXGIAdapter1* adapter = nullptr; - if (factory->EnumAdapters1(adapterIndex, &adapter) == DXGI_ERROR_NOT_FOUND) { - break; // No more adapters to enumerate. - } - - // Check to see if the adapter supports Direct3D 12, but don't create the actual - // device yet. - if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, - _uuidof(ID3D12Device), nullptr))) { - *hardwareAdapter = adapter; - return true; - } - adapter->Release(); - } - return false; - } }; BackendBinding* CreateD3D12Binding() {