summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichel Dänzer <[email protected]>2014-01-08 17:48:21 +0900
committerMichel Dänzer <[email protected]>2014-01-29 11:08:33 +0900
commit67e385b3b79e86507211442152072cb86fc834fd (patch)
treef72cbdb2b894d0e03e68a4e13a6d2a05371c5eac /src
parentd88a3752294444fc92f25fa6ca5bf4209f0e4266 (diff)
radeonsi: Fix streamout from geometry shader
Reviewed-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index b80a7d552c2..999ccf25680 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -50,6 +50,7 @@ struct si_shader_output_values
LLVMValueRef values[4];
unsigned name;
unsigned index;
+ unsigned sid;
unsigned usage;
};
@@ -876,7 +877,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;
@@ -937,8 +940,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;
@@ -953,10 +954,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;
@@ -1005,13 +1018,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:
@@ -1263,8 +1276,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++)
@@ -2242,7 +2256,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,
@@ -2386,6 +2402,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++) {