gallivm/nir: handle non-uniform texture offsets
authorDave Airlie <airlied@redhat.com>
Fri, 10 Apr 2020 04:13:44 +0000 (14:13 +1000)
committerMarge Bot <eric+marge@anholt.net>
Thu, 2 Jul 2020 04:12:17 +0000 (04:12 +0000)
The way we construt vertex/geom shaders means these can
diverge, so we have to just hammer it out manually,
there are likely optimisation opportuniities in here

Signed-off-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3778>

src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c

index 8eb442998b82e28672a0261bf4b7ae491c18bc62..0cabe848529761cc84ec5d1ae47f322825b34b70 100644 (file)
@@ -838,6 +838,16 @@ lp_build_fetch_rgba_soa(struct gallivm_state *gallivm,
       tmp_type = type;
       tmp_type.length = 4;
 
+      if (type.length == 1) {
+         LLVMValueRef fetch = lp_build_fetch_rgba_aos(gallivm, format_desc, tmp_type,
+                                                      aligned, base_ptr, offset,
+                                                      i, j, cache);
+
+         for (k = 0; k < 4; k++)
+            rgba_out[k] = LLVMBuildExtractElement(gallivm->builder, fetch, lp_build_const_int32(gallivm, k), "");
+         return;
+      }
+
       /*
        * Note that vector transpose can be worse compared to insert/extract
        * for aos->soa conversion (for formats with 1 or 2 channels). However,
index 9c8b5221888bf6f6ab27457ffca6aed0dad0513d..6444ae2237fb519ea1bafa684152156ff304ebcf 100644 (file)
@@ -1291,15 +1291,64 @@ static void emit_tex(struct lp_build_nir_context *bld_base,
                      struct lp_sampler_params *params)
 {
    struct lp_build_nir_soa_context *bld = (struct lp_build_nir_soa_context *)bld_base;
+   struct gallivm_state *gallivm = bld_base->base.gallivm;
 
    params->type = bld_base->base.type;
    params->context_ptr = bld->context_ptr;
    params->thread_data_ptr = bld->thread_data_ptr;
 
+   if (params->texture_index_offset && bld_base->shader->info.stage != MESA_SHADER_FRAGMENT) {
+      /* this is horrible but this can be dynamic */
+      LLVMValueRef coords[5];
+      LLVMValueRef *orig_texel_ptr;
+      struct lp_build_context *uint_bld = &bld_base->uint_bld;
+      LLVMValueRef result[4] = { LLVMGetUndef(bld_base->base.vec_type),
+                                 LLVMGetUndef(bld_base->base.vec_type),
+                                 LLVMGetUndef(bld_base->base.vec_type),
+                                 LLVMGetUndef(bld_base->base.vec_type) };
+      LLVMValueRef texel[4], orig_offset;
+      unsigned i;
+      orig_texel_ptr = params->texel;
+
+      for (i = 0; i < 5; i++) {
+         coords[i] = params->coords[i];
+      }
+      orig_offset = params->texture_index_offset;
+
+      for (unsigned v = 0; v < uint_bld->type.length; v++) {
+         LLVMValueRef idx = lp_build_const_int32(gallivm, v);
+         LLVMValueRef new_coords[5];
+         for (i = 0; i < 5; i++) {
+            new_coords[i] = LLVMBuildExtractElement(gallivm->builder,
+                                                    coords[i], idx, "");
+         }
+         params->coords = new_coords;
+         params->texture_index_offset = LLVMBuildExtractElement(gallivm->builder,
+                                                                orig_offset,
+                                                                idx, "");
+         params->type = lp_elem_type(bld_base->base.type);
+
+         params->texel = texel;
+         bld->sampler->emit_tex_sample(bld->sampler,
+                                       gallivm,
+                                       params);
+
+         for (i = 0; i < 4; i++) {
+            result[i] = LLVMBuildInsertElement(gallivm->builder, result[i], texel[i], idx, "");
+         }
+      }
+      for (i = 0; i < 4; i++) {
+         orig_texel_ptr[i] = result[i];
+      }
+      return;
+   }
+
    if (params->texture_index_offset)
       params->texture_index_offset = LLVMBuildExtractElement(bld_base->base.gallivm->builder,
                                                              params->texture_index_offset,
                                                              lp_build_const_int32(bld_base->base.gallivm, 0), "");
+
+   params->type = bld_base->base.type;
    bld->sampler->emit_tex_sample(bld->sampler,
                                  bld->bld_base.base.gallivm,
                                  params);