summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZack Rusin <[email protected]>2013-09-03 13:41:30 -0400
committerZack Rusin <[email protected]>2013-09-06 15:05:27 -0400
commite9f1f6ab42a7c466b3b6cb5460fcf875822c1dbd (patch)
tree2e6e5fce32b9d53d2d1125fdc56ec47d8528a22f
parentf9b37f7183ca2df228f2b7382ac9e2d0f74cb904 (diff)
gallivm: support indirect registers on both dimensions
We support indirect addressing only on the vertex index, but some shaders also use indirect addressing on attributes. This patch adds support for indirect addressing on both dimensions inside gs arrays. Signed-off-by: Zack Rusin <[email protected]> Reviewed-by: Brian Paul <[email protected]> Reviewed-by: José Fonseca <[email protected]>
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c23
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi.h3
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c4
3 files changed, 22 insertions, 8 deletions
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index 820d6b0013e..03668d9d285 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -1360,8 +1360,9 @@ 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,
+ boolean is_vindex_indirect,
LLVMValueRef vertex_index,
+ boolean is_aindex_indirect,
LLVMValueRef attrib_index,
LLVMValueRef swizzle_index)
{
@@ -1372,18 +1373,28 @@ draw_gs_llvm_fetch_input(const struct lp_build_tgsi_gs_iface *gs_iface,
LLVMValueRef res;
struct lp_type type = bld_base->base.type;
- if (is_indirect) {
+ if (is_vindex_indirect || is_aindex_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 vert_chan_index = vertex_index;
+ LLVMValueRef attr_chan_index = attrib_index;
LLVMValueRef channel_vec, value;
+
+ if (is_vindex_indirect) {
+ vert_chan_index = LLVMBuildExtractElement(builder,
+ vertex_index, idx, "");
+ }
+ if (is_aindex_indirect) {
+ attr_chan_index = LLVMBuildExtractElement(builder,
+ attrib_index, idx, "");
+ }
+
indices[0] = vert_chan_index;
- indices[1] = attrib_index;
+ indices[1] = attr_chan_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, "");
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
index 522302ef4f7..8bcdbc8f7bd 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
@@ -395,8 +395,9 @@ 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,
+ boolean is_vindex_indirect,
LLVMValueRef vertex_index,
+ boolean is_aindex_indirect,
LLVMValueRef attrib_index,
LLVMValueRef swizzle_index);
void (*emit_vertex)(const struct lp_build_tgsi_gs_iface *gs_iface,
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 4c6b6ec5ab6..e50f1d14604 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -1135,7 +1135,9 @@ emit_fetch_gs_input(
res = bld->gs_iface->fetch_input(bld->gs_iface, bld_base,
reg->Dimension.Indirect,
- vertex_index, attrib_index,
+ vertex_index,
+ reg->Register.Indirect,
+ attrib_index,
swizzle_index);
assert(res);