From 3f7490e69b270503e96e93a9746d5c0e46a86569 Mon Sep 17 00:00:00 2001 From: Robert Konrad Date: Sat, 30 Nov 2024 13:20:12 +0100 Subject: [PATCH] Add async and copy queues --- .../Sources/kope/direct3d12/device.cpp | 53 ++++++++++++++++--- .../kope/direct3d12/device_functions.h | 4 ++ .../Sources/kope/direct3d12/device_structs.h | 2 + Sources/kope/graphics5/device.c | 8 +++ Sources/kope/graphics5/device.h | 4 ++ 5 files changed, 64 insertions(+), 7 deletions(-) diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp index cd6cabf22..f5fa89234 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp @@ -111,6 +111,22 @@ void kope_d3d12_device_create(kope_g5_device *device, const kope_g5_device_wishl kinc_microsoft_affirm(device->d3d12.device->CreateCommandQueue(&desc, IID_PPV_ARGS(&device->d3d12.queue))); } + { + D3D12_COMMAND_QUEUE_DESC desc = {}; + desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + desc.Type = D3D12_COMMAND_LIST_TYPE_COMPUTE; + + kinc_microsoft_affirm(device->d3d12.device->CreateCommandQueue(&desc, IID_PPV_ARGS(&device->d3d12.async_queue))); + } + + { + D3D12_COMMAND_QUEUE_DESC desc = {}; + desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + desc.Type = D3D12_COMMAND_LIST_TYPE_COPY; + + kinc_microsoft_affirm(device->d3d12.device->CreateCommandQueue(&desc, IID_PPV_ARGS(&device->d3d12.copy_queue))); + } + { DXGI_SWAP_CHAIN_DESC desc = {0}; desc.BufferCount = 2; @@ -578,8 +594,10 @@ static void clean_buffer_accesses(kope_g5_buffer *buffer, uint64_t finished_exec buffer->d3d12.ranges_count = ranges_count; } -void kope_d3d12_device_execute_command_list(kope_g5_device *device, kope_g5_command_list *list) { - if (list->d3d12.presenting) { +enum command_list_type { COMMAND_LIST_TYPE_DIRECT, COMMAND_LIST_TYPE_ASYNC, COMMAND_LIST_TYPE_COPY }; + +static void execute_command_list(command_list_type list_type, kope_g5_device *device, kope_g5_command_list *list) { + if (list_type == COMMAND_LIST_TYPE_DIRECT && list->d3d12.presenting) { kope_g5_texture *framebuffer = kope_d3d12_device_get_framebuffer(device); if (framebuffer->d3d12.resource_states[0] != D3D12_RESOURCE_STATE_PRESENT) { D3D12_RESOURCE_BARRIER barrier; @@ -596,7 +614,7 @@ void kope_d3d12_device_execute_command_list(kope_g5_device *device, kope_g5_comm } } - if (list->d3d12.blocking_frame_index > 0) { + if (list_type == COMMAND_LIST_TYPE_DIRECT && list->d3d12.blocking_frame_index > 0) { wait_for_frame(device, list->d3d12.blocking_frame_index); list->d3d12.blocking_frame_index = 0; } @@ -627,9 +645,18 @@ void kope_d3d12_device_execute_command_list(kope_g5_device *device, kope_g5_comm list->d3d12.allocator_execution_index[list->d3d12.current_allocator_index] = device->d3d12.execution_index; ID3D12CommandList *lists[] = {list->d3d12.list}; - device->d3d12.queue->ExecuteCommandLists(1, lists); - - device->d3d12.queue->Signal(device->d3d12.execution_fence, device->d3d12.execution_index); + if (list_type == COMMAND_LIST_TYPE_DIRECT) { + device->d3d12.queue->ExecuteCommandLists(1, lists); + device->d3d12.queue->Signal(device->d3d12.execution_fence, device->d3d12.execution_index); + } + else if (list_type == COMMAND_LIST_TYPE_ASYNC) { + device->d3d12.async_queue->ExecuteCommandLists(1, lists); + device->d3d12.async_queue->Signal(device->d3d12.execution_fence, device->d3d12.execution_index); + } + else if (list_type == COMMAND_LIST_TYPE_COPY) { + device->d3d12.copy_queue->ExecuteCommandLists(1, lists); + device->d3d12.copy_queue->Signal(device->d3d12.execution_fence, device->d3d12.execution_index); + } uint8_t allocator_index = command_list_oldest_allocator(list); list->d3d12.current_allocator_index = allocator_index; @@ -644,7 +671,7 @@ void kope_d3d12_device_execute_command_list(kope_g5_device *device, kope_g5_comm ID3D12DescriptorHeap *heaps[] = {list->d3d12.device->descriptor_heap, list->d3d12.device->sampler_heap}; list->d3d12.list->SetDescriptorHeaps(2, heaps); - if (list->d3d12.presenting) { + if (list_type == COMMAND_LIST_TYPE_DIRECT && list->d3d12.presenting) { kope_g5_texture *framebuffer = kope_d3d12_device_get_framebuffer(device); framebuffer->d3d12.in_flight_frame_index = device->d3d12.current_frame_index; @@ -661,6 +688,18 @@ void kope_d3d12_device_execute_command_list(kope_g5_device *device, kope_g5_comm device->d3d12.execution_index += 1; } +void kope_d3d12_device_execute_command_list(kope_g5_device *device, kope_g5_command_list *list) { + execute_command_list(COMMAND_LIST_TYPE_DIRECT, device, list); +} + +void kope_d3d12_device_execute_async_command_list(kope_g5_device *device, kope_g5_command_list *list) { + execute_command_list(COMMAND_LIST_TYPE_ASYNC, device, list); +} + +void kope_d3d12_device_execute_copy_command_list(kope_g5_device *device, kope_g5_command_list *list) { + execute_command_list(COMMAND_LIST_TYPE_COPY, device, list); +} + void kope_d3d12_device_wait_until_idle(kope_g5_device *device) { wait_for_fence(device, device->d3d12.execution_fence, device->d3d12.execution_event, device->d3d12.execution_index - 1); } diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_functions.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_functions.h index 35f14e58e..63a53864c 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_functions.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_functions.h @@ -32,6 +32,10 @@ kope_g5_texture *kope_d3d12_device_get_framebuffer(kope_g5_device *device); void kope_d3d12_device_execute_command_list(kope_g5_device *device, kope_g5_command_list *list); +void kope_d3d12_device_execute_async_command_list(kope_g5_device *device, kope_g5_command_list *list); + +void kope_d3d12_device_execute_copy_command_list(kope_g5_device *device, kope_g5_command_list *list); + void kope_d3d12_device_wait_until_idle(kope_g5_device *device); void kope_d3d12_device_create_raytracing_volume(kope_g5_device *device, kope_g5_buffer *vertex_buffer, uint64_t vertex_count, kope_g5_buffer *index_buffer, diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h index 48ac2e904..faf0e8381 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h @@ -21,6 +21,8 @@ struct ID3D12QueryHeap; typedef struct kope_d3d12_device { struct ID3D12Device5 *device; struct ID3D12CommandQueue *queue; + struct ID3D12CommandQueue *async_queue; + struct ID3D12CommandQueue *copy_queue; struct IDXGISwapChain *swap_chain; uint32_t cbv_srv_uav_increment; diff --git a/Sources/kope/graphics5/device.c b/Sources/kope/graphics5/device.c index bb5de4116..a99b00df3 100644 --- a/Sources/kope/graphics5/device.c +++ b/Sources/kope/graphics5/device.c @@ -56,6 +56,14 @@ void kope_g5_device_execute_command_list(kope_g5_device *device, kope_g5_command KOPE_G5_CALL2(device_execute_command_list, device, list); } +void kope_g5_device_execute_async_command_list(kope_g5_device *device, kope_g5_command_list *list) { + KOPE_G5_CALL2(device_execute_async_command_list, device, list); +} + +void kope_g5_device_execute_copy_command_list(kope_g5_device *device, kope_g5_command_list *list) { + KOPE_G5_CALL2(device_execute_copy_command_list, device, list); +} + void kope_g5_device_create_sampler(kope_g5_device *device, const kope_g5_sampler_parameters *parameters, kope_g5_sampler *sampler) { KOPE_G5_CALL3(device_create_sampler, device, parameters, sampler); } diff --git a/Sources/kope/graphics5/device.h b/Sources/kope/graphics5/device.h index c76e5b9fb..f8eee7e7a 100644 --- a/Sources/kope/graphics5/device.h +++ b/Sources/kope/graphics5/device.h @@ -134,6 +134,10 @@ KOPE_FUNC void kope_g5_device_create_query_set(kope_g5_device *device, const kop KOPE_FUNC void kope_g5_device_execute_command_list(kope_g5_device *device, kope_g5_command_list *list); +KOPE_FUNC void kope_g5_device_execute_async_command_list(kope_g5_device *device, kope_g5_command_list *list); + +KOPE_FUNC void kope_g5_device_execute_copy_command_list(kope_g5_device *device, kope_g5_command_list *list); + KOPE_FUNC void kope_g5_device_wait_until_idle(kope_g5_device *device); typedef struct kope_g5_raytracing_volume {