[Mesa-dev] [PATCH] gallivm/gs: fix indirect addressing in geometry shaders
Zack Rusin
zackr at vmware.com
Wed Apr 17 12:17:02 PDT 2013
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 at vmware.com>
---
src/gallium/auxiliary/draw/draw_llvm.c | 34 +++++++++++++++++++----
src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 1 +
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 33fe40d..8e3ea88 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 0fbb8aa..78a1f0e 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 28eb57b..ea7dec7 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);
--
1.7.10.4
More information about the mesa-dev
mailing list