create separate dx12 direct & compute queues
This commit is contained in:
parent
45afac951a
commit
f1ac650471
@ -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;
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user