diff options
author | Zack Rusin <[email protected]> | 2013-04-17 12:15:12 -0700 |
---|---|---|
committer | Zack Rusin <[email protected]> | 2013-04-17 15:28:54 -0700 |
commit | cb58c79efb1402cd89504856033b6322d0096233 (patch) | |
tree | d78c1e274341b5f3a7ca23d3cc6d3f78c11950a7 | |
parent | 02039066a8bd4e9cdce7f7d4c90606b54018d74e (diff) |
gallivm/gs: fix indirect addressing in geometry shaders
We were always treating the vertex index as a scalar but when the
shader is using indirect addressing it will be a vector of indices
for each channel. This was causing some nasty crashes insides
LLVM.
Signed-off-by: Zack Rusin <[email protected]>
Reviewed-by: Jose Fonseca <[email protected]>
Reviewed-by: Roland Scheidegger <[email protected]>
-rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm.c | 34 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 1 |
3 files changed, 30 insertions, 6 deletions
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 33fe40d5e7f..8e3ea8897d0 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -1253,6 +1253,7 @@ clipmask_booli32(struct gallivm_state *gallivm, static LLVMValueRef draw_gs_llvm_fetch_input(const struct lp_build_tgsi_gs_iface *gs_iface, struct lp_build_tgsi_context * bld_base, + boolean is_indirect, LLVMValueRef vertex_index, LLVMValueRef attrib_index, LLVMValueRef swizzle_index) @@ -1262,13 +1263,34 @@ draw_gs_llvm_fetch_input(const struct lp_build_tgsi_gs_iface *gs_iface, LLVMBuilderRef builder = gallivm->builder; LLVMValueRef indices[3]; LLVMValueRef res; + struct lp_type type = bld_base->base.type; + + if (is_indirect) { + int i; + res = bld_base->base.zero; + for (i = 0; i < type.length; ++i) { + LLVMValueRef idx = lp_build_const_int32(gallivm, i); + LLVMValueRef vert_chan_index = LLVMBuildExtractElement(builder, + vertex_index, idx, ""); + LLVMValueRef channel_vec, value; + indices[0] = vert_chan_index; + indices[1] = attrib_index; + indices[2] = swizzle_index; + + channel_vec = LLVMBuildGEP(builder, gs->input, indices, 3, ""); + channel_vec = LLVMBuildLoad(builder, channel_vec, ""); + value = LLVMBuildExtractElement(builder, channel_vec, idx, ""); + + res = LLVMBuildInsertElement(builder, res, value, idx, ""); + } + } else { + indices[0] = vertex_index; + indices[1] = attrib_index; + indices[2] = swizzle_index; - indices[0] = vertex_index; - indices[1] = attrib_index; - indices[2] = swizzle_index; - - res = LLVMBuildGEP(builder, gs->input, indices, 3, ""); - res = LLVMBuildLoad(builder, res, ""); + res = LLVMBuildGEP(builder, gs->input, indices, 3, ""); + res = LLVMBuildLoad(builder, res, ""); + } return res; } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index 0fbb8aabbb0..78a1f0ea4ee 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -368,6 +368,7 @@ struct lp_build_tgsi_gs_iface { LLVMValueRef (*fetch_input)(const struct lp_build_tgsi_gs_iface *gs_iface, struct lp_build_tgsi_context * bld_base, + boolean is_indirect, LLVMValueRef vertex_index, LLVMValueRef attrib_index, LLVMValueRef swizzle_index); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 28eb57b4b51..ea7dec727d2 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -829,6 +829,7 @@ emit_fetch_gs_input( } res = bld->gs_iface->fetch_input(bld->gs_iface, bld_base, + reg->Dimension.Indirect, vertex_index, attrib_index, swizzle_index); |