radv: Use a struct for AABBs

Reviewed-by: Konstantin Seurer <konstantin.seurer@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19292>
This commit is contained in:
Friedrich Vock
2022-10-25 08:26:06 +02:00
committed by Marge Bot
parent ccf0a69e05
commit 030a1f6843
8 changed files with 60 additions and 92 deletions

View File

@@ -216,11 +216,7 @@ from_emulated_float(int32_t bits)
return intBitsToFloat(bits < 0 ? -2147483648 - bits : bits);
}
struct AABB {
vec3 min;
vec3 max;
};
TYPE(AABB, 4);
TYPE(radv_aabb, 4);
struct key_id_pair {
uint32_t id;
@@ -296,29 +292,29 @@ ir_type_to_bvh_type(uint32_t type)
return RADV_BVH_INVALID_NODE;
}
AABB
radv_aabb
calculate_instance_node_bounds(uint64_t base_ptr, mat3x4 otw_matrix)
{
AABB aabb;
radv_aabb aabb;
radv_accel_struct_header header = DEREF(REF(radv_accel_struct_header)(base_ptr));
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[0][col],
otw_matrix[comp][col] * header.aabb[1][col]);
aabb.max[comp] += max(otw_matrix[comp][col] * header.aabb[0][col],
otw_matrix[comp][col] * header.aabb[1][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;
}
AABB
radv_aabb
calculate_node_bounds(VOID_REF bvh, uint32_t id)
{
AABB aabb;
radv_aabb aabb;
VOID_REF node = OFFSET(bvh, id_to_offset(id));
switch (id_to_type(id)) {
@@ -338,13 +334,8 @@ calculate_node_bounds(VOID_REF bvh, uint32_t id)
aabb.min = vec3(INFINITY);
aabb.max = vec3(-INFINITY);
for (uint32_t i = 0; i < 4; i++) {
aabb.min.x = min(aabb.min.x, internal.coords[i][0][0]);
aabb.min.y = min(aabb.min.y, internal.coords[i][0][1]);
aabb.min.z = min(aabb.min.z, internal.coords[i][0][2]);
aabb.max.x = max(aabb.max.x, internal.coords[i][1][0]);
aabb.max.y = max(aabb.max.y, internal.coords[i][1][1]);
aabb.max.z = max(aabb.max.z, internal.coords[i][1][2]);
aabb.min = min(aabb.min, internal.coords[i].min);
aabb.max = max(aabb.max, internal.coords[i].max);
}
break;
}
@@ -355,15 +346,7 @@ calculate_node_bounds(VOID_REF bvh, uint32_t id)
break;
}
case radv_bvh_node_aabb: {
radv_bvh_aabb_node custom = DEREF(REF(radv_bvh_aabb_node)(node));
aabb.min.x = custom.aabb[0][0];
aabb.min.y = custom.aabb[0][1];
aabb.min.z = custom.aabb[0][2];
aabb.max.x = custom.aabb[1][0];
aabb.max.y = custom.aabb[1][1];
aabb.max.z = custom.aabb[1][2];
aabb = DEREF(REF(radv_bvh_aabb_node)(node)).aabb;
break;
}
}
@@ -371,20 +354,8 @@ calculate_node_bounds(VOID_REF bvh, uint32_t id)
return aabb;
}
AABB
load_aabb(REF(radv_ir_node) node) {
AABB bounds;
bounds.min.x = DEREF(node).aabb[0][0];
bounds.min.y = DEREF(node).aabb[0][1];
bounds.min.z = DEREF(node).aabb[0][2];
bounds.max.x = DEREF(node).aabb[1][0];
bounds.max.y = DEREF(node).aabb[1][1];
bounds.max.z = DEREF(node).aabb[1][2];
return bounds;
}
float
aabb_surface_area(AABB aabb)
aabb_surface_area(radv_aabb aabb)
{
vec3 diagonal = aabb.max - aabb.min;
return 2 * diagonal.x * diagonal.y + 2 * diagonal.y * diagonal.z + 2 * diagonal.x * diagonal.z;

View File

@@ -47,8 +47,21 @@ typedef struct {
float values[3][4];
} mat3x4;
typedef struct {
float x;
float y;
float z;
} vec3;
typedef struct radv_aabb radv_aabb;
#endif
struct radv_aabb {
vec3 min;
vec3 max;
};
struct radv_accel_struct_serialization_header {
uint8_t driver_uuid[VK_UUID_SIZE];
uint8_t accel_struct_compat[VK_UUID_SIZE];
@@ -69,7 +82,7 @@ struct radv_accel_struct_geometry_info {
struct radv_accel_struct_header {
uint32_t bvh_offset;
uint32_t reserved;
float aabb[2][3];
radv_aabb aabb;
/* Everything after this gets updated/copied from the CPU. */
uint64_t compacted_size;
@@ -83,7 +96,7 @@ struct radv_accel_struct_header {
};
struct radv_ir_node {
float aabb[2][3];
radv_aabb aabb;
};
#define FINAL_TREE_PRESENT 0
@@ -136,7 +149,7 @@ struct radv_bvh_triangle_node {
};
struct radv_bvh_aabb_node {
float aabb[2][3];
radv_aabb aabb;
uint32_t primitive_id;
/* flags in upper 4 bits */
uint32_t geometry_id_and_flags;
@@ -167,7 +180,7 @@ struct radv_bvh_box16_node {
struct radv_bvh_box32_node {
uint32_t children[4];
float coords[4][2][3];
radv_aabb coords[4];
uint32_t reserved[4];
};

View File

@@ -114,9 +114,9 @@ main()
if (ir_id_to_type(children[i]) != radv_ir_node_internal)
continue;
AABB bounds =
load_aabb(REF(radv_ir_node)OFFSET(args.intermediate_bvh,
ir_id_to_offset(children[i])));
radv_aabb bounds =
DEREF(REF(radv_ir_node)OFFSET(args.intermediate_bvh,
ir_id_to_offset(children[i]))).aabb;
float surface_area = aabb_surface_area(bounds);
if (surface_area > largest_surface_area) {
@@ -170,15 +170,10 @@ main()
}
}
AABB child_aabb =
load_aabb(REF(radv_ir_node)OFFSET(args.intermediate_bvh, offset));
radv_aabb child_aabb =
DEREF(REF(radv_ir_node)OFFSET(args.intermediate_bvh, offset)).aabb;
DEREF(dst_node).coords[i][0][0] = child_aabb.min.x;
DEREF(dst_node).coords[i][0][1] = child_aabb.min.y;
DEREF(dst_node).coords[i][0][2] = child_aabb.min.z;
DEREF(dst_node).coords[i][1][0] = child_aabb.max.x;
DEREF(dst_node).coords[i][1][1] = child_aabb.max.y;
DEREF(dst_node).coords[i][1][2] = child_aabb.max.z;
DEREF(dst_node).coords[i] = child_aabb;
uint32_t child_id = pack_node_id(dst_offset, ir_type_to_bvh_type(type));
children[i] = child_id;
@@ -187,9 +182,10 @@ main()
}
for (uint i = found_child_count; i < 4; ++i) {
for (uint vec = 0; vec < 2; ++vec)
for (uint comp = 0; comp < 3; ++comp)
DEREF(dst_node).coords[i][vec][comp] = NAN;
for (uint comp = 0; comp < 3; ++comp) {
DEREF(dst_node).coords[i].min[comp] = NAN;
DEREF(dst_node).coords[i].max[comp] = NAN;
}
}
DEREF(dst_node).children = children;

View File

@@ -55,13 +55,13 @@ main(void)
REF(radv_ir_box_node) dst_node = REF(radv_ir_box_node)(OFFSET(args.bvh, dst_offset));
AABB total_bounds;
radv_aabb total_bounds;
total_bounds.min = vec3(INFINITY);
total_bounds.max = vec3(-INFINITY);
bool is_active = false;
for (uint32_t i = 0; i < 2; i++) {
AABB bounds;
radv_aabb bounds;
bounds.min = vec3(NAN);
bounds.max = vec3(NAN);
@@ -70,7 +70,7 @@ main(void)
if (i < child_count && child_id != RADV_BVH_INVALID_NODE) {
VOID_REF node = OFFSET(args.bvh, ir_id_to_offset(child_id));
REF(radv_ir_node) child = REF(radv_ir_node)(node);
bounds = load_aabb(child);
bounds = DEREF(child).aabb;
total_bounds.min = min(total_bounds.min, bounds.min);
total_bounds.max = max(total_bounds.max, bounds.max);
@@ -81,12 +81,7 @@ main(void)
DEREF(dst_node).children[i] = child_id;
}
DEREF(dst_node).base.aabb[0][0] = total_bounds.min.x;
DEREF(dst_node).base.aabb[0][1] = total_bounds.min.y;
DEREF(dst_node).base.aabb[0][2] = total_bounds.min.z;
DEREF(dst_node).base.aabb[1][0] = total_bounds.max.x;
DEREF(dst_node).base.aabb[1][1] = total_bounds.max.y;
DEREF(dst_node).base.aabb[1][2] = total_bounds.max.z;
DEREF(dst_node).base.aabb = total_bounds;
DEREF(dst_node).in_final_tree = is_active ? FINAL_TREE_UNKNOWN : FINAL_TREE_NOT_PRESENT;
/* An internal node is considered inactive if it has no children. Set the resulting scratch node

View File

@@ -183,7 +183,7 @@ TYPE(AccelerationStructureInstance, 8);
/* Returns whether the instance is active. */
bool
build_instance(inout AABB bounds, VOID_REF src_ptr, VOID_REF dst_ptr, uint32_t global_id)
build_instance(inout radv_aabb bounds, VOID_REF src_ptr, VOID_REF dst_ptr, uint32_t global_id)
{
REF(radv_ir_instance_node) node = REF(radv_ir_instance_node)(dst_ptr);
@@ -204,12 +204,7 @@ build_instance(inout AABB bounds, VOID_REF src_ptr, VOID_REF dst_ptr, uint32_t g
DEREF(node).sbt_offset_and_flags = instance.sbt_offset_and_flags;
DEREF(node).instance_id = global_id;
DEREF(node).base.aabb[0][0] = bounds.min.x;
DEREF(node).base.aabb[0][1] = bounds.min.y;
DEREF(node).base.aabb[0][2] = bounds.min.z;
DEREF(node).base.aabb[1][0] = bounds.max.x;
DEREF(node).base.aabb[1][1] = bounds.max.y;
DEREF(node).base.aabb[1][2] = bounds.max.z;
DEREF(node).base.aabb = bounds;
return true;
}
@@ -238,7 +233,7 @@ main(void)
uint32_t dst_offset = args.dst_offset + global_id * dst_stride;
VOID_REF dst_ptr = OFFSET(args.bvh, dst_offset);
AABB bounds;
radv_aabb bounds;
bool is_active = true;
if (args.geometry_type == VK_GEOMETRY_TYPE_TRIANGLES_KHR) {
triangle_indices indices = load_indices(args.indices, args.index_format, global_id);
@@ -269,12 +264,7 @@ main(void)
bounds.max[comp] = max(bounds.max[comp], vertices.vertex[coord][comp]);
}
DEREF(node).base.aabb[0][0] = bounds.min.x;
DEREF(node).base.aabb[0][1] = bounds.min.y;
DEREF(node).base.aabb[0][2] = bounds.min.z;
DEREF(node).base.aabb[1][0] = bounds.max.x;
DEREF(node).base.aabb[1][1] = bounds.max.y;
DEREF(node).base.aabb[1][2] = bounds.max.z;
DEREF(node).base.aabb = bounds;
DEREF(node).triangle_id = global_id;
DEREF(node).geometry_id_and_flags = args.geometry_id;
@@ -288,7 +278,6 @@ main(void)
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));
DEREF(node).base.aabb[vec][comp] = coord;
if (vec == 0)
bounds.min[comp] = coord;
@@ -296,6 +285,7 @@ main(void)
bounds.max[comp] = coord;
}
DEREF(node).base.aabb = bounds;
DEREF(node).primitive_id = global_id;
DEREF(node).geometry_id_and_flags = args.geometry_id;
} else {

View File

@@ -74,10 +74,10 @@ main(void)
uint32_t key;
if (id != RADV_BVH_INVALID_NODE) {
AABB bounds = load_aabb(REF(radv_ir_node)OFFSET(args.bvh, ir_id_to_offset(id)));
radv_aabb bounds = DEREF(REF(radv_ir_node)OFFSET(args.bvh, ir_id_to_offset(id))).aabb;
vec3 center = (bounds.min + bounds.max) * 0.5;
AABB bvh_bounds;
radv_aabb bvh_bounds;
bvh_bounds.min.x = from_emulated_float(DEREF(args.header).min_bounds[0]);
bvh_bounds.min.y = from_emulated_float(DEREF(args.header).min_bounds[1]);
bvh_bounds.min.z = from_emulated_float(DEREF(args.header).min_bounds[2]);

View File

@@ -546,9 +546,12 @@ rra_transcode_aabb_node(struct rra_transcoding_context *ctx, const struct radv_b
struct rra_aabb_node *dst = (struct rra_aabb_node *)(ctx->dst + ctx->dst_leaf_offset);
ctx->dst_leaf_offset += sizeof(struct rra_aabb_node);
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 3; ++j)
dst->aabb[i][j] = src->aabb[i][j];
dst->aabb[0][0] = src->aabb.min.x;
dst->aabb[0][1] = src->aabb.min.y;
dst->aabb[0][2] = src->aabb.min.z;
dst->aabb[1][0] = src->aabb.max.x;
dst->aabb[1][1] = src->aabb.max.y;
dst->aabb[1][2] = src->aabb.max.z;
dst->geometry_id = src->geometry_id_and_flags & 0xfffffff;
dst->flags = src->geometry_id_and_flags >> 28;
@@ -609,7 +612,7 @@ rra_transcode_box32_node(struct rra_transcoding_context *ctx, const struct radv_
memcpy(dst->coords, src->coords, sizeof(dst->coords));
for (uint32_t i = 0; i < 4; ++i) {
if (isnan(src->coords[i][0][0])) {
if (isnan(src->coords[i].min.x)) {
dst->children[i] = 0xffffffff;
continue;
}

View File

@@ -99,8 +99,8 @@ intersect_ray_amd_software_box(struct radv_device *device, nir_builder *b, nir_s
for (int i = 0; i < 4; i++) {
const uint32_t child_offset = offsetof(struct radv_bvh_box32_node, children[i]);
const uint32_t coord_offsets[2] = {
offsetof(struct radv_bvh_box32_node, coords[i][0][0]),
offsetof(struct radv_bvh_box32_node, coords[i][1][0]),
offsetof(struct radv_bvh_box32_node, coords[i].min.x),
offsetof(struct radv_bvh_box32_node, coords[i].max.x),
};
/* node->children[i] -> uint */