diff --git a/src/amd/vulkan/bvh/build_helpers.h b/src/amd/vulkan/bvh/build_helpers.h index a8e17b58515..aba61253b0f 100644 --- a/src/amd/vulkan/bvh/build_helpers.h +++ b/src/amd/vulkan/bvh/build_helpers.h @@ -157,6 +157,13 @@ #define VK_GEOMETRY_TYPE_TRIANGLES_KHR 0 #define VK_GEOMETRY_TYPE_AABBS_KHR 1 +#define VK_GEOMETRY_OPAQUE_BIT_KHR 1 + +#define VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR 1 +#define VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR 2 +#define VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR 4 +#define VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR 8 + #define TYPE(type, align) \ layout(buffer_reference, buffer_reference_align = align, scalar) buffer type##_ref \ { \ diff --git a/src/amd/vulkan/bvh/bvh.h b/src/amd/vulkan/bvh/bvh.h index e2be4fc4651..6cd11077570 100644 --- a/src/amd/vulkan/bvh/bvh.h +++ b/src/amd/vulkan/bvh/bvh.h @@ -35,6 +35,13 @@ #define radv_ir_node_instance 2 #define radv_ir_node_aabb 3 +#define RADV_GEOMETRY_OPAQUE (1u << 31) + +#define RADV_INSTANCE_FORCE_OPAQUE (1u << 31) +#define RADV_INSTANCE_NO_FORCE_NOT_OPAQUE (1u << 30) +#define RADV_INSTANCE_TRIANGLE_FACING_CULL_DISABLE (1u << 29) +#define RADV_INSTANCE_TRIANGLE_FLIP_FACING (1u << 28) + #ifdef VULKAN #define VK_UUID_SIZE 16 #else diff --git a/src/amd/vulkan/bvh/converter_leaf.comp b/src/amd/vulkan/bvh/converter_leaf.comp index f8e7e68fe2b..ca73c177fab 100644 --- a/src/amd/vulkan/bvh/converter_leaf.comp +++ b/src/amd/vulkan/bvh/converter_leaf.comp @@ -43,6 +43,32 @@ layout(push_constant) uniform CONSTS { convert_leaf_args args; }; +uint32_t +convert_geometry_id_and_flags(uint32_t src) +{ + uint32_t flags = src >> 28; + uint32_t ret = src & 0xfffffffu; + if ((flags & VK_GEOMETRY_OPAQUE_BIT_KHR) != 0) + ret |= RADV_GEOMETRY_OPAQUE; + return ret; +} + +uint32_t +convert_sbt_offset_and_flags(uint32_t src) +{ + uint32_t flags = src >> 24; + uint32_t ret = src & 0xffffffu; + if ((flags & VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR) != 0) + ret |= RADV_INSTANCE_FORCE_OPAQUE; + if ((flags & VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR) == 0) + ret |= RADV_INSTANCE_NO_FORCE_NOT_OPAQUE; + if ((flags & VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR) != 0) + ret |= RADV_INSTANCE_TRIANGLE_FACING_CULL_DISABLE; + if ((flags & VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR) != 0) + ret |= RADV_INSTANCE_TRIANGLE_FLIP_FACING; + return ret; +} + void main() { @@ -60,7 +86,7 @@ main() DEREF(dst).coords = src.coords; DEREF(dst).triangle_id = src.triangle_id; - DEREF(dst).geometry_id_and_flags = src.geometry_id_and_flags; + DEREF(dst).geometry_id_and_flags = convert_geometry_id_and_flags(src.geometry_id_and_flags); DEREF(dst).id = src.id; break; } @@ -71,7 +97,7 @@ main() INDEX(radv_bvh_aabb_node, dst_leaves, global_id); DEREF(dst).aabb = src.base.aabb; DEREF(dst).primitive_id = src.primitive_id; - DEREF(dst).geometry_id_and_flags = src.geometry_id_and_flags; + DEREF(dst).geometry_id_and_flags = convert_geometry_id_and_flags(src.geometry_id_and_flags); break; } default: { /* instances */ @@ -85,7 +111,7 @@ main() DEREF(dst).bvh_ptr = src.base_ptr + bvh_offset; DEREF(dst).custom_instance_and_mask = src.custom_instance_and_mask; - DEREF(dst).sbt_offset_and_flags = src.sbt_offset_and_flags; + DEREF(dst).sbt_offset_and_flags = convert_sbt_offset_and_flags(src.sbt_offset_and_flags); DEREF(dst).instance_id = src.instance_id; DEREF(dst).bvh_offset = bvh_offset; diff --git a/src/amd/vulkan/radv_rt_common.c b/src/amd/vulkan/radv_rt_common.c index c0fd6d11846..2d8324e6fdb 100644 --- a/src/amd/vulkan/radv_rt_common.c +++ b/src/amd/vulkan/radv_rt_common.c @@ -395,17 +395,9 @@ static nir_ssa_def * hit_is_opaque(nir_builder *b, nir_ssa_def *sbt_offset_and_flags, const struct radv_ray_flags *ray_flags, nir_ssa_def *geometry_id_and_flags) { - nir_ssa_def *geom_force_opaque = - nir_test_mask(b, geometry_id_and_flags, VK_GEOMETRY_OPAQUE_BIT_KHR << 28); - nir_ssa_def *instance_force_opaque = - nir_test_mask(b, sbt_offset_and_flags, VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR << 24); - nir_ssa_def *instance_force_non_opaque = - nir_test_mask(b, sbt_offset_and_flags, VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR << 24); - - nir_ssa_def *opaque = geom_force_opaque; - opaque = nir_bcsel(b, instance_force_opaque, nir_imm_bool(b, true), opaque); - opaque = nir_bcsel(b, instance_force_non_opaque, nir_imm_bool(b, false), opaque); - + nir_ssa_def *opaque = + nir_uge(b, nir_ior(b, geometry_id_and_flags, sbt_offset_and_flags), + nir_imm_int(b, RADV_INSTANCE_FORCE_OPAQUE | RADV_INSTANCE_NO_FORCE_NOT_OPAQUE)); opaque = nir_bcsel(b, ray_flags->force_opaque, nir_imm_bool(b, true), opaque); opaque = nir_bcsel(b, ray_flags->force_not_opaque, nir_imm_bool(b, false), opaque); return opaque; @@ -440,20 +432,19 @@ insert_traversal_triangle_case(struct radv_device *device, nir_builder *b, nir_push_if(b, nir_flt(b, intersection.t, nir_load_deref(b, args->vars.tmax))); { intersection.frontface = nir_flt(b, nir_imm_float(b, 0), div); - nir_ssa_def *switch_ccw = - nir_test_mask(b, nir_load_deref(b, args->vars.sbt_offset_and_flags), - VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR << 24); + nir_ssa_def *switch_ccw = nir_test_mask(b, nir_load_deref(b, args->vars.sbt_offset_and_flags), + RADV_INSTANCE_TRIANGLE_FLIP_FACING); intersection.frontface = nir_ixor(b, intersection.frontface, switch_ccw); nir_ssa_def *not_cull = ray_flags->no_skip_triangles; nir_ssa_def *not_facing_cull = nir_bcsel(b, intersection.frontface, ray_flags->no_cull_front, ray_flags->no_cull_back); - not_cull = nir_iand( - b, not_cull, - nir_ior(b, not_facing_cull, - nir_test_mask(b, nir_load_deref(b, args->vars.sbt_offset_and_flags), - VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR << 24))); + not_cull = + nir_iand(b, not_cull, + nir_ior(b, not_facing_cull, + nir_test_mask(b, nir_load_deref(b, args->vars.sbt_offset_and_flags), + RADV_INSTANCE_TRIANGLE_FACING_CULL_DISABLE))); nir_push_if(b, nir_iand(b,