From d89b16b7b9c3de8b7a7b896822f3893fdda4dbec Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 19 Feb 2018 05:49:04 +0000 Subject: [PATCH] radv/shader_info: start gathering tess output info (v2) This gathers the ls outputs written by the vertex shader, and the tcs outputs, these are needed to calculate certain tcs parameters. These have to be separate for combined gfx9 shaders. This is a bit pessimistic compared to the nir pass, as we don't work out the individual slots for tcs outputs, but I actually thing it should be fine to just mark the whole thing used here. v2: move to radv, handle clip dist (Samuel), handle compacts and patchs properly. Reviewed-by: Samuel Pitoiset Signed-off-by: Dave Airlie --- src/amd/vulkan/radv_shader.h | 5 ++++ src/amd/vulkan/radv_shader_info.c | 49 +++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h index 47cb23df0d3..99f677c524e 100644 --- a/src/amd/vulkan/radv_shader.h +++ b/src/amd/vulkan/radv_shader.h @@ -133,6 +133,7 @@ struct radv_shader_info { bool uses_invocation_id; bool uses_prim_id; struct { + uint64_t ls_outputs_written; uint8_t input_usage_mask[VERT_ATTRIB_MAX]; uint8_t output_usage_mask[VARYING_SLOT_VAR31 + 1]; bool has_vertex_buffers; /* needs vertex buffers and base/start */ @@ -160,6 +161,10 @@ struct radv_shader_info { bool uses_thread_id[3]; bool uses_local_invocation_idx; } cs; + struct { + uint64_t outputs_written; + uint64_t patch_outputs_written; + } tcs; }; struct radv_userdata_info { diff --git a/src/amd/vulkan/radv_shader_info.c b/src/amd/vulkan/radv_shader_info.c index 3cce0c2f6e4..ded3281516d 100644 --- a/src/amd/vulkan/radv_shader_info.c +++ b/src/amd/vulkan/radv_shader_info.c @@ -30,6 +30,23 @@ static void mark_sampler_desc(const nir_variable *var, info->desc_set_used_mask |= (1 << var->data.descriptor_set); } +static void mark_ls_output(struct radv_shader_info *info, + uint32_t param, int num_slots) +{ + uint64_t mask = (1ull << num_slots) - 1ull; + info->vs.ls_outputs_written |= (mask << param); +} + +static void mark_tess_output(struct radv_shader_info *info, + bool is_patch, uint32_t param, int num_slots) +{ + uint64_t mask = (1ull << num_slots) - 1ull; + if (is_patch) + info->tcs.patch_outputs_written |= (mask << param); + else + info->tcs.outputs_written |= (mask << param); +} + static void gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr, struct radv_shader_info *info) @@ -162,6 +179,17 @@ gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr, } else if (nir->info.stage == MESA_SHADER_TESS_EVAL) { info->tes.output_usage_mask[idx] |= instr->const_index[0] << comp; + } else if (nir->info.stage == MESA_SHADER_TESS_CTRL) { + unsigned param = shader_io_get_unique_index(idx); + const struct glsl_type *type = var->type; + if (!var->data.patch) + type = glsl_get_array_element(var->type); + unsigned slots = + var->data.compact ? DIV_ROUND_UP(glsl_get_length(type), 4) + : glsl_count_attribute_slots(type, false); + if (idx == VARYING_SLOT_CLIP_DIST0) + slots = (nir->info.clip_distance_array_size + nir->info.cull_distance_array_size > 4) ? 2 : 1; + mark_tess_output(info, var->data.patch, param, slots); } } break; @@ -252,6 +280,18 @@ gather_info_input_decl(const nir_shader *nir, const nir_variable *var, } } +static void +gather_info_output_decl_ls(const nir_shader *nir, const nir_variable *var, + struct radv_shader_info *info) +{ + int idx = var->data.location; + unsigned param = shader_io_get_unique_index(idx); + int num_slots = glsl_count_attribute_slots(var->type, false); + if (idx == VARYING_SLOT_CLIP_DIST0) + num_slots = (nir->info.clip_distance_array_size + nir->info.cull_distance_array_size > 4) ? 2 : 1; + mark_ls_output(info, param, num_slots); +} + static void gather_info_output_decl_ps(const nir_shader *nir, const nir_variable *var, struct radv_shader_info *info) @@ -275,12 +315,17 @@ gather_info_output_decl_ps(const nir_shader *nir, const nir_variable *var, static void gather_info_output_decl(const nir_shader *nir, const nir_variable *var, - struct radv_shader_info *info) + struct radv_shader_info *info, + const struct radv_nir_compiler_options *options) { switch (nir->info.stage) { case MESA_SHADER_FRAGMENT: gather_info_output_decl_ps(nir, var, info); break; + case MESA_SHADER_VERTEX: + if (options->key.vs.as_ls) + gather_info_output_decl_ls(nir, var, info); + break; default: break; } @@ -305,5 +350,5 @@ radv_nir_shader_info_pass(const struct nir_shader *nir, } nir_foreach_variable(variable, &nir->outputs) - gather_info_output_decl(nir, variable, info); + gather_info_output_decl(nir, variable, info, options); } -- 2.30.2