anv: Compile trivial return and trampoline shaders

These don't necessarily go in any group but are required for dispatch to
work properly.  The trampoline is a compute shader that is the initial
start point for the trace.  It's in charge of invoking the actual
ray-gen shader.  The trivial return shader is used whenever another
shader is missing and it does no work except the minimum required to do
a stack return.

v2: Rebase on upstream changes (Lionel)

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8637>
This commit is contained in:
Jason Ekstrand 2021-01-21 15:30:27 -06:00 committed by Marge Bot
parent e104555851
commit 79dc25d867
2 changed files with 71 additions and 0 deletions

View file

@ -360,6 +360,8 @@ void anv_DestroyPipeline(
anv_shader_bin_unref(device, *shader);
}
anv_state_pool_free(&device->instruction_state_pool,
rt_pipeline->trampoline);
break;
}
@ -2481,6 +2483,32 @@ compile_upload_rt_shader(struct anv_ray_tracing_pipeline *pipeline,
return VK_SUCCESS;
}
static VkResult
compile_trivial_return_shader(struct anv_ray_tracing_pipeline *pipeline)
{
const struct brw_compiler *compiler =
pipeline->base.device->physical->compiler;
assert(pipeline->trivial_return_shader == NULL);
void *mem_ctx = ralloc_context(NULL);
nir_shader *nir = brw_nir_create_trivial_return_shader(compiler, mem_ctx);
struct anv_pipeline_stage stage = {
.stage = nir->info.stage,
.nir = nir,
};
VkResult result =
compile_upload_rt_shader(pipeline, stage.nir, &stage,
&pipeline->trivial_return_shader, mem_ctx);
ralloc_free(mem_ctx);
return result;
}
static VkResult
anv_pipeline_compile_ray_tracing(struct anv_ray_tracing_pipeline *pipeline,
struct anv_pipeline_cache *cache,
@ -2547,6 +2575,8 @@ anv_pipeline_compile_ray_tracing(struct anv_ray_tracing_pipeline *pipeline,
}
}
compile_trivial_return_shader(pipeline);
for (uint32_t i = 0; i < info->stageCount; i++) {
if (!stages[i].entrypoint)
continue;
@ -2691,9 +2721,42 @@ anv_ray_tracing_pipeline_init(struct anv_ray_tracing_pipeline *pipeline,
/* Zero things out so our clean-up works */
memset(pipeline->groups, 0,
pipeline->group_count * sizeof(*pipeline->groups));
pipeline->trivial_return_shader = NULL;
util_dynarray_init(&pipeline->shaders, pipeline->base.mem_ctx);
/* TODO: We should probably create this once per device */
{
void *tmp_ctx = ralloc_context(NULL);
nir_shader *trampoline_nir =
brw_nir_create_raygen_trampoline(device->physical->compiler, tmp_ctx);
struct brw_cs_prog_key key = {
/* TODO: Other subgroup sizes? */
.base.subgroup_size_type = BRW_SUBGROUP_SIZE_REQUIRE_8,
};
struct brw_cs_prog_data prog_data = {
.base.nr_params = 4,
.uses_inline_data = true,
.uses_btd_stack_ids = true,
};
struct brw_compile_cs_params params = {
.nir = trampoline_nir,
.key = &key,
.prog_data = &prog_data,
.log_data = pipeline->base.device,
};
const unsigned *tramp_data =
brw_compile_cs(device->physical->compiler, tmp_ctx, &params);
pipeline->trampoline =
anv_state_pool_alloc(&device->instruction_state_pool,
prog_data.base.program_size, 64);
memcpy(pipeline->trampoline.map, tramp_data, prog_data.base.program_size);
ralloc_free(tmp_ctx);
}
result = anv_pipeline_compile_ray_tracing(pipeline, cache, pCreateInfo);
if (result != VK_SUCCESS)
goto fail;
@ -2703,6 +2766,8 @@ anv_ray_tracing_pipeline_init(struct anv_ray_tracing_pipeline *pipeline,
return VK_SUCCESS;
fail:
anv_state_pool_free(&device->instruction_state_pool,
pipeline->trampoline);
util_dynarray_foreach(&pipeline->shaders,
struct anv_shader_bin *, shader) {
anv_shader_bin_unref(device, *shader);

View file

@ -3576,6 +3576,12 @@ struct anv_ray_tracing_pipeline {
/* All shaders in the pipeline */
struct util_dynarray shaders;
/* Trampoline shader */
struct anv_state trampoline;
/* Dummy stack return shader */
struct anv_shader_bin * trivial_return_shader;
uint32_t group_count;
struct anv_rt_shader_group * groups;
};