Mesa (main): radv: Fix handling of primitiveOffset

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon May 30 00:21:01 UTC 2022


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

Author: Konstantin Seurer <konstantin.seurer at gmail.com>
Date:   Thu May 26 13:24:45 2022 +0200

radv: Fix handling of primitiveOffset

VkAccelerationStructureBuildRangeInfoKHR spec:
If the geometry uses indices, primitiveCount × 3 indices are consumed from VkAccelerationStructureGeometryTrianglesDataKHR::indexData, starting at an offset of primitiveOffset. The value of firstVertex is added to the index values before fetching vertices.

If the geometry does not use indices, primitiveCount × 3 vertices are consumed from VkAccelerationStructureGeometryTrianglesDataKHR::vertexData, starting at an offset of primitiveOffset + VkAccelerationStructureGeometryTrianglesDataKHR::vertexStride × firstVertex.

Meaning: We always add firstVertex * vertexStride
to the vertex address and add primitiveOffset
either to the vertex address or the index address,
depending on wether indices are used.

Also add missing handling with instances.

Fixes: 0dad88b ("radv: Implement device-side BVH building.")
Signed-off-by: Konstantin Seurer <konstantin.seurer at gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16719>

---

 src/amd/vulkan/radv_acceleration_structure.c | 36 ++++++++++++++++++----------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/src/amd/vulkan/radv_acceleration_structure.c b/src/amd/vulkan/radv_acceleration_structure.c
index ff2e693009e..49e004fd995 100644
--- a/src/amd/vulkan/radv_acceleration_structure.c
+++ b/src/amd/vulkan/radv_acceleration_structure.c
@@ -234,7 +234,13 @@ build_triangles(struct radv_bvh_build_ctx *ctx, const VkAccelerationStructureGeo
 {
    const VkAccelerationStructureGeometryTrianglesDataKHR *tri_data = &geom->geometry.triangles;
    VkTransformMatrixKHR matrix;
-   const char *index_data = (const char *)tri_data->indexData.hostAddress + range->primitiveOffset;
+   const char *index_data = (const char *)tri_data->indexData.hostAddress;
+   const char *v_data_base = (const char *)tri_data->vertexData.hostAddress;
+
+   if (tri_data->indexType == VK_INDEX_TYPE_NONE_KHR)
+      v_data_base += range->primitiveOffset;
+   else
+      index_data += range->primitiveOffset;
 
    if (tri_data->transformData.hostAddress) {
       matrix = *(const VkTransformMatrixKHR *)((const char *)tri_data->transformData.hostAddress +
@@ -273,8 +279,7 @@ build_triangles(struct radv_bvh_build_ctx *ctx, const VkAccelerationStructureGeo
             break;
          }
 
-         const char *v_data =
-            (const char *)tri_data->vertexData.hostAddress + v_index * tri_data->vertexStride;
+         const char *v_data = v_data_base + v_index * tri_data->vertexStride;
          float coords[4];
          switch (tri_data->vertexFormat) {
          case VK_FORMAT_R32G32_SFLOAT:
@@ -396,10 +401,12 @@ build_instances(struct radv_device *device, struct radv_bvh_build_ctx *ctx,
    const VkAccelerationStructureGeometryInstancesDataKHR *inst_data = &geom->geometry.instances;
 
    for (uint32_t p = 0; p < range->primitiveCount; ++p, ctx->curr_ptr += 128) {
+      const char *instance_data =
+         (const char *)inst_data->data.hostAddress + range->primitiveOffset;
       const VkAccelerationStructureInstanceKHR *instance =
          inst_data->arrayOfPointers
-            ? (((const VkAccelerationStructureInstanceKHR *const *)inst_data->data.hostAddress)[p])
-            : &((const VkAccelerationStructureInstanceKHR *)inst_data->data.hostAddress)[p];
+            ? (((const VkAccelerationStructureInstanceKHR *const *)instance_data)[p])
+            : &((const VkAccelerationStructureInstanceKHR *)instance_data)[p];
       if (!instance->accelerationStructureReference) {
          continue;
       }
@@ -467,7 +474,7 @@ build_aabbs(struct radv_bvh_build_ctx *ctx, const VkAccelerationStructureGeometr
 
       const VkAabbPositionsKHR *aabb =
          (const VkAabbPositionsKHR *)((const char *)aabb_data->data.hostAddress +
-                                      p * aabb_data->stride);
+                                      range->primitiveOffset + p * aabb_data->stride);
 
       node->aabb[0][0] = aabb->minX;
       node->aabb[0][1] = aabb->minY;
@@ -2087,12 +2094,14 @@ radv_CmdBuildAccelerationStructuresKHR(
             case VK_GEOMETRY_TYPE_TRIANGLES_KHR:
                prim_consts.vertex_addr =
                   geom->geometry.triangles.vertexData.deviceAddress +
-                  ppBuildRangeInfos[i][j].firstVertex * geom->geometry.triangles.vertexStride +
-                  (geom->geometry.triangles.indexType != VK_INDEX_TYPE_NONE_KHR
-                      ? ppBuildRangeInfos[i][j].primitiveOffset
-                      : 0);
-               prim_consts.index_addr = geom->geometry.triangles.indexData.deviceAddress +
-                                        ppBuildRangeInfos[i][j].primitiveOffset;
+                  ppBuildRangeInfos[i][j].firstVertex * geom->geometry.triangles.vertexStride;
+               prim_consts.index_addr = geom->geometry.triangles.indexData.deviceAddress;
+
+               if (geom->geometry.triangles.indexType == VK_INDEX_TYPE_NONE_KHR)
+                  prim_consts.vertex_addr += ppBuildRangeInfos[i][j].primitiveOffset;
+               else
+                  prim_consts.index_addr += ppBuildRangeInfos[i][j].primitiveOffset;
+
                prim_consts.transform_addr = geom->geometry.triangles.transformData.deviceAddress +
                                             ppBuildRangeInfos[i][j].transformOffset;
                prim_consts.vertex_stride = geom->geometry.triangles.vertexStride;
@@ -2107,7 +2116,8 @@ radv_CmdBuildAccelerationStructuresKHR(
                prim_size = 64;
                break;
             case VK_GEOMETRY_TYPE_INSTANCES_KHR:
-               prim_consts.instance_data = geom->geometry.instances.data.deviceAddress;
+               prim_consts.instance_data = geom->geometry.instances.data.deviceAddress +
+                                           ppBuildRangeInfos[i][j].primitiveOffset;
                prim_consts.array_of_pointers = geom->geometry.instances.arrayOfPointers ? 1 : 0;
                prim_size = 128;
                bvh_states[i].instance_count += ppBuildRangeInfos[i][j].primitiveCount;



More information about the mesa-commit mailing list