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);
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);
@ -822,7 +822,7 @@ INTERNAL void dx11_include_handler_release(struct dx11_include_handler *handler)
/* 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)
{
__prof;

View File

@ -75,9 +75,12 @@ GLOBAL struct {
/* Desc sizes */
u32 desc_size_rtv;
/* Command queues */
ID3D12CommandQueue *cq_direct;
ID3D12CommandQueue *cq_compute;
/* Swapchain */
u32 swapchain_frame_index;
ID3D12CommandQueue *swapchain_cq;
ID3D12CommandAllocator *swapchain_ca;
IDXGISwapChain3 *swapchain;
ID3D12DescriptorHeap *swapchain_rtv_heap;
@ -91,6 +94,14 @@ GLOBAL struct {
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)
{
__prof;
@ -104,13 +115,13 @@ INTERNAL void dx12_init(struct sys_window *window)
ID3D12Debug *debug_controller0 = NULL;
hr = D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug_controller0);
if (FAILED(hr)) {
sys_panic(LIT("Failed to create ID3D12Debug0"));
dx12_init_error(LIT("Failed to create ID3D12Debug0"));
}
ID3D12Debug1 *debug_controller1 = NULL;
hr = ID3D12Debug_QueryInterface(debug_controller0, &IID_ID3D12Debug1, (void **)&debug_controller1);
if (FAILED(hr)) {
sys_panic(LIT("Failed to create ID3D12Debug1"));
dx12_init_error(LIT("Failed to create ID3D12Debug1"));
}
ID3D12Debug_EnableDebugLayer(debug_controller0);
@ -128,7 +139,7 @@ INTERNAL void dx12_init(struct sys_window *window)
IDXGIFactory6 *factory = NULL;
hr = CreateDXGIFactory2(dxgi_factory_flags, &IID_IDXGIFactory6, (void **)&factory);
if (FAILED(hr)) {
sys_panic(LIT("Failed to initialize DXGI factory"));
dx12_init_error(LIT("Failed to initialize DXGI factory"));
}
/* Create device */
@ -163,12 +174,13 @@ INTERNAL void dx12_init(struct sys_window *window)
break;
}
}
device = NULL;
if (!device) {
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));
}
sys_panic(error);
dx12_init_error(error);
}
}
@ -181,7 +193,7 @@ INTERNAL void dx12_init(struct sys_window *window)
ID3D12InfoQueue *info = NULL;
hr = ID3D12Device_QueryInterface(device, &IID_ID3D12InfoQueue, (void **)&info);
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_ERROR, TRUE);
@ -193,7 +205,7 @@ INTERNAL void dx12_init(struct sys_window *window)
IDXGIInfoQueue *dxgi_info = NULL;
hr = DXGIGetDebugInterface1(0, &IID_IDXGIInfoQueue, (void **)&dxgi_info);
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_ERROR, TRUE);
@ -202,24 +214,37 @@ INTERNAL void dx12_init(struct sys_window *window)
#endif
/* Create direct command queue */
ID3D12CommandQueue *swapchain_cq = NULL;
ID3D12CommandQueue *cq_direct = NULL;
{
D3D12_COMMAND_QUEUE_DESC desc = ZI;
desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
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)) {
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;
{
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"));
dx12_init_error(LIT("Failed to create swapchain command allocator"));
}
}
@ -241,15 +266,15 @@ INTERNAL void dx12_init(struct sys_window *window)
/* Create swapchain1 */
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)) {
sys_panic(LIT("Failed to create IDXGISwapChain1"));
dx12_init_error(LIT("Failed to create IDXGISwapChain1"));
}
/* Upgrade to swapchain3 */
hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&swapchain);
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 */
@ -271,7 +296,7 @@ INTERNAL void dx12_init(struct sys_window *window)
hr = ID3D12Device_CreateDescriptorHeap(device, &desc, &IID_ID3D12DescriptorHeap, (void **)&swapchain_rtv_heap);
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) {
hr = IDXGISwapChain3_GetBuffer(swapchain, i, &IID_ID3D12Resource, (void **)&swapchain_rtvs[i]);
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);
@ -291,12 +316,11 @@ INTERNAL void dx12_init(struct sys_window *window)
}
}
/* 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.cq_direct = cq_direct;
G.cq_compute = cq_compute;
G.swapchain_ca = swapchain_ca;
G.swapchain = swapchain;
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);
ID3D12CommandQueue_Release(G.swapchain_ca);
ID3D12CommandQueue_Release(G.swapchain_cq);
ID3D12CommandQueue_Release(G.cq_direct);
ID3D12CommandQueue_Release(G.cq_compute);
IDXGISwapChain3_Release(G.swapchain);
ID3D12Device_Release(G.device);
#endif

View File

@ -2123,7 +2123,6 @@ void sys_panic(struct string msg)
if (atomic_i32_eval_compare_exchange(&G.panicking, 0, 1) == 0) {
log_panic(msg);
/* FIXME: Atomic panic str */
wchar_t *wstr = G.panic_wstr;
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)));
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;
u64 pos8 = 0;
while (pos8 < str8.len) {
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_encode_utf16_result encoded = uni_encode_utf16(decoded.codepoint);
u64 wstr_new_len = wstr_len + encoded.count16;
if (wstr_new_len < (ARRAY_COUNT(G.panic_wstr) - 1)) {
u16 *dest = wstr + wstr_len;