gallivm/nir: add indirect swizzle output loading support
authorDave Airlie <airlied@redhat.com>
Fri, 19 Jun 2020 07:05:39 +0000 (17:05 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 31 Aug 2020 03:20:11 +0000 (13:20 +1000)
Fixes:
dEQP-VK.clipping.user_defined.clip_distance.*

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6381>

src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c
src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
src/gallium/drivers/swr/swr_shader.cpp

index aabece0ce135403f1ce7f5c7d81086cb12ce932f..58636316dfb59c5653eae237d051ea8654dcef76 100644 (file)
@@ -3075,6 +3075,7 @@ draw_tcs_llvm_emit_fetch_input(const struct lp_build_tcs_iface *tes_iface,
                                LLVMValueRef vertex_index,
                                boolean is_aindex_indirect,
                                LLVMValueRef attrib_index,
+                               boolean is_sindex_indirect,
                                LLVMValueRef swizzle_index)
 {
    const struct draw_tcs_llvm_iface *tcs = draw_tcs_llvm_iface(tes_iface);
@@ -3084,7 +3085,7 @@ draw_tcs_llvm_emit_fetch_input(const struct lp_build_tcs_iface *tes_iface,
    LLVMValueRef res;
    struct lp_type type = bld->type;
 
-   if (is_vindex_indirect || is_aindex_indirect) {
+   if (is_vindex_indirect || is_aindex_indirect || is_sindex_indirect) {
       int i;
 
       res = bld->zero;
@@ -3092,6 +3093,7 @@ draw_tcs_llvm_emit_fetch_input(const struct lp_build_tcs_iface *tes_iface,
          LLVMValueRef idx = lp_build_const_int32(gallivm, i);
          LLVMValueRef vert_chan_index = vertex_index;
          LLVMValueRef attr_chan_index = attrib_index;
+         LLVMValueRef swiz_chan_index = swizzle_index;
          LLVMValueRef channel_vec;
 
          if (is_vindex_indirect) {
@@ -3102,10 +3104,14 @@ draw_tcs_llvm_emit_fetch_input(const struct lp_build_tcs_iface *tes_iface,
             attr_chan_index = LLVMBuildExtractElement(builder,
                                                       attrib_index, idx, "");
          }
+         if (is_sindex_indirect) {
+            swiz_chan_index = LLVMBuildExtractElement(builder,
+                                                      swizzle_index, idx, "");
+         }
 
          indices[0] = vert_chan_index;
          indices[1] = attr_chan_index;
-         indices[2] = swizzle_index;
+         indices[2] = swiz_chan_index;
 
          channel_vec = LLVMBuildGEP(builder, tcs->input, indices, 3, "");
          channel_vec = LLVMBuildLoad(builder, channel_vec, "");
@@ -3131,6 +3137,7 @@ draw_tcs_llvm_emit_fetch_output(const struct lp_build_tcs_iface *tes_iface,
                                 LLVMValueRef vertex_index,
                                 boolean is_aindex_indirect,
                                 LLVMValueRef attrib_index,
+                                boolean is_sindex_indirect,
                                 LLVMValueRef swizzle_index,
                                 uint32_t name)
 {
@@ -3141,7 +3148,7 @@ draw_tcs_llvm_emit_fetch_output(const struct lp_build_tcs_iface *tes_iface,
    LLVMValueRef res;
    struct lp_type type = bld->type;
 
-   if (is_vindex_indirect || is_aindex_indirect) {
+   if (is_vindex_indirect || is_aindex_indirect || is_sindex_indirect) {
       int i;
 
       res = bld->zero;
@@ -3149,6 +3156,7 @@ draw_tcs_llvm_emit_fetch_output(const struct lp_build_tcs_iface *tes_iface,
          LLVMValueRef idx = lp_build_const_int32(gallivm, i);
          LLVMValueRef vert_chan_index = vertex_index;
          LLVMValueRef attr_chan_index = attrib_index;
+         LLVMValueRef swiz_chan_index = swizzle_index;
          LLVMValueRef channel_vec;
 
          if (is_vindex_indirect) {
@@ -3159,10 +3167,14 @@ draw_tcs_llvm_emit_fetch_output(const struct lp_build_tcs_iface *tes_iface,
             attr_chan_index = LLVMBuildExtractElement(builder,
                                                       attrib_index, idx, "");
          }
+         if (is_sindex_indirect) {
+            swiz_chan_index = LLVMBuildExtractElement(builder,
+                                                      swizzle_index, idx, "");
+         }
 
          indices[0] = vert_chan_index;
          indices[1] = attr_chan_index;
-         indices[2] = swizzle_index;
+         indices[2] = swiz_chan_index;
 
          channel_vec = LLVMBuildGEP(builder, tcs->output, indices, 3, "");
          channel_vec = LLVMBuildLoad(builder, channel_vec, "");
@@ -3734,6 +3746,7 @@ draw_tes_llvm_fetch_vertex_input(const struct lp_build_tes_iface *tes_iface,
                                  LLVMValueRef vertex_index,
                                  boolean is_aindex_indirect,
                                  LLVMValueRef attrib_index,
+                                 boolean is_sindex_indirect,
                                  LLVMValueRef swizzle_index)
 {
    const struct draw_tes_llvm_iface *tes = draw_tes_llvm_iface(tes_iface);
@@ -3743,7 +3756,7 @@ draw_tes_llvm_fetch_vertex_input(const struct lp_build_tes_iface *tes_iface,
    LLVMValueRef res;
    struct lp_type type = bld->type;
 
-   if (is_vindex_indirect || is_aindex_indirect) {
+   if (is_vindex_indirect || is_aindex_indirect || is_sindex_indirect) {
       int i;
 
       res = bld->zero;
@@ -3752,6 +3765,7 @@ draw_tes_llvm_fetch_vertex_input(const struct lp_build_tes_iface *tes_iface,
          LLVMValueRef idx = lp_build_const_int32(gallivm, i);
          LLVMValueRef vert_chan_index = vertex_index;
          LLVMValueRef attr_chan_index = attrib_index;
+         LLVMValueRef swiz_chan_index = swizzle_index;
          LLVMValueRef channel_vec;
 
          if (is_vindex_indirect) {
@@ -3762,10 +3776,14 @@ draw_tes_llvm_fetch_vertex_input(const struct lp_build_tes_iface *tes_iface,
             attr_chan_index = LLVMBuildExtractElement(builder,
                                                       attrib_index, idx, "");
          }
+         if (is_sindex_indirect) {
+            swiz_chan_index = LLVMBuildExtractElement(builder,
+                                                      swizzle_index, idx, "");
+         }
 
          indices[0] = vert_chan_index;
          indices[1] = attr_chan_index;
-         indices[2] = swizzle_index;
+         indices[2] = swiz_chan_index;
 
          channel_vec = LLVMBuildGEP(builder, tes->input, indices, 3, "");
          channel_vec = LLVMBuildLoad(builder, channel_vec, "");
index ad6df764f6fbee35637ead1d4c4f6589e9e13b99..b83acd0b58fda00a4ca07fef64ed5c917194307d 100644 (file)
@@ -307,15 +307,27 @@ static void emit_load_var(struct lp_build_nir_context *bld_base,
    struct lp_build_nir_soa_context *bld = (struct lp_build_nir_soa_context *)bld_base;
    struct gallivm_state *gallivm = bld_base->base.gallivm;
    int dmul = bit_size == 64 ? 2 : 1;
+   unsigned location = var->data.driver_location;
+   unsigned location_frac = var->data.location_frac;
+
+   if (!var->data.compact && !indir_index)
+      location += const_index;
+   else if (var->data.compact) {
+      location += const_index / 4;
+      location_frac += const_index % 4;
+      const_index = 0;
+   }
    switch (deref_mode) {
    case nir_var_shader_in:
       for (unsigned i = 0; i < num_components; i++) {
-         int idx = (i * dmul) + var->data.location_frac;
+         int idx = (i * dmul) + location_frac;
+
          if (bld->gs_iface) {
             LLVMValueRef vertex_index_val = lp_build_const_int32(gallivm, vertex_index);
-            LLVMValueRef attrib_index_val = lp_build_const_int32(gallivm, const_index + var->data.driver_location);
+            LLVMValueRef attrib_index_val = lp_build_const_int32(gallivm, location);
             LLVMValueRef swizzle_index_val = lp_build_const_int32(gallivm, idx);
             LLVMValueRef result2;
+
             result[i] = bld->gs_iface->fetch_input(bld->gs_iface, &bld_base->base,
                                                    false, vertex_index_val, 0, attrib_index_val, swizzle_index_val);
             if (bit_size == 64) {
@@ -330,10 +342,15 @@ static void emit_load_var(struct lp_build_nir_context *bld_base,
             LLVMValueRef swizzle_index_val = lp_build_const_int32(gallivm, idx);
             LLVMValueRef result2;
 
-            if (indir_index)
-               attrib_index_val = lp_build_add(&bld_base->uint_bld, indir_index, lp_build_const_int_vec(gallivm, bld_base->uint_bld.type, var->data.driver_location));
-            else
-               attrib_index_val = lp_build_const_int32(gallivm, const_index + var->data.driver_location);
+            if (indir_index) {
+               if (var->data.compact) {
+                  swizzle_index_val = lp_build_add(&bld_base->uint_bld, indir_index, lp_build_const_int_vec(gallivm, bld_base->uint_bld.type, idx));
+                  attrib_index_val = lp_build_const_int32(gallivm, location);
+               } else
+                  attrib_index_val = lp_build_add(&bld_base->uint_bld, indir_index, lp_build_const_int_vec(gallivm, bld_base->uint_bld.type, var->data.driver_location));
+            } else
+               attrib_index_val = lp_build_const_int32(gallivm, location);
+
             if (var->data.patch) {
                result[i] = bld->tes_iface->fetch_patch_input(bld->tes_iface, &bld_base->base,
                                                              indir_index ? true : false, attrib_index_val, swizzle_index_val);
@@ -348,13 +365,14 @@ static void emit_load_var(struct lp_build_nir_context *bld_base,
                result[i] = bld->tes_iface->fetch_vertex_input(bld->tes_iface, &bld_base->base,
                                                               indir_vertex_index ? true : false,
                                                               indir_vertex_index ? indir_vertex_index : vertex_index_val,
-                                                              indir_index ? true : false, attrib_index_val, swizzle_index_val);
+                                                              (indir_index && !var->data.compact) ? true : false, attrib_index_val,
+                                                              (indir_index && var->data.compact) ? true : false, swizzle_index_val);
                if (bit_size == 64) {
                   LLVMValueRef swizzle_index_val = lp_build_const_int32(gallivm, idx + 1);
                   result2 = bld->tes_iface->fetch_vertex_input(bld->tes_iface, &bld_base->base,
                                                                indir_vertex_index ? true : false,
                                                                indir_vertex_index ? indir_vertex_index : vertex_index_val,
-                                                               indir_index ? true : false, attrib_index_val, swizzle_index_val);
+                                                               indir_index ? true : false, attrib_index_val, false, swizzle_index_val);
                   result[i] = emit_fetch_64bit(bld_base, result[i], result2);
                }
             }
@@ -363,18 +381,24 @@ static void emit_load_var(struct lp_build_nir_context *bld_base,
             LLVMValueRef attrib_index_val;
             LLVMValueRef swizzle_index_val = lp_build_const_int32(gallivm, idx);
 
-            if (indir_index)
-               attrib_index_val = lp_build_add(&bld_base->uint_bld, indir_index, lp_build_const_int_vec(gallivm, bld_base->uint_bld.type, var->data.driver_location));
-            else
-               attrib_index_val = lp_build_const_int32(gallivm, const_index + var->data.driver_location);
+            if (indir_index) {
+               if (var->data.compact) {
+                  swizzle_index_val = lp_build_add(&bld_base->uint_bld, indir_index, lp_build_const_int_vec(gallivm, bld_base->uint_bld.type, idx));
+                  attrib_index_val = lp_build_const_int32(gallivm, location);
+               } else
+                  attrib_index_val = lp_build_add(&bld_base->uint_bld, indir_index, lp_build_const_int_vec(gallivm, bld_base->uint_bld.type, var->data.driver_location));
+            } else
+               attrib_index_val = lp_build_const_int32(gallivm, location);
             result[i] = bld->tcs_iface->emit_fetch_input(bld->tcs_iface, &bld_base->base,
                                                          indir_vertex_index ? true : false, indir_vertex_index ? indir_vertex_index : vertex_index_val,
-                                                         indir_index ? true : false, attrib_index_val, swizzle_index_val);
+                                                         (indir_index && !var->data.compact) ? true : false, attrib_index_val,
+                                                         (indir_index && var->data.compact) ? true : false, swizzle_index_val);
             if (bit_size == 64) {
                LLVMValueRef swizzle_index_val = lp_build_const_int32(gallivm, idx + 1);
                LLVMValueRef result2 = bld->tcs_iface->emit_fetch_input(bld->tcs_iface, &bld_base->base,
                                                                        indir_vertex_index ? true : false, indir_vertex_index ? indir_vertex_index : vertex_index_val,
-                                                                       indir_index ? true : false, attrib_index_val, swizzle_index_val);
+                                                                       indir_index ? true : false, attrib_index_val,
+                                                                       false, swizzle_index_val);
                result[i] = emit_fetch_64bit(bld_base, result[i], result2);
             }
          } else {
@@ -398,12 +422,12 @@ static void emit_load_var(struct lp_build_nir_context *bld_base,
             } else {
                if (bld->indirects & nir_var_shader_in) {
                   LLVMValueRef lindex = lp_build_const_int32(gallivm,
-                                                             var->data.driver_location * 4 + idx);
+                                                             location * 4 + idx);
                   LLVMValueRef input_ptr = lp_build_pointer_get(gallivm->builder,
                                                              bld->inputs_array, lindex);
                   if (bit_size == 64) {
                      LLVMValueRef lindex2 = lp_build_const_int32(gallivm,
-                                                                 var->data.driver_location * 4 + (idx + 1));
+                                                                 location * 4 + (idx + 1));
                      LLVMValueRef input_ptr2 = lp_build_pointer_get(gallivm->builder,
                                                                     bld->inputs_array, lindex2);
                      result[i] = emit_fetch_64bit(bld_base, input_ptr, input_ptr2);
@@ -413,11 +437,11 @@ static void emit_load_var(struct lp_build_nir_context *bld_base,
                } else {
                   if (bit_size == 64) {
                      LLVMValueRef tmp[2];
-                     tmp[0] = bld->inputs[var->data.driver_location + const_index][idx];
-                     tmp[1] = bld->inputs[var->data.driver_location + const_index][idx + 1];
+                     tmp[0] = bld->inputs[location][idx];
+                     tmp[1] = bld->inputs[location][idx + 1];
                      result[i] = emit_fetch_64bit(bld_base, tmp[0], tmp[1]);
                   } else {
-                     result[i] = bld->inputs[var->data.driver_location + const_index][idx];
+                     result[i] = bld->inputs[location][idx];
                   }
                }
             }
@@ -430,7 +454,7 @@ static void emit_load_var(struct lp_build_nir_context *bld_base,
          return;
       }
       for (unsigned i = 0; i < num_components; i++) {
-         int idx = (i * dmul) + var->data.location_frac;
+         int idx = (i * dmul) + location_frac;
          if (bld->tcs_iface) {
             LLVMValueRef vertex_index_val = lp_build_const_int32(gallivm, vertex_index);
             LLVMValueRef attrib_index_val;
@@ -439,16 +463,18 @@ static void emit_load_var(struct lp_build_nir_context *bld_base,
             if (indir_index)
                attrib_index_val = lp_build_add(&bld_base->uint_bld, indir_index, lp_build_const_int_vec(gallivm, bld_base->uint_bld.type, var->data.driver_location));
             else
-               attrib_index_val = lp_build_const_int32(gallivm, const_index + var->data.driver_location);
+               attrib_index_val = lp_build_const_int32(gallivm, location);
 
             result[i] = bld->tcs_iface->emit_fetch_output(bld->tcs_iface, &bld_base->base,
-                                                         indir_vertex_index ? true : false, indir_vertex_index ? indir_vertex_index : vertex_index_val,
-                                                          indir_index ? true : false, attrib_index_val, swizzle_index_val, 0);
+                                                          indir_vertex_index ? true : false, indir_vertex_index ? indir_vertex_index : vertex_index_val,
+                                                          (indir_index && !var->data.compact) ? true : false, attrib_index_val,
+                                                          (indir_index && var->data.compact) ? true : false, swizzle_index_val, 0);
             if (bit_size == 64) {
                LLVMValueRef swizzle_index_val = lp_build_const_int32(gallivm, idx + 1);
                LLVMValueRef result2 = bld->tcs_iface->emit_fetch_output(bld->tcs_iface, &bld_base->base,
                                                                         indir_vertex_index ? true : false, indir_vertex_index ? indir_vertex_index : vertex_index_val,
-                                                                        indir_index ? true : false, attrib_index_val, swizzle_index_val, 0);
+                                                                        indir_index ? true : false, attrib_index_val,
+                                                                        false, swizzle_index_val, 0);
                result[i] = emit_fetch_64bit(bld_base, result[i], result2);
             }
          }
index 12bf55b3f40b8c3b38116e619c255969b54a1420..d5a01f82c161668e7f8daaed03ac39296d4f15ac 100644 (file)
@@ -470,6 +470,7 @@ struct lp_build_tcs_iface
                                     LLVMValueRef vertex_index,
                                     boolean is_aindex_indirect,
                                     LLVMValueRef attrib_index,
+                                    boolean is_sindex_indirect,
                                     LLVMValueRef swizzle_index);
 
    LLVMValueRef (*emit_fetch_output)(const struct lp_build_tcs_iface *tcs_iface,
@@ -478,6 +479,7 @@ struct lp_build_tcs_iface
                                     LLVMValueRef vertex_index,
                                     boolean is_aindex_indirect,
                                     LLVMValueRef attrib_index,
+                                    boolean is_sindex_indirect,
                                     LLVMValueRef swizzle_index,
                                     uint32_t name);
 };
@@ -490,6 +492,7 @@ struct lp_build_tes_iface
                                       LLVMValueRef vertex_index,
                                       boolean is_aindex_indirect,
                                       LLVMValueRef attrib_index,
+                                      boolean is_sindex_indirect,
                                       LLVMValueRef swizzle_index);
 
    LLVMValueRef (*fetch_patch_input)(const struct lp_build_tes_iface *tes_iface,
index 5104a572c4dc78ba2274817e2cee1af09fef60e9..cbaebca48812eb91feceab48b832f22ee9bd06e6 100644 (file)
@@ -1255,6 +1255,7 @@ emit_fetch_tcs_input(
                                               vertex_index,
                                               reg->Register.Indirect,
                                               attrib_index,
+                                              FALSE,
                                               swizzle_index,
                                               bld_base->info->output_semantic_name[reg->Register.Index]);
    } else {
@@ -1263,6 +1264,7 @@ emit_fetch_tcs_input(
                                              vertex_index,
                                              reg->Register.Indirect,
                                              attrib_index,
+                                             FALSE,
                                              swizzle_index);
    }
 
@@ -1277,6 +1279,7 @@ emit_fetch_tcs_input(
                                                   vertex_index,
                                                   reg->Register.Indirect,
                                                   attrib_index,
+                                                  FALSE,
                                                   swizzle_index,
                                                   bld_base->info->output_semantic_name[reg->Register.Index]);
       } else {
@@ -1285,6 +1288,7 @@ emit_fetch_tcs_input(
                                                  vertex_index,
                                                  reg->Register.Indirect,
                                                  attrib_index,
+                                                 FALSE,
                                                  swizzle_index);
       }
       assert(res2);
@@ -1358,6 +1362,7 @@ emit_fetch_tes_input(
                                        vertex_index,
                                        reg->Register.Indirect,
                                        attrib_index,
+                                       FALSE,
                                        swizzle_index);
    }
 
@@ -1377,6 +1382,7 @@ emit_fetch_tes_input(
                                              vertex_index,
                                              reg->Register.Indirect,
                                              attrib_index,
+                                             FALSE,
                                              swizzle_index);
       }
       assert(res2);
index e5f0074033a88755c7e7aef8c423f16a0ecd3c68..cd1a136d0c936e466a17c64497b62e3a751ae3e9 100644 (file)
@@ -551,6 +551,7 @@ swr_tcs_llvm_fetch_input(const struct lp_build_tcs_iface *tcs_iface,
                          LLVMValueRef vertex_index,
                          boolean is_aindex_indirect,
                          LLVMValueRef attrib_index,
+                         boolean is_sindex_indirect,
                          LLVMValueRef swizzle_index)
 {
     swr_tcs_llvm_iface *iface = (swr_tcs_llvm_iface*)tcs_iface;
@@ -571,6 +572,7 @@ swr_tcs_llvm_fetch_output(const struct lp_build_tcs_iface *tcs_iface,
                           LLVMValueRef vertex_index,
                           boolean is_aindex_indirect,
                           LLVMValueRef attrib_index,
+                          boolean is_sindex_indirect,
                           LLVMValueRef swizzle_index,
                           uint32_t name)
 {
@@ -649,6 +651,7 @@ swr_tes_llvm_fetch_vtx_input(const struct lp_build_tes_iface *tes_iface,
                              LLVMValueRef vertex_index,
                              boolean is_aindex_indirect,
                              LLVMValueRef attrib_index,
+                             boolean is_sindex_indirect,
                              LLVMValueRef swizzle_index)
 {
     swr_tes_llvm_iface *iface = (swr_tes_llvm_iface*)tes_iface;