gallivm: support indirect registers on both dimensions
authorZack Rusin <zackr@vmware.com>
Tue, 3 Sep 2013 17:41:30 +0000 (13:41 -0400)
committerZack Rusin <zackr@vmware.com>
Fri, 6 Sep 2013 19:05:27 +0000 (15:05 -0400)
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 <zackr@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: José Fonseca <jfonseca@vmware.com>
src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c

index 820d6b0013e1c7f170c0b09876cccdd935d3189d..03668d9d285ba579f01784fe1f36156b2091c97d 100644 (file)
@@ -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, "");
index 522302ef4f7a432d813964e1f687ddc37a011fbc..8bcdbc8f7bd26f4dbf237781a0779bf22c0a5fd3 100644 (file)
@@ -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,
index 4c6b6ec5ab62937aa205d57d384034d90d79f62a..e50f1d1460479314ca2bcec960eb5dd6ae52f72e 100644 (file)
@@ -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);