D3D12: Move initialization of the device in the backend

This commit is contained in:
Corentin Wallez 2018-02-07 09:34:30 -05:00 committed by Corentin Wallez
parent 9b491437b1
commit 6569f9f0a4
4 changed files with 85 additions and 105 deletions

View File

@ -43,13 +43,10 @@ namespace backend { namespace d3d12 {
nxtProcTable GetNonValidatingProcs(); nxtProcTable GetNonValidatingProcs();
nxtProcTable GetValidatingProcs(); nxtProcTable GetValidatingProcs();
void Init(ComPtr<IDXGIFactory4> factory, void Init(nxtProcTable* procs, nxtDevice* device) {
ComPtr<ID3D12Device> d3d12Device,
nxtProcTable* procs,
nxtDevice* device) {
*device = nullptr; *device = nullptr;
*procs = GetValidatingProcs(); *procs = GetValidatingProcs();
*device = reinterpret_cast<nxtDevice>(new Device(factory, d3d12Device)); *device = reinterpret_cast<nxtDevice>(new Device());
} }
nxtSwapChainImplementation CreateNativeSwapChainImpl(nxtDevice device, HWND window) { nxtSwapChainImplementation CreateNativeSwapChainImpl(nxtDevice device, HWND window) {
@ -67,24 +64,83 @@ namespace backend { namespace d3d12 {
ASSERT(SUCCEEDED(hr)); ASSERT(SUCCEEDED(hr));
} }
Device::Device(ComPtr<IDXGIFactory4> factory, ComPtr<ID3D12Device> d3d12Device) namespace {
: mFactory(factory), ComPtr<IDXGIFactory4> CreateFactory() {
mD3d12Device(d3d12Device), ComPtr<IDXGIFactory4> factory;
mCommandAllocatorManager(new CommandAllocatorManager(this)),
mDescriptorHeapAllocator(new DescriptorHeapAllocator(this)), uint32_t dxgiFactoryFlags = 0;
mMapReadRequestTracker(new MapReadRequestTracker(this)), #if defined(NXT_ENABLE_ASSERTS)
mResourceAllocator(new ResourceAllocator(this)), // Enable the debug layer (requires the Graphics Tools "optional feature").
mResourceUploader(new ResourceUploader(this)) { {
ComPtr<ID3D12Debug> debugController;
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) {
debugController->EnableDebugLayer();
// Enable additional debug layers.
dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG;
}
ComPtr<IDXGIDebug1> 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<IDXGIAdapter1> GetHardwareAdapter(ComPtr<IDXGIFactory4> 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 = {}; D3D12_COMMAND_QUEUE_DESC queueDesc = {};
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; 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( 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); mFenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
ASSERT(mFenceEvent != 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(); NextSerial();
} }

View File

@ -86,7 +86,7 @@ namespace backend { namespace d3d12 {
// Definition of backend types // Definition of backend types
class Device : public DeviceBase { class Device : public DeviceBase {
public: public:
Device(ComPtr<IDXGIFactory4> factory, ComPtr<ID3D12Device> d3d12Device); Device();
~Device(); ~Device();
BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override; BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
@ -135,14 +135,15 @@ namespace backend { namespace d3d12 {
HANDLE mFenceEvent; HANDLE mFenceEvent;
ComPtr<IDXGIFactory4> mFactory; ComPtr<IDXGIFactory4> mFactory;
ComPtr<IDXGIAdapter1> mHardwareAdapter;
ComPtr<ID3D12Device> mD3d12Device; ComPtr<ID3D12Device> mD3d12Device;
ComPtr<ID3D12CommandQueue> mCommandQueue; ComPtr<ID3D12CommandQueue> mCommandQueue;
CommandAllocatorManager* mCommandAllocatorManager; CommandAllocatorManager* mCommandAllocatorManager = nullptr;
DescriptorHeapAllocator* mDescriptorHeapAllocator; DescriptorHeapAllocator* mDescriptorHeapAllocator = nullptr;
MapReadRequestTracker* mMapReadRequestTracker; MapReadRequestTracker* mMapReadRequestTracker = nullptr;
ResourceAllocator* mResourceAllocator; ResourceAllocator* mResourceAllocator = nullptr;
ResourceUploader* mResourceUploader; ResourceUploader* mResourceUploader = nullptr;
struct PendingCommandList { struct PendingCommandList {
ComPtr<ID3D12GraphicsCommandList> commandList; ComPtr<ID3D12GraphicsCommandList> commandList;

View File

@ -19,6 +19,10 @@
#include <dxgi1_4.h> #include <dxgi1_4.h>
#include <wrl.h> #include <wrl.h>
#if defined(NXT_ENABLE_ASSERTS)
# include <dxgidebug.h>
#endif // defined(NXT_ENABLE_ASSERTS)
using Microsoft::WRL::ComPtr; using Microsoft::WRL::ComPtr;
#endif // BACKEND_D3D12_D3D12PLATFORM_H_ #endif // BACKEND_D3D12_D3D12PLATFORM_H_

View File

@ -17,67 +17,18 @@
#include "common/Assert.h" #include "common/Assert.h"
#include "nxt/nxt_wsi.h" #include "nxt/nxt_wsi.h"
#define GLFW_EXPOSE_NATIVE_WIN32
#include "GLFW/glfw3.h" #include "GLFW/glfw3.h"
#define GLFW_EXPOSE_NATIVE_WIN32
#include "GLFW/glfw3native.h" #include "GLFW/glfw3native.h"
#include <d3d12.h>
#include <dxgi1_4.h>
#include <wrl.h>
#include <initializer_list>
#ifdef _DEBUG
#include <dxgidebug.h>
#endif
using Microsoft::WRL::ComPtr;
namespace backend { namespace d3d12 { namespace backend { namespace d3d12 {
void Init(ComPtr<IDXGIFactory4> factory, void Init(nxtProcTable* procs, nxtDevice* device);
ComPtr<ID3D12Device> d3d12Device,
nxtProcTable* procs,
nxtDevice* device);
nxtSwapChainImplementation CreateNativeSwapChainImpl(nxtDevice device, HWND window); nxtSwapChainImplementation CreateNativeSwapChainImpl(nxtDevice device, HWND window);
nxtTextureFormat GetNativeSwapChainPreferredFormat(const nxtSwapChainImplementation* swapChain); nxtTextureFormat GetNativeSwapChainPreferredFormat(const nxtSwapChainImplementation* swapChain);
}} // namespace backend::d3d12 }} // namespace backend::d3d12
namespace utils { namespace utils {
namespace {
void ASSERT_SUCCESS(HRESULT hr) {
ASSERT(SUCCEEDED(hr));
}
ComPtr<IDXGIFactory4> CreateFactory() {
ComPtr<IDXGIFactory4> 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<ID3D12Debug> debugController;
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) {
debugController->EnableDebugLayer();
// Enable additional debug layers.
dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG;
}
ComPtr<IDXGIDebug1> 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 { class D3D12Binding : public BackendBinding {
public: public:
@ -86,14 +37,8 @@ namespace utils {
} }
void GetProcAndDevice(nxtProcTable* procs, nxtDevice* device) override { void GetProcAndDevice(nxtProcTable* procs, nxtDevice* device) override {
mFactory = CreateFactory(); backend::d3d12::Init(procs, device);
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);
mBackendDevice = *device; mBackendDevice = *device;
mProcTable = *procs;
} }
uint64_t GetSwapChainImplementation() override { uint64_t GetSwapChainImplementation() override {
@ -113,32 +58,6 @@ namespace utils {
private: private:
nxtDevice mBackendDevice = nullptr; nxtDevice mBackendDevice = nullptr;
nxtSwapChainImplementation mSwapchainImpl = {}; nxtSwapChainImplementation mSwapchainImpl = {};
nxtProcTable mProcTable = {};
// Initialization
ComPtr<IDXGIFactory4> mFactory;
ComPtr<IDXGIAdapter1> mHardwareAdapter;
ComPtr<ID3D12Device> 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() { BackendBinding* CreateD3D12Binding() {