[Mesa-dev] [RFC PATCH] nir: add support for tg4 with multiple offsets

Karol Herbst kherbst at redhat.com
Tue Feb 27 12:54:09 UTC 2018


Just want quick feedback on this. Nouveau can make use of it, which would
eliminate the need of having 4 seperate tg4 instructions.

The current code runs into the assert when PIPE_CAP_TEXTURE_GATHER_OFFSETS is
enabled.

Signed-off-by: Karol Herbst <kherbst at redhat.com>
---
 src/compiler/glsl/glsl_to_nir.cpp                  | 25 ++++++++++++++++------
 src/compiler/nir/nir.h                             |  9 +++++++-
 src/compiler/nir/nir_print.c                       |  9 ++++++++
 .../drivers/nouveau/codegen/nv50_ir_from_nir.cpp   | 15 ++++++++++---
 4 files changed, 47 insertions(+), 11 deletions(-)

diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp
index 7a9d15015e..a4a7526aa5 100644
--- a/src/compiler/glsl/glsl_to_nir.cpp
+++ b/src/compiler/glsl/glsl_to_nir.cpp
@@ -2038,7 +2038,9 @@ nir_visitor::visit(ir_texture *ir)
       num_srcs++;
    if (ir->shadow_comparator != NULL)
       num_srcs++;
-   if (ir->offset != NULL)
+   if (ir->offset != NULL && ir->offset->type->is_array())
+      num_srcs += ir->offset->type->array_size();
+   else if (ir->offset != NULL)
       num_srcs++;
 
    nir_tex_instr *instr = nir_tex_instr_create(this->shader, num_srcs);
@@ -2093,12 +2095,21 @@ nir_visitor::visit(ir_texture *ir)
 
    if (ir->offset != NULL) {
       /* we don't support multiple offsets yet */
-      assert(ir->offset->type->is_vector() || ir->offset->type->is_scalar());
-
-      instr->src[src_number].src =
-         nir_src_for_ssa(evaluate_rvalue(ir->offset));
-      instr->src[src_number].src_type = nir_tex_src_offset;
-      src_number++;
+      if (ir->offset->type->is_vector() || ir->offset->type->is_scalar()) {
+         instr->src[src_number].src =
+            nir_src_for_ssa(evaluate_rvalue(ir->offset));
+         instr->src[src_number].src_type = nir_tex_src_offset;
+         src_number++;
+      } else if (ir->offset->type->is_array()) {
+         for (int i = 0; i < ir->offset->type->array_size(); i++) {
+            instr->src[src_number].src =
+               nir_src_for_ssa(evaluate_rvalue(ir->offset->as_constant()->get_array_element(i)->as_rvalue()));
+            instr->src[src_number].src_type = (nir_tex_src_type)(nir_tex_src_offset + i);
+            src_number++;
+         }
+      } else {
+         assert(false);
+      }
    }
 
    switch (ir->op) {
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 2acd9511f5..bc83573b90 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -1162,6 +1162,9 @@ typedef enum {
    nir_tex_src_projector,
    nir_tex_src_comparator, /* shadow comparator */
    nir_tex_src_offset,
+   nir_tex_src_offset1,
+   nir_tex_src_offset2,
+   nir_tex_src_offset3,
    nir_tex_src_bias,
    nir_tex_src_lod,
    nir_tex_src_ms_index, /* MSAA sample index */
@@ -1364,6 +1367,9 @@ nir_tex_instr_src_type(const nir_tex_instr *instr, unsigned src)
       return nir_type_float;
 
    case nir_tex_src_offset:
+   case nir_tex_src_offset1:
+   case nir_tex_src_offset2:
+   case nir_tex_src_offset3:
    case nir_tex_src_ms_index:
    case nir_tex_src_texture_offset:
    case nir_tex_src_sampler_offset:
@@ -1395,7 +1401,8 @@ nir_tex_instr_src_size(const nir_tex_instr *instr, unsigned src)
    /* Usual APIs don't allow cube + offset, but we allow it, with 2 coords for
     * the offset, since a cube maps to a single face.
     */
-   if (instr->src[src].src_type == nir_tex_src_offset) {
+   if (instr->src[src].src_type >= nir_tex_src_offset &&
+       instr->src[src].src_type <= nir_tex_src_offset3) {
       if (instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE)
          return 2;
       else if (instr->is_array)
diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c
index fcc8025346..e4736e38a7 100644
--- a/src/compiler/nir/nir_print.c
+++ b/src/compiler/nir/nir_print.c
@@ -744,6 +744,15 @@ print_tex_instr(nir_tex_instr *instr, print_state *state)
       case nir_tex_src_offset:
          fprintf(fp, "(offset)");
          break;
+      case nir_tex_src_offset1:
+         fprintf(fp, "(offset1)");
+         break;
+      case nir_tex_src_offset2:
+         fprintf(fp, "(offset2)");
+         break;
+      case nir_tex_src_offset3:
+         fprintf(fp, "(offset3)");
+         break;
       case nir_tex_src_bias:
          fprintf(fp, "(bias)");
          break;
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp
index d877a73054..bc762c2610 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp
@@ -2697,7 +2697,10 @@ Converter::visit(nir_tex_instr *insn)
       int ddyIdx = nir_tex_instr_src_index(insn, nir_tex_src_ddy);
       int msIdx = nir_tex_instr_src_index(insn, nir_tex_src_ms_index);
       int lodIdx = nir_tex_instr_src_index(insn, nir_tex_src_lod);
-      int offsetIdx = nir_tex_instr_src_index(insn, nir_tex_src_offset);
+      int offsetIdx0 = nir_tex_instr_src_index(insn, nir_tex_src_offset);
+      int offsetIdx1 = nir_tex_instr_src_index(insn, nir_tex_src_offset1);
+      int offsetIdx2 = nir_tex_instr_src_index(insn, nir_tex_src_offset2);
+      int offsetIdx3 = nir_tex_instr_src_index(insn, nir_tex_src_offset3);
       int projIdx = nir_tex_instr_src_index(insn, nir_tex_src_projector);
       int sampOffIdx = nir_tex_instr_src_index(insn, nir_tex_src_sampler_offset);
       int texOffIdx = nir_tex_instr_src_index(insn, nir_tex_src_texture_offset);
@@ -2730,8 +2733,14 @@ Converter::visit(nir_tex_instr *insn)
          srcs.push_back(getSrc(&insn->src[lodIdx].src, 0));
       if (msIdx != -1)
          srcs.push_back(getSrc(&insn->src[msIdx].src, 0));
-      if (offsetIdx != -1)
-         offsets.push_back(&insn->src[offsetIdx].src);
+      if (offsetIdx0 != -1)
+         offsets.push_back(&insn->src[offsetIdx0].src);
+      if (offsetIdx1 != -1)
+         offsets.push_back(&insn->src[offsetIdx1].src);
+      if (offsetIdx2 != -1)
+         offsets.push_back(&insn->src[offsetIdx2].src);
+      if (offsetIdx3 != -1)
+         offsets.push_back(&insn->src[offsetIdx3].src);
       if (compIdx != -1)
          srcs.push_back(applyProjection(getSrc(&insn->src[compIdx].src, 0), proj));
       if (texOffIdx != -1) {
-- 
2.14.3



More information about the mesa-dev mailing list