xref: /aosp_15_r20/external/mesa3d/src/amd/vulkan/bvh/encode.comp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker/*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2022 Friedrich Vock
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
5*61046927SAndroid Build Coastguard Worker */
6*61046927SAndroid Build Coastguard Worker
7*61046927SAndroid Build Coastguard Worker#version 460
8*61046927SAndroid Build Coastguard Worker
9*61046927SAndroid Build Coastguard Worker#extension GL_GOOGLE_include_directive : require
10*61046927SAndroid Build Coastguard Worker
11*61046927SAndroid Build Coastguard Worker#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require
12*61046927SAndroid Build Coastguard Worker#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require
13*61046927SAndroid Build Coastguard Worker#extension GL_EXT_shader_explicit_arithmetic_types_int32 : require
14*61046927SAndroid Build Coastguard Worker#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
15*61046927SAndroid Build Coastguard Worker#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require
16*61046927SAndroid Build Coastguard Worker#extension GL_EXT_scalar_block_layout : require
17*61046927SAndroid Build Coastguard Worker#extension GL_EXT_buffer_reference : require
18*61046927SAndroid Build Coastguard Worker#extension GL_EXT_buffer_reference2 : require
19*61046927SAndroid Build Coastguard Worker#extension GL_KHR_memory_scope_semantics : require
20*61046927SAndroid Build Coastguard Worker
21*61046927SAndroid Build Coastguard Workerlayout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
22*61046927SAndroid Build Coastguard Worker
23*61046927SAndroid Build Coastguard Worker#include "build_helpers.h"
24*61046927SAndroid Build Coastguard Worker#include "build_interface.h"
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Workerlayout(push_constant) uniform CONSTS {
27*61046927SAndroid Build Coastguard Worker   encode_args args;
28*61046927SAndroid Build Coastguard Worker};
29*61046927SAndroid Build Coastguard Worker
30*61046927SAndroid Build Coastguard Workervoid set_parent(uint32_t child, uint32_t parent)
31*61046927SAndroid Build Coastguard Worker{
32*61046927SAndroid Build Coastguard Worker   uint64_t addr = args.output_bvh - child / 8 * 4 - 4;
33*61046927SAndroid Build Coastguard Worker   DEREF(REF(uint32_t)(addr)) = parent;
34*61046927SAndroid Build Coastguard Worker}
35*61046927SAndroid Build Coastguard Worker
36*61046927SAndroid Build Coastguard Workervoid
37*61046927SAndroid Build Coastguard Workermain()
38*61046927SAndroid Build Coastguard Worker{
39*61046927SAndroid Build Coastguard Worker   /* Revert the order so we start at the root */
40*61046927SAndroid Build Coastguard Worker   uint32_t global_id = DEREF(args.header).ir_internal_node_count - 1 - gl_GlobalInvocationID.x;
41*61046927SAndroid Build Coastguard Worker
42*61046927SAndroid Build Coastguard Worker   uint32_t output_leaf_node_size;
43*61046927SAndroid Build Coastguard Worker   switch (args.geometry_type) {
44*61046927SAndroid Build Coastguard Worker   case VK_GEOMETRY_TYPE_TRIANGLES_KHR:
45*61046927SAndroid Build Coastguard Worker      output_leaf_node_size = SIZEOF(radv_bvh_triangle_node);
46*61046927SAndroid Build Coastguard Worker      break;
47*61046927SAndroid Build Coastguard Worker   case VK_GEOMETRY_TYPE_AABBS_KHR:
48*61046927SAndroid Build Coastguard Worker      output_leaf_node_size = SIZEOF(radv_bvh_aabb_node);
49*61046927SAndroid Build Coastguard Worker      break;
50*61046927SAndroid Build Coastguard Worker   default: /* instances */
51*61046927SAndroid Build Coastguard Worker      output_leaf_node_size = SIZEOF(radv_bvh_instance_node);
52*61046927SAndroid Build Coastguard Worker      break;
53*61046927SAndroid Build Coastguard Worker   }
54*61046927SAndroid Build Coastguard Worker
55*61046927SAndroid Build Coastguard Worker   uint32_t intermediate_leaf_nodes_size = args.leaf_node_count * SIZEOF(radv_ir_node);
56*61046927SAndroid Build Coastguard Worker   uint32_t dst_leaf_offset =
57*61046927SAndroid Build Coastguard Worker      id_to_offset(RADV_BVH_ROOT_NODE) + SIZEOF(radv_bvh_box32_node);
58*61046927SAndroid Build Coastguard Worker   uint32_t dst_internal_offset = dst_leaf_offset + args.leaf_node_count * output_leaf_node_size;
59*61046927SAndroid Build Coastguard Worker
60*61046927SAndroid Build Coastguard Worker   REF(radv_ir_box_node) intermediate_internal_nodes =
61*61046927SAndroid Build Coastguard Worker      REF(radv_ir_box_node)OFFSET(args.intermediate_bvh, intermediate_leaf_nodes_size);
62*61046927SAndroid Build Coastguard Worker   REF(radv_ir_box_node) src_node = INDEX(radv_ir_box_node, intermediate_internal_nodes, global_id);
63*61046927SAndroid Build Coastguard Worker   radv_ir_box_node src = DEREF(src_node);
64*61046927SAndroid Build Coastguard Worker
65*61046927SAndroid Build Coastguard Worker   bool is_root_node = global_id == DEREF(args.header).ir_internal_node_count - 1;
66*61046927SAndroid Build Coastguard Worker
67*61046927SAndroid Build Coastguard Worker   for (;;) {
68*61046927SAndroid Build Coastguard Worker      /* Make changes to the current node's BVH offset value visible. */
69*61046927SAndroid Build Coastguard Worker      memoryBarrier(gl_ScopeDevice, gl_StorageSemanticsBuffer,
70*61046927SAndroid Build Coastguard Worker                    gl_SemanticsAcquireRelease | gl_SemanticsMakeAvailable | gl_SemanticsMakeVisible);
71*61046927SAndroid Build Coastguard Worker
72*61046927SAndroid Build Coastguard Worker      uint32_t bvh_offset = is_root_node ? id_to_offset(RADV_BVH_ROOT_NODE) : DEREF(src_node).bvh_offset;
73*61046927SAndroid Build Coastguard Worker      if (bvh_offset == RADV_UNKNOWN_BVH_OFFSET)
74*61046927SAndroid Build Coastguard Worker         continue;
75*61046927SAndroid Build Coastguard Worker
76*61046927SAndroid Build Coastguard Worker      if (bvh_offset == RADV_NULL_BVH_OFFSET)
77*61046927SAndroid Build Coastguard Worker         break;
78*61046927SAndroid Build Coastguard Worker
79*61046927SAndroid Build Coastguard Worker      REF(radv_bvh_box32_node) dst_node = REF(radv_bvh_box32_node)(OFFSET(args.output_bvh, bvh_offset));
80*61046927SAndroid Build Coastguard Worker      uint32_t node_id = pack_node_id(bvh_offset, radv_bvh_node_box32);
81*61046927SAndroid Build Coastguard Worker
82*61046927SAndroid Build Coastguard Worker      uint32_t found_child_count = 0;
83*61046927SAndroid Build Coastguard Worker      uint32_t children[4] = {RADV_BVH_INVALID_NODE, RADV_BVH_INVALID_NODE,
84*61046927SAndroid Build Coastguard Worker                              RADV_BVH_INVALID_NODE, RADV_BVH_INVALID_NODE};
85*61046927SAndroid Build Coastguard Worker
86*61046927SAndroid Build Coastguard Worker      for (uint32_t i = 0; i < 2; ++i)
87*61046927SAndroid Build Coastguard Worker         if (src.children[i] != RADV_BVH_INVALID_NODE)
88*61046927SAndroid Build Coastguard Worker            children[found_child_count++] = src.children[i];
89*61046927SAndroid Build Coastguard Worker
90*61046927SAndroid Build Coastguard Worker      while (found_child_count < 4) {
91*61046927SAndroid Build Coastguard Worker         int32_t collapsed_child_index = -1;
92*61046927SAndroid Build Coastguard Worker         float largest_surface_area = -INFINITY;
93*61046927SAndroid Build Coastguard Worker
94*61046927SAndroid Build Coastguard Worker         for (int32_t i = 0; i < found_child_count; ++i) {
95*61046927SAndroid Build Coastguard Worker            if (ir_id_to_type(children[i]) != radv_ir_node_internal)
96*61046927SAndroid Build Coastguard Worker               continue;
97*61046927SAndroid Build Coastguard Worker
98*61046927SAndroid Build Coastguard Worker            radv_aabb bounds =
99*61046927SAndroid Build Coastguard Worker               DEREF(REF(radv_ir_node)OFFSET(args.intermediate_bvh,
100*61046927SAndroid Build Coastguard Worker                                             ir_id_to_offset(children[i]))).aabb;
101*61046927SAndroid Build Coastguard Worker
102*61046927SAndroid Build Coastguard Worker            float surface_area = aabb_surface_area(bounds);
103*61046927SAndroid Build Coastguard Worker            if (surface_area > largest_surface_area) {
104*61046927SAndroid Build Coastguard Worker               largest_surface_area = surface_area;
105*61046927SAndroid Build Coastguard Worker               collapsed_child_index = i;
106*61046927SAndroid Build Coastguard Worker            }
107*61046927SAndroid Build Coastguard Worker         }
108*61046927SAndroid Build Coastguard Worker
109*61046927SAndroid Build Coastguard Worker         if (collapsed_child_index != -1) {
110*61046927SAndroid Build Coastguard Worker            REF(radv_ir_box_node) child_node =
111*61046927SAndroid Build Coastguard Worker               REF(radv_ir_box_node)OFFSET(args.intermediate_bvh,
112*61046927SAndroid Build Coastguard Worker                                        ir_id_to_offset(children[collapsed_child_index]));
113*61046927SAndroid Build Coastguard Worker            uint32_t grandchildren[2] = DEREF(child_node).children;
114*61046927SAndroid Build Coastguard Worker            uint32_t valid_grandchild_count = 0;
115*61046927SAndroid Build Coastguard Worker
116*61046927SAndroid Build Coastguard Worker            if (grandchildren[1] != RADV_BVH_INVALID_NODE)
117*61046927SAndroid Build Coastguard Worker               ++valid_grandchild_count;
118*61046927SAndroid Build Coastguard Worker
119*61046927SAndroid Build Coastguard Worker            if (grandchildren[0] != RADV_BVH_INVALID_NODE)
120*61046927SAndroid Build Coastguard Worker               ++valid_grandchild_count;
121*61046927SAndroid Build Coastguard Worker            else
122*61046927SAndroid Build Coastguard Worker               grandchildren[0] = grandchildren[1];
123*61046927SAndroid Build Coastguard Worker
124*61046927SAndroid Build Coastguard Worker            if (valid_grandchild_count > 1)
125*61046927SAndroid Build Coastguard Worker               children[found_child_count++] = grandchildren[1];
126*61046927SAndroid Build Coastguard Worker
127*61046927SAndroid Build Coastguard Worker            if (valid_grandchild_count > 0)
128*61046927SAndroid Build Coastguard Worker               children[collapsed_child_index] = grandchildren[0];
129*61046927SAndroid Build Coastguard Worker            else {
130*61046927SAndroid Build Coastguard Worker               found_child_count--;
131*61046927SAndroid Build Coastguard Worker               children[collapsed_child_index] = children[found_child_count];
132*61046927SAndroid Build Coastguard Worker            }
133*61046927SAndroid Build Coastguard Worker
134*61046927SAndroid Build Coastguard Worker            DEREF(child_node).bvh_offset = RADV_NULL_BVH_OFFSET;
135*61046927SAndroid Build Coastguard Worker         } else
136*61046927SAndroid Build Coastguard Worker            break;
137*61046927SAndroid Build Coastguard Worker      }
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Worker      for (uint32_t i = 0; i < found_child_count; ++i) {
140*61046927SAndroid Build Coastguard Worker         uint32_t type = ir_id_to_type(children[i]);
141*61046927SAndroid Build Coastguard Worker         uint32_t offset = ir_id_to_offset(children[i]);
142*61046927SAndroid Build Coastguard Worker         uint32_t dst_offset;
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker         if (type == radv_ir_node_internal) {
145*61046927SAndroid Build Coastguard Worker#if COMPACT
146*61046927SAndroid Build Coastguard Worker            dst_offset = atomicAdd(DEREF(args.header).dst_node_offset, SIZEOF(radv_bvh_box32_node));
147*61046927SAndroid Build Coastguard Worker#else
148*61046927SAndroid Build Coastguard Worker            uint32_t offset_in_internal_nodes = offset - intermediate_leaf_nodes_size;
149*61046927SAndroid Build Coastguard Worker            uint32_t child_index = offset_in_internal_nodes / SIZEOF(radv_ir_box_node);
150*61046927SAndroid Build Coastguard Worker            dst_offset = dst_internal_offset + child_index * SIZEOF(radv_bvh_box32_node);
151*61046927SAndroid Build Coastguard Worker#endif
152*61046927SAndroid Build Coastguard Worker
153*61046927SAndroid Build Coastguard Worker            REF(radv_ir_box_node) child_node = REF(radv_ir_box_node)OFFSET(args.intermediate_bvh, offset);
154*61046927SAndroid Build Coastguard Worker            DEREF(child_node).bvh_offset = dst_offset;
155*61046927SAndroid Build Coastguard Worker         } else {
156*61046927SAndroid Build Coastguard Worker            uint32_t child_index = offset / SIZEOF(radv_ir_node);
157*61046927SAndroid Build Coastguard Worker            dst_offset = dst_leaf_offset + child_index * output_leaf_node_size;
158*61046927SAndroid Build Coastguard Worker         }
159*61046927SAndroid Build Coastguard Worker
160*61046927SAndroid Build Coastguard Worker         radv_aabb child_aabb =
161*61046927SAndroid Build Coastguard Worker            DEREF(REF(radv_ir_node)OFFSET(args.intermediate_bvh, offset)).aabb;
162*61046927SAndroid Build Coastguard Worker
163*61046927SAndroid Build Coastguard Worker         DEREF(dst_node).coords[i] = child_aabb;
164*61046927SAndroid Build Coastguard Worker
165*61046927SAndroid Build Coastguard Worker         uint32_t child_id = pack_node_id(dst_offset, ir_type_to_bvh_type(type));
166*61046927SAndroid Build Coastguard Worker         children[i] = child_id;
167*61046927SAndroid Build Coastguard Worker         set_parent(child_id, node_id);
168*61046927SAndroid Build Coastguard Worker      }
169*61046927SAndroid Build Coastguard Worker
170*61046927SAndroid Build Coastguard Worker      for (uint i = found_child_count; i < 4; ++i) {
171*61046927SAndroid Build Coastguard Worker            for (uint comp = 0; comp < 3; ++comp) {
172*61046927SAndroid Build Coastguard Worker               DEREF(dst_node).coords[i].min[comp] = NAN;
173*61046927SAndroid Build Coastguard Worker               DEREF(dst_node).coords[i].max[comp] = NAN;
174*61046927SAndroid Build Coastguard Worker            }
175*61046927SAndroid Build Coastguard Worker      }
176*61046927SAndroid Build Coastguard Worker
177*61046927SAndroid Build Coastguard Worker      /* Make changes to the children's BVH offset value available to the other invocations. */
178*61046927SAndroid Build Coastguard Worker      memoryBarrier(gl_ScopeDevice, gl_StorageSemanticsBuffer,
179*61046927SAndroid Build Coastguard Worker                    gl_SemanticsAcquireRelease | gl_SemanticsMakeAvailable | gl_SemanticsMakeVisible);
180*61046927SAndroid Build Coastguard Worker
181*61046927SAndroid Build Coastguard Worker      DEREF(dst_node).children = children;
182*61046927SAndroid Build Coastguard Worker      break;
183*61046927SAndroid Build Coastguard Worker   }
184*61046927SAndroid Build Coastguard Worker
185*61046927SAndroid Build Coastguard Worker   if (is_root_node) {
186*61046927SAndroid Build Coastguard Worker      REF(radv_accel_struct_header) header = REF(radv_accel_struct_header)(args.output_bvh - args.output_bvh_offset);
187*61046927SAndroid Build Coastguard Worker      DEREF(header).aabb = src.base.aabb;
188*61046927SAndroid Build Coastguard Worker      DEREF(header).bvh_offset = args.output_bvh_offset;
189*61046927SAndroid Build Coastguard Worker
190*61046927SAndroid Build Coastguard Worker      set_parent(RADV_BVH_ROOT_NODE, RADV_BVH_INVALID_NODE);
191*61046927SAndroid Build Coastguard Worker   }
192*61046927SAndroid Build Coastguard Worker}
193