[Mesa-dev] [PATCH 1/2] r600g: tgsi to llvm emits stream output intrinsics.

Vincent Lejeune vljn at ovi.com
Fri Jan 11 10:48:28 PST 2013


---
 src/gallium/drivers/r600/eg_asm.c        |  2 ++
 src/gallium/drivers/r600/r600_asm.c      |  2 ++
 src/gallium/drivers/r600/r600_llvm.c     | 32 ++++++++++++++++++++++++++++++++
 src/gallium/drivers/r600/r600_shader.c   |  3 ++-
 src/gallium/drivers/radeon/radeon_llvm.h |  1 +
 5 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/r600/eg_asm.c b/src/gallium/drivers/r600/eg_asm.c
index 70dc94a..0dc3ffd 100644
--- a/src/gallium/drivers/r600/eg_asm.c
+++ b/src/gallium/drivers/r600/eg_asm.c
@@ -161,4 +161,6 @@ void eg_bytecode_export_read(struct r600_bytecode_output *output, uint32_t word0
 	output->end_of_program = G_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(word1);
 	output->inst = EG_S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(G_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(word1));
 	output->barrier = G_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(word1);
+	output->array_size = G_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE(word1);
+	output->comp_mask = G_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK(word1);
 }
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index 268137f..6a1a8bd 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -2965,4 +2965,6 @@ void r600_bytecode_export_read(struct r600_bytecode_output *output, uint32_t wor
 	output->end_of_program = G_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(word1);
 	output->inst = R600_S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(G_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(word1));
 	output->barrier = G_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(word1);
+	output->array_size = G_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE(word1);
+	output->comp_mask = G_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK(word1);
 }
diff --git a/src/gallium/drivers/r600/r600_llvm.c b/src/gallium/drivers/r600/r600_llvm.c
index d76b9c9..9fe130e 100644
--- a/src/gallium/drivers/r600/r600_llvm.c
+++ b/src/gallium/drivers/r600/r600_llvm.c
@@ -237,11 +237,43 @@ static void llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
 {
 	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
 	struct lp_build_context * base = &bld_base->base;
+	struct pipe_stream_output_info * so = ctx->stream_outputs;
 	unsigned i;
 	
 	unsigned color_count = 0;
 	boolean has_color = false;
 
+	if (ctx->type == TGSI_PROCESSOR_VERTEX && so->num_outputs) {
+		for (i = 0; i < so->num_outputs; i++) {
+			unsigned register_index = so->output[i].register_index;
+			unsigned start_component = so->output[i].start_component;
+			unsigned num_components = so->output[i].num_components;
+			unsigned dst_offset = so->output[i].dst_offset;
+			unsigned chan;
+			LLVMValueRef elements[4];
+			if (dst_offset < start_component) {
+				for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+					elements[chan] = LLVMBuildLoad(base->gallivm->builder,
+						ctx->soa.outputs[register_index][(chan + start_component) % TGSI_NUM_CHANNELS], "");
+				}
+				start_component = 0;
+			} else {
+				for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+					elements[chan] = LLVMBuildLoad(base->gallivm->builder,
+						ctx->soa.outputs[register_index][chan], "");
+				}
+			}
+			LLVMValueRef output = lp_build_gather_values(base->gallivm, elements, 4);
+			LLVMValueRef args[4];
+			args[0] = output;
+			args[1] = lp_build_const_int32(base->gallivm, dst_offset - start_component);
+			args[2] = lp_build_const_int32(base->gallivm, so->output[i].output_buffer);
+			args[3] = lp_build_const_int32(base->gallivm, ((1 << num_components) - 1) << start_component);
+			lp_build_intrinsic(base->gallivm->builder, "llvm.R600.store.stream.output",
+				LLVMVoidTypeInContext(base->gallivm->context), args, 4);
+		}
+	}
+
 	/* Add the necessary export instructions */
 	for (i = 0; i < ctx->output_reg_count; i++) {
 		unsigned chan;
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index f7b1e84..6b4ab35 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -1398,6 +1398,7 @@ static int r600_shader_from_tgsi(struct r600_screen *rscreen,
 		radeon_llvm_ctx.color_buffer_count = MAX2(key.nr_cbufs , 1);
 		radeon_llvm_ctx.chip_class = ctx.bc->chip_class;
 		radeon_llvm_ctx.fs_color_all = shader->fs_write_all && (rscreen->chip_class >= EVERGREEN);
+		radeon_llvm_ctx.stream_outputs = &so;
 		mod = r600_tgsi_llvm(&radeon_llvm_ctx, tokens);
 		if (debug_get_bool_option("R600_DUMP_SHADERS", FALSE)) {
 			dump = 1;
@@ -1554,7 +1555,7 @@ static int r600_shader_from_tgsi(struct r600_screen *rscreen,
 	}
 
 	/* Add stream outputs. */
-	if (ctx.type == TGSI_PROCESSOR_VERTEX && so.num_outputs) {
+	if (ctx.type == TGSI_PROCESSOR_VERTEX && so.num_outputs && !use_llvm) {
 		unsigned so_gpr[PIPE_MAX_SHADER_OUTPUTS];
 
 		/* Sanity checking. */
diff --git a/src/gallium/drivers/radeon/radeon_llvm.h b/src/gallium/drivers/radeon/radeon_llvm.h
index b8dc771..c593228 100644
--- a/src/gallium/drivers/radeon/radeon_llvm.h
+++ b/src/gallium/drivers/radeon/radeon_llvm.h
@@ -60,6 +60,7 @@ struct radeon_llvm_context {
 	unsigned two_side;
 	struct r600_shader_io * r600_inputs;
 	struct r600_shader_io * r600_outputs;
+	struct pipe_stream_output_info *stream_outputs;
 	unsigned color_buffer_count;
 	unsigned fs_color_all;
 
-- 
1.8.0.1



More information about the mesa-dev mailing list