1
0

DirectX12 Create Device & Commandqueue

This commit is contained in:
2023-05-10 20:08:45 +02:00
parent 1ecccf3c99
commit 7d2525482b
3 changed files with 144 additions and 35 deletions

View File

@@ -8,5 +8,4 @@ Following tutorials and documentation to learn the basics of the directX graphic
## Resources Used
[github.com/Microsoft/DirectXTK12](https://github.com/microsoft/DirectXTK12/wiki/The-basic-game-loop)
[3dgep.com](https://www.3dgep.com/learning-directx-12-1/#Introduction)

View File

@@ -7,7 +7,7 @@ project "LearnDirectX"
targetdir "bin/%{cfg.buildcfg}"
architecture "x64"
links {"glfw3", "d3d9"}
links {"glfw3", "d3d12", "dxgi"}
libdirs{ "vendor/GLFW/lib"}
includedirs {"vendor/GLFW/include"}

View File

@@ -1,47 +1,157 @@
#include <iostream>
#include <Windows.h>
#include <wrl.h>
#define GLFW_EXPOSE_NATIVE_WIN32
#include "GLFW/glfw3.h"
#include "GLFW/glfw3native.h"
#include <d3d9.h>
LPDIRECT3D9 d3d; // pointer to our Direct3D interface
LPDIRECT3DDEVICE9 d3ddev; // pointer to the device class
void initD3D(HWND hWnd) {
d3d = Direct3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface
// DirectX headers
#include <d3d12.h>
#include <dxgi1_6.h>
#include <d3dcompiler.h>
#include <DirectXMath.h>
#include <DirectXColors.h>
D3DPRESENT_PARAMETERS d3dpp; // create the strcut to hold device info
using namespace Microsoft::WRL;
ZeroMemory(&d3dpp, sizeof(d3dpp)); // clear the struct
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
// create a device class using the information gathered
d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
inline void ThrowIfFailed(HRESULT hr) {
if (FAILED(hr)) {
throw std::exception();
}
}
const uint8_t NumFrames = 3;
bool UseWarp = false;
bool IsInitialized = false;
void render_frame() {
d3ddev->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
d3ddev->BeginScene();
// do 3D rendering
d3ddev->EndScene();
ComPtr<ID3D12Device2> Device;
ComPtr<ID3D12CommandQueue> CommandQueue;
ComPtr<IDXGISwapChain4> SwapChain;
ComPtr<ID3D12Resource> backbuffer[NumFrames];
ComPtr<ID3D12GraphicsCommandList> CommandList;
ComPtr<ID3D12CommandAllocator> CommandAllocator[NumFrames];
// RTV stands for Render Target View
// A descriptor describes a resource
ComPtr<ID3D12DescriptorHeap> RTVDescriptorHeap;
UINT RTVDescriptorSize;
UINT CurrentBackBufferIndex;
d3ddev->Present(NULL, NULL, NULL, NULL);
// Synchronization objects
ComPtr<ID3D12Fence> Fence;
uint64_t FenceValue;
uint64_t FrameFenceValues[NumFrames] = {};
HANDLE FenceEvent;
bool Vsync = true;
bool TearingSupported = false;
bool fullscreen = false;
void EnableDebugLayer() {
#ifdef DEBUG
ComPtr<ID3D12Debug> debugInterface;
ThrowIfFailed(D3D12GetDebugInterface(IID_PPV_ARGS(&debugInterface)));
debugInterface->EnableDebugLayer();
#endif
}
void cleanD3D() {
d3ddev->Release();
d3d->Release();
// Query DirectX12 adapter
ComPtr<IDXGIAdapter4> GetAdapter(bool useWarp) {
ComPtr<IDXGIFactory4> dxgiFactory;
UINT createFactoryFlags = 0;
#ifdef DEBUG
createFactoryFlags = DXGI_CREATE_FACTORY_DEBUG;
#endif
ThrowIfFailed(CreateDXGIFactory2(createFactoryFlags, IID_PPV_ARGS(&dxgiFactory)));
ComPtr<IDXGIAdapter1> dxgiAdapter1;
ComPtr<IDXGIAdapter4> dxgiAdapter4;
if (useWarp) {
ThrowIfFailed(dxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(&dxgiAdapter1)));
ThrowIfFailed(dxgiAdapter1.As(&dxgiAdapter4));
}
else {
SIZE_T maxDedicatedVideoMemory = 0;
for (UINT i = 0; dxgiFactory->EnumAdapters1(i, &dxgiAdapter1) != DXGI_ERROR_NOT_FOUND; ++i) {
DXGI_ADAPTER_DESC1 dxgiAdapterDesc1;
dxgiAdapter1->GetDesc1(&dxgiAdapterDesc1);
// check if the device can create D3D12 device
// The Adapter with the largest video memory is favored
if ((dxgiAdapterDesc1.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) == 0 && SUCCEEDED(D3D12CreateDevice(dxgiAdapter1.Get(),
D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), nullptr)) && dxgiAdapterDesc1.DedicatedVideoMemory > maxDedicatedVideoMemory) {
maxDedicatedVideoMemory = dxgiAdapterDesc1.DedicatedVideoMemory;
ThrowIfFailed(dxgiAdapter1.As(&dxgiAdapter4));
}
}
}
return dxgiAdapter4;
}
ComPtr<ID3D12Device2> CreateDevice(ComPtr<IDXGIAdapter4> adapter) {
ComPtr<ID3D12Device2> d3d12Device2;
ThrowIfFailed(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&d3d12Device2)));
#ifdef DEBUG
// Enable Debug message
ComPtr<ID3D12InfoQueue> InfoQueue;
if (SUCCEEDED(d3d12Device2.As(&InfoQueue))) {
InfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE);
InfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, TRUE);
InfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, TRUE);
// Suppress whole Categories and severities of messsage
D3D12_MESSAGE_SEVERITY Severities[] = {
D3D12_MESSAGE_SEVERITY_INFO
};
// Suppress message by their ID
D3D12_MESSAGE_ID DenyIds[] = {
D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE,
D3D12_MESSAGE_ID_MAP_INVALID_NULLRANGE,
D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE
};
D3D12_INFO_QUEUE_FILTER newfilter = {};
newfilter.DenyList.NumSeverities = _countof(Severities);
newfilter.DenyList.pSeverityList = Severities;
newfilter.DenyList.NumIDs = _countof(DenyIds);
newfilter.DenyList.pIDList = DenyIds;
ThrowIfFailed(InfoQueue->PushStorageFilter(&newfilter));
}
#endif
return d3d12Device2;
}
ComPtr<ID3D12CommandQueue> CreateCommandQueue(ComPtr<ID3D12Device2> device, D3D12_COMMAND_LIST_TYPE type) {
ComPtr<ID3D12CommandQueue> d3d12CommandQueue;
D3D12_COMMAND_QUEUE_DESC desc = {};
desc.Type = type;
desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
desc.NodeMask = 0;
ThrowIfFailed(device->CreateCommandQueue(&desc, IID_PPV_ARGS(&d3d12CommandQueue)));
return d3d12CommandQueue;
}
void error_callback(int code , const char* description) {
std::cerr << description << std::endl;
@@ -67,22 +177,22 @@ int main ( int argc , char** argv){
return -1;
}
HWND NativeWindowHandle = glfwGetWin32Window(window);
initD3D(NativeWindowHandle);
EnableDebugLayer();
auto adapter = GetAdapter(UseWarp);
auto device = CreateDevice(adapter);
auto commandQueue = CreateCommandQueue(device, D3D12_COMMAND_LIST_TYPE_DIRECT);
while (!glfwWindowShouldClose(window)) {
render_frame();
glfwPollEvents();
}
cleanD3D();
glfwTerminate();