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 GetValidatingProcs();
void Init(ComPtr<IDXGIFactory4> factory,
ComPtr<ID3D12Device> d3d12Device,
nxtProcTable* procs,
nxtDevice* device) {
void Init(nxtProcTable* procs, nxtDevice* device) {
*device = nullptr;
*procs = GetValidatingProcs();
*device = reinterpret_cast<nxtDevice>(new Device(factory, d3d12Device));
*device = reinterpret_cast<nxtDevice>(new Device());
}
nxtSwapChainImplementation CreateNativeSwapChainImpl(nxtDevice device, HWND window) {
@ -67,24 +64,83 @@ namespace backend { namespace d3d12 {
ASSERT(SUCCEEDED(hr));
}
Device::Device(ComPtr<IDXGIFactory4> factory, ComPtr<ID3D12Device> 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<IDXGIFactory4> CreateFactory() {
ComPtr<IDXGIFactory4> factory;
uint32_t dxgiFactoryFlags = 0;
#if defined(NXT_ENABLE_ASSERTS)
// Enable the debug layer (requires the Graphics Tools "optional feature").
{
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 = {};
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();
}

View File

@ -86,7 +86,7 @@ namespace backend { namespace d3d12 {
// Definition of backend types
class Device : public DeviceBase {
public:
Device(ComPtr<IDXGIFactory4> factory, ComPtr<ID3D12Device> d3d12Device);
Device();
~Device();
BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
@ -135,14 +135,15 @@ namespace backend { namespace d3d12 {
HANDLE mFenceEvent;
ComPtr<IDXGIFactory4> mFactory;
ComPtr<IDXGIAdapter1> mHardwareAdapter;
ComPtr<ID3D12Device> mD3d12Device;
ComPtr<ID3D12CommandQueue> 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<ID3D12GraphicsCommandList> commandList;

View File

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

View File

@ -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 <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 {
void Init(ComPtr<IDXGIFactory4> factory,
ComPtr<ID3D12Device> 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<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 {
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<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() {