From 36dcd53882e9e45991f1172af58f7765bd815ffa Mon Sep 17 00:00:00 2001 From: Robert Konrad Date: Sun, 15 Sep 2024 13:34:26 +0200 Subject: [PATCH] Build raytracing volumes --- .../Sources/kope/direct3d12/commandlist.cpp | 31 ++++++++++ .../kope/direct3d12/commandlist_functions.h | 2 + .../kope/direct3d12/commandlist_structs.h | 2 +- .../Sources/kope/direct3d12/device.cpp | 59 +++++++++++-------- .../kope/direct3d12/device_functions.h | 4 +- .../Sources/kope/direct3d12/device_structs.h | 10 ++++ Sources/kope/graphics5/commandlist.c | 4 ++ Sources/kope/graphics5/commandlist.h | 4 ++ Sources/kope/graphics5/device.c | 5 ++ Sources/kope/graphics5/device.h | 10 +++- 10 files changed, 102 insertions(+), 29 deletions(-) diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp index 042ed79e2..498639ac0 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp @@ -171,3 +171,34 @@ void kope_d3d12_command_list_set_compute_pipeline(kope_g5_command_list *list, ko void kope_d3d12_command_list_compute(kope_g5_command_list *list, uint32_t workgroup_count_x, uint32_t workgroup_count_y, uint32_t workgroup_count_z) { list->d3d12.list->Dispatch(workgroup_count_x, workgroup_count_y, workgroup_count_z); } + +void kope_d3d12_command_list_prepare_raytracing_volume(kope_g5_command_list *list, kope_g5_raytracing_volume *volume) { + D3D12_RAYTRACING_GEOMETRY_DESC geometry_desc = {}; + + geometry_desc.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES; + geometry_desc.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE; + + geometry_desc.Triangles.Transform3x4 = 0; + + geometry_desc.Triangles.IndexFormat = volume->d3d12.index_buffer != nullptr ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_UNKNOWN; + geometry_desc.Triangles.VertexFormat = DXGI_FORMAT_R32G32B32_FLOAT; + geometry_desc.Triangles.IndexCount = volume->d3d12.index_count; + geometry_desc.Triangles.VertexCount = (UINT)volume->d3d12.vertex_count; + geometry_desc.Triangles.IndexBuffer = volume->d3d12.index_buffer != nullptr ? volume->d3d12.index_buffer->d3d12.resource->GetGPUVirtualAddress() : 0; + geometry_desc.Triangles.VertexBuffer.StartAddress = volume->d3d12.vertex_buffer->d3d12.resource->GetGPUVirtualAddress(); + geometry_desc.Triangles.VertexBuffer.StrideInBytes = sizeof(float) * 3; + + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS inputs = {}; + inputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; + inputs.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE; + inputs.NumDescs = 1; + inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + inputs.pGeometryDescs = &geometry_desc; + + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC build_desc = {}; + build_desc.DestAccelerationStructureData = volume->d3d12.acceleration_structure.d3d12.resource->GetGPUVirtualAddress(); + build_desc.Inputs = inputs; + build_desc.ScratchAccelerationStructureData = volume->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 6556438b7..dee9996ca 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_functions.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_functions.h @@ -33,6 +33,8 @@ void kope_d3d12_command_list_set_compute_pipeline(kope_g5_command_list *list, ko void kope_d3d12_command_list_compute(kope_g5_command_list *list, uint32_t workgroup_count_x, uint32_t workgroup_count_y, uint32_t workgroup_count_z); +void kope_d3d12_command_list_prepare_raytracing_volume(kope_g5_command_list *list, kope_g5_raytracing_volume *volume); + #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 f0a84d565..91eb54e0c 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_structs.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_structs.h @@ -20,7 +20,7 @@ typedef struct kope_d3d12_command_list { struct ID3D12CommandAllocator *allocator[KOPE_D3D12_COMMAND_LIST_ALLOCATOR_COUNT]; - struct ID3D12GraphicsCommandList *list; + struct ID3D12GraphicsCommandList4 *list; // a bunch of variables used to figure out what allocators can be reused uint64_t execution_index; diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp index f7162ae72..48d166459 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp @@ -190,10 +190,22 @@ void kope_d3d12_device_create_buffer(kope_g5_device *device, const kope_g5_buffe buffer->d3d12.size = parameters->size; - buffer->d3d12.resource_state = D3D12_RESOURCE_STATE_GENERIC_READ; + if ((parameters->usage_flags & KOPE_G5_BUFFER_USAGE_READ_WRITE) != 0) { + buffer->d3d12.resource_state = D3D12_RESOURCE_STATE_COMMON; + resourceDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; + } + else { + buffer->d3d12.resource_state = D3D12_RESOURCE_STATE_GENERIC_READ; + } + + if ((parameters->usage_flags & KOPE_G5_BUFFER_USAGE_RAYTRACING_VOLUME) != 0) { + buffer->d3d12.resource_state = D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE; + resourceDesc.Flags |= D3D12_RESOURCE_FLAG_RAYTRACING_ACCELERATION_STRUCTURE; + } - kinc_microsoft_affirm(device->d3d12.device->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, - NULL, IID_GRAPHICS_PPV_ARGS(&buffer->d3d12.resource))); + kinc_microsoft_affirm(device->d3d12.device->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, + (D3D12_RESOURCE_STATES)buffer->d3d12.resource_state, NULL, + IID_GRAPHICS_PPV_ARGS(&buffer->d3d12.resource))); } static uint32_t current_command_list_allocator_index(kope_g5_command_list *list) { @@ -556,48 +568,45 @@ void kope_d3d12_device_create_sampler(kope_g5_device *device, const kope_g5_samp device->d3d12.device->CreateSampler(&desc, descriptor_handle); } -void kope_d3d12_device_create_raytracing_instance(kope_g5_device *device, kope_g5_buffer *vertex_buffer, uint64_t vertex_count, kope_g5_buffer *index_buffer, - uint32_t index_count) { - D3D12_RAYTRACING_GEOMETRY_DESC geometry_desc; +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) { + volume->d3d12.vertex_buffer = vertex_buffer; + volume->d3d12.vertex_count = vertex_count; + volume->d3d12.index_buffer = index_buffer; + volume->d3d12.index_count = index_count; + + D3D12_RAYTRACING_GEOMETRY_DESC geometry_desc = {}; geometry_desc.Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES; geometry_desc.Flags = D3D12_RAYTRACING_GEOMETRY_FLAG_OPAQUE; geometry_desc.Triangles.Transform3x4 = 0; - geometry_desc.Triangles.IndexFormat = index_buffer != nullptr ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_UNKNOWN; + geometry_desc.Triangles.IndexFormat = volume->d3d12.index_buffer != nullptr ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_UNKNOWN; geometry_desc.Triangles.VertexFormat = DXGI_FORMAT_R32G32B32_FLOAT; - geometry_desc.Triangles.IndexCount = index_count; - geometry_desc.Triangles.VertexCount = (UINT)vertex_count; - geometry_desc.Triangles.IndexBuffer = index_buffer != nullptr ? index_buffer->d3d12.resource->GetGPUVirtualAddress() : 0; - geometry_desc.Triangles.VertexBuffer.StartAddress = vertex_buffer->d3d12.resource->GetGPUVirtualAddress(); + geometry_desc.Triangles.IndexCount = volume->d3d12.index_count; + geometry_desc.Triangles.VertexCount = (UINT)volume->d3d12.vertex_count; + geometry_desc.Triangles.IndexBuffer = volume->d3d12.index_buffer != nullptr ? volume->d3d12.index_buffer->d3d12.resource->GetGPUVirtualAddress() : 0; + geometry_desc.Triangles.VertexBuffer.StartAddress = volume->d3d12.vertex_buffer->d3d12.resource->GetGPUVirtualAddress(); geometry_desc.Triangles.VertexBuffer.StrideInBytes = sizeof(float) * 3; - D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS inputs; + D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS inputs = {}; inputs.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; inputs.Flags = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_PREFER_FAST_TRACE; inputs.NumDescs = 1; inputs.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; inputs.pGeometryDescs = &geometry_desc; - D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO prebuild_info; + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO prebuild_info = {}; device->d3d12.device->GetRaytracingAccelerationStructurePrebuildInfo(&inputs, &prebuild_info); - kope_g5_buffer scratch; 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, &scratch); + kope_g5_device_create_buffer(device, &scratch_params, &volume->d3d12.scratch_buffer); // TODO: delete later - kope_g5_buffer acceleration_structure; kope_g5_buffer_parameters as_params; - scratch_params.size = prebuild_info.ResultDataMaxSizeInBytes; - scratch_params.usage_flags = KOPE_G5_BUFFER_USAGE_READ_WRITE; - kope_g5_device_create_buffer(device, &as_params, &acceleration_structure); - - D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC build_desc; - - build_desc.DestAccelerationStructureData = acceleration_structure.d3d12.resource->GetGPUVirtualAddress(); - build_desc.Inputs = inputs; - build_desc.ScratchAccelerationStructureData = scratch.d3d12.resource->GetGPUVirtualAddress(); + 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, &volume->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 1c0b67010..a2e605921 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_functions.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_functions.h @@ -29,8 +29,8 @@ 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_create_raytracing_instance(kope_g5_device *device, kope_g5_buffer *vertex_buffer, uint64_t vertex_count, kope_g5_buffer *index_buffer, - uint32_t index_count); +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); #ifdef __cplusplus } diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h index 6da55043e..b86f22def 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device_structs.h @@ -52,6 +52,16 @@ typedef struct kope_d3d12_device { kope_g5_command_list management_list; } kope_d3d12_device; +typedef struct kope_d3d12_raytracing_volume { + kope_g5_buffer *vertex_buffer; + uint64_t vertex_count; + kope_g5_buffer *index_buffer; + uint32_t index_count; + + kope_g5_buffer scratch_buffer; + kope_g5_buffer acceleration_structure; +} kope_d3d12_raytracing_volume; + #ifdef __cplusplus } #endif diff --git a/Sources/kope/graphics5/commandlist.c b/Sources/kope/graphics5/commandlist.c index 8d474b1eb..989623c74 100644 --- a/Sources/kope/graphics5/commandlist.c +++ b/Sources/kope/graphics5/commandlist.c @@ -33,3 +33,7 @@ void kope_g5_command_list_draw_indexed(kope_g5_command_list *list, uint32_t inde void kope_g5_command_list_compute(kope_g5_command_list *list, uint32_t workgroup_count_x, uint32_t workgroup_count_y, uint32_t workgroup_count_z) { KOPE_G5_CALL4(command_list_compute, list, workgroup_count_x, workgroup_count_y, workgroup_count_z); } + +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); +} diff --git a/Sources/kope/graphics5/commandlist.h b/Sources/kope/graphics5/commandlist.h index 48ad5a6ea..4458f7a7d 100644 --- a/Sources/kope/graphics5/commandlist.h +++ b/Sources/kope/graphics5/commandlist.h @@ -125,6 +125,10 @@ KOPE_FUNC void kope_g5_command_list_compute(kope_g5_command_list *list, uint32_t KOPE_FUNC void kope_g5_command_list_compute_indirect(kope_g5_command_list *list, kope_g5_buffer *indirect_buffer, uint64_t indirect_offset); +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); + 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 c522ec0f6..f1776d2aa 100644 --- a/Sources/kope/graphics5/device.c +++ b/Sources/kope/graphics5/device.c @@ -158,3 +158,8 @@ bool kope_g5_texture_format_is_depth(kope_g5_texture_format format) { 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); } + +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_G5_CALL6(device_create_raytracing_volume, device, vertex_buffer, vertex_count, index_buffer, index_count, volume); +} diff --git a/Sources/kope/graphics5/device.h b/Sources/kope/graphics5/device.h index 8c5181663..03de7405a 100644 --- a/Sources/kope/graphics5/device.h +++ b/Sources/kope/graphics5/device.h @@ -42,7 +42,8 @@ typedef enum kope_g5_buffer_usage { KOPE_G5_BUFFER_USAGE_INDEX = 0x0010, KOPE_G5_BUFFER_USAGE_READ_WRITE = 0x0020, KOPE_G5_BUFFER_USAGE_INDIRECT = 0x0040, - KOPE_G5_BUFFER_USAGE_QUERY_RESOLVE = 0x0080 + KOPE_G5_BUFFER_USAGE_QUERY_RESOLVE = 0x0080, + KOPE_G5_BUFFER_USAGE_RAYTRACING_VOLUME = 0x0100 } kope_g5_buffer_usage; typedef struct kope_g5_buffer_parameters { @@ -168,6 +169,13 @@ KOPE_FUNC void kope_g5_device_create_query_set(void *descriptor); KOPE_FUNC void kope_g5_device_execute_command_list(kope_g5_device *device, kope_g5_command_list *list); +typedef struct kope_g5_raytracing_volume { + KOPE_G5_IMPL(raytracing_volume); +} kope_g5_raytracing_volume; + +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); + #ifdef __cplusplus } #endif