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

Author: Friedrich Vock <[email protected]>
Date:   Sun Dec 17 17:27:31 2023 +0100

radv/rt: Move per-geometry build info into a geometry_data struct

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

---

 src/amd/vulkan/bvh/build_helpers.h           | 276 +++++++++++++++++++++++++
 src/amd/vulkan/bvh/build_interface.h         |  13 +-
 src/amd/vulkan/bvh/bvh.h                     |  14 ++
 src/amd/vulkan/bvh/leaf.comp                 | 298 +--------------------------
 src/amd/vulkan/radv_acceleration_structure.c | 109 +++++-----
 5 files changed, 363 insertions(+), 347 deletions(-)

diff --git a/src/amd/vulkan/bvh/build_helpers.h 
b/src/amd/vulkan/bvh/build_helpers.h
index 436faba7038..adbf621a308 100644
--- a/src/amd/vulkan/bvh/build_helpers.h
+++ b/src/amd/vulkan/bvh/build_helpers.h
@@ -317,6 +317,282 @@ aabb_surface_area(radv_aabb aabb)
    return 2 * diagonal.x * diagonal.y + 2 * diagonal.y * diagonal.z + 2 * 
diagonal.x * diagonal.z;
 }
 
+/* Just a wrapper for 3 uints. */
+struct triangle_indices {
+   uint32_t index[3];
+};
+
+triangle_indices
+load_indices(VOID_REF indices, uint32_t index_format, uint32_t global_id)
+{
+   triangle_indices result;
+
+   uint32_t index_base = global_id * 3;
+
+   switch (index_format) {
+   case VK_INDEX_TYPE_UINT16: {
+      result.index[0] = DEREF(INDEX(uint16_t, indices, index_base + 0));
+      result.index[1] = DEREF(INDEX(uint16_t, indices, index_base + 1));
+      result.index[2] = DEREF(INDEX(uint16_t, indices, index_base + 2));
+      break;
+   }
+   case VK_INDEX_TYPE_UINT32: {
+      result.index[0] = DEREF(INDEX(uint32_t, indices, index_base + 0));
+      result.index[1] = DEREF(INDEX(uint32_t, indices, index_base + 1));
+      result.index[2] = DEREF(INDEX(uint32_t, indices, index_base + 2));
+      break;
+   }
+   case VK_INDEX_TYPE_NONE_KHR: {
+      result.index[0] = index_base + 0;
+      result.index[1] = index_base + 1;
+      result.index[2] = index_base + 2;
+      break;
+   }
+   case VK_INDEX_TYPE_UINT8_EXT: {
+      result.index[0] = DEREF(INDEX(uint8_t, indices, index_base + 0));
+      result.index[1] = DEREF(INDEX(uint8_t, indices, index_base + 1));
+      result.index[2] = DEREF(INDEX(uint8_t, indices, index_base + 2));
+      break;
+   }
+   }
+
+   return result;
+}
+
+/* Just a wrapper for 3 vec4s. */
+struct triangle_vertices {
+   vec4 vertex[3];
+};
+
+TYPE(float16_t, 2);
+
+triangle_vertices
+load_vertices(VOID_REF vertices, triangle_indices indices, uint32_t 
vertex_format, uint32_t stride)
+{
+   triangle_vertices result;
+
+   for (uint32_t i = 0; i < 3; i++) {
+      VOID_REF vertex_ptr = OFFSET(vertices, indices.index[i] * stride);
+      vec4 vertex = vec4(0.0, 0.0, 0.0, 1.0);
+
+      switch (vertex_format) {
+      case VK_FORMAT_R32G32_SFLOAT:
+         vertex.x = DEREF(INDEX(float, vertex_ptr, 0));
+         vertex.y = DEREF(INDEX(float, vertex_ptr, 1));
+         break;
+      case VK_FORMAT_R32G32B32_SFLOAT:
+      case VK_FORMAT_R32G32B32A32_SFLOAT:
+         vertex.x = DEREF(INDEX(float, vertex_ptr, 0));
+         vertex.y = DEREF(INDEX(float, vertex_ptr, 1));
+         vertex.z = DEREF(INDEX(float, vertex_ptr, 2));
+         break;
+      case VK_FORMAT_R16G16_SFLOAT:
+         vertex.x = DEREF(INDEX(float16_t, vertex_ptr, 0));
+         vertex.y = DEREF(INDEX(float16_t, vertex_ptr, 1));
+         break;
+      case VK_FORMAT_R16G16B16_SFLOAT:
+      case VK_FORMAT_R16G16B16A16_SFLOAT:
+         vertex.x = DEREF(INDEX(float16_t, vertex_ptr, 0));
+         vertex.y = DEREF(INDEX(float16_t, vertex_ptr, 1));
+         vertex.z = DEREF(INDEX(float16_t, vertex_ptr, 2));
+         break;
+      case VK_FORMAT_R16G16_SNORM:
+         vertex.x = max(-1.0, DEREF(INDEX(int16_t, vertex_ptr, 0)) / 
float(0x7FFF));
+         vertex.y = max(-1.0, DEREF(INDEX(int16_t, vertex_ptr, 1)) / 
float(0x7FFF));
+         break;
+      case VK_FORMAT_R16G16B16A16_SNORM:
+         vertex.x = max(-1.0, DEREF(INDEX(int16_t, vertex_ptr, 0)) / 
float(0x7FFF));
+         vertex.y = max(-1.0, DEREF(INDEX(int16_t, vertex_ptr, 1)) / 
float(0x7FFF));
+         vertex.z = max(-1.0, DEREF(INDEX(int16_t, vertex_ptr, 2)) / 
float(0x7FFF));
+         break;
+      case VK_FORMAT_R8G8_SNORM:
+         vertex.x = max(-1.0, DEREF(INDEX(int8_t, vertex_ptr, 0)) / 
float(0x7F));
+         vertex.y = max(-1.0, DEREF(INDEX(int8_t, vertex_ptr, 1)) / 
float(0x7F));
+         break;
+      case VK_FORMAT_R8G8B8A8_SNORM:
+         vertex.x = max(-1.0, DEREF(INDEX(int8_t, vertex_ptr, 0)) / 
float(0x7F));
+         vertex.y = max(-1.0, DEREF(INDEX(int8_t, vertex_ptr, 1)) / 
float(0x7F));
+         vertex.z = max(-1.0, DEREF(INDEX(int8_t, vertex_ptr, 2)) / 
float(0x7F));
+         break;
+      case VK_FORMAT_R16G16_UNORM:
+         vertex.x = DEREF(INDEX(uint16_t, vertex_ptr, 0)) / float(0xFFFF);
+         vertex.y = DEREF(INDEX(uint16_t, vertex_ptr, 1)) / float(0xFFFF);
+         break;
+      case VK_FORMAT_R16G16B16A16_UNORM:
+         vertex.x = DEREF(INDEX(uint16_t, vertex_ptr, 0)) / float(0xFFFF);
+         vertex.y = DEREF(INDEX(uint16_t, vertex_ptr, 1)) / float(0xFFFF);
+         vertex.z = DEREF(INDEX(uint16_t, vertex_ptr, 2)) / float(0xFFFF);
+         break;
+      case VK_FORMAT_R8G8_UNORM:
+         vertex.x = DEREF(INDEX(uint8_t, vertex_ptr, 0)) / float(0xFF);
+         vertex.y = DEREF(INDEX(uint8_t, vertex_ptr, 1)) / float(0xFF);
+         break;
+      case VK_FORMAT_R8G8B8A8_UNORM:
+         vertex.x = DEREF(INDEX(uint8_t, vertex_ptr, 0)) / float(0xFF);
+         vertex.y = DEREF(INDEX(uint8_t, vertex_ptr, 1)) / float(0xFF);
+         vertex.z = DEREF(INDEX(uint8_t, vertex_ptr, 2)) / float(0xFF);
+         break;
+      case VK_FORMAT_A2B10G10R10_UNORM_PACK32: {
+         uint32_t data = DEREF(REF(uint32_t)(vertex_ptr));
+         vertex.x = float(data & 0x3FF) / 0x3FF;
+         vertex.y = float((data >> 10) & 0x3FF) / 0x3FF;
+         vertex.z = float((data >> 20) & 0x3FF) / 0x3FF;
+         break;
+      }
+      }
+
+      result.vertex[i] = vertex;
+   }
+
+   return result;
+}
+
+/* A GLSL-adapted copy of VkAccelerationStructureInstanceKHR. */
+struct AccelerationStructureInstance {
+   mat3x4 transform;
+   uint32_t custom_instance_and_mask;
+   uint32_t sbt_offset_and_flags;
+   uint64_t accelerationStructureReference;
+};
+TYPE(AccelerationStructureInstance, 8);
+
+bool
+build_triangle(inout radv_aabb bounds, VOID_REF dst_ptr, 
radv_bvh_geometry_data geom_data, uint32_t global_id)
+{
+   triangle_indices indices = load_indices(geom_data.indices, 
geom_data.index_format, global_id);
+
+   triangle_vertices vertices = load_vertices(geom_data.data, indices, 
geom_data.vertex_format, geom_data.stride);
+
+   /* An inactive triangle is one for which the first (X) component of any 
vertex is NaN. If any
+    * other vertex component is NaN, and the first is not, the behavior is 
undefined. If the vertex
+    * format does not have a NaN representation, then all triangles are 
considered active.
+    */
+   if (isnan(vertices.vertex[0].x) || isnan(vertices.vertex[1].x) || 
isnan(vertices.vertex[2].x))
+      return false;
+
+   if (geom_data.transform != NULL) {
+      mat4 transform = mat4(1.0);
+
+      for (uint32_t col = 0; col < 4; col++)
+         for (uint32_t row = 0; row < 3; row++)
+            transform[col][row] = DEREF(INDEX(float, geom_data.transform, col 
+ row * 4));
+
+      for (uint32_t i = 0; i < 3; i++)
+         vertices.vertex[i] = transform * vertices.vertex[i];
+   }
+
+   REF(radv_bvh_triangle_node) node = REF(radv_bvh_triangle_node)(dst_ptr);
+
+   bounds.min = vec3(INFINITY);
+   bounds.max = vec3(-INFINITY);
+
+   for (uint32_t coord = 0; coord < 3; coord++)
+      for (uint32_t comp = 0; comp < 3; comp++) {
+         DEREF(node).coords[coord][comp] = vertices.vertex[coord][comp];
+         bounds.min[comp] = min(bounds.min[comp], 
vertices.vertex[coord][comp]);
+         bounds.max[comp] = max(bounds.max[comp], 
vertices.vertex[coord][comp]);
+      }
+
+   DEREF(node).triangle_id = global_id;
+   DEREF(node).geometry_id_and_flags = geom_data.geometry_id;
+   DEREF(node).id = 9;
+
+   return true;
+}
+
+bool
+build_aabb(inout radv_aabb bounds, VOID_REF src_ptr, VOID_REF dst_ptr, 
uint32_t geometry_id, uint32_t global_id)
+{
+   REF(radv_bvh_aabb_node) node = REF(radv_bvh_aabb_node)(dst_ptr);
+
+   for (uint32_t vec = 0; vec < 2; vec++)
+      for (uint32_t comp = 0; comp < 3; comp++) {
+         float coord = DEREF(INDEX(float, src_ptr, comp + vec * 3));
+
+         if (vec == 0)
+            bounds.min[comp] = coord;
+         else
+            bounds.max[comp] = coord;
+      }
+
+   /* An inactive AABB is one for which the minimum X coordinate is NaN. If 
any other component is
+    * NaN, and the first is not, the behavior is undefined.
+    */
+   if (isnan(bounds.min.x))
+      return false;
+
+   DEREF(node).primitive_id = global_id;
+   DEREF(node).geometry_id_and_flags = geometry_id;
+
+   return true;
+}
+
+radv_aabb
+calculate_instance_node_bounds(radv_accel_struct_header header, mat3x4 
otw_matrix)
+{
+   radv_aabb aabb;
+   for (uint32_t comp = 0; comp < 3; ++comp) {
+      aabb.min[comp] = otw_matrix[comp][3];
+      aabb.max[comp] = otw_matrix[comp][3];
+      for (uint32_t col = 0; col < 3; ++col) {
+         aabb.min[comp] +=
+            min(otw_matrix[comp][col] * header.aabb.min[col], 
otw_matrix[comp][col] * header.aabb.max[col]);
+         aabb.max[comp] +=
+            max(otw_matrix[comp][col] * header.aabb.min[col], 
otw_matrix[comp][col] * header.aabb.max[col]);
+      }
+   }
+   return aabb;
+}
+
+uint32_t
+encode_sbt_offset_and_flags(uint32_t src)
+{
+   uint32_t flags = src >> 24;
+   uint32_t ret = src & 0xffffffu;
+   if ((flags & VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR) != 0)
+      ret |= RADV_INSTANCE_FORCE_OPAQUE;
+   if ((flags & VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR) == 0)
+      ret |= RADV_INSTANCE_NO_FORCE_NOT_OPAQUE;
+   if ((flags & VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR) != 
0)
+      ret |= RADV_INSTANCE_TRIANGLE_FACING_CULL_DISABLE;
+   if ((flags & VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR) != 0)
+      ret |= RADV_INSTANCE_TRIANGLE_FLIP_FACING;
+   return ret;
+}
+
+bool
+build_instance(inout radv_aabb bounds, VOID_REF src_ptr, VOID_REF dst_ptr, 
uint32_t global_id)
+{
+   REF(radv_bvh_instance_node) node = REF(radv_bvh_instance_node)(dst_ptr);
+
+   AccelerationStructureInstance instance = 
DEREF(REF(AccelerationStructureInstance)(src_ptr));
+
+   /* An inactive instance is one whose acceleration structure handle is 
VK_NULL_HANDLE. Since the active terminology is
+    * only relevant for BVH updates, which we do not implement, we can also 
skip instances with mask == 0.
+    */
+   if (instance.accelerationStructureReference == 0 || 
instance.custom_instance_and_mask < (1u << 24u))
+      return false;
+
+   radv_accel_struct_header instance_header =
+      
DEREF(REF(radv_accel_struct_header)(instance.accelerationStructureReference));
+
+   DEREF(node).bvh_ptr = addr_to_node(instance.accelerationStructureReference 
+ instance_header.bvh_offset);
+   DEREF(node).bvh_offset = instance_header.bvh_offset;
+
+   mat4 transform = mat4(instance.transform);
+   mat4 inv_transform = transpose(inverse(transpose(transform)));
+   DEREF(node).wto_matrix = mat3x4(inv_transform);
+   DEREF(node).otw_matrix = mat3x4(transform);
+
+   bounds = calculate_instance_node_bounds(instance_header, mat3x4(transform));
+
+   DEREF(node).custom_instance_and_mask = instance.custom_instance_and_mask;
+   DEREF(node).sbt_offset_and_flags = 
encode_sbt_offset_and_flags(instance.sbt_offset_and_flags);
+   DEREF(node).instance_id = global_id;
+
+   return true;
+}
+
 /** Compute ceiling of integer quotient of A divided by B.
     From macros.h */
 #define DIV_ROUND_UP(A, B) (((A) + (B)-1) / (B))
diff --git a/src/amd/vulkan/bvh/build_interface.h 
b/src/amd/vulkan/bvh/build_interface.h
index 2ee640d9cc5..09c49230537 100644
--- a/src/amd/vulkan/bvh/build_interface.h
+++ b/src/amd/vulkan/bvh/build_interface.h
@@ -28,6 +28,7 @@
 #include "build_helpers.h"
 #else
 #include <stdint.h>
+#include "bvh.h"
 #define REF(type) uint64_t
 #define VOID_REF  uint64_t
 #endif
@@ -38,17 +39,7 @@ struct leaf_args {
    REF(radv_ir_header) header;
    REF(key_id_pair) ids;
 
-   VOID_REF data;
-   VOID_REF indices;
-   VOID_REF transform;
-
-   uint32_t first_id;
-   uint32_t geometry_type;
-   uint32_t geometry_id;
-
-   uint32_t stride;
-   uint32_t vertex_format;
-   uint32_t index_format;
+   radv_bvh_geometry_data geom_data;
 };
 
 struct morton_args {
diff --git a/src/amd/vulkan/bvh/bvh.h b/src/amd/vulkan/bvh/bvh.h
index b77c6b8d47a..be11c8d1b56 100644
--- a/src/amd/vulkan/bvh/bvh.h
+++ b/src/amd/vulkan/bvh/bvh.h
@@ -48,6 +48,7 @@
 #include <vulkan/vulkan.h>
 typedef struct radv_ir_node radv_ir_node;
 typedef struct radv_global_sync_data radv_global_sync_data;
+typedef struct radv_bvh_geometry_data radv_bvh_geometry_data;
 
 typedef uint16_t float16_t;
 
@@ -197,4 +198,17 @@ struct radv_bvh_box32_node {
  * more work to do. */
 #define TASK_INDEX_INVALID 0xFFFFFFFF
 
+struct radv_bvh_geometry_data {
+   uint64_t data;
+   uint64_t indices;
+   uint64_t transform;
+
+   uint32_t geometry_id;
+   uint32_t geometry_type;
+   uint32_t first_id;
+   uint32_t stride;
+   uint32_t vertex_format;
+   uint32_t index_format;
+};
+
 #endif
diff --git a/src/amd/vulkan/bvh/leaf.comp b/src/amd/vulkan/bvh/leaf.comp
index 6ef35cf156d..ba706fbb91c 100644
--- a/src/amd/vulkan/bvh/leaf.comp
+++ b/src/amd/vulkan/bvh/leaf.comp
@@ -45,297 +45,21 @@ layout(push_constant) uniform CONSTS {
    leaf_args args;
 };
 
-/* Just a wrapper for 3 uints. */
-struct triangle_indices {
-   uint32_t index[3];
-};
-
-triangle_indices
-load_indices(VOID_REF indices, uint32_t index_format, uint32_t global_id)
-{
-   triangle_indices result;
-
-   uint32_t index_base = global_id * 3;
-
-   switch (index_format) {
-   case VK_INDEX_TYPE_UINT16: {
-      result.index[0] = DEREF(INDEX(uint16_t, indices, index_base + 0));
-      result.index[1] = DEREF(INDEX(uint16_t, indices, index_base + 1));
-      result.index[2] = DEREF(INDEX(uint16_t, indices, index_base + 2));
-      break;
-   }
-   case VK_INDEX_TYPE_UINT32: {
-      result.index[0] = DEREF(INDEX(uint32_t, indices, index_base + 0));
-      result.index[1] = DEREF(INDEX(uint32_t, indices, index_base + 1));
-      result.index[2] = DEREF(INDEX(uint32_t, indices, index_base + 2));
-      break;
-   }
-   case VK_INDEX_TYPE_NONE_KHR: {
-      result.index[0] = index_base + 0;
-      result.index[1] = index_base + 1;
-      result.index[2] = index_base + 2;
-      break;
-   }
-   case VK_INDEX_TYPE_UINT8_EXT: {
-      result.index[0] = DEREF(INDEX(uint8_t, indices, index_base + 0));
-      result.index[1] = DEREF(INDEX(uint8_t, indices, index_base + 1));
-      result.index[2] = DEREF(INDEX(uint8_t, indices, index_base + 2));
-      break;
-   }
-   }
-
-   return result;
-}
-
-/* Just a wrapper for 3 vec4s. */
-struct triangle_vertices {
-   vec4 vertex[3];
-};
-
-TYPE(float16_t, 2);
-
-triangle_vertices
-load_vertices(VOID_REF vertices, triangle_indices indices, uint32_t 
vertex_format, uint32_t stride)
-{
-   triangle_vertices result;
-
-   for (uint32_t i = 0; i < 3; i++) {
-      VOID_REF vertex_ptr = OFFSET(vertices, indices.index[i] * stride);
-      vec4 vertex = vec4(0.0, 0.0, 0.0, 1.0);
-
-      switch (vertex_format) {
-      case VK_FORMAT_R32G32_SFLOAT:
-         vertex.x = DEREF(INDEX(float, vertex_ptr, 0));
-         vertex.y = DEREF(INDEX(float, vertex_ptr, 1));
-         break;
-      case VK_FORMAT_R32G32B32_SFLOAT:
-      case VK_FORMAT_R32G32B32A32_SFLOAT:
-         vertex.x = DEREF(INDEX(float, vertex_ptr, 0));
-         vertex.y = DEREF(INDEX(float, vertex_ptr, 1));
-         vertex.z = DEREF(INDEX(float, vertex_ptr, 2));
-         break;
-      case VK_FORMAT_R16G16_SFLOAT:
-         vertex.x = DEREF(INDEX(float16_t, vertex_ptr, 0));
-         vertex.y = DEREF(INDEX(float16_t, vertex_ptr, 1));
-         break;
-      case VK_FORMAT_R16G16B16_SFLOAT:
-      case VK_FORMAT_R16G16B16A16_SFLOAT:
-         vertex.x = DEREF(INDEX(float16_t, vertex_ptr, 0));
-         vertex.y = DEREF(INDEX(float16_t, vertex_ptr, 1));
-         vertex.z = DEREF(INDEX(float16_t, vertex_ptr, 2));
-         break;
-      case VK_FORMAT_R16G16_SNORM:
-         vertex.x = max(-1.0, DEREF(INDEX(int16_t, vertex_ptr, 0)) / 
float(0x7FFF));
-         vertex.y = max(-1.0, DEREF(INDEX(int16_t, vertex_ptr, 1)) / 
float(0x7FFF));
-         break;
-      case VK_FORMAT_R16G16B16A16_SNORM:
-         vertex.x = max(-1.0, DEREF(INDEX(int16_t, vertex_ptr, 0)) / 
float(0x7FFF));
-         vertex.y = max(-1.0, DEREF(INDEX(int16_t, vertex_ptr, 1)) / 
float(0x7FFF));
-         vertex.z = max(-1.0, DEREF(INDEX(int16_t, vertex_ptr, 2)) / 
float(0x7FFF));
-         break;
-      case VK_FORMAT_R8G8_SNORM:
-         vertex.x = max(-1.0, DEREF(INDEX(int8_t, vertex_ptr, 0)) / 
float(0x7F));
-         vertex.y = max(-1.0, DEREF(INDEX(int8_t, vertex_ptr, 1)) / 
float(0x7F));
-         break;
-      case VK_FORMAT_R8G8B8A8_SNORM:
-         vertex.x = max(-1.0, DEREF(INDEX(int8_t, vertex_ptr, 0)) / 
float(0x7F));
-         vertex.y = max(-1.0, DEREF(INDEX(int8_t, vertex_ptr, 1)) / 
float(0x7F));
-         vertex.z = max(-1.0, DEREF(INDEX(int8_t, vertex_ptr, 2)) / 
float(0x7F));
-         break;
-      case VK_FORMAT_R16G16_UNORM:
-         vertex.x = DEREF(INDEX(uint16_t, vertex_ptr, 0)) / float(0xFFFF);
-         vertex.y = DEREF(INDEX(uint16_t, vertex_ptr, 1)) / float(0xFFFF);
-         break;
-      case VK_FORMAT_R16G16B16A16_UNORM:
-         vertex.x = DEREF(INDEX(uint16_t, vertex_ptr, 0)) / float(0xFFFF);
-         vertex.y = DEREF(INDEX(uint16_t, vertex_ptr, 1)) / float(0xFFFF);
-         vertex.z = DEREF(INDEX(uint16_t, vertex_ptr, 2)) / float(0xFFFF);
-         break;
-      case VK_FORMAT_R8G8_UNORM:
-         vertex.x = DEREF(INDEX(uint8_t, vertex_ptr, 0)) / float(0xFF);
-         vertex.y = DEREF(INDEX(uint8_t, vertex_ptr, 1)) / float(0xFF);
-         break;
-      case VK_FORMAT_R8G8B8A8_UNORM:
-         vertex.x = DEREF(INDEX(uint8_t, vertex_ptr, 0)) / float(0xFF);
-         vertex.y = DEREF(INDEX(uint8_t, vertex_ptr, 1)) / float(0xFF);
-         vertex.z = DEREF(INDEX(uint8_t, vertex_ptr, 2)) / float(0xFF);
-         break;
-      case VK_FORMAT_A2B10G10R10_UNORM_PACK32: {
-         uint32_t data = DEREF(REF(uint32_t)(vertex_ptr));
-         vertex.x = float(data & 0x3FF) / 0x3FF;
-         vertex.y = float((data >> 10) & 0x3FF) / 0x3FF;
-         vertex.z = float((data >> 20) & 0x3FF) / 0x3FF;
-         break;
-      }
-      }
-
-      result.vertex[i] = vertex;
-   }
-
-   return result;
-}
-
-/* A GLSL-adapted copy of VkAccelerationStructureInstanceKHR. */
-struct AccelerationStructureInstance {
-   mat3x4 transform;
-   uint32_t custom_instance_and_mask;
-   uint32_t sbt_offset_and_flags;
-   uint64_t accelerationStructureReference;
-};
-TYPE(AccelerationStructureInstance, 8);
-
-bool
-build_triangle(inout radv_aabb bounds, VOID_REF dst_ptr, uint32_t global_id)
-{
-   triangle_indices indices = load_indices(args.indices, args.index_format, 
global_id);
-
-   triangle_vertices vertices = load_vertices(args.data, indices, 
args.vertex_format, args.stride);
-
-   /* An inactive triangle is one for which the first (X) component of any 
vertex is NaN. If any
-    * other vertex component is NaN, and the first is not, the behavior is 
undefined. If the vertex
-    * format does not have a NaN representation, then all triangles are 
considered active.
-    */
-   if (isnan(vertices.vertex[0].x) || isnan(vertices.vertex[1].x) || 
isnan(vertices.vertex[2].x))
-      return false;
-
-   if (args.transform != NULL) {
-      mat4 transform = mat4(1.0);
-
-      for (uint32_t col = 0; col < 4; col++)
-         for (uint32_t row = 0; row < 3; row++)
-            transform[col][row] = DEREF(INDEX(float, args.transform, col + row 
* 4));
-
-      for (uint32_t i = 0; i < 3; i++)
-         vertices.vertex[i] = transform * vertices.vertex[i];
-   }
-
-   REF(radv_bvh_triangle_node) node = REF(radv_bvh_triangle_node)(dst_ptr);
-
-   bounds.min = vec3(INFINITY);
-   bounds.max = vec3(-INFINITY);
-
-   for (uint32_t coord = 0; coord < 3; coord++)
-      for (uint32_t comp = 0; comp < 3; comp++) {
-         DEREF(node).coords[coord][comp] = vertices.vertex[coord][comp];
-         bounds.min[comp] = min(bounds.min[comp], 
vertices.vertex[coord][comp]);
-         bounds.max[comp] = max(bounds.max[comp], 
vertices.vertex[coord][comp]);
-      }
-
-   DEREF(node).triangle_id = global_id;
-   DEREF(node).geometry_id_and_flags = args.geometry_id;
-   DEREF(node).id = 9;
-
-   return true;
-}
-
-bool
-build_aabb(inout radv_aabb bounds, VOID_REF src_ptr, VOID_REF dst_ptr, 
uint32_t global_id)
-{
-   REF(radv_bvh_aabb_node) node = REF(radv_bvh_aabb_node)(dst_ptr);
-
-   for (uint32_t vec = 0; vec < 2; vec++)
-      for (uint32_t comp = 0; comp < 3; comp++) {
-         float coord = DEREF(INDEX(float, src_ptr, comp + vec * 3));
-
-         if (vec == 0)
-            bounds.min[comp] = coord;
-         else
-            bounds.max[comp] = coord;
-      }
-
-   /* An inactive AABB is one for which the minimum X coordinate is NaN. If 
any other component is
-    * NaN, and the first is not, the behavior is undefined.
-    */
-   if (isnan(bounds.min.x))
-      return false;
-
-   DEREF(node).primitive_id = global_id;
-   DEREF(node).geometry_id_and_flags = args.geometry_id;
-
-   return true;
-}
-
-radv_aabb
-calculate_instance_node_bounds(radv_accel_struct_header header, mat3x4 
otw_matrix)
-{
-   radv_aabb aabb;
-   for (uint32_t comp = 0; comp < 3; ++comp) {
-      aabb.min[comp] = otw_matrix[comp][3];
-      aabb.max[comp] = otw_matrix[comp][3];
-      for (uint32_t col = 0; col < 3; ++col) {
-         aabb.min[comp] +=
-            min(otw_matrix[comp][col] * header.aabb.min[col], 
otw_matrix[comp][col] * header.aabb.max[col]);
-         aabb.max[comp] +=
-            max(otw_matrix[comp][col] * header.aabb.min[col], 
otw_matrix[comp][col] * header.aabb.max[col]);
-      }
-   }
-   return aabb;
-}
-
-uint32_t
-encode_sbt_offset_and_flags(uint32_t src)
-{
-   uint32_t flags = src >> 24;
-   uint32_t ret = src & 0xffffffu;
-   if ((flags & VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR) != 0)
-      ret |= RADV_INSTANCE_FORCE_OPAQUE;
-   if ((flags & VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR) == 0)
-      ret |= RADV_INSTANCE_NO_FORCE_NOT_OPAQUE;
-   if ((flags & VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR) != 
0)
-      ret |= RADV_INSTANCE_TRIANGLE_FACING_CULL_DISABLE;
-   if ((flags & VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR) != 0)
-      ret |= RADV_INSTANCE_TRIANGLE_FLIP_FACING;
-   return ret;
-}
-
-bool
-build_instance(inout radv_aabb bounds, VOID_REF src_ptr, VOID_REF dst_ptr, 
uint32_t global_id)
-{
-   REF(radv_bvh_instance_node) node = REF(radv_bvh_instance_node)(dst_ptr);
-
-   AccelerationStructureInstance instance = 
DEREF(REF(AccelerationStructureInstance)(src_ptr));
-
-   /* An inactive instance is one whose acceleration structure handle is 
VK_NULL_HANDLE. Since the active terminology is
-    * only relevant for BVH updates, which we do not implement, we can also 
skip instances with mask == 0.
-    */
-   if (instance.accelerationStructureReference == 0 || 
instance.custom_instance_and_mask < (1u << 24u))
-      return false;
-
-   radv_accel_struct_header instance_header =
-      
DEREF(REF(radv_accel_struct_header)(instance.accelerationStructureReference));
-
-   DEREF(node).bvh_ptr = addr_to_node(instance.accelerationStructureReference 
+ instance_header.bvh_offset);
-   DEREF(node).bvh_offset = instance_header.bvh_offset;
-
-   mat4 transform = mat4(instance.transform);
-   mat4 inv_transform = transpose(inverse(transpose(transform)));
-   DEREF(node).wto_matrix = mat3x4(inv_transform);
-   DEREF(node).otw_matrix = mat3x4(transform);
-
-   bounds = calculate_instance_node_bounds(instance_header, mat3x4(transform));
-
-   DEREF(node).custom_instance_and_mask = instance.custom_instance_and_mask;
-   DEREF(node).sbt_offset_and_flags = 
encode_sbt_offset_and_flags(instance.sbt_offset_and_flags);
-   DEREF(node).instance_id = global_id;
-
-   return true;
-}
-
 void
 main(void)
 {
    uint32_t global_id = gl_GlobalInvocationID.x;
-   uint32_t primitive_id = args.first_id + global_id;
+   uint32_t primitive_id = args.geom_data.first_id + global_id;
 
    REF(key_id_pair) id_ptr = INDEX(key_id_pair, args.ids, primitive_id);
-   uint32_t src_offset = global_id * args.stride;
+   uint32_t src_offset = global_id * args.geom_data.stride;
 
    uint32_t dst_stride;
    uint32_t node_type;
-   if (args.geometry_type == VK_GEOMETRY_TYPE_TRIANGLES_KHR) {
+   if (args.geom_data.geometry_type == VK_GEOMETRY_TYPE_TRIANGLES_KHR) {
       dst_stride = SIZEOF(radv_bvh_triangle_node);
       node_type = radv_ir_node_triangle;
-   } else if (args.geometry_type == VK_GEOMETRY_TYPE_AABBS_KHR) {
+   } else if (args.geom_data.geometry_type == VK_GEOMETRY_TYPE_AABBS_KHR) {
       dst_stride = SIZEOF(radv_bvh_aabb_node);
       node_type = radv_ir_node_aabb;
    } else {
@@ -348,15 +72,15 @@ main(void)
 
    radv_aabb bounds;
    bool is_active;
-   if (args.geometry_type == VK_GEOMETRY_TYPE_TRIANGLES_KHR) {
-      is_active = build_triangle(bounds, dst_ptr, global_id);
-   } else if (args.geometry_type == VK_GEOMETRY_TYPE_AABBS_KHR) {
-      VOID_REF src_ptr = OFFSET(args.data, src_offset);
-      is_active = build_aabb(bounds, src_ptr, dst_ptr, global_id);
+   if (args.geom_data.geometry_type == VK_GEOMETRY_TYPE_TRIANGLES_KHR) {
+      is_active = build_triangle(bounds, dst_ptr, args.geom_data, global_id);
+   } else if (args.geom_data.geometry_type == VK_GEOMETRY_TYPE_AABBS_KHR) {
+      VOID_REF src_ptr = OFFSET(args.geom_data.data, src_offset);
+      is_active = build_aabb(bounds, src_ptr, dst_ptr, 
args.geom_data.geometry_id, global_id);
    } else {
-      VOID_REF src_ptr = OFFSET(args.data, src_offset);
+      VOID_REF src_ptr = OFFSET(args.geom_data.data, src_offset);
       /* arrayOfPointers */
-      if (args.stride == 8) {
+      if (args.geom_data.stride == 8) {
          src_ptr = DEREF(REF(VOID_REF)(src_ptr));
       }
 
diff --git a/src/amd/vulkan/radv_acceleration_structure.c 
b/src/amd/vulkan/radv_acceleration_structure.c
index a2981306d58..1b1dfcd5d83 100644
--- a/src/amd/vulkan/radv_acceleration_structure.c
+++ b/src/amd/vulkan/radv_acceleration_structure.c
@@ -608,6 +608,61 @@ pack_geometry_id_and_flags(uint32_t geometry_id, uint32_t 
flags)
    return geometry_id_and_flags;
 }
 
+static struct radv_bvh_geometry_data
+fill_geometry_data(VkAccelerationStructureTypeKHR type, struct bvh_state 
*bvh_state, uint32_t geom_index,
+                   const VkAccelerationStructureGeometryKHR *geometry,
+                   const VkAccelerationStructureBuildRangeInfoKHR 
*build_range_info)
+{
+   struct radv_bvh_geometry_data data = {
+      .first_id = bvh_state->node_count,
+      .geometry_id = pack_geometry_id_and_flags(geom_index, geometry->flags),
+      .geometry_type = geometry->geometryType,
+   };
+
+   switch (geometry->geometryType) {
+   case VK_GEOMETRY_TYPE_TRIANGLES_KHR:
+      assert(type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR);
+
+      data.data = geometry->geometry.triangles.vertexData.deviceAddress +
+                  build_range_info->firstVertex * 
geometry->geometry.triangles.vertexStride;
+      data.indices = geometry->geometry.triangles.indexData.deviceAddress;
+
+      if (geometry->geometry.triangles.indexType == VK_INDEX_TYPE_NONE_KHR)
+         data.data += build_range_info->primitiveOffset;
+      else
+         data.indices += build_range_info->primitiveOffset;
+
+      data.transform = 
geometry->geometry.triangles.transformData.deviceAddress;
+      if (data.transform)
+         data.transform += build_range_info->transformOffset;
+
+      data.stride = geometry->geometry.triangles.vertexStride;
+      data.vertex_format = geometry->geometry.triangles.vertexFormat;
+      data.index_format = geometry->geometry.triangles.indexType;
+      break;
+   case VK_GEOMETRY_TYPE_AABBS_KHR:
+      assert(type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR);
+
+      data.data = geometry->geometry.aabbs.data.deviceAddress + 
build_range_info->primitiveOffset;
+      data.stride = geometry->geometry.aabbs.stride;
+      break;
+   case VK_GEOMETRY_TYPE_INSTANCES_KHR:
+      assert(type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR);
+
+      data.data = geometry->geometry.instances.data.deviceAddress + 
build_range_info->primitiveOffset;
+
+      if (geometry->geometry.instances.arrayOfPointers)
+         data.stride = 8;
+      else
+         data.stride = sizeof(VkAccelerationStructureInstanceKHR);
+      break;
+   default:
+      unreachable("Unknown geometryType");
+   }
+
+   return data;
+}
+
 static void
 build_leaves(VkCommandBuffer commandBuffer, uint32_t infoCount,
              const VkAccelerationStructureBuildGeometryInfoKHR *pInfos,
@@ -631,60 +686,16 @@ build_leaves(VkCommandBuffer commandBuffer, uint32_t 
infoCount,
          const VkAccelerationStructureGeometryKHR *geom =
             pInfos[i].pGeometries ? &pInfos[i].pGeometries[j] : 
pInfos[i].ppGeometries[j];
 
-         const VkAccelerationStructureBuildRangeInfoKHR *buildRangeInfo = 
&ppBuildRangeInfos[i][j];
-
-         leaf_consts.first_id = bvh_states[i].node_count;
-
-         leaf_consts.geometry_type = geom->geometryType;
-         leaf_consts.geometry_id = pack_geometry_id_and_flags(j, geom->flags);
-
-         switch (geom->geometryType) {
-         case VK_GEOMETRY_TYPE_TRIANGLES_KHR:
-            assert(pInfos[i].type == 
VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR);
-
-            leaf_consts.data = 
geom->geometry.triangles.vertexData.deviceAddress +
-                               buildRangeInfo->firstVertex * 
geom->geometry.triangles.vertexStride;
-            leaf_consts.indices = 
geom->geometry.triangles.indexData.deviceAddress;
-
-            if (geom->geometry.triangles.indexType == VK_INDEX_TYPE_NONE_KHR)
-               leaf_consts.data += buildRangeInfo->primitiveOffset;
-            else
-               leaf_consts.indices += buildRangeInfo->primitiveOffset;
-
-            leaf_consts.transform = 
geom->geometry.triangles.transformData.deviceAddress;
-            if (leaf_consts.transform)
-               leaf_consts.transform += buildRangeInfo->transformOffset;
-
-            leaf_consts.stride = geom->geometry.triangles.vertexStride;
-            leaf_consts.vertex_format = geom->geometry.triangles.vertexFormat;
-            leaf_consts.index_format = geom->geometry.triangles.indexType;
-            break;
-         case VK_GEOMETRY_TYPE_AABBS_KHR:
-            assert(pInfos[i].type == 
VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR);
-
-            leaf_consts.data = geom->geometry.aabbs.data.deviceAddress + 
buildRangeInfo->primitiveOffset;
-            leaf_consts.stride = geom->geometry.aabbs.stride;
-            break;
-         case VK_GEOMETRY_TYPE_INSTANCES_KHR:
-            assert(pInfos[i].type == 
VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR);
-
-            leaf_consts.data = geom->geometry.instances.data.deviceAddress + 
buildRangeInfo->primitiveOffset;
+         const VkAccelerationStructureBuildRangeInfoKHR *build_range_info = 
&ppBuildRangeInfos[i][j];
 
-            if (geom->geometry.instances.arrayOfPointers)
-               leaf_consts.stride = 8;
-            else
-               leaf_consts.stride = sizeof(VkAccelerationStructureInstanceKHR);
-            break;
-         default:
-            unreachable("Unknown geometryType");
-         }
+         leaf_consts.geom_data = fill_geometry_data(pInfos[i].type, 
&bvh_states[i], j, geom, build_range_info);
 
          vk_common_CmdPushConstants(commandBuffer, 
cmd_buffer->device->meta_state.accel_struct_build.leaf_p_layout,
                                     VK_SHADER_STAGE_COMPUTE_BIT, 0, 
sizeof(leaf_consts), &leaf_consts);
-         radv_unaligned_dispatch(cmd_buffer, buildRangeInfo->primitiveCount, 
1, 1);
+         radv_unaligned_dispatch(cmd_buffer, build_range_info->primitiveCount, 
1, 1);
 
-         bvh_states[i].leaf_node_count += buildRangeInfo->primitiveCount;
-         bvh_states[i].node_count += buildRangeInfo->primitiveCount;
+         bvh_states[i].leaf_node_count += build_range_info->primitiveCount;
+         bvh_states[i].node_count += build_range_info->primitiveCount;
       }
    }
 

Reply via email to