From: Zack Rusin Date: Wed, 17 Apr 2013 19:15:12 +0000 (-0700) Subject: gallivm/gs: fix indirect addressing in geometry shaders X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cb58c79efb1402cd89504856033b6322d0096233;p=mesa.git 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 Reviewed-by: Jose Fonseca Reviewed-by: Roland Scheidegger --- 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);