create separate dx12 direct & compute queues

This commit is contained in:
jacob 2025-06-06 21:26:06 -05:00
parent 45afac951a
commit f1ac650471
3 changed files with 51 additions and 26 deletions

View File

@ -766,7 +766,7 @@ INTERNAL HRESULT dx11_include_open(ID3DInclude *d3d_handler, D3D_INCLUDE_TYPE in
struct string name = string_from_cstr_no_limit((char *)name_cstr); struct string name = string_from_cstr_no_limit((char *)name_cstr);
if (handler->has_open_resource) { if (handler->has_open_resource) {
sys_panic(LIT("D3d include handler somehow already has a resource open")); sys_panic(LIT("Dx11 include handler somehow already has a resource open"));
} }
struct resource res = resource_open(name); struct resource res = resource_open(name);
@ -822,7 +822,7 @@ INTERNAL void dx11_include_handler_release(struct dx11_include_handler *handler)
/* TODO: Multithread shader compilation */ /* TODO: Multithread shader compilation */
/* If shader compilation fails, then error string is returned allocated on `arena` */ /* If shader compilation fails, then function returns error string allocated on `arena` */
INTERNAL struct string shader_alloc(struct arena *arena, struct dx11_shader *shader, struct dx11_shader_desc *shader_desc, struct resource *src_res) INTERNAL struct string shader_alloc(struct arena *arena, struct dx11_shader *shader, struct dx11_shader_desc *shader_desc, struct resource *src_res)
{ {
__prof; __prof;

View File

@ -75,9 +75,12 @@ GLOBAL struct {
/* Desc sizes */ /* Desc sizes */
u32 desc_size_rtv; u32 desc_size_rtv;
/* Command queues */
ID3D12CommandQueue *cq_direct;
ID3D12CommandQueue *cq_compute;
/* Swapchain */ /* Swapchain */
u32 swapchain_frame_index; u32 swapchain_frame_index;
ID3D12CommandQueue *swapchain_cq;
ID3D12CommandAllocator *swapchain_ca; ID3D12CommandAllocator *swapchain_ca;
IDXGISwapChain3 *swapchain; IDXGISwapChain3 *swapchain;
ID3D12DescriptorHeap *swapchain_rtv_heap; ID3D12DescriptorHeap *swapchain_rtv_heap;
@ -91,6 +94,14 @@ GLOBAL struct {
INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gpu_shutdown); INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gpu_shutdown);
INTERNAL void dx12_init_error(struct string error)
{
struct temp_arena scratch = scratch_begin_no_conflict();
struct string msg = string_format(scratch.arena, LIT("Failed to initialize DirectX 12.\n\n%F"), FMT_STR(error));
sys_panic(msg);
scratch_end(scratch);
}
INTERNAL void dx12_init(struct sys_window *window) INTERNAL void dx12_init(struct sys_window *window)
{ {
__prof; __prof;
@ -104,13 +115,13 @@ INTERNAL void dx12_init(struct sys_window *window)
ID3D12Debug *debug_controller0 = NULL; ID3D12Debug *debug_controller0 = NULL;
hr = D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug_controller0); hr = D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug_controller0);
if (FAILED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to create ID3D12Debug0")); dx12_init_error(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 (FAILED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to create ID3D12Debug1")); dx12_init_error(LIT("Failed to create ID3D12Debug1"));
} }
ID3D12Debug_EnableDebugLayer(debug_controller0); ID3D12Debug_EnableDebugLayer(debug_controller0);
@ -128,7 +139,7 @@ INTERNAL void dx12_init(struct sys_window *window)
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 (FAILED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to initialize DXGI factory")); dx12_init_error(LIT("Failed to initialize DXGI factory"));
} }
/* Create device */ /* Create device */
@ -163,12 +174,13 @@ INTERNAL void dx12_init(struct sys_window *window)
break; break;
} }
} }
device = NULL;
if (!device) { if (!device) {
if (first_gpu_name.len > 0) { if (first_gpu_name.len > 0) {
struct string fmt = LIT("Could not initialize device '%F' with DirectX feature level 12_0. Ensure that the device is capable and drivers are up to date."); struct string fmt = LIT("Could not initialize device '%F' with D3D_FEATURE_LEVEL_12_0. Ensure that the device is capable and drivers are up to date.");
error = string_format(scratch.arena, fmt, FMT_STR(first_gpu_name)); error = string_format(scratch.arena, fmt, FMT_STR(first_gpu_name));
} }
sys_panic(error); dx12_init_error(error);
} }
} }
@ -181,7 +193,7 @@ INTERNAL void dx12_init(struct sys_window *window)
ID3D12InfoQueue *info = NULL; ID3D12InfoQueue *info = NULL;
hr = ID3D12Device_QueryInterface(device, &IID_ID3D12InfoQueue, (void **)&info); hr = ID3D12Device_QueryInterface(device, &IID_ID3D12InfoQueue, (void **)&info);
if (FAILED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to query ID3D12Device interface")); dx12_init_error(LIT("Failed to query ID3D12Device interface"));
} }
ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE); ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE);
ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_ERROR, TRUE); ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_ERROR, TRUE);
@ -193,7 +205,7 @@ INTERNAL void dx12_init(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 (FAILED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to get DXGI debug interface")); dx12_init_error(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);
IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, TRUE); IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, TRUE);
@ -202,24 +214,37 @@ INTERNAL void dx12_init(struct sys_window *window)
#endif #endif
/* Create direct command queue */ /* Create direct command queue */
ID3D12CommandQueue *swapchain_cq = NULL; ID3D12CommandQueue *cq_direct = NULL;
{ {
D3D12_COMMAND_QUEUE_DESC desc = ZI; D3D12_COMMAND_QUEUE_DESC desc = ZI;
desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
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 **)&cq_direct);
if (FAILED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to create swapchain command queue")); dx12_init_error(LIT("Failed to create direct command queue"));
} }
} }
/* Create direct command allocator */ /* Create compute command queue */
ID3D12CommandQueue *cq_compute = NULL;
{
D3D12_COMMAND_QUEUE_DESC desc = ZI;
desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
desc.Type = D3D12_COMMAND_LIST_TYPE_COMPUTE;
hr = ID3D12Device_CreateCommandQueue(device, &desc, &IID_ID3D12CommandQueue, (void **)&cq_compute);
if (FAILED(hr)) {
dx12_init_error(LIT("Failed to create compute command queue"));
}
}
/* Create swapchain command allocator */
ID3D12CommandAllocator *swapchain_ca = NULL; ID3D12CommandAllocator *swapchain_ca = NULL;
{ {
hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT, &IID_ID3D12CommandAllocator, (void **)&swapchain_ca); hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT, &IID_ID3D12CommandAllocator, (void **)&swapchain_ca);
if (FAILED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to create swapchain command allocator")); dx12_init_error(LIT("Failed to create swapchain command allocator"));
} }
} }
@ -241,15 +266,15 @@ INTERNAL void dx12_init(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 *)cq_direct, hwnd, &desc, NULL, NULL, &swapchain1);
if (FAILED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to create IDXGISwapChain1")); dx12_init_error(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 (FAILED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to create IDXGISwapChain3")); dx12_init_error(LIT("Failed to create IDXGISwapChain3"));
} }
/* Disable Alt+Enter changing monitor resolution to match window size */ /* Disable Alt+Enter changing monitor resolution to match window size */
@ -271,7 +296,7 @@ INTERNAL void dx12_init(struct sys_window *window)
hr = ID3D12Device_CreateDescriptorHeap(device, &desc, &IID_ID3D12DescriptorHeap, (void **)&swapchain_rtv_heap); hr = ID3D12Device_CreateDescriptorHeap(device, &desc, &IID_ID3D12DescriptorHeap, (void **)&swapchain_rtv_heap);
if (FAILED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to create swapchain RTV heap")); dx12_init_error(LIT("Failed to create swapchain RTV heap"));
} }
} }
@ -283,7 +308,7 @@ INTERNAL void dx12_init(struct sys_window *window)
for (u32 i = 0; i < DX12_SWAPCHAIN_BUFFER_COUNT; ++i) { for (u32 i = 0; i < DX12_SWAPCHAIN_BUFFER_COUNT; ++i) {
hr = IDXGISwapChain3_GetBuffer(swapchain, i, &IID_ID3D12Resource, (void **)&swapchain_rtvs[i]); hr = IDXGISwapChain3_GetBuffer(swapchain, i, &IID_ID3D12Resource, (void **)&swapchain_rtvs[i]);
if (FAILED(hr)) { if (FAILED(hr)) {
sys_panic(LIT("Failed to create swapchain RTV")); dx12_init_error(LIT("Failed to create swapchain RTV"));
} }
ID3D12Device_CreateRenderTargetView(device, swapchain_rtvs[i], NULL, rtv_handle); ID3D12Device_CreateRenderTargetView(device, swapchain_rtvs[i], NULL, rtv_handle);
@ -291,12 +316,11 @@ INTERNAL void dx12_init(struct sys_window *window)
} }
} }
/* Create command allocator */
G.device = device; G.device = device;
G.desc_size_rtv = desc_size_rtv; G.desc_size_rtv = desc_size_rtv;
G.swapchain_frame_index = swapchain_frame_index; G.swapchain_frame_index = swapchain_frame_index;
G.swapchain_cq = swapchain_cq; G.cq_direct = cq_direct;
G.cq_compute = cq_compute;
G.swapchain_ca = swapchain_ca; G.swapchain_ca = swapchain_ca;
G.swapchain = swapchain; G.swapchain = swapchain;
G.swapchain_rtv_heap = swapchain_rtv_heap; G.swapchain_rtv_heap = swapchain_rtv_heap;
@ -331,7 +355,8 @@ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gpu_shutdown)
} }
ID3D12DescriptorHeap_Release(G.swapchain_rtv_heap); ID3D12DescriptorHeap_Release(G.swapchain_rtv_heap);
ID3D12CommandQueue_Release(G.swapchain_ca); ID3D12CommandQueue_Release(G.swapchain_ca);
ID3D12CommandQueue_Release(G.swapchain_cq); ID3D12CommandQueue_Release(G.cq_direct);
ID3D12CommandQueue_Release(G.cq_compute);
IDXGISwapChain3_Release(G.swapchain); IDXGISwapChain3_Release(G.swapchain);
ID3D12Device_Release(G.device); ID3D12Device_Release(G.device);
#endif #endif

View File

@ -2123,7 +2123,6 @@ void sys_panic(struct string msg)
if (atomic_i32_eval_compare_exchange(&G.panicking, 0, 1) == 0) { if (atomic_i32_eval_compare_exchange(&G.panicking, 0, 1) == 0) {
log_panic(msg); log_panic(msg);
/* FIXME: Atomic panic str */
wchar_t *wstr = G.panic_wstr; wchar_t *wstr = G.panic_wstr;
u64 wstr_len = 0; u64 wstr_len = 0;
@ -2131,13 +2130,14 @@ void sys_panic(struct string msg)
MEMCPY(wstr, prefix, min_u64(ARRAY_COUNT(G.panic_wstr), (ARRAY_COUNT(prefix) << 1))); MEMCPY(wstr, prefix, min_u64(ARRAY_COUNT(G.panic_wstr), (ARRAY_COUNT(prefix) << 1)));
wstr_len += ARRAY_COUNT(prefix) - 1; wstr_len += ARRAY_COUNT(prefix) - 1;
/* Perform manual string encode to avoid any implicit memory
* allocation (in case allocation is unreliable) */
struct string str8 = msg; struct string str8 = msg;
u64 pos8 = 0; u64 pos8 = 0;
while (pos8 < str8.len) { while (pos8 < str8.len) {
struct string str8_remaining = { .len = (str8.len - pos8), .text = str8.text + pos8 }; struct string str8_remaining = { .len = (str8.len - pos8), .text = str8.text + pos8 };
struct uni_decode_utf8_result decoded = uni_decode_utf8(str8_remaining); struct uni_decode_utf8_result decoded = uni_decode_utf8(str8_remaining);
struct uni_encode_utf16_result encoded = uni_encode_utf16(decoded.codepoint); struct uni_encode_utf16_result encoded = uni_encode_utf16(decoded.codepoint);
u64 wstr_new_len = wstr_len + encoded.count16; u64 wstr_new_len = wstr_len + encoded.count16;
if (wstr_new_len < (ARRAY_COUNT(G.panic_wstr) - 1)) { if (wstr_new_len < (ARRAY_COUNT(G.panic_wstr) - 1)) {
u16 *dest = wstr + wstr_len; u16 *dest = wstr + wstr_len;