From 750b2af4d9eb7a175355d1769f913b8bd690fe29 Mon Sep 17 00:00:00 2001 From: Konstantin Seurer Date: Thu, 14 Mar 2024 19:35:30 +0100 Subject: [PATCH] lavapipe: Implement VK_KHR_ray_tracing_position_fetch Reviewed-By: Mike Blumenkrantz Part-of: --- src/gallium/frontends/lavapipe/lvp_device.c | 4 ++++ .../lavapipe/lvp_nir_lower_ray_queries.c | 4 ++++ .../frontends/lavapipe/lvp_nir_ray_tracing.c | 17 +++++++++++++++++ .../frontends/lavapipe/lvp_nir_ray_tracing.h | 3 +++ src/gallium/frontends/lavapipe/lvp_pipeline.c | 1 + .../lavapipe/lvp_ray_tracing_pipeline.c | 6 ++++++ 6 files changed, 35 insertions(+) diff --git a/src/gallium/frontends/lavapipe/lvp_device.c b/src/gallium/frontends/lavapipe/lvp_device.c index 572a8246094..897ff8605f7 100644 --- a/src/gallium/frontends/lavapipe/lvp_device.c +++ b/src/gallium/frontends/lavapipe/lvp_device.c @@ -142,6 +142,7 @@ static const struct vk_device_extension_table lvp_device_extensions_supported = .KHR_ray_query = true, .KHR_ray_tracing_maintenance1 = true, .KHR_ray_tracing_pipeline = true, + .KHR_ray_tracing_position_fetch = true, .KHR_relaxed_block_layout = true, .KHR_sampler_mirror_clamp_to_edge = true, .KHR_sampler_ycbcr_conversion = true, @@ -506,6 +507,9 @@ lvp_get_features(const struct lvp_physical_device *pdevice, /* VK_EXT_pipeline_library_group_handles */ .pipelineLibraryGroupHandles = true, + /* VK_KHR_ray_tracing_position_fetch */ + .rayTracingPositionFetch = true, + /* VK_EXT_shader_object */ .shaderObject = true, diff --git a/src/gallium/frontends/lavapipe/lvp_nir_lower_ray_queries.c b/src/gallium/frontends/lavapipe/lvp_nir_lower_ray_queries.c index 2eb6d5bce43..1ae12238ddb 100644 --- a/src/gallium/frontends/lavapipe/lvp_nir_lower_ray_queries.c +++ b/src/gallium/frontends/lavapipe/lvp_nir_lower_ray_queries.c @@ -439,6 +439,10 @@ lower_rq_load(nir_builder *b, nir_def *index, nir_intrinsic_instr *instr, return rq_load_var(b, index, vars->direction); case nir_ray_query_value_world_ray_origin: return rq_load_var(b, index, vars->origin); + case nir_ray_query_value_intersection_triangle_vertex_positions: + return lvp_load_vertex_position( + b, rq_load_var(b, index, intersection->instance_addr), + rq_load_var(b, index, intersection->primitive_id), column); default: unreachable("Invalid nir_ray_query_value!"); } diff --git a/src/gallium/frontends/lavapipe/lvp_nir_ray_tracing.c b/src/gallium/frontends/lavapipe/lvp_nir_ray_tracing.c index 1e29dc95e21..95fc4293c76 100644 --- a/src/gallium/frontends/lavapipe/lvp_nir_ray_tracing.c +++ b/src/gallium/frontends/lavapipe/lvp_nir_ray_tracing.c @@ -40,6 +40,23 @@ lvp_load_wto_matrix(nir_builder *b, nir_def *instance_addr, nir_def **out) } } +nir_def * +lvp_load_vertex_position(nir_builder *b, nir_def *instance_addr, nir_def *primitive_id, + uint32_t index) +{ + nir_def *bvh_addr = nir_build_load_global( + b, 1, 64, nir_iadd_imm(b, instance_addr, offsetof(struct lvp_bvh_instance_node, bvh_ptr))); + + nir_def *leaf_nodes_offset = nir_build_load_global( + b, 1, 32, nir_iadd_imm(b, bvh_addr, offsetof(struct lvp_bvh_header, leaf_nodes_offset))); + + nir_def *offset = nir_imul_imm(b, primitive_id, sizeof(struct lvp_bvh_triangle_node)); + offset = nir_iadd(b, offset, leaf_nodes_offset); + offset = nir_iadd_imm(b, offset, index * 3 * sizeof(float)); + + return nir_build_load_global(b, 3, 32, nir_iadd(b, bvh_addr, nir_u2u64(b, offset))); +} + static nir_def * lvp_build_intersect_ray_box(nir_builder *b, nir_def *node_addr, nir_def *ray_tmax, nir_def *origin, nir_def *dir, nir_def *inv_dir) diff --git a/src/gallium/frontends/lavapipe/lvp_nir_ray_tracing.h b/src/gallium/frontends/lavapipe/lvp_nir_ray_tracing.h index 80ba660efec..18a9acfd6f1 100644 --- a/src/gallium/frontends/lavapipe/lvp_nir_ray_tracing.h +++ b/src/gallium/frontends/lavapipe/lvp_nir_ray_tracing.h @@ -14,6 +14,9 @@ nir_def *lvp_mul_vec3_mat(nir_builder *b, nir_def *vec, nir_def *matrix[], bool void lvp_load_wto_matrix(nir_builder *b, nir_def *instance_addr, nir_def **out); +nir_def *lvp_load_vertex_position(nir_builder *b, nir_def *instance_addr, + nir_def *primitive_id, uint32_t index); + struct lvp_ray_traversal_args; struct lvp_ray_flags { diff --git a/src/gallium/frontends/lavapipe/lvp_pipeline.c b/src/gallium/frontends/lavapipe/lvp_pipeline.c index 65eacc18c5d..77c163c555c 100644 --- a/src/gallium/frontends/lavapipe/lvp_pipeline.c +++ b/src/gallium/frontends/lavapipe/lvp_pipeline.c @@ -352,6 +352,7 @@ compile_spirv(struct lvp_device *pdevice, const VkPipelineShaderStageCreateInfo .ray_query = true, .ray_cull_mask = true, .ray_tracing = true, + .ray_tracing_position_fetch = true, }, .ubo_addr_format = nir_address_format_vec2_index_32bit_offset, .ssbo_addr_format = nir_address_format_vec2_index_32bit_offset, diff --git a/src/gallium/frontends/lavapipe/lvp_ray_tracing_pipeline.c b/src/gallium/frontends/lavapipe/lvp_ray_tracing_pipeline.c index 88bb0296745..56b11af6991 100644 --- a/src/gallium/frontends/lavapipe/lvp_ray_tracing_pipeline.c +++ b/src/gallium/frontends/lavapipe/lvp_ray_tracing_pipeline.c @@ -997,6 +997,12 @@ lvp_lower_ray_tracing_instr(nir_builder *b, nir_instr *instr, void *data) nir_src_rewrite(&intr->src[1], nir_iadd(b, nir_load_var(b, state->stack_ptr), intr->src[1].ssa)); return true; } + case nir_intrinsic_load_ray_triangle_vertex_positions: { + def = lvp_load_vertex_position( + b, nir_load_var(b, state->instance_addr), nir_load_var(b, state->primitive_id), + nir_intrinsic_column(intr)); + break; + } /* Internal system values */ case nir_intrinsic_load_shader_call_data_offset_lvp: def = nir_load_var(b, state->shader_call_data_offset);