From 930f218734654e67778cbcc236a3e2f3b588d3b0 Mon Sep 17 00:00:00 2001 From: Robert Konrad Date: Mon, 30 Sep 2024 10:44:19 +0200 Subject: [PATCH] Implement occlusion queries --- .../Sources/kope/direct3d12/commandlist.cpp | 18 ++++++++++++++++++ .../kope/direct3d12/commandlist_functions.h | 7 +++++++ .../kope/direct3d12/commandlist_structs.h | 5 +++++ .../Sources/kope/direct3d12/device.cpp | 4 ++++ .../Sources/kope/direct3d12/device_structs.h | 1 + Sources/kope/graphics5/commandlist.c | 13 +++++++++++++ Sources/kope/graphics5/commandlist.h | 8 +++++--- 7 files changed, 53 insertions(+), 3 deletions(-) diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp index b86cf0665..06d8549ee 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp @@ -146,6 +146,8 @@ void kope_d3d12_command_list_begin_render_pass(kope_g5_command_list *list, const NULL); } } + + list->d3d12.occlusion_query_set = parameters->occlusion_query_set; } void kope_d3d12_command_list_end_render_pass(kope_g5_command_list *list) {} @@ -662,3 +664,19 @@ void kope_d3d12_command_list_insert_debug_marker(kope_g5_command_list *list, con PIXSetMarker(list->d3d12.list, 0, "%s", name); #endif } + +void kope_d3d12_command_list_begin_occlusion_query(kope_g5_command_list *list, uint32_t query_index) { + list->d3d12.current_occlusion_query_index = query_index; + list->d3d12.list->BeginQuery(list->d3d12.occlusion_query_set->d3d12.query_heap, D3D12_QUERY_TYPE_OCCLUSION, query_index); +} + +void kope_d3d12_command_list_end_occlusion_query(kope_g5_command_list *list) { + list->d3d12.list->EndQuery(list->d3d12.occlusion_query_set->d3d12.query_heap, D3D12_QUERY_TYPE_OCCLUSION, list->d3d12.current_occlusion_query_index); +} + +void kope_d3d12_command_list_resolve_query_set(kope_g5_command_list *list, kope_g5_query_set *query_set, uint32_t first_query, uint32_t query_count, + kope_g5_buffer *destination, uint64_t destination_offset) { + list->d3d12.list->ResolveQueryData(query_set->d3d12.query_heap, + query_set->d3d12.query_type == KOPE_G5_QUERY_TYPE_OCCLUSION ? D3D12_QUERY_TYPE_OCCLUSION : D3D12_QUERY_TYPE_TIMESTAMP, + first_query, query_count, destination->d3d12.resource, destination_offset); +} diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_functions.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_functions.h index ccce71aa5..fc80709cd 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_functions.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_functions.h @@ -81,6 +81,13 @@ void kope_d3d12_command_list_pop_debug_group(kope_g5_command_list *list); void kope_d3d12_command_list_insert_debug_marker(kope_g5_command_list *list, const char *name); +void kope_d3d12_command_list_begin_occlusion_query(kope_g5_command_list *list, uint32_t query_index); + +void kope_d3d12_command_list_end_occlusion_query(kope_g5_command_list *list); + +void kope_d3d12_command_list_resolve_query_set(kope_g5_command_list *list, kope_g5_query_set *query_set, uint32_t first_query, uint32_t query_count, + kope_g5_buffer *destination, uint64_t destination_offset); + #ifdef __cplusplus } #endif diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_structs.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_structs.h index 7586e435b..457403e05 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_structs.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_structs.h @@ -10,6 +10,8 @@ extern "C" { struct kope_d3d12_device; struct kope_d3d12_texture; struct kope_d3d12_ray_pipeline; +struct kope_g5_query_set; + struct ID3D12Fence; // Allocators can not be re-used while a command-list is executing. We carry along a bag of allocators so we only have to wait when we ran out of in-flight @@ -38,6 +40,9 @@ typedef struct kope_d3d12_command_list { struct kope_d3d12_ray_pipeline *ray_pipe; + struct kope_g5_query_set *occlusion_query_set; + uint32_t current_occlusion_query_index; + bool presenting; } kope_d3d12_command_list; diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp index 59962e22d..8be721eb4 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp @@ -312,6 +312,9 @@ void kope_d3d12_device_create_command_list(kope_g5_device *device, kope_g5_comma list->d3d12.dsv_increment = device->d3d12.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); } + list->d3d12.occlusion_query_set = NULL; + list->d3d12.current_occlusion_query_index = 0; + list->d3d12.blocking_frame_index = 0; list->d3d12.presenting = false; @@ -739,6 +742,7 @@ void kope_d3d12_device_create_query_set(kope_g5_device *device, const kope_g5_qu desc.Count = parameters->count; desc.NodeMask = 0; + query_set->d3d12.query_type = (uint8_t)parameters->type; device->d3d12.device->CreateQueryHeap(&desc, IID_GRAPHICS_PPV_ARGS(&query_set->d3d12.query_heap)); } diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h index e3161c742..48ac2e904 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h @@ -51,6 +51,7 @@ typedef struct kope_d3d12_device { typedef struct kope_d3d12_query_set { struct ID3D12QueryHeap *query_heap; + uint8_t query_type; } kope_d3d12_query_set; typedef struct kope_d3d12_raytracing_volume { diff --git a/Sources/kope/graphics5/commandlist.c b/Sources/kope/graphics5/commandlist.c index d85d05bd8..177540162 100644 --- a/Sources/kope/graphics5/commandlist.c +++ b/Sources/kope/graphics5/commandlist.c @@ -117,3 +117,16 @@ void kope_g5_command_list_pop_debug_group(kope_g5_command_list *list) { void kope_g5_command_list_insert_debug_marker(kope_g5_command_list *list, const char *name) { KOPE_G5_CALL2(command_list_insert_debug_marker, list, name); } + +void kope_g5_command_list_begin_occlusion_query(kope_g5_command_list *list, uint32_t query_index) { + KOPE_G5_CALL2(command_list_begin_occlusion_query, list, query_index); +} + +void kope_g5_command_list_end_occlusion_query(kope_g5_command_list *list) { + KOPE_G5_CALL1(command_list_end_occlusion_query, list); +} + +void kope_g5_command_list_resolve_query_set(kope_g5_command_list *list, kope_g5_query_set *query_set, uint32_t first_query, uint32_t query_count, + kope_g5_buffer *destination, uint64_t destination_offset) { + KOPE_G5_CALL6(command_list_resolve_query_set, list, query_set, first_query, query_count, destination, destination_offset); +} diff --git a/Sources/kope/graphics5/commandlist.h b/Sources/kope/graphics5/commandlist.h index 5a6b539f9..1873760dd 100644 --- a/Sources/kope/graphics5/commandlist.h +++ b/Sources/kope/graphics5/commandlist.h @@ -25,6 +25,8 @@ extern "C" { #endif +struct kope_g5_query_set; + typedef struct kope_g5_command_list { KOPE_G5_IMPL(command_list); } kope_g5_command_list; @@ -75,7 +77,7 @@ typedef struct kope_g5_render_pass_parameters { kope_g5_render_pass_color_attachment color_attachments[8]; size_t color_attachments_count; kope_g5_render_pass_depth_stencil_attachment depth_stencil_attachment; - // GPUQuerySet occlusionQuerySet; + struct kope_g5_query_set *occlusion_query_set; // GPURenderPassTimestampWrites timestampWrites; } kope_g5_render_pass_parameters; @@ -114,8 +116,8 @@ KOPE_FUNC void kope_g5_command_list_copy_texture_to_texture(kope_g5_command_list KOPE_FUNC void kope_g5_command_list_clear_buffer(kope_g5_command_list *list, kope_g5_buffer *buffer, size_t offset, uint64_t size); -// KOPE_FUNC void kope_g5_command_list_resolve_query_set(kope_g5_command_list *list, GPUQuerySet query_set, uint32_t first_query, uint32_t query_count, -// kope_g5_buffer *destination, uint64_t destination_offset); +KOPE_FUNC void kope_g5_command_list_resolve_query_set(kope_g5_command_list *list, struct kope_g5_query_set *query_set, uint32_t first_query, + uint32_t query_count, kope_g5_buffer *destination, uint64_t destination_offset); typedef enum kope_g5_index_format { KOPE_G5_INDEX_FORMAT_UINT16, KOPE_G5_INDEX_FORMAT_UINT32 } kope_g5_index_format;