diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c index 685fec4a182..2db361f1b4e 100644 --- a/src/intel/vulkan/anv_pipeline.c +++ b/src/intel/vulkan/anv_pipeline.c @@ -3002,14 +3002,26 @@ VkResult anv_GetPipelineExecutableInternalRepresentationsKHR( VkResult anv_GetRayTracingShaderGroupHandlesKHR( VkDevice device, - VkPipeline pipeline, + VkPipeline _pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData) { - unreachable("Unimplemented"); - return vk_error(VK_ERROR_FEATURE_NOT_PRESENT); + ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline); + if (pipeline->type != ANV_PIPELINE_RAY_TRACING) + return vk_error(VK_ERROR_FEATURE_NOT_PRESENT); + + struct anv_ray_tracing_pipeline *rt_pipeline = + anv_pipeline_to_ray_tracing(pipeline); + + for (uint32_t i = 0; i < groupCount; i++) { + struct anv_rt_shader_group *group = &rt_pipeline->groups[firstGroup + i]; + memcpy(pData, group->handle, sizeof(group->handle)); + pData += sizeof(group->handle); + } + + return VK_SUCCESS; } VkResult diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 9b0af3a4895..8798855eef5 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -3436,6 +3436,19 @@ anv_shader_bin_unref(struct anv_device *device, struct anv_shader_bin *shader) anv_shader_bin_destroy(device, shader); } +#define anv_shader_bin_get_bsr(bin, local_arg_offset) ({ \ + assert((local_arg_offset) % 8 == 0); \ + const struct brw_bs_prog_data *prog_data = \ + brw_bs_prog_data_const(bin->prog_data); \ + assert(prog_data->simd_size == 8 || prog_data->simd_size == 16); \ + \ + (struct GFX_BINDLESS_SHADER_RECORD) { \ + .OffsetToLocalArguments = (local_arg_offset) / 8, \ + .BindlessShaderDispatchMode = prog_data->simd_size / 16, \ + .KernelStartPointer = bin->kernel.offset, \ + }; \ +}) + struct anv_pipeline_executable { gl_shader_stage stage; diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c index 1fe481ef8c7..e7d79de63e8 100644 --- a/src/intel/vulkan/genX_pipeline.c +++ b/src/intel/vulkan/genX_pipeline.c @@ -25,6 +25,7 @@ #include "genxml/gen_macros.h" #include "genxml/genX_pack.h" +#include "genxml/gen_rt_pack.h" #include "common/intel_l3_config.h" #include "common/intel_sample_positions.h" @@ -2901,6 +2902,41 @@ ray_tracing_pipeline_create( return result; } + for (uint32_t i = 0; i < pipeline->group_count; i++) { + struct anv_rt_shader_group *group = &pipeline->groups[i]; + + switch (group->type) { + case VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR: { + struct GFX_RT_GENERAL_SBT_HANDLE sh = {}; + sh.General = anv_shader_bin_get_bsr(group->general, 32); + GFX_RT_GENERAL_SBT_HANDLE_pack(NULL, group->handle, &sh); + break; + } + + case VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR: { + struct GFX_RT_TRIANGLES_SBT_HANDLE sh = {}; + if (group->closest_hit) + sh.ClosestHit = anv_shader_bin_get_bsr(group->closest_hit, 32); + if (group->any_hit) + sh.AnyHit = anv_shader_bin_get_bsr(group->any_hit, 24); + GFX_RT_TRIANGLES_SBT_HANDLE_pack(NULL, group->handle, &sh); + break; + } + + case VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR: { + struct GFX_RT_PROCEDURAL_SBT_HANDLE sh = {}; + if (group->closest_hit) + sh.ClosestHit = anv_shader_bin_get_bsr(group->closest_hit, 32); + sh.Intersection = anv_shader_bin_get_bsr(group->intersection, 24); + GFX_RT_PROCEDURAL_SBT_HANDLE_pack(NULL, group->handle, &sh); + break; + } + + default: + unreachable("Invalid shader group type"); + } + } + *pPipeline = anv_pipeline_to_handle(&pipeline->base); return pipeline->base.batch.status;