radv/shader_info: start gathering tess output info (v2)
authorDave Airlie <airlied@redhat.com>
Mon, 19 Feb 2018 05:49:04 +0000 (05:49 +0000)
committerDave Airlie <airlied@redhat.com>
Fri, 16 Mar 2018 05:22:23 +0000 (05:22 +0000)
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 <samuel.pitoiset@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/amd/vulkan/radv_shader.h
src/amd/vulkan/radv_shader_info.c

index 47cb23df0d32e3f538836d9464379cc15260f696..99f677c524eb8847b97b5240d6de212f8333b706 100644 (file)
@@ -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 {
index 3cce0c2f6e45d7add8c115f9d97d4b54549356e7..ded3281516d2c0298603f3d5dcbcf59147a51953 100644 (file)
@@ -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);
 }