From 31ca19589fe3583a8e5667521f420d76a84ca193 Mon Sep 17 00:00:00 2001 From: Konstantin Seurer Date: Thu, 5 Jan 2023 17:39:39 +0100 Subject: [PATCH] radv: Create a null TLAS as meta state Reviewed-by: Friedrich Vock Part-of: --- src/amd/vulkan/radv_acceleration_structure.c | 118 +++++++++++++++++++++++++++ src/amd/vulkan/radv_meta.c | 9 ++ src/amd/vulkan/radv_meta.h | 1 + src/amd/vulkan/radv_private.h | 6 ++ 4 files changed, 134 insertions(+) diff --git a/src/amd/vulkan/radv_acceleration_structure.c b/src/amd/vulkan/radv_acceleration_structure.c index beb33f8..42b6357 100644 --- a/src/amd/vulkan/radv_acceleration_structure.c +++ b/src/amd/vulkan/radv_acceleration_structure.c @@ -363,6 +363,13 @@ radv_device_finish_accel_struct_build_state(struct radv_device *device) if (state->accel_struct_build.radix_sort) radix_sort_vk_destroy(state->accel_struct_build.radix_sort, radv_device_to_handle(device), &state->alloc); + + radv_DestroyBuffer(radv_device_to_handle(device), state->accel_struct_build.null.buffer, + &state->alloc); + radv_FreeMemory(radv_device_to_handle(device), state->accel_struct_build.null.memory, + &state->alloc); + radv_DestroyAccelerationStructureKHR(radv_device_to_handle(device), + state->accel_struct_build.null.accel_struct, &state->alloc); } static VkResult @@ -439,6 +446,117 @@ radix_sort_fill_buffer(VkCommandBuffer commandBuffer, size, data); } +VkResult +radv_device_init_null_accel_struct(struct radv_device *device) +{ + VkDevice _device = radv_device_to_handle(device); + + uint32_t bvh_offset = ALIGN(sizeof(struct radv_accel_struct_header), 64); + uint32_t size = bvh_offset + sizeof(struct radv_bvh_box32_node); + + VkResult result; + + VkBuffer buffer = VK_NULL_HANDLE; + VkDeviceMemory memory = VK_NULL_HANDLE; + VkAccelerationStructureKHR accel_struct = VK_NULL_HANDLE; + + VkBufferCreateInfo buffer_create_info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .size = size, + .usage = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + }; + + result = radv_CreateBuffer(_device, &buffer_create_info, &device->meta_state.alloc, &buffer); + if (result != VK_SUCCESS) + return result; + + VkBufferMemoryRequirementsInfo2 info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, + .buffer = buffer, + }; + VkMemoryRequirements2 mem_req = { + .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, + }; + radv_GetBufferMemoryRequirements2(_device, &info, &mem_req); + + VkMemoryAllocateInfo alloc_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .allocationSize = mem_req.memoryRequirements.size, + .memoryTypeIndex = + radv_find_memory_index(device->physical_device, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), + }; + + result = radv_AllocateMemory(_device, &alloc_info, &device->meta_state.alloc, &memory); + if (result != VK_SUCCESS) + return result; + + VkBindBufferMemoryInfo bind_info = { + .sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO, + .buffer = buffer, + .memory = memory, + }; + + result = radv_BindBufferMemory2(_device, 1, &bind_info); + if (result != VK_SUCCESS) + return result; + + void *data; + result = radv_MapMemory(_device, memory, 0, size, 0, &data); + if (result != VK_SUCCESS) + return result; + + struct radv_accel_struct_header header = { + .bvh_offset = bvh_offset, + }; + memcpy(data, &header, sizeof(struct radv_accel_struct_header)); + + struct radv_bvh_box32_node root = { + .children = + { + RADV_BVH_INVALID_NODE, + RADV_BVH_INVALID_NODE, + RADV_BVH_INVALID_NODE, + RADV_BVH_INVALID_NODE, + }, + }; + + for (uint32_t child = 0; child < 4; child++) { + root.coords[child] = (radv_aabb){ + .min.x = NAN, + .min.y = NAN, + .min.z = NAN, + .max.x = NAN, + .max.y = NAN, + .max.z = NAN, + }; + } + + memcpy((uint8_t *)data + bvh_offset, &root, sizeof(struct radv_bvh_box32_node)); + + radv_UnmapMemory(_device, memory); + + VkAccelerationStructureCreateInfoKHR create_info = { + .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR, + .buffer = buffer, + .size = size, + .type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR, + }; + + result = radv_CreateAccelerationStructureKHR(_device, &create_info, &device->meta_state.alloc, + &accel_struct); + if (result != VK_SUCCESS) + return result; + + device->meta_state.accel_struct_build.null.buffer = buffer; + device->meta_state.accel_struct_build.null.memory = memory; + device->meta_state.accel_struct_build.null.accel_struct = accel_struct; + + return VK_SUCCESS; +} + static VkResult radv_device_init_accel_struct_build_state(struct radv_device *device) { diff --git a/src/amd/vulkan/radv_meta.c b/src/amd/vulkan/radv_meta.c index e76feb0..55b2aa1 100644 --- a/src/amd/vulkan/radv_meta.c +++ b/src/amd/vulkan/radv_meta.c @@ -488,10 +488,19 @@ radv_device_init_meta(struct radv_device *device) goto fail_dgc; } + if (device->vk.enabled_features.nullDescriptor && + device->vk.enabled_extensions.KHR_acceleration_structure) { + result = radv_device_init_null_accel_struct(device); + if (result != VK_SUCCESS) + goto fail_accel_struct; + } + device->app_shaders_internal = false; return VK_SUCCESS; +fail_accel_struct: + radv_device_finish_accel_struct_build_state(device); fail_dgc: radv_device_finish_dgc_prepare_state(device); fail_etc_decode: diff --git a/src/amd/vulkan/radv_meta.h b/src/amd/vulkan/radv_meta.h index 21aed2a..a954398c 100644 --- a/src/amd/vulkan/radv_meta.h +++ b/src/amd/vulkan/radv_meta.h @@ -101,6 +101,7 @@ void radv_device_finish_meta_dcc_retile_state(struct radv_device *device); void radv_device_finish_meta_copy_vrs_htile_state(struct radv_device *device); +VkResult radv_device_init_null_accel_struct(struct radv_device *device); void radv_device_finish_accel_struct_build_state(struct radv_device *device); VkResult radv_device_init_meta_etc_decode_state(struct radv_device *device, bool on_demand); diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 3a44d94..beea674 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -697,6 +697,12 @@ struct radv_meta_state { struct radix_sort_vk *radix_sort; struct radix_sort_vk_sort_devaddr_info radix_sort_info; + + struct { + VkBuffer buffer; + VkDeviceMemory memory; + VkAccelerationStructureKHR accel_struct; + } null; } accel_struct_build; struct { -- 2.7.4