Module: Mesa
Branch: main
Commit: e2fa9ba9c657193202fb2b77cb9f9db1c9ba6362
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=e2fa9ba9c657193202fb2b77cb9f9db1c9ba6362

Author: Konstantin Seurer <[email protected]>
Date:   Fri Jan 20 21:52:06 2023 +0100

radv: Use indirect header filling for compact builds

Sets the accel struct size fields to the correct values which should
allow for more compaction.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20818>

---

 src/amd/vulkan/radv_acceleration_structure.c | 48 +++++++++++++++++++++++++---
 src/amd/vulkan/radv_private.h                |  2 ++
 2 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/src/amd/vulkan/radv_acceleration_structure.c 
b/src/amd/vulkan/radv_acceleration_structure.c
index 604746a2036..ee8a8bef36d 100644
--- a/src/amd/vulkan/radv_acceleration_structure.c
+++ b/src/amd/vulkan/radv_acceleration_structure.c
@@ -71,6 +71,10 @@ static const uint32_t encode_compact_spv[] = {
 #include "bvh/encode_compact.spv.h"
 };
 
+static const uint32_t header_spv[] = {
+#include "bvh/header.spv.h"
+};
+
 #define KEY_ID_PAIR_SIZE 8
 
 enum internal_build_type {
@@ -307,6 +311,8 @@ radv_device_finish_accel_struct_build_state(struct 
radv_device *device)
                         &state->alloc);
    radv_DestroyPipeline(radv_device_to_handle(device),
                         state->accel_struct_build.encode_compact_pipeline, 
&state->alloc);
+   radv_DestroyPipeline(radv_device_to_handle(device), 
state->accel_struct_build.header_pipeline,
+                        &state->alloc);
    radv_DestroyPipeline(radv_device_to_handle(device), 
state->accel_struct_build.morton_pipeline,
                         &state->alloc);
    radv_DestroyPipelineLayout(radv_device_to_handle(device),
@@ -321,6 +327,8 @@ radv_device_finish_accel_struct_build_state(struct 
radv_device *device)
                               state->accel_struct_build.leaf_p_layout, 
&state->alloc);
    radv_DestroyPipelineLayout(radv_device_to_handle(device),
                               state->accel_struct_build.encode_p_layout, 
&state->alloc);
+   radv_DestroyPipelineLayout(radv_device_to_handle(device),
+                              state->accel_struct_build.header_p_layout, 
&state->alloc);
    radv_DestroyPipelineLayout(radv_device_to_handle(device),
                               state->accel_struct_build.morton_p_layout, 
&state->alloc);
 
@@ -581,6 +589,13 @@ radv_device_init_accel_struct_build_state(struct 
radv_device *device)
    if (result != VK_SUCCESS)
       goto exit;
 
+   result =
+      create_build_pipeline_spv(device, header_spv, sizeof(header_spv), 
sizeof(struct header_args),
+                                
&device->meta_state.accel_struct_build.header_pipeline,
+                                
&device->meta_state.accel_struct_build.header_p_layout);
+   if (result != VK_SUCCESS)
+      goto exit;
+
    result =
       create_build_pipeline_spv(device, morton_spv, sizeof(morton_spv), 
sizeof(struct morton_args),
                                 
&device->meta_state.accel_struct_build.morton_pipeline,
@@ -1045,19 +1060,44 @@ radv_CmdBuildAccelerationStructuresKHR(
    encode_nodes(commandBuffer, infoCount, pInfos, bvh_states, false);
    encode_nodes(commandBuffer, infoCount, pInfos, bvh_states, true);
 
+   cmd_buffer->state.flush_bits |= flush_bits;
+
+   radv_CmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE,
+                        
cmd_buffer->device->meta_state.accel_struct_build.header_pipeline);
+
    for (uint32_t i = 0; i < infoCount; ++i) {
       RADV_FROM_HANDLE(vk_acceleration_structure, accel_struct, 
pInfos[i].dstAccelerationStructure);
-      const size_t base = offsetof(struct radv_accel_struct_header, 
compacted_size);
-      struct radv_accel_struct_header header;
+      size_t base = offsetof(struct radv_accel_struct_header, compacted_size);
+
+      uint64_t instance_count = pInfos[i].type == 
VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR
+                                   ? bvh_states[i].leaf_node_count
+                                   : 0;
+
+      if (bvh_states[i].config.compact) {
+         base = offsetof(struct radv_accel_struct_header, geometry_count);
+
+         struct header_args args = {
+            .src = pInfos[i].scratchData.deviceAddress + 
bvh_states[i].scratch.header_offset,
+            .dst = vk_acceleration_structure_get_va(accel_struct),
+            .bvh_offset = bvh_states[i].accel_struct.bvh_offset,
+            .instance_count = instance_count,
+         };
 
-      bool is_tlas = pInfos[i].type == 
VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
+         radv_CmdPushConstants(commandBuffer,
+                               
cmd_buffer->device->meta_state.accel_struct_build.header_p_layout,
+                               VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(args), 
&args);
+
+         radv_unaligned_dispatch(cmd_buffer, 1, 1, 1);
+      }
+
+      struct radv_accel_struct_header header;
 
       uint64_t geometry_infos_size =
          pInfos[i].geometryCount * sizeof(struct 
radv_accel_struct_geometry_info);
 
       header.instance_offset =
          bvh_states[i].accel_struct.bvh_offset + sizeof(struct 
radv_bvh_box32_node);
-      header.instance_count = is_tlas ? bvh_states[i].leaf_node_count : 0;
+      header.instance_count = instance_count;
       header.compacted_size = bvh_states[i].accel_struct.size;
 
       header.copy_dispatch_size[0] = DIV_ROUND_UP(header.compacted_size, 16 * 
64);
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index d4a6aed3fd6..99d398d9317 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -699,6 +699,8 @@ struct radv_meta_state {
       VkPipelineLayout encode_p_layout;
       VkPipeline encode_pipeline;
       VkPipeline encode_compact_pipeline;
+      VkPipelineLayout header_p_layout;
+      VkPipeline header_pipeline;
       VkPipelineLayout copy_p_layout;
       VkPipeline copy_pipeline;
 

Reply via email to