[Mesa-dev] [PATCH 3/6] radv: implement new path for exporting generic varyings

Samuel Pitoiset samuel.pitoiset at gmail.com
Wed Jul 10 13:18:55 UTC 2019


Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
---
 src/amd/vulkan/radv_nir_to_llvm.c | 102 ++++++++++++++++++++----------
 1 file changed, 70 insertions(+), 32 deletions(-)

diff --git a/src/amd/vulkan/radv_nir_to_llvm.c b/src/amd/vulkan/radv_nir_to_llvm.c
index b83fee304fb..fc598222fcf 100644
--- a/src/amd/vulkan/radv_nir_to_llvm.c
+++ b/src/amd/vulkan/radv_nir_to_llvm.c
@@ -2710,16 +2710,57 @@ radv_emit_streamout(struct radv_shader_context *ctx, unsigned stream)
 	ac_nir_build_endif(&if_ctx);
 }
 
+struct radv_shader_output_values {
+	LLVMValueRef values[4];
+	unsigned slot_name;
+	unsigned slot_index;
+	unsigned usage_mask;
+};
+
+static void
+radv_build_param_exports(struct radv_shader_context *ctx,
+			 struct radv_shader_output_values *outputs,
+			 unsigned noutput,
+			 struct radv_vs_output_info *outinfo,
+			 bool export_clip_dists)
+{
+	unsigned param_count = 0;
+
+	for (unsigned i = 0; i < noutput; i++) {
+		unsigned slot_name = outputs[i].slot_name;
+		unsigned usage_mask = outputs[i].usage_mask;
+
+		if (slot_name != VARYING_SLOT_LAYER &&
+		    slot_name != VARYING_SLOT_PRIMITIVE_ID &&
+		    slot_name != VARYING_SLOT_CLIP_DIST0 &&
+		    slot_name != VARYING_SLOT_CLIP_DIST1 &&
+		    slot_name < VARYING_SLOT_VAR0)
+			continue;
+
+		if ((slot_name == VARYING_SLOT_CLIP_DIST0 ||
+		     slot_name == VARYING_SLOT_CLIP_DIST1) && !export_clip_dists)
+			continue;
+
+		radv_export_param(ctx, param_count, outputs[i].values, usage_mask);
+
+		assert(i < ARRAY_SIZE(outinfo->vs_output_param_offset));
+		outinfo->vs_output_param_offset[slot_name] = param_count++;
+        }
+
+	outinfo->param_exports = param_count;
+}
+
 static void
 handle_vs_outputs_post(struct radv_shader_context *ctx,
 		       bool export_prim_id,
 		       bool export_clip_dists,
 		       struct radv_vs_output_info *outinfo)
 {
-	uint32_t param_count = 0;
 	unsigned pos_idx, num_pos_exports = 0;
 	struct ac_export_args pos_args[4] = {};
 	LLVMValueRef psize_value = NULL, layer_value = NULL, viewport_index_value = NULL;
+	struct radv_shader_output_values *outputs;
+	unsigned noutput = 0;
 	int i;
 
 	if (ctx->options->key.has_multiview_view_index) {
@@ -2863,60 +2904,57 @@ handle_vs_outputs_post(struct radv_shader_context *ctx,
 		ac_build_export(&ctx->ac, &pos_args[i]);
 	}
 
-	for (unsigned i = 0; i < AC_LLVM_MAX_OUTPUTS; ++i) {
-		LLVMValueRef values[4];
-		if (!(ctx->output_mask & (1ull << i)))
-			continue;
+	outinfo->pos_exports = num_pos_exports;
 
-		if (i != VARYING_SLOT_LAYER &&
-		    i != VARYING_SLOT_PRIMITIVE_ID &&
-		    i != VARYING_SLOT_CLIP_DIST0 &&
-		    i != VARYING_SLOT_CLIP_DIST1 &&
-		    i < VARYING_SLOT_VAR0)
-			continue;
+	/* Allocate a temporary array for the output values. */
+	unsigned num_outputs = util_bitcount64(ctx->output_mask) + export_prim_id;
+	outputs = malloc(num_outputs * sizeof(outputs[0]));
 
-		if ((i == VARYING_SLOT_CLIP_DIST0 ||
-		     i == VARYING_SLOT_CLIP_DIST1) && !export_clip_dists)
+	for (unsigned i = 0; i < AC_LLVM_MAX_OUTPUTS; ++i) {
+		if (!(ctx->output_mask & (1ull << i)))
 			continue;
 
-		for (unsigned j = 0; j < 4; j++)
-			values[j] = ac_to_float(&ctx->ac, radv_load_output(ctx, i, j));
-
-		unsigned output_usage_mask;
+		outputs[noutput].slot_name = i;
+		outputs[noutput].slot_index = 0;
 
 		if (ctx->stage == MESA_SHADER_VERTEX &&
 		    !ctx->is_gs_copy_shader) {
-			output_usage_mask =
+			outputs[noutput].usage_mask =
 				ctx->shader_info->info.vs.output_usage_mask[i];
 		} else if (ctx->stage == MESA_SHADER_TESS_EVAL) {
-			output_usage_mask =
+			outputs[noutput].usage_mask =
 				ctx->shader_info->info.tes.output_usage_mask[i];
 		} else {
 			assert(ctx->is_gs_copy_shader);
-			output_usage_mask =
+			outputs[noutput].usage_mask =
 				ctx->shader_info->info.gs.output_usage_mask[i];
 		}
 
-		radv_export_param(ctx, param_count, values, output_usage_mask);
+		for (unsigned j = 0; j < 4; j++) {
+			outputs[noutput].values[j] =
+				ac_to_float(&ctx->ac, radv_load_output(ctx, i, j));
+		}
 
-		outinfo->vs_output_param_offset[i] = param_count++;
+		noutput++;
 	}
 
+	/* Export PrimitiveID. */
 	if (export_prim_id) {
-		LLVMValueRef values[4];
+		outinfo->export_prim_id = true;
 
-		values[0] = ctx->vs_prim_id;
+		outputs[noutput].slot_name = VARYING_SLOT_PRIMITIVE_ID;
+		outputs[noutput].slot_index = 0;
+		outputs[noutput].usage_mask = 0x1;
+		outputs[noutput].values[0] = ctx->vs_prim_id;
 		for (unsigned j = 1; j < 4; j++)
-			values[j] = ctx->ac.f32_0;
-
-		radv_export_param(ctx, param_count, values, 0x1);
-
-		outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = param_count++;
-		outinfo->export_prim_id = true;
+			outputs[noutput].values[j] = ctx->ac.f32_0;
+		noutput++;
 	}
 
-	outinfo->pos_exports = num_pos_exports;
-	outinfo->param_exports = param_count;
+	/* Build parameter exports. */
+	radv_build_param_exports(ctx, outputs, noutput, outinfo, export_clip_dists);
+
+	free(outputs);
 }
 
 static void
-- 
2.22.0



More information about the mesa-dev mailing list