nir: Separate texture from sampler in nir_tex_instr
authorJason Ekstrand <jason.ekstrand@intel.com>
Tue, 3 Nov 2015 01:58:29 +0000 (17:58 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 9 Feb 2016 23:00:17 +0000 (15:00 -0800)
This commit adds the capability to NIR to support separate textures and
samplers.  As it currently stands, glsl_to_nir only sets the texture deref
and leaves the sampler deref alone as it did before and nir_lower_samplers
assumes this.  Backends can still assume that they are combined and only
look at only at the texture index.  Or, if they wish, they can assume that
they are separate because nir_lower_samplers, tgsi_to_nir, and prog_to_nir
all set both texture and sampler index whenever a sampler is required (the
two indices are the same in this case).

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
14 files changed:
src/compiler/nir/nir.c
src/compiler/nir/nir.h
src/compiler/nir/nir_clone.c
src/compiler/nir/nir_instr_set.c
src/compiler/nir/nir_lower_samplers.c
src/compiler/nir/nir_lower_tex.c
src/compiler/nir/nir_opt_constant_folding.c
src/compiler/nir/nir_print.c
src/compiler/nir/nir_remove_dead_variables.c
src/compiler/nir/nir_validate.c
src/gallium/auxiliary/nir/tgsi_to_nir.c
src/mesa/drivers/dri/i965/brw_fs_nir.cpp
src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
src/mesa/program/prog_to_nir.c

index 6a070f530b2bc402a370b22760358d0adfb9c9d8..df40a554714cdbb7e0d6ba5808c9eee8e31f1823 100644 (file)
@@ -489,6 +489,8 @@ nir_tex_instr_create(nir_shader *shader, unsigned num_srcs)
    instr->texture_index = 0;
    instr->texture_array_size = 0;
    instr->texture = NULL;
+   instr->sampler_index = 0;
+   instr->sampler = NULL;
 
    return instr;
 }
@@ -1012,6 +1014,11 @@ visit_tex_src(nir_tex_instr *instr, nir_foreach_src_cb cb, void *state)
          return false;
    }
 
+   if (instr->sampler != NULL) {
+      if (!visit_deref_src(instr->sampler, cb, state))
+         return false;
+   }
+
    return true;
 }
 
index 48dda99a94913adaf95281262f13a00d2d034bea..8085341b55226a5bbb8900352e8fb247212a2cfc 100644 (file)
@@ -966,6 +966,7 @@ typedef enum {
    nir_tex_src_ddx,
    nir_tex_src_ddy,
    nir_tex_src_texture_offset, /* < dynamically uniform indirect offset */
+   nir_tex_src_sampler_offset, /* < dynamically uniform indirect offset */
    nir_num_tex_src_types
 } nir_tex_src_type;
 
@@ -1025,7 +1026,35 @@ typedef struct {
    /** The size of the texture array or 0 if it's not an array */
    unsigned texture_array_size;
 
-   nir_deref_var *texture; /* if this is NULL, use texture_index instead */
+   /** The texture deref
+    *
+    * If this is null, use texture_index instead.
+    */
+   nir_deref_var *texture;
+
+   /** The sampler index
+    *
+    * The following operations do not require a sampler and, as such, this
+    * field should be ignored:
+    *    - nir_texop_txf
+    *    - nir_texop_txf_ms
+    *    - nir_texop_txs
+    *    - nir_texop_lod
+    *    - nir_texop_tg4
+    *    - nir_texop_query_levels
+    *    - nir_texop_texture_samples
+    *    - nir_texop_samples_identical
+    *
+    * If this texture instruction has a nir_tex_src_sampler_offset source,
+    * then the sampler index is given by sampler_index + sampler_offset.
+    */
+   unsigned sampler_index;
+
+   /** The sampler deref
+    *
+    * If this is null, use sampler_index instead.
+    */
+   nir_deref_var *sampler;
 } nir_tex_instr;
 
 static inline unsigned
index d9c190d35e9cede360b0688469c6d0cee34ddb5c..a666d8ee451e731b07da5cbbe1b07eeb6a1cd964 100644 (file)
@@ -357,10 +357,15 @@ clone_tex(clone_state *state, const nir_tex_instr *tex)
    ntex->is_new_style_shadow = tex->is_new_style_shadow;
    memcpy(ntex->const_offset, tex->const_offset, sizeof(ntex->const_offset));
    ntex->component = tex->component;
+
    ntex->texture_index = tex->texture_index;
-   ntex->texture_array_size = tex->texture_array_size;
    if (tex->texture)
       ntex->texture = clone_deref_var(state, tex->texture, &ntex->instr);
+   ntex->texture_array_size = tex->texture_array_size;
+
+   ntex->sampler_index = tex->sampler_index;
+   if (tex->sampler)
+      ntex->sampler = clone_deref_var(state, tex->sampler, &ntex->instr);
 
    return ntex;
 }
index 4489a881905c142c79c456c20b0a162ecd914663..c3cf2579be7674bb8be37f13e927deff751cca98 100644 (file)
@@ -157,8 +157,9 @@ hash_tex(uint32_t hash, const nir_tex_instr *instr)
    hash = HASH(hash, component);
    hash = HASH(hash, instr->texture_index);
    hash = HASH(hash, instr->texture_array_size);
+   hash = HASH(hash, instr->sampler_index);
 
-   assert(!instr->texture);
+   assert(!instr->texture && !instr->sampler);
 
    return hash;
 }
@@ -306,12 +307,14 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2)
                  sizeof(tex1->const_offset)) != 0 ||
           tex1->component != tex2->component ||
          tex1->texture_index != tex2->texture_index ||
-         tex1->texture_array_size != tex2->texture_array_size) {
+         tex1->texture_array_size != tex2->texture_array_size ||
+         tex1->sampler_index != tex2->sampler_index) {
          return false;
       }
 
-      /* Don't support un-lowered texture derefs currently. */
-      assert(!tex1->texture && !tex2->texture);
+      /* Don't support un-lowered sampler derefs currently. */
+      assert(!tex1->texture && !tex1->sampler &&
+             !tex2->texture && !tex2->sampler);
 
       return true;
    }
@@ -421,8 +424,8 @@ instr_can_rewrite(nir_instr *instr)
    case nir_instr_type_tex: {
       nir_tex_instr *tex = nir_instr_as_tex(instr);
 
-      /* Don't support un-lowered texture derefs currently. */
-      if (tex->texture)
+      /* Don't support un-lowered sampler derefs currently. */
+      if (tex->texture || tex->sampler)
          return false;
 
       return true;
index bccb544dc91216cb02f77c71322fd1a72736ee39..f5d3e596c20317475e83c9fd8210f36715db8e10 100644 (file)
@@ -94,6 +94,9 @@ lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_progr
    if (instr->texture == NULL)
       return;
 
+   /* In GLSL, we only fill out the texture field.  The sampler is inferred */
+   assert(instr->sampler == NULL);
+
    instr->texture_index = 0;
    unsigned location = instr->texture->var->data.location;
    unsigned array_elements = 1;
@@ -106,7 +109,7 @@ lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_progr
    if (indirect) {
       /* First, we have to resize the array of texture sources */
       nir_tex_src *new_srcs = rzalloc_array(instr, nir_tex_src,
-                                            instr->num_srcs + 1);
+                                            instr->num_srcs + 2);
 
       for (unsigned i = 0; i < instr->num_srcs; i++) {
          new_srcs[i].src_type = instr->src[i].src_type;
@@ -126,6 +129,12 @@ lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_progr
                             &instr->src[instr->num_srcs - 1].src,
                             nir_src_for_ssa(indirect));
 
+      instr->src[instr->num_srcs].src_type = nir_tex_src_sampler_offset;
+      instr->num_srcs++;
+      nir_instr_rewrite_src(&instr->instr,
+                            &instr->src[instr->num_srcs - 1].src,
+                            nir_src_for_ssa(indirect));
+
       instr->texture_array_size = array_elements;
    }
 
@@ -138,6 +147,8 @@ lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_progr
    instr->texture_index +=
       shader_program->UniformStorage[location].opaque[stage].index;
 
+   instr->sampler_index = instr->texture_index;
+
    instr->texture = NULL;
 }
 
index 4c0759b8788f99f3a866e8bf47bfd4c7e1c68d0f..806acd8333c46fb0b6800f89ab6558bf30844131 100644 (file)
@@ -291,11 +291,11 @@ nir_lower_tex_block(nir_block *block, void *void_state)
       /* mask of src coords to saturate (clamp): */
       unsigned sat_mask = 0;
 
-      if ((1 << tex->texture_index) & state->options->saturate_r)
+      if ((1 << tex->sampler_index) & state->options->saturate_r)
          sat_mask |= (1 << 2);    /* .z */
-      if ((1 << tex->texture_index) & state->options->saturate_t)
+      if ((1 << tex->sampler_index) & state->options->saturate_t)
          sat_mask |= (1 << 1);    /* .y */
-      if ((1 << tex->texture_index) & state->options->saturate_s)
+      if ((1 << tex->sampler_index) & state->options->saturate_s)
          sat_mask |= (1 << 0);    /* .x */
 
       /* If we are clamping any coords, we must lower projector first
index 20b31a8110cd4298e9efebfbea32c5242e4e8272..04876a42fd72b67498039bb9f48e6c646b566362 100644 (file)
@@ -136,10 +136,15 @@ constant_fold_intrinsic_instr(nir_intrinsic_instr *instr)
 static bool
 constant_fold_tex_instr(nir_tex_instr *instr)
 {
+   bool progress = false;
+
    if (instr->texture)
-      return constant_fold_deref(&instr->instr, instr->texture);
-   else
-      return false;
+      progress |= constant_fold_deref(&instr->instr, instr->texture);
+
+   if (instr->sampler)
+      progress |= constant_fold_deref(&instr->instr, instr->sampler);
+
+   return progress;
 }
 
 static bool
index 5e7ae820968775de77b1c53a1832c8d9bcbd7b9c..d9d75c2e8dfb33ed18c81ca694b6ce9d48b4da96 100644 (file)
@@ -625,6 +625,9 @@ print_tex_instr(nir_tex_instr *instr, print_state *state)
       case nir_tex_src_texture_offset:
          fprintf(fp, "(texture_offset)");
          break;
+      case nir_tex_src_sampler_offset:
+         fprintf(fp, "(sampler_offset)");
+         break;
 
       default:
          unreachable("Invalid texture source type");
@@ -654,11 +657,16 @@ print_tex_instr(nir_tex_instr *instr, print_state *state)
 
    if (instr->texture) {
       print_deref(instr->texture, state);
+      fprintf(fp, " (texture)");
+      if (instr->sampler) {
+         print_deref(instr->sampler, state);
+         fprintf(fp, " (sampler)");
+      }
    } else {
-      fprintf(fp, "%u", instr->texture_index);
+      assert(instr->sampler == NULL);
+      fprintf(fp, "%u (texture) %u (sampler)",
+              instr->texture_index, instr->sampler_index);
    }
-
-   fprintf(fp, " (texture)");
 }
 
 static void
index 24bae46c7fc19aed11aafb63e239e451d2ae22a7..65192682d3c8e61954888631c3a1580e4faeca35 100644 (file)
@@ -58,6 +58,11 @@ add_var_use_tex(nir_tex_instr *instr, struct set *live)
       nir_variable *var = instr->texture->var;
       _mesa_set_add(live, var);
    }
+
+   if (instr->sampler != NULL) {
+      nir_variable *var = instr->sampler->var;
+      _mesa_set_add(live, var);
+   }
 }
 
 static bool
index 2fadff7869e7d9c90824f7df490e65253ad3931c..d1a90485e7ecfda1c03162cbf9edd72d96d27b1f 100644 (file)
@@ -448,6 +448,9 @@ validate_tex_instr(nir_tex_instr *instr, validate_state *state)
    if (instr->texture != NULL)
       validate_deref_var(instr, instr->texture, state);
 
+   if (instr->sampler != NULL)
+      validate_deref_var(instr, instr->sampler, state);
+
    validate_dest(&instr->dest, state);
 }
 
index 8cd8ea4cb66c8fa387fd87278aa1c42b6b553dae..b71917618c1923844401c61b227ce29f3522f30a 100644 (file)
@@ -1310,6 +1310,7 @@ ttn_tex(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
 
    assert(tgsi_inst->Src[samp].Register.File == TGSI_FILE_SAMPLER);
    instr->texture_index = tgsi_inst->Src[samp].Register.Index;
+   instr->sampler_index = tgsi_inst->Src[samp].Register.Index;
 
    /* TODO if we supported any opc's which take an explicit SVIEW
     * src, we would use that here instead.  But for the "legacy"
index ecca3ef718341a884fff535cadb41745294c5758..1a2c39f4b35154c7094964d2f62dab3e32f3f407 100644 (file)
@@ -3024,6 +3024,9 @@ fs_visitor::nir_emit_texture(const fs_builder &bld, nir_tex_instr *instr)
          break;
       }
 
+      case nir_tex_src_sampler_offset:
+         break; /* Ignored for now */
+
       default:
          unreachable("unknown texture source");
       }
index 40a7530d940e2efef0a18d0d8ae458366cbd7c4f..41d20ff0d13512767cafb53ecf233f8369bb0301 100644 (file)
@@ -1738,6 +1738,9 @@ vec4_visitor::nir_emit_texture(nir_tex_instr *instr)
          break;
       }
 
+      case nir_tex_src_sampler_offset:
+         break; /* Ignored for now */
+
       case nir_tex_src_projector:
          unreachable("Should be lowered by do_lower_texture_projection");
 
index 93a167e0aa1311ca6c07ae85bf1cfdab33a956c3..74cbbfb1cc6f1126cd5cfbfba52c54a3dae759dd 100644 (file)
@@ -610,6 +610,7 @@ ptn_tex(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src,
    instr->dest_type = nir_type_float;
    instr->is_shadow = prog_inst->TexShadow;
    instr->texture_index = prog_inst->TexSrcUnit;
+   instr->sampler_index = prog_inst->TexSrcUnit;
 
    switch (prog_inst->TexSrcTarget) {
    case TEXTURE_1D_INDEX: