diff options
author | Michel Dänzer <[email protected]> | 2014-01-08 17:48:21 +0900 |
---|---|---|
committer | Michel Dänzer <[email protected]> | 2014-01-29 11:08:33 +0900 |
commit | 67e385b3b79e86507211442152072cb86fc834fd (patch) | |
tree | f72cbdb2b894d0e03e68a4e13a6d2a05371c5eac /src | |
parent | d88a3752294444fc92f25fa6ca5bf4209f0e4266 (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.c | 37 |
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++) { |