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 <zackr@vmware.com>
Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
This commit is contained in:
Zack Rusin
2013-04-17 12:15:12 -07:00
parent 02039066a8
commit cb58c79efb
3 changed files with 30 additions and 6 deletions
+28 -6
View File
@@ -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;
indices[0] = vertex_index;
indices[1] = attrib_index;
indices[2] = swizzle_index;
res = LLVMBuildGEP(builder, gs->input, indices, 3, "");
res = LLVMBuildLoad(builder, res, "");
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;
res = LLVMBuildGEP(builder, gs->input, indices, 3, "");
res = LLVMBuildLoad(builder, res, "");
}
return res;
}
@@ -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);
@@ -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);