xref: /aosp_15_r20/external/mesa3d/src/amd/vulkan/bvh/update.comp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker/*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2023 Valve Corporation
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_interface.h"
24*61046927SAndroid Build Coastguard Worker
25*61046927SAndroid Build Coastguard Workerlayout(push_constant) uniform CONSTS {
26*61046927SAndroid Build Coastguard Worker    update_args args;
27*61046927SAndroid Build Coastguard Worker};
28*61046927SAndroid Build Coastguard Worker
29*61046927SAndroid Build Coastguard Workeruint32_t fetch_parent_node(VOID_REF bvh, uint32_t node)
30*61046927SAndroid Build Coastguard Worker{
31*61046927SAndroid Build Coastguard Worker    uint64_t addr = bvh - node / 8 * 4 - 4;
32*61046927SAndroid Build Coastguard Worker    return DEREF(REF(uint32_t)(addr));
33*61046927SAndroid Build Coastguard Worker}
34*61046927SAndroid Build Coastguard Worker
35*61046927SAndroid Build Coastguard Workervoid main() {
36*61046927SAndroid Build Coastguard Worker    uint32_t bvh_offset = DEREF(args.src).bvh_offset;
37*61046927SAndroid Build Coastguard Worker
38*61046927SAndroid Build Coastguard Worker    VOID_REF src_bvh = OFFSET(args.src, bvh_offset);
39*61046927SAndroid Build Coastguard Worker    VOID_REF dst_bvh = OFFSET(args.dst, bvh_offset);
40*61046927SAndroid Build Coastguard Worker
41*61046927SAndroid Build Coastguard Worker    uint32_t leaf_node_size;
42*61046927SAndroid Build Coastguard Worker    if (args.geom_data.geometry_type == VK_GEOMETRY_TYPE_TRIANGLES_KHR)
43*61046927SAndroid Build Coastguard Worker        leaf_node_size = SIZEOF(radv_bvh_triangle_node);
44*61046927SAndroid Build Coastguard Worker    else if (args.geom_data.geometry_type == VK_GEOMETRY_TYPE_AABBS_KHR)
45*61046927SAndroid Build Coastguard Worker        leaf_node_size = SIZEOF(radv_bvh_aabb_node);
46*61046927SAndroid Build Coastguard Worker    else
47*61046927SAndroid Build Coastguard Worker        leaf_node_size = SIZEOF(radv_bvh_instance_node);
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker    uint32_t leaf_node_id = args.geom_data.first_id + gl_GlobalInvocationID.x;
50*61046927SAndroid Build Coastguard Worker    uint32_t first_leaf_offset = id_to_offset(RADV_BVH_ROOT_NODE) + SIZEOF(radv_bvh_box32_node);
51*61046927SAndroid Build Coastguard Worker
52*61046927SAndroid Build Coastguard Worker    uint32_t dst_offset = leaf_node_id * leaf_node_size + first_leaf_offset;
53*61046927SAndroid Build Coastguard Worker    VOID_REF dst_ptr = OFFSET(dst_bvh, dst_offset);
54*61046927SAndroid Build Coastguard Worker    uint32_t src_offset = gl_GlobalInvocationID.x * args.geom_data.stride;
55*61046927SAndroid Build Coastguard Worker
56*61046927SAndroid Build Coastguard Worker    radv_aabb bounds;
57*61046927SAndroid Build Coastguard Worker    bool is_active;
58*61046927SAndroid Build Coastguard Worker    if (args.geom_data.geometry_type == VK_GEOMETRY_TYPE_TRIANGLES_KHR) {
59*61046927SAndroid Build Coastguard Worker        is_active = build_triangle(bounds, dst_ptr, args.geom_data, gl_GlobalInvocationID.x);
60*61046927SAndroid Build Coastguard Worker    } else {
61*61046927SAndroid Build Coastguard Worker        VOID_REF src_ptr = OFFSET(args.geom_data.data, src_offset);
62*61046927SAndroid Build Coastguard Worker        is_active = build_aabb(bounds, src_ptr, dst_ptr, args.geom_data.geometry_id, gl_GlobalInvocationID.x);
63*61046927SAndroid Build Coastguard Worker    }
64*61046927SAndroid Build Coastguard Worker
65*61046927SAndroid Build Coastguard Worker    if (!is_active)
66*61046927SAndroid Build Coastguard Worker        return;
67*61046927SAndroid Build Coastguard Worker
68*61046927SAndroid Build Coastguard Worker    DEREF(INDEX(radv_aabb, args.leaf_bounds, leaf_node_id)) = bounds;
69*61046927SAndroid Build Coastguard Worker    memoryBarrier(gl_ScopeDevice,
70*61046927SAndroid Build Coastguard Worker        gl_StorageSemanticsBuffer,
71*61046927SAndroid Build Coastguard Worker        gl_SemanticsAcquireRelease | gl_SemanticsMakeAvailable | gl_SemanticsMakeVisible);
72*61046927SAndroid Build Coastguard Worker
73*61046927SAndroid Build Coastguard Worker    uint32_t node_id = pack_node_id(dst_offset, 0);
74*61046927SAndroid Build Coastguard Worker    uint32_t parent_id = fetch_parent_node(src_bvh, node_id);
75*61046927SAndroid Build Coastguard Worker    uint32_t internal_nodes_offset = first_leaf_offset + args.leaf_node_count * leaf_node_size;
76*61046927SAndroid Build Coastguard Worker    while (parent_id != RADV_BVH_INVALID_NODE) {
77*61046927SAndroid Build Coastguard Worker        uint32_t offset = id_to_offset(parent_id);
78*61046927SAndroid Build Coastguard Worker
79*61046927SAndroid Build Coastguard Worker        uint32_t parent_index = (offset - internal_nodes_offset) / SIZEOF(radv_bvh_box32_node) + 1;
80*61046927SAndroid Build Coastguard Worker        if (parent_id == RADV_BVH_ROOT_NODE)
81*61046927SAndroid Build Coastguard Worker            parent_index = 0;
82*61046927SAndroid Build Coastguard Worker
83*61046927SAndroid Build Coastguard Worker        /* Make accesses to internal nodes in dst_bvh available and visible */
84*61046927SAndroid Build Coastguard Worker        memoryBarrier(gl_ScopeDevice,
85*61046927SAndroid Build Coastguard Worker                      gl_StorageSemanticsBuffer,
86*61046927SAndroid Build Coastguard Worker                      gl_SemanticsAcquireRelease | gl_SemanticsMakeAvailable | gl_SemanticsMakeVisible);
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Worker        REF(radv_bvh_box32_node) src_node = REF(radv_bvh_box32_node)OFFSET(src_bvh, offset);
89*61046927SAndroid Build Coastguard Worker        REF(radv_bvh_box32_node) dst_node = REF(radv_bvh_box32_node)OFFSET(dst_bvh, offset);
90*61046927SAndroid Build Coastguard Worker        uint32_t children[4];
91*61046927SAndroid Build Coastguard Worker        for (uint32_t i = 0; i < 4; ++i)
92*61046927SAndroid Build Coastguard Worker            children[i] = DEREF(src_node).children[i];
93*61046927SAndroid Build Coastguard Worker
94*61046927SAndroid Build Coastguard Worker        uint32_t valid_child_count = 0;
95*61046927SAndroid Build Coastguard Worker        for (uint32_t i = 0; i < 4; ++valid_child_count, ++i)
96*61046927SAndroid Build Coastguard Worker            if (children[i] == RADV_BVH_INVALID_NODE)
97*61046927SAndroid Build Coastguard Worker                break;
98*61046927SAndroid Build Coastguard Worker
99*61046927SAndroid Build Coastguard Worker        /* Check if all children have been processed. As this is an atomic the last path coming from
100*61046927SAndroid Build Coastguard Worker         * a child will pass here, while earlier paths break.
101*61046927SAndroid Build Coastguard Worker         */
102*61046927SAndroid Build Coastguard Worker        uint32_t ready_child_count = atomicAdd(
103*61046927SAndroid Build Coastguard Worker            DEREF(INDEX(uint32_t, args.internal_ready_count, parent_index)), 1, gl_ScopeDevice,
104*61046927SAndroid Build Coastguard Worker            gl_StorageSemanticsBuffer,
105*61046927SAndroid Build Coastguard Worker            gl_SemanticsAcquireRelease | gl_SemanticsMakeAvailable | gl_SemanticsMakeVisible);
106*61046927SAndroid Build Coastguard Worker
107*61046927SAndroid Build Coastguard Worker        if (ready_child_count != valid_child_count - 1)
108*61046927SAndroid Build Coastguard Worker            break;
109*61046927SAndroid Build Coastguard Worker
110*61046927SAndroid Build Coastguard Worker        for (uint32_t i = 0; i < 4; ++i)
111*61046927SAndroid Build Coastguard Worker            DEREF(dst_node).children[i] = children[i];
112*61046927SAndroid Build Coastguard Worker
113*61046927SAndroid Build Coastguard Worker        for (uint32_t i = 0; i < valid_child_count; ++i) {
114*61046927SAndroid Build Coastguard Worker            uint32_t child_offset = id_to_offset(children[i]);
115*61046927SAndroid Build Coastguard Worker            radv_aabb child_bounds;
116*61046927SAndroid Build Coastguard Worker            if (child_offset == dst_offset)
117*61046927SAndroid Build Coastguard Worker                child_bounds = bounds;
118*61046927SAndroid Build Coastguard Worker            else if (child_offset >= internal_nodes_offset) {
119*61046927SAndroid Build Coastguard Worker                child_bounds = radv_aabb(vec3(INFINITY), vec3(-INFINITY));
120*61046927SAndroid Build Coastguard Worker                REF(radv_bvh_box32_node) child_node = REF(radv_bvh_box32_node)OFFSET(dst_bvh, child_offset);
121*61046927SAndroid Build Coastguard Worker                for (uint32_t j = 0; j < 4; ++j) {
122*61046927SAndroid Build Coastguard Worker                    if (DEREF(child_node).children[j] == RADV_BVH_INVALID_NODE)
123*61046927SAndroid Build Coastguard Worker                        break;
124*61046927SAndroid Build Coastguard Worker                    child_bounds.min = min(child_bounds.min, DEREF(child_node).coords[j].min);
125*61046927SAndroid Build Coastguard Worker                    child_bounds.max = max(child_bounds.max, DEREF(child_node).coords[j].max);
126*61046927SAndroid Build Coastguard Worker                }
127*61046927SAndroid Build Coastguard Worker            } else {
128*61046927SAndroid Build Coastguard Worker                uint32_t child_index = (child_offset - first_leaf_offset) / leaf_node_size;
129*61046927SAndroid Build Coastguard Worker                child_bounds = DEREF(INDEX(radv_aabb, args.leaf_bounds, child_index));
130*61046927SAndroid Build Coastguard Worker            }
131*61046927SAndroid Build Coastguard Worker
132*61046927SAndroid Build Coastguard Worker            DEREF(dst_node).coords[i] = child_bounds;
133*61046927SAndroid Build Coastguard Worker        }
134*61046927SAndroid Build Coastguard Worker
135*61046927SAndroid Build Coastguard Worker        if (parent_id == RADV_BVH_ROOT_NODE) {
136*61046927SAndroid Build Coastguard Worker            radv_aabb root_bounds = radv_aabb(vec3(INFINITY), vec3(-INFINITY));
137*61046927SAndroid Build Coastguard Worker            for (uint32_t i = 0; i < valid_child_count; ++i) {
138*61046927SAndroid Build Coastguard Worker                radv_aabb bounds = DEREF(dst_node).coords[i];
139*61046927SAndroid Build Coastguard Worker                root_bounds.min = min(root_bounds.min, bounds.min);
140*61046927SAndroid Build Coastguard Worker                root_bounds.max = max(root_bounds.max, bounds.max);
141*61046927SAndroid Build Coastguard Worker            }
142*61046927SAndroid Build Coastguard Worker            DEREF(args.dst).aabb = root_bounds;
143*61046927SAndroid Build Coastguard Worker        }
144*61046927SAndroid Build Coastguard Worker
145*61046927SAndroid Build Coastguard Worker        parent_id = fetch_parent_node(src_bvh, parent_id);
146*61046927SAndroid Build Coastguard Worker    }
147*61046927SAndroid Build Coastguard Worker}
148