DirectX12 Create Device & Commandqueue
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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"}
|
||||
|
||||
174
src/main.cpp
174
src/main.cpp
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user