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