From 2837c7fb01e34219f0745ea5ec86f04f1a059475 Mon Sep 17 00:00:00 2001 From: Robert Konrad Date: Sun, 15 Sep 2024 18:30:02 +0200 Subject: [PATCH] Build a raytracing hierarchy --- .../Sources/kope/direct3d12/commandlist.cpp | 16 ++++++++ .../kope/direct3d12/commandlist_functions.h | 2 + .../Sources/kope/direct3d12/device.cpp | 39 +++++++++++++++++++ .../kope/direct3d12/device_functions.h | 3 ++ .../Sources/kope/direct3d12/device_structs.h | 8 ++++ Sources/kope/graphics5/commandlist.c | 3 ++ Sources/kope/graphics5/commandlist.h | 4 ++ Sources/kope/graphics5/device.c | 5 +++ Sources/kope/graphics5/device.h | 7 ++++ 9 files changed, 87 insertions(+) diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp index 498639ac0..b6cbd362c 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp @@ -202,3 +202,19 @@ void kope_d3d12_command_list_prepare_raytracing_volume(kope_g5_command_list *lis list->d3d12.list->BuildRaytracingAccelerationStructure(&build_desc, 0, nullptr); } + +void kope_d3d12_command_list_prepare_raytracing_hierarchy(kope_g5_command_list *list, kope_g5_raytracing_hierarchy *hierarchy) { + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS inputs = {}; + inputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + inputs.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE; + inputs.NumDescs = hierarchy->d3d12.volumes_count; + inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + inputs.InstanceDescs = hierarchy->d3d12.instances.d3d12.resource->GetGPUVirtualAddress(); + + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC build_desc = {}; + build_desc.DestAccelerationStructureData = hierarchy->d3d12.acceleration_structure.d3d12.resource->GetGPUVirtualAddress(); + build_desc.Inputs = inputs; + build_desc.ScratchAccelerationStructureData = hierarchy->d3d12.scratch_buffer.d3d12.resource->GetGPUVirtualAddress(); + + list->d3d12.list->BuildRaytracingAccelerationStructure(&build_desc, 0, nullptr); +} diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_functions.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_functions.h index dee9996ca..6fef594a6 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_functions.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_functions.h @@ -35,6 +35,8 @@ void kope_d3d12_command_list_compute(kope_g5_command_list *list, uint32_t workgr void kope_d3d12_command_list_prepare_raytracing_volume(kope_g5_command_list *list, kope_g5_raytracing_volume *volume); +void kope_d3d12_command_list_prepare_raytracing_hierarchy(kope_g5_command_list *list, kope_g5_raytracing_hierarchy *hierarchy); + #ifdef __cplusplus } #endif diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp index 48d166459..9679b478b 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp @@ -610,3 +610,42 @@ void kope_d3d12_device_create_raytracing_volume(kope_g5_device *device, kope_g5_ as_params.usage_flags = KOPE_G5_BUFFER_USAGE_READ_WRITE | KOPE_G5_BUFFER_USAGE_RAYTRACING_VOLUME; kope_g5_device_create_buffer(device, &as_params, &volume->d3d12.acceleration_structure); } + +void kope_d3d12_device_create_raytracing_hierarchy(kope_g5_device *device, kope_g5_raytracing_volume **volumes, uint32_t volumes_count, + kope_g5_raytracing_hierarchy *hierarchy) { + hierarchy->d3d12.volumes_count = volumes_count; + + kope_g5_buffer_parameters instances_params; + instances_params.size = sizeof(D3D12_RAYTRACING_INSTANCE_DESC) * hierarchy->d3d12.volumes_count; + instances_params.usage_flags = KOPE_G5_BUFFER_USAGE_CPU_WRITE; + kope_g5_device_create_buffer(device, &instances_params, &hierarchy->d3d12.instances); + + D3D12_RAYTRACING_INSTANCE_DESC *descs = (D3D12_RAYTRACING_INSTANCE_DESC *)kope_g5_buffer_lock(&hierarchy->d3d12.instances); + for (uint32_t volume_index = 0; volume_index < hierarchy->d3d12.volumes_count; ++volume_index) { + memset(&descs[volume_index], 0, sizeof(D3D12_RAYTRACING_INSTANCE_DESC)); + descs[volume_index].InstanceID = volume_index; + descs[volume_index].InstanceMask = 1; + descs[volume_index].AccelerationStructure = volumes[volume_index]->d3d12.acceleration_structure.d3d12.resource->GetGPUVirtualAddress(); + } + kope_g5_buffer_unlock(&hierarchy->d3d12.instances); + + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS inputs = {}; + inputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + inputs.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_UPDATE; + inputs.NumDescs = hierarchy->d3d12.volumes_count; + inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + inputs.InstanceDescs = hierarchy->d3d12.instances.d3d12.resource->GetGPUVirtualAddress(); + + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO prebuild_info = {}; + device->d3d12.device->GetRaytracingAccelerationStructurePrebuildInfo(&inputs, &prebuild_info); + + kope_g5_buffer_parameters scratch_params; + scratch_params.size = prebuild_info.ScratchDataSizeInBytes; + scratch_params.usage_flags = KOPE_G5_BUFFER_USAGE_READ_WRITE; + kope_g5_device_create_buffer(device, &scratch_params, &hierarchy->d3d12.scratch_buffer); // TODO: delete later + + kope_g5_buffer_parameters as_params; + as_params.size = prebuild_info.ResultDataMaxSizeInBytes; + as_params.usage_flags = KOPE_G5_BUFFER_USAGE_READ_WRITE | KOPE_G5_BUFFER_USAGE_RAYTRACING_VOLUME; + kope_g5_device_create_buffer(device, &as_params, &hierarchy->d3d12.acceleration_structure); +} diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_functions.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_functions.h index a2e605921..b8108af17 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_functions.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_functions.h @@ -32,6 +32,9 @@ void kope_d3d12_device_execute_command_list(kope_g5_device *device, kope_g5_comm 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, uint32_t index_count, kope_g5_raytracing_volume *volume); +void kope_d3d12_device_create_raytracing_hierarchy(kope_g5_device *device, kope_g5_raytracing_volume **volumes, uint32_t volumes_count, + kope_g5_raytracing_hierarchy *hierarchy); + #ifdef __cplusplus } #endif diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h index b86f22def..c46494d72 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h @@ -62,6 +62,14 @@ typedef struct kope_d3d12_raytracing_volume { kope_g5_buffer acceleration_structure; } kope_d3d12_raytracing_volume; +typedef struct kope_d3d12_raytracing_hierarchy { + uint32_t volumes_count; + kope_g5_buffer instances; + + kope_g5_buffer scratch_buffer; + kope_g5_buffer acceleration_structure; +} kope_d3d12_raytracing_hierarchy; + #ifdef __cplusplus } #endif diff --git a/Sources/kope/graphics5/commandlist.c b/Sources/kope/graphics5/commandlist.c index 989623c74..068f2b535 100644 --- a/Sources/kope/graphics5/commandlist.c +++ b/Sources/kope/graphics5/commandlist.c @@ -37,3 +37,6 @@ void kope_g5_command_list_compute(kope_g5_command_list *list, uint32_t workgroup void kope_g5_command_list_prepare_raytracing_volume(kope_g5_command_list *list, kope_g5_raytracing_volume *volume) { KOPE_G5_CALL2(command_list_prepare_raytracing_volume, list, volume); } +void kope_g5_command_list_prepare_raytracing_hierarchy(kope_g5_command_list *list, kope_g5_raytracing_hierarchy *hierarchy) { + KOPE_G5_CALL2(command_list_prepare_raytracing_hierarchy, list, hierarchy); +} diff --git a/Sources/kope/graphics5/commandlist.h b/Sources/kope/graphics5/commandlist.h index 4458f7a7d..8c5e158fd 100644 --- a/Sources/kope/graphics5/commandlist.h +++ b/Sources/kope/graphics5/commandlist.h @@ -129,6 +129,10 @@ struct kope_g5_raytracing_volume; KOPE_FUNC void kope_g5_command_list_prepare_raytracing_volume(kope_g5_command_list *list, struct kope_g5_raytracing_volume *volume); +struct kope_g5_raytracing_hierarchy; + +KOPE_FUNC void kope_g5_command_list_prepare_raytracing_hierarchy(kope_g5_command_list *list, struct kope_g5_raytracing_hierarchy *hierarchy); + KOPE_FUNC void kope_g5_command_list_present(kope_g5_command_list *list); #ifdef __cplusplus diff --git a/Sources/kope/graphics5/device.c b/Sources/kope/graphics5/device.c index f1776d2aa..d0b09c5c3 100644 --- a/Sources/kope/graphics5/device.c +++ b/Sources/kope/graphics5/device.c @@ -163,3 +163,8 @@ void kope_g5_device_create_raytracing_volume(kope_g5_device *device, kope_g5_buf uint32_t index_count, kope_g5_raytracing_volume *volume) { KOPE_G5_CALL6(device_create_raytracing_volume, device, vertex_buffer, vertex_count, index_buffer, index_count, volume); } + +void kope_g5_device_create_raytracing_hierarchy(kope_g5_device *device, kope_g5_raytracing_volume **volumes, uint32_t volumes_count, + kope_g5_raytracing_hierarchy *hierarchy) { + KOPE_G5_CALL4(device_create_raytracing_hierarchy, device, volumes, volumes_count, hierarchy); +} diff --git a/Sources/kope/graphics5/device.h b/Sources/kope/graphics5/device.h index 03de7405a..de149ee9f 100644 --- a/Sources/kope/graphics5/device.h +++ b/Sources/kope/graphics5/device.h @@ -173,9 +173,16 @@ typedef struct kope_g5_raytracing_volume { KOPE_G5_IMPL(raytracing_volume); } kope_g5_raytracing_volume; +typedef struct kope_g5_raytracing_hierarchy { + KOPE_G5_IMPL(raytracing_hierarchy); +} kope_g5_raytracing_hierarchy; + KOPE_FUNC void kope_g5_device_create_raytracing_volume(kope_g5_device *device, kope_g5_buffer *vertex_buffer, uint64_t vertex_count, kope_g5_buffer *index_buffer, uint32_t index_count, kope_g5_raytracing_volume *volume); +KOPE_FUNC void kope_g5_device_create_raytracing_hierarchy(kope_g5_device *device, kope_g5_raytracing_volume **volumes, uint32_t volumes_count, + kope_g5_raytracing_hierarchy *hierarchy); + #ifdef __cplusplus } #endif