more dx12 initialization

This commit is contained in:
jacob 2025-06-06 18:54:15 -05:00
parent 50ca2387fa
commit 4fb1e0231b

View File

@ -72,10 +72,17 @@ GLOBAL struct {
/* Device */ /* Device */
ID3D12Device *device; ID3D12Device *device;
/* Desc sizes */
u32 desc_size_rtv;
/* Swapchain */ /* Swapchain */
u32 swapchain_frame_index; u32 swapchain_frame_index;
ID3D12CommandQueue *swapchain_cq; ID3D12CommandQueue *swapchain_cq;
ID3D12CommandAllocator *swapchain_ca;
IDXGISwapChain3 *swapchain; IDXGISwapChain3 *swapchain;
ID3D12DescriptorHeap *swapchain_rtv_heap;
ID3D12Resource *swapchain_rtvs[DX12_SWAPCHAIN_BUFFER_COUNT];
} G = ZI, DEBUG_ALIAS(G, G_gpu_dx12); } G = ZI, DEBUG_ALIAS(G, G_gpu_dx12);
/* ========================== * /* ========================== *
@ -84,30 +91,25 @@ GLOBAL struct {
INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gpu_shutdown); INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gpu_shutdown);
struct gpu_startup_receipt gpu_startup(struct sys_window *window) INTERNAL void dx12_init(struct sys_window *window)
{ {
__prof;
struct temp_arena scratch = scratch_begin_no_conflict(); struct temp_arena scratch = scratch_begin_no_conflict();
HRESULT hr; HRESULT hr = 0;
/* Initialize handles pool */
G.handle_entries_mutex = sys_mutex_alloc();
G.handle_entries_arena = arena_alloc(GIGABYTE(64));
/* Initialize dx12 */
{
/* Enable debug layer */ /* Enable debug layer */
u32 dxgi_factory_flags = 0; u32 dxgi_factory_flags = 0;
#if DX12_DEBUG #if DX12_DEBUG
{ {
ID3D12Debug *debug_controller0 = NULL; ID3D12Debug *debug_controller0 = NULL;
hr = D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug_controller0); hr = D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug_controller0);
if (!SUCCEEDED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to create ID3D12Debug0")); sys_panic(LIT("Failed to create ID3D12Debug0"));
} }
ID3D12Debug1 *debug_controller1 = NULL; ID3D12Debug1 *debug_controller1 = NULL;
hr = ID3D12Debug_QueryInterface(debug_controller0, &IID_ID3D12Debug1, (void **)&debug_controller1); hr = ID3D12Debug_QueryInterface(debug_controller0, &IID_ID3D12Debug1, (void **)&debug_controller1);
if (!SUCCEEDED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to create ID3D12Debug1")); sys_panic(LIT("Failed to create ID3D12Debug1"));
} }
@ -125,7 +127,7 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
/* Create factory */ /* Create factory */
IDXGIFactory6 *factory = NULL; IDXGIFactory6 *factory = NULL;
hr = CreateDXGIFactory2(dxgi_factory_flags, &IID_IDXGIFactory6, (void **)&factory); hr = CreateDXGIFactory2(dxgi_factory_flags, &IID_IDXGIFactory6, (void **)&factory);
if (!SUCCEEDED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to initialize DXGI factory")); sys_panic(LIT("Failed to initialize DXGI factory"));
} }
@ -145,8 +147,6 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
if (first_gpu_name.len == 0) { if (first_gpu_name.len == 0) {
first_gpu_name = string_from_wstr_no_limit(scratch.arena, desc.Description); first_gpu_name = string_from_wstr_no_limit(scratch.arena, desc.Description);
} }
/* Using feature level 12_0 instead of 12_2 because mesh feature check happens separately
* (because 1600 series cards support mesh shaders but not the rest of 12_2) */
hr = D3D12CreateDevice((IUnknown *)adapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device, (void **)&device); hr = D3D12CreateDevice((IUnknown *)adapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device, (void **)&device);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
D3D12_FEATURE_DATA_D3D12_OPTIONS7 features = ZI; D3D12_FEATURE_DATA_D3D12_OPTIONS7 features = ZI;
@ -178,12 +178,15 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
} }
} }
/* Get desc sizes */
u32 desc_size_rtv = ID3D12Device_GetDescriptorHandleIncrementSize(device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
#if DX12_DEBUG #if DX12_DEBUG
/* Enable D3D12 Debug break */ /* Enable D3D12 Debug break */
{ {
ID3D12InfoQueue *info = NULL; ID3D12InfoQueue *info = NULL;
hr = ID3D12Device_QueryInterface(device, &IID_ID3D12InfoQueue, (void **)&info); hr = ID3D12Device_QueryInterface(device, &IID_ID3D12InfoQueue, (void **)&info);
if (!SUCCEEDED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to query ID3D12Device interface")); sys_panic(LIT("Failed to query ID3D12Device interface"));
} }
ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE); ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE);
@ -195,7 +198,7 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
{ {
IDXGIInfoQueue *dxgi_info = NULL; IDXGIInfoQueue *dxgi_info = NULL;
hr = DXGIGetDebugInterface1(0, &IID_IDXGIInfoQueue, (void **)&dxgi_info); hr = DXGIGetDebugInterface1(0, &IID_IDXGIInfoQueue, (void **)&dxgi_info);
if (!SUCCEEDED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to get DXGI debug interface")); sys_panic(LIT("Failed to get DXGI debug interface"));
} }
IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, TRUE); IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, TRUE);
@ -212,11 +215,20 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
hr = ID3D12Device_CreateCommandQueue(device, &desc, &IID_ID3D12CommandQueue, (void **)&swapchain_cq); hr = ID3D12Device_CreateCommandQueue(device, &desc, &IID_ID3D12CommandQueue, (void **)&swapchain_cq);
if (!SUCCEEDED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to create swapchain command queue")); sys_panic(LIT("Failed to create swapchain command queue"));
} }
} }
/* Create direct command allocator */
ID3D12CommandAllocator *swapchain_ca = NULL;
{
hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT, &IID_ID3D12CommandAllocator, (void **)&swapchain_ca);
if (FAILED(hr)) {
sys_panic(LIT("Failed to create swapchain command allocator"));
}
}
/* Create swapchain */ /* Create swapchain */
IDXGISwapChain3 *swapchain = NULL; IDXGISwapChain3 *swapchain = NULL;
u32 swapchain_frame_index = 0; u32 swapchain_frame_index = 0;
@ -226,7 +238,7 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
.Format = DX12_SWAPCHAIN_FORMAT, .Format = DX12_SWAPCHAIN_FORMAT,
.SampleDesc = { 1, 0 }, .SampleDesc = { 1, 0 },
.BufferUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT, .BufferUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT,
.BufferCount = 3, .BufferCount = DX12_SWAPCHAIN_BUFFER_COUNT,
.Scaling = DXGI_SCALING_NONE, .Scaling = DXGI_SCALING_NONE,
.Flags = DX12_SWAPCHAIN_FLAGS, .Flags = DX12_SWAPCHAIN_FLAGS,
.AlphaMode = DXGI_ALPHA_MODE_IGNORE, .AlphaMode = DXGI_ALPHA_MODE_IGNORE,
@ -236,13 +248,13 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
/* Create swapchain1 */ /* Create swapchain1 */
IDXGISwapChain1 *swapchain1 = NULL; IDXGISwapChain1 *swapchain1 = NULL;
hr = IDXGIFactory2_CreateSwapChainForHwnd(factory, (IUnknown *)swapchain_cq, hwnd, &desc, NULL, NULL, &swapchain1); hr = IDXGIFactory2_CreateSwapChainForHwnd(factory, (IUnknown *)swapchain_cq, hwnd, &desc, NULL, NULL, &swapchain1);
if (!SUCCEEDED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to create IDXGISwapChain1")); sys_panic(LIT("Failed to create IDXGISwapChain1"));
} }
/* Upgrade to swapchain3 */ /* Upgrade to swapchain3 */
hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&swapchain); hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&swapchain);
if (!SUCCEEDED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to create IDXGISwapChain3")); sys_panic(LIT("Failed to create IDXGISwapChain3"));
} }
@ -255,17 +267,63 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
IDXGISwapChain1_Release(swapchain1); IDXGISwapChain1_Release(swapchain1);
} }
G.device = device; /* Create swapchain RTV heap */
G.swapchain_frame_index = swapchain_frame_index; ID3D12DescriptorHeap *swapchain_rtv_heap = NULL;
G.swapchain_cq = swapchain_cq; {
G.swapchain = swapchain; D3D12_DESCRIPTOR_HEAP_DESC desc = ZI;
desc.NumDescriptors = DX12_SWAPCHAIN_BUFFER_COUNT;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
IDXGIFactory6_Release(factory); hr = ID3D12Device_CreateDescriptorHeap(device, &desc, &IID_ID3D12DescriptorHeap, (void **)&swapchain_rtv_heap);
if (FAILED(hr)) {
sys_panic(LIT("Failed to create swapchain RTV heap"));
}
} }
/* Create swacphain RTVs */
ID3D12Resource *swapchain_rtvs[DX12_SWAPCHAIN_BUFFER_COUNT] = ZI;
{
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = ZI;
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(swapchain_rtv_heap, &rtv_handle);
for (u32 i = 0; i < DX12_SWAPCHAIN_BUFFER_COUNT; ++i) {
hr = IDXGISwapChain3_GetBuffer(swapchain, i, &IID_ID3D12Resource, (void **)&swapchain_rtvs[i]);
if (FAILED(hr)) {
sys_panic(LIT("Failed to create swapchain RTV"));
}
ID3D12Device_CreateRenderTargetView(device, swapchain_rtvs[i], NULL, rtv_handle);
rtv_handle.ptr += desc_size_rtv;
}
}
/* Create command allocator */
G.device = device;
G.desc_size_rtv = desc_size_rtv;
G.swapchain_frame_index = swapchain_frame_index;
G.swapchain_cq = swapchain_cq;
G.swapchain_ca = swapchain_ca;
G.swapchain = swapchain;
G.swapchain_rtv_heap = swapchain_rtv_heap;
MEMCPY(&G.swapchain_rtvs, swapchain_rtvs, sizeof(G.swapchain_rtvs));
IDXGIFactory6_Release(factory);
scratch_end(scratch);
}
struct gpu_startup_receipt gpu_startup(struct sys_window *window)
{
/* Initialize handles pool */
G.handle_entries_mutex = sys_mutex_alloc();
G.handle_entries_arena = arena_alloc(GIGABYTE(64));
/* Initialize dx12 */
dx12_init(window);
/* Register callbacks */
app_register_exit_callback(gpu_shutdown); app_register_exit_callback(gpu_shutdown);
scratch_end(scratch);
struct gpu_startup_receipt res = ZI; struct gpu_startup_receipt res = ZI;
return res; return res;
} }
@ -274,11 +332,14 @@ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gpu_shutdown)
{ {
#if DX12_DEBUG #if DX12_DEBUG
/* Release objects to make live object reporting less noisy */ /* Release objects to make live object reporting less noisy */
{ for (u64 i = 0; i < ARRAY_COUNT(G.swapchain_rtvs); ++i) {
ID3D12Device_Release(G.device); ID3D12Resource_Release(G.swapchain_rtvs[i]);
}
ID3D12DescriptorHeap_Release(G.swapchain_rtv_heap);
ID3D12CommandQueue_Release(G.swapchain_ca);
ID3D12CommandQueue_Release(G.swapchain_cq); ID3D12CommandQueue_Release(G.swapchain_cq);
IDXGISwapChain3_Release(G.swapchain); IDXGISwapChain3_Release(G.swapchain);
} ID3D12Device_Release(G.device);
#endif #endif
} }