[Mesa-dev] [PATCH 02/14] radv/shader_info: start gathering tess output info (v2)

Dave Airlie airlied at gmail.com
Wed Mar 14 04:41:08 UTC 2018


From: Dave Airlie <airlied at redhat.com>

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.
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 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 cab0fc43bda..23ca3b8858e 100644
--- a/src/amd/vulkan/radv_shader.h
+++ b/src/amd/vulkan/radv_shader.h
@@ -131,6 +131,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 */
@@ -158,6 +159,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.14.3



More information about the mesa-dev mailing list