[Mesa-dev] [PATCH 12/16] radeonsi: Fix streamout from geometry shader

Michel Dänzer michel at daenzer.net
Fri Jan 24 01:33:24 PST 2014


From: Michel Dänzer <michel.daenzer at amd.com>

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 src/gallium/drivers/radeonsi/si_shader.c | 37 +++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 1d93d8b..8f6b131 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -58,6 +58,7 @@ struct si_shader_output_values
 	LLVMValueRef values[4];
 	unsigned name;
 	unsigned index;
+	unsigned sid;
 	unsigned usage;
 };
 
@@ -888,7 +889,9 @@ static void build_streamout_store(struct si_shader_context *shader,
 
 /* On SI, the vertex shader is responsible for writing streamout data
  * to buffers. */
-static void si_llvm_emit_streamout(struct si_shader_context *shader)
+static void si_llvm_emit_streamout(struct si_shader_context *shader,
+				   struct si_shader_output_values *outputs,
+				   unsigned noutput)
 {
 	struct pipe_stream_output_info *so = &shader->shader->selector->so;
 	struct gallivm_state *gallivm = &shader->radeon_bld.gallivm;
@@ -949,8 +952,6 @@ static void si_llvm_emit_streamout(struct si_shader_context *shader)
 			so_write_offset[i] = LLVMBuildAdd(builder, so_write_offset[i], so_offset, "");
 		}
 
-		LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS] = shader->radeon_bld.soa.outputs;
-
 		/* Write streamout data. */
 		for (i = 0; i < so->num_outputs; i++) {
 			unsigned buf_idx = so->output[i].output_buffer;
@@ -965,10 +966,22 @@ static void si_llvm_emit_streamout(struct si_shader_context *shader)
 
 			/* Load the output as int. */
 			for (j = 0; j < num_comps; j++) {
-				out[j] = LLVMBuildLoad(builder, outputs[reg][start+j], "");
-				out[j] = LLVMBuildBitCast(builder, out[j], i32, "");
+				unsigned outidx = 0;
+
+				while (outidx < noutput && outputs[outidx].index != reg)
+					outidx++;
+
+				if (outidx < noutput)
+					out[j] = LLVMBuildBitCast(builder,
+								  outputs[outidx].values[start+j],
+								  i32, "");
+				else
+					out[j] = NULL;
 			}
 
+			if (!out[0])
+				continue;
+
 			/* Pack the output. */
 			LLVMValueRef vdata = NULL;
 
@@ -1017,13 +1030,13 @@ static void si_llvm_export_vs(struct lp_build_tgsi_context *bld_base,
 	unsigned pos_idx;
 	int i;
 
-	if (si_shader_ctx->shader->selector->so.num_outputs) {
-		si_llvm_emit_streamout(si_shader_ctx);
+	if (outputs && si_shader_ctx->shader->selector->so.num_outputs) {
+		si_llvm_emit_streamout(si_shader_ctx, outputs, noutput);
 	}
 
 	for (i = 0; i < noutput; i++) {
 		semantic_name = outputs[i].name;
-		semantic_index = outputs[i].index;
+		semantic_index = outputs[i].sid;
 		semantic_usage = outputs[i].usage;
 
 handle_semantic:
@@ -1279,8 +1292,9 @@ static void si_llvm_emit_vs_epilogue(struct lp_build_tgsi_context * bld_base)
 		outputs = REALLOC(outputs, noutput * sizeof(outputs[0]),
 				  (noutput + 1) * sizeof(outputs[0]));
 		for (index = d->Range.First; index <= d->Range.Last; index++) {
+			outputs[noutput].index = index;
 			outputs[noutput].name = d->Semantic.Name;
-			outputs[noutput].index = d->Semantic.Index;
+			outputs[noutput].sid = d->Semantic.Index;
 			outputs[noutput].usage = d->Declaration.UsageMask;
 
 			for (i = 0; i < 4; i++)
@@ -2270,7 +2284,9 @@ static void preload_streamout_buffers(struct si_shader_context *si_shader_ctx)
 	struct gallivm_state * gallivm = bld_base->base.gallivm;
 	unsigned i;
 
-	if (!si_shader_ctx->shader->selector->so.num_outputs)
+	if (si_shader_ctx->type != TGSI_PROCESSOR_VERTEX ||
+	    si_shader_ctx->shader->key.vs.as_es ||
+	    !si_shader_ctx->shader->selector->so.num_outputs)
 		return;
 
 	LLVMValueRef buf_ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn,
@@ -2416,6 +2432,7 @@ static int si_generate_gs_copy_shader(struct si_context *sctx,
 
 		outputs[i].name = out->name;
 		outputs[i].index = out->index;
+		outputs[i].sid = out->sid;
 		outputs[i].usage = out->usage;
 
 		for (chan = 0; chan < 4; chan++) {
-- 
1.8.5.3



More information about the mesa-dev mailing list