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
|
## 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}"
|
targetdir "bin/%{cfg.buildcfg}"
|
||||||
architecture "x64"
|
architecture "x64"
|
||||||
|
|
||||||
links {"glfw3", "d3d9"}
|
links {"glfw3", "d3d12", "dxgi"}
|
||||||
|
|
||||||
libdirs{ "vendor/GLFW/lib"}
|
libdirs{ "vendor/GLFW/lib"}
|
||||||
includedirs {"vendor/GLFW/include"}
|
includedirs {"vendor/GLFW/include"}
|
||||||
|
|||||||
174
src/main.cpp
174
src/main.cpp
@@ -1,48 +1,158 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
#include <wrl.h>
|
||||||
|
|
||||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||||
#include "GLFW/glfw3.h"
|
#include "GLFW/glfw3.h"
|
||||||
#include "GLFW/glfw3native.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) {
|
// DirectX headers
|
||||||
d3d = Direct3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface
|
#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
|
inline void ThrowIfFailed(HRESULT hr) {
|
||||||
d3dpp.Windowed = TRUE;
|
if (FAILED(hr)) {
|
||||||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
throw std::exception();
|
||||||
d3dpp.hDeviceWindow = hWnd;
|
}
|
||||||
|
|
||||||
// create a device class using the information gathered
|
|
||||||
d3d->CreateDevice(D3DADAPTER_DEFAULT,
|
|
||||||
D3DDEVTYPE_HAL,
|
|
||||||
hWnd,
|
|
||||||
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
|
|
||||||
&d3dpp,
|
|
||||||
&d3ddev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint8_t NumFrames = 3;
|
||||||
|
bool UseWarp = false;
|
||||||
|
bool IsInitialized = false;
|
||||||
|
|
||||||
void render_frame() {
|
ComPtr<ID3D12Device2> Device;
|
||||||
d3ddev->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
|
ComPtr<ID3D12CommandQueue> CommandQueue;
|
||||||
d3ddev->BeginScene();
|
ComPtr<IDXGISwapChain4> SwapChain;
|
||||||
// do 3D rendering
|
ComPtr<ID3D12Resource> backbuffer[NumFrames];
|
||||||
d3ddev->EndScene();
|
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() {
|
// Query DirectX12 adapter
|
||||||
d3ddev->Release();
|
ComPtr<IDXGIAdapter4> GetAdapter(bool useWarp) {
|
||||||
d3d->Release();
|
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) {
|
void error_callback(int code , const char* description) {
|
||||||
std::cerr << description << std::endl;
|
std::cerr << description << std::endl;
|
||||||
}
|
}
|
||||||
@@ -67,22 +177,22 @@ int main ( int argc , char** argv){
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HWND NativeWindowHandle = glfwGetWin32Window(window);
|
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)) {
|
while (!glfwWindowShouldClose(window)) {
|
||||||
render_frame();
|
|
||||||
|
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanD3D();
|
|
||||||
|
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user