radv/rt: implement radv_rt_nir_to_asm()

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22096>
This commit is contained in:
Daniel Schürmann
2023-03-08 04:27:30 +01:00
committed by Marge Bot
parent 99466ca185
commit 81e48613b9
+119
View File
@@ -22,6 +22,7 @@
*/
#include "nir/nir.h"
#include "nir/nir_control_flow.h"
#include "radv_debug.h"
#include "radv_private.h"
@@ -241,6 +242,124 @@ radv_create_merged_rt_create_info(const VkRayTracingPipelineCreateInfoKHR *pCrea
return local_create_info;
}
static bool
should_move_rt_instruction(nir_intrinsic_op intrinsic)
{
switch (intrinsic) {
case nir_intrinsic_load_hit_attrib_amd:
case nir_intrinsic_load_rt_arg_scratch_offset_amd:
case nir_intrinsic_load_ray_flags:
case nir_intrinsic_load_ray_object_origin:
case nir_intrinsic_load_ray_world_origin:
case nir_intrinsic_load_ray_t_min:
case nir_intrinsic_load_ray_object_direction:
case nir_intrinsic_load_ray_world_direction:
case nir_intrinsic_load_ray_t_max:
return true;
default:
return false;
}
}
static void
move_rt_instructions(nir_shader *shader)
{
nir_cursor target = nir_before_cf_list(&nir_shader_get_entrypoint(shader)->body);
nir_foreach_block (block, nir_shader_get_entrypoint(shader)) {
nir_foreach_instr_safe (instr, block) {
if (instr->type != nir_instr_type_intrinsic)
continue;
nir_intrinsic_instr *intrinsic = nir_instr_as_intrinsic(instr);
if (!should_move_rt_instruction(intrinsic->intrinsic))
continue;
nir_instr_move(target, instr);
}
}
nir_metadata_preserve(nir_shader_get_entrypoint(shader),
nir_metadata_all & (~nir_metadata_instr_index));
}
static struct radv_shader *
radv_rt_nir_to_asm(struct radv_device *device, struct vk_pipeline_cache *cache,
const VkRayTracingPipelineCreateInfoKHR *pCreateInfo,
const struct radv_pipeline_key *pipeline_key, struct radv_pipeline_stage *stage,
uint32_t *stack_size)
{
struct radv_shader_binary *binary;
RADV_FROM_HANDLE(radv_pipeline_layout, pipeline_layout, pCreateInfo->layout);
bool keep_executable_info = radv_pipeline_capture_shaders(device, pCreateInfo->flags);
bool keep_statistic_info = radv_pipeline_capture_shader_stats(device, pCreateInfo->flags);
/* Gather shader info. */
nir_shader_gather_info(stage->nir, nir_shader_get_entrypoint(stage->nir));
radv_nir_shader_info_init(&stage->info);
radv_nir_shader_info_pass(device, stage->nir, MESA_SHADER_NONE, pipeline_layout, pipeline_key,
RADV_PIPELINE_RAY_TRACING, false, &stage->info);
/* Declare shader arguments. */
radv_declare_shader_args(device, pipeline_key, &stage->info, stage->stage, MESA_SHADER_NONE,
RADV_SHADER_TYPE_DEFAULT, &stage->args);
stage->info.user_sgprs_locs = stage->args.user_sgprs_locs;
stage->info.inline_push_constant_mask = stage->args.ac.inline_push_const_mask;
/* Move ray tracing system values to the top that are set by rt_trace_ray
* to prevent them from being overwritten by other rt_trace_ray calls.
*/
NIR_PASS_V(stage->nir, move_rt_instructions);
const nir_lower_shader_calls_options opts = {
.address_format = nir_address_format_32bit_offset,
.stack_alignment = 16,
.localized_loads = true,
.vectorizer_callback = radv_mem_vectorize_callback,
};
uint32_t num_resume_shaders = 0;
nir_shader **resume_shaders = NULL;
nir_lower_shader_calls(stage->nir, &opts, &resume_shaders, &num_resume_shaders, stage->nir);
unsigned num_shaders = num_resume_shaders + 1;
nir_shader **shaders = ralloc_array(stage->nir, nir_shader *, num_shaders);
if (!shaders)
return NULL;
shaders[0] = stage->nir;
for (uint32_t i = 0; i < num_resume_shaders; i++)
shaders[i + 1] = resume_shaders[i];
/* Postprocess shader parts. */
for (uint32_t i = 0; i < num_shaders; i++) {
struct radv_pipeline_stage temp_stage = *stage;
temp_stage.nir = shaders[i];
radv_nir_lower_rt_abi(temp_stage.nir, pCreateInfo, &temp_stage.args, pipeline_key,
stack_size);
radv_optimize_nir(temp_stage.nir, pipeline_key->optimisations_disabled);
radv_postprocess_nir(device, pipeline_layout, pipeline_key, MESA_SHADER_NONE, &temp_stage);
if (radv_can_dump_shader(device, temp_stage.nir, false))
nir_print_shader(temp_stage.nir, stderr);
}
/* Compile NIR shader to AMD assembly. */
struct radv_shader *shader;
shader = radv_shader_nir_to_asm(device, cache, stage, shaders, num_shaders, pipeline_key,
keep_executable_info, keep_statistic_info, &binary);
if (shader && keep_executable_info && stage->spirv.size) {
shader->spirv = malloc(stage->spirv.size);
memcpy(shader->spirv, stage->spirv.data, stage->spirv.size);
shader->spirv_size = stage->spirv.size;
}
free(binary);
return shader;
}
static VkResult
radv_rt_precompile_shaders(struct radv_device *device, struct vk_pipeline_cache *cache,
const VkRayTracingPipelineCreateInfoKHR *pCreateInfo,