diff options
author | Dave Airlie <[email protected]> | 2018-02-19 05:49:04 +0000 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2018-03-16 05:22:23 +0000 |
commit | d89b16b7b9c3de8b7a7b896822f3893fdda4dbec (patch) | |
tree | b050ad413679533bf6c7f6af58438d4f2678b78b /src/amd/vulkan/radv_shader_info.c | |
parent | 2012dae19a1ef73224c4e54eab4cd731f1d59ddf (diff) |
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 <[email protected]>
Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/amd/vulkan/radv_shader_info.c')
-rw-r--r-- | src/amd/vulkan/radv_shader_info.c | 49 |
1 files changed, 47 insertions, 2 deletions
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; @@ -253,6 +281,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); } |