Here brw_setup_vue_interpolation() is rewritten not to use the InterpQualifier
array in gl_fragment_program which allows us to remove it.

This change also makes the code which is only used by gen4/5 more self contained
as it now has its own gen5_fragment_program struct rather than storing the map
in brw_context. This means the interpolation map will only get processed once
and will get stored in the in memory cache rather than being processed everytime
the fs changes.

Also by calling this from the fs compile code rather than from the upload code
and using the interpolation assigned there we can get rid of the
BRW_NEW_INTERPOLATION_MAP flag.

It might not seem ideal to add a gen5_fragment_program struct however by the end
of this series we will have gotten rid of all the brw_{shader_stage}_program
structs and replaced them with a generic brw_program struct so there will only
be two program structs which is better than what we have now.
---
 src/compiler/glsl/ir_set_program_inouts.cpp       |  7 +-
 src/intel/blorp/blorp.c                           |  6 +-
 src/intel/vulkan/anv_pipeline.c                   |  2 +-
 src/mesa/drivers/dri/i965/brw_clip.c              | 19 ++---
 src/mesa/drivers/dri/i965/brw_clip.h              |  7 +-
 src/mesa/drivers/dri/i965/brw_clip_line.c         |  2 +-
 src/mesa/drivers/dri/i965/brw_clip_tri.c          |  2 +-
 src/mesa/drivers/dri/i965/brw_clip_unfilled.c     |  2 +-
 src/mesa/drivers/dri/i965/brw_clip_util.c         | 10 +--
 src/mesa/drivers/dri/i965/brw_compiler.h          |  8 ++-
 src/mesa/drivers/dri/i965/brw_context.h           | 47 ++++---------
 src/mesa/drivers/dri/i965/brw_fs.cpp              |  4 +-
 src/mesa/drivers/dri/i965/brw_interpolation_map.c | 85 +++++++++++------------
 src/mesa/drivers/dri/i965/brw_nir.c               |  7 +-
 src/mesa/drivers/dri/i965/brw_nir.h               |  3 +-
 src/mesa/drivers/dri/i965/brw_program.c           | 10 ++-
 src/mesa/drivers/dri/i965/brw_sf.c                | 14 ++--
 src/mesa/drivers/dri/i965/brw_sf.h                |  4 +-
 src/mesa/drivers/dri/i965/brw_sf_emit.c           | 12 ++--
 src/mesa/drivers/dri/i965/brw_state.h             |  4 +-
 src/mesa/drivers/dri/i965/brw_state_upload.c      |  6 +-
 src/mesa/drivers/dri/i965/brw_wm.c                | 18 +++--
 src/mesa/drivers/dri/i965/brw_wm.h                |  3 +-
 src/mesa/main/mtypes.h                            |  7 --
 24 files changed, 145 insertions(+), 144 deletions(-)

diff --git a/src/compiler/glsl/ir_set_program_inouts.cpp 
b/src/compiler/glsl/ir_set_program_inouts.cpp
index f5b36df..baa52b1 100644
--- a/src/compiler/glsl/ir_set_program_inouts.cpp
+++ b/src/compiler/glsl/ir_set_program_inouts.cpp
@@ -26,8 +26,8 @@
  *
  * Sets the InputsRead and OutputsWritten of Mesa programs.
  *
- * Additionally, for fragment shaders, sets the InterpQualifier array, and the
- * IsCentroid and IsSample bitfields.
+ * Additionally, for fragment shaders, sets the IsCentroid and IsSample
+ * bitfields.
  *
  * Mesa programs (gl_program, not gl_shader_program) have a set of
  * flags indicating which varyings are read and written.  Computing
@@ -125,8 +125,6 @@ mark(struct gl_program *prog, ir_variable *var, int offset, 
int len,
 
          if (stage == MESA_SHADER_FRAGMENT) {
             gl_fragment_program *fprog = (gl_fragment_program *) prog;
-            fprog->InterpQualifier[idx] =
-               (glsl_interp_mode) var->data.interpolation;
             if (var->data.centroid)
                fprog->IsCentroid |= bitfield;
             if (var->data.sample)
@@ -445,7 +443,6 @@ do_set_program_inouts(exec_list *instructions, struct 
gl_program *prog,
    prog->SystemValuesRead = 0;
    if (shader_stage == MESA_SHADER_FRAGMENT) {
       gl_fragment_program *fprog = (gl_fragment_program *) prog;
-      memset(fprog->InterpQualifier, 0, sizeof(fprog->InterpQualifier));
       fprog->IsCentroid = 0;
       fprog->IsSample = 0;
       fprog->UsesKill = false;
diff --git a/src/intel/blorp/blorp.c b/src/intel/blorp/blorp.c
index 5209ee2..8905cfa 100644
--- a/src/intel/blorp/blorp.c
+++ b/src/intel/blorp/blorp.c
@@ -211,9 +211,9 @@ brw_blorp_compile_nir_shader(struct blorp_context *blorp, 
struct nir_shader *nir
    nir_lower_io(nir, nir_var_uniform, nir_uniform_type_size, 0);
 
    const unsigned *program =
-      brw_compile_fs(compiler, blorp->driver_ctx, mem_ctx,
-                     wm_key, &wm_prog_data, nir,
-                     NULL, -1, -1, false, use_repclear, program_size, NULL);
+      brw_compile_fs(compiler, blorp->driver_ctx, mem_ctx, wm_key,
+                     &wm_prog_data, nir, NULL, -1, -1, false, use_repclear,
+                     NULL, program_size, NULL);
 
    /* Copy the relavent bits of wm_prog_data over into the blorp prog data */
    prog_data->dispatch_8 = wm_prog_data.dispatch_8;
diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c
index 45cc3ae..72ad25a 100644
--- a/src/intel/vulkan/anv_pipeline.c
+++ b/src/intel/vulkan/anv_pipeline.c
@@ -678,7 +678,7 @@ anv_pipeline_compile_fs(struct anv_pipeline *pipeline,
       unsigned code_size;
       const unsigned *shader_code =
          brw_compile_fs(compiler, NULL, mem_ctx, &key, &prog_data, nir,
-                        NULL, -1, -1, true, false, &code_size, NULL);
+                        NULL, -1, -1, true, false, NULL, &code_size, NULL);
       if (shader_code == NULL) {
          ralloc_free(mem_ctx);
          return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
diff --git a/src/mesa/drivers/dri/i965/brw_clip.c 
b/src/mesa/drivers/dri/i965/brw_clip.c
index 1134fa4..06650b6 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.c
+++ b/src/mesa/drivers/dri/i965/brw_clip.c
@@ -68,11 +68,6 @@ static void compile_clip_prog( struct brw_context *brw,
    c.key = *key;
    c.vue_map = brw->vue_map_geom_out;
 
-   c.has_flat_shading =
-      brw_any_flat_varyings(&key->interpolation_mode);
-   c.has_noperspective_shading =
-      brw_any_noperspective_varyings(&key->interpolation_mode);
-
    /* nr_regs is the number of registers filled by reading data from the VUE.
     * This program accesses the entire VUE, so nr_regs needs to be the size of
     * the VUE (measured in pairs, since two slots are stored in each
@@ -144,7 +139,7 @@ brw_upload_clip_prog(struct brw_context *brw)
                         _NEW_POLYGON |
                         _NEW_TRANSFORM,
                         BRW_NEW_BLORP |
-                        BRW_NEW_INTERPOLATION_MAP |
+                        BRW_NEW_FRAGMENT_PROGRAM |
                         BRW_NEW_REDUCED_PRIMITIVE |
                         BRW_NEW_VUE_MAP_GEOM_OUT))
       return;
@@ -154,8 +149,16 @@ brw_upload_clip_prog(struct brw_context *brw)
    /* Populate the key:
     */
 
-   /* BRW_NEW_INTERPOLATION_MAP */
-   key.interpolation_mode = brw->interpolation_mode;
+   const struct gl_fragment_program *fprog = brw->fragment_program;
+   if (fprog) {
+      assert(brw->gen < 6);
+      struct gen5_fragment_program *p = (struct gen5_fragment_program *) fprog;
+
+      /* BRW_NEW_FRAGMENT_PROGRAM */
+      key.contains_flat_varying = p->contains_flat_varying;
+      key.contains_noperspective_varying = p->contains_noperspective_varying;
+      key.interp_mode = p->interp_mode;
+   }
 
    /* BRW_NEW_REDUCED_PRIMITIVE */
    key.primitive = brw->reduced_primitive;
diff --git a/src/mesa/drivers/dri/i965/brw_clip.h 
b/src/mesa/drivers/dri/i965/brw_clip.h
index 54c7682..355ae64 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.h
+++ b/src/mesa/drivers/dri/i965/brw_clip.h
@@ -47,7 +47,9 @@
  */
 struct brw_clip_prog_key {
    GLbitfield64 attrs;
-   struct interpolation_mode_map interpolation_mode;
+   bool contains_flat_varying;
+   bool contains_noperspective_varying;
+   unsigned char *interp_mode;
    GLuint primitive:4;
    GLuint nr_userclip:4;
    GLuint pv_first:1;
@@ -128,9 +130,6 @@ struct brw_clip_compile {
    bool need_direction;
 
    struct brw_vue_map vue_map;
-
-   bool has_flat_shading;
-   bool has_noperspective_shading;
 };
 
 /**
diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c 
b/src/mesa/drivers/dri/i965/brw_clip_line.c
index 2c7f85a..f9cabd2 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_line.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_line.c
@@ -302,7 +302,7 @@ void brw_emit_line_clip( struct brw_clip_compile *c )
    brw_clip_line_alloc_regs(c);
    brw_clip_init_ff_sync(c);
 
-   if (c->has_flat_shading) {
+   if (c->key.contains_flat_varying) {
       if (c->key.pv_first)
          brw_clip_copy_flatshaded_attributes(c, 1, 0);
       else
diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c 
b/src/mesa/drivers/dri/i965/brw_clip_tri.c
index 4caa8f5..52402e3 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_tri.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c
@@ -650,7 +650,7 @@ void brw_emit_tri_clip( struct brw_clip_compile *c )
     * flatshading, need to apply the flatshade here because we don't
     * respect the PV when converting to trifan for emit:
     */
-   if (c->has_flat_shading)
+   if (c->key.contains_flat_varying)
       brw_clip_tri_flat_shade(c);
 
    if ((c->key.clip_mode == BRW_CLIPMODE_NORMAL) ||
diff --git a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c 
b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c
index d333d10..7c06857 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c
@@ -519,7 +519,7 @@ void brw_emit_unfilled_clip( struct brw_clip_compile *c )
 
    /* Need to do this whether we clip or not:
     */
-   if (c->has_flat_shading)
+   if (c->key.contains_flat_varying)
       brw_clip_tri_flat_shade(c);
 
    brw_clip_init_clipmask(c);
diff --git a/src/mesa/drivers/dri/i965/brw_clip_util.c 
b/src/mesa/drivers/dri/i965/brw_clip_util.c
index f5d0a5a..4f1b0fd 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_util.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_util.c
@@ -157,7 +157,7 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
     */
 
    /* Take a copy of the v0 NDC coordinates, in case dest == v0. */
-   if (c->has_noperspective_shading) {
+   if (c->key.contains_noperspective_varying) {
       GLuint offset = brw_varying_to_offset(&c->vue_map,
                                                  BRW_VARYING_SLOT_NDC);
       v0_ndc_copy = get_tmp(c);
@@ -183,7 +183,7 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
    /* If we have noperspective attributes,
     * we need to compute the screen-space t
     */
-   if (c->has_noperspective_shading) {
+   if (c->key.contains_noperspective_varying) {
       GLuint delta = brw_varying_to_offset(&c->vue_map,
                                                 BRW_VARYING_SLOT_NDC);
       struct brw_reg tmp = get_tmp(c);
@@ -272,7 +272,7 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
           * Unless the attribute is flat shaded -- in which case just copy
           * from one of the sources (doesn't matter which; already copied from 
pv)
          */
-         GLuint interp = c->key.interpolation_mode.mode[slot];
+         GLuint interp = c->key.interp_mode[slot];
 
          if (interp != INTERP_MODE_FLAT) {
             struct brw_reg tmp = get_tmp(c);
@@ -310,7 +310,7 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
       brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0));
    }
 
-   if (c->has_noperspective_shading)
+   if (c->key.contains_noperspective_varying)
       release_tmp(c, t_nopersp);
 }
 
@@ -406,7 +406,7 @@ void brw_clip_copy_flatshaded_attributes( struct 
brw_clip_compile *c,
    struct brw_codegen *p = &c->func;
 
    for (int i = 0; i < c->vue_map.num_slots; i++) {
-      if (c->key.interpolation_mode.mode[i] == INTERP_MODE_FLAT) {
+      if (c->key.interp_mode[i] == INTERP_MODE_FLAT) {
          brw_MOV(p,
                  byte_offset(c->reg.vertex[to], brw_vue_slot_to_offset(i)),
                  byte_offset(c->reg.vertex[from], brw_vue_slot_to_offset(i)));
diff --git a/src/mesa/drivers/dri/i965/brw_compiler.h 
b/src/mesa/drivers/dri/i965/brw_compiler.h
index 447d05b..772c11e 100644
--- a/src/mesa/drivers/dri/i965/brw_compiler.h
+++ b/src/mesa/drivers/dri/i965/brw_compiler.h
@@ -575,6 +575,12 @@ void brw_compute_tess_vue_map(struct brw_vue_map *const 
vue_map,
                               const GLbitfield64 slots_valid,
                               const GLbitfield is_patch);
 
+/* brw_interpolation_map.c */
+void brw_setup_vue_interpolation(struct brw_vue_map *vue_map,
+                                 struct nir_shader *nir,
+                                 struct gl_program *prog,
+                                 const struct gen_device_info *devinfo);
+
 enum shader_dispatch_mode {
    DISPATCH_MODE_4X1_SINGLE = 0,
    DISPATCH_MODE_4X2_DUAL_INSTANCE = 1,
@@ -834,7 +840,7 @@ brw_compile_fs(const struct brw_compiler *compiler, void 
*log_data,
                int shader_time_index8,
                int shader_time_index16,
                bool allow_spilling,
-               bool use_rep_send,
+               bool use_rep_send, struct brw_vue_map *vue_map,
                unsigned *final_assembly_size,
                char **error_str);
 
diff --git a/src/mesa/drivers/dri/i965/brw_context.h 
b/src/mesa/drivers/dri/i965/brw_context.h
index e190d53..519c198 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -211,7 +211,6 @@ enum brw_state_id {
    BRW_STATE_ATOMIC_BUFFER,
    BRW_STATE_IMAGE_UNITS,
    BRW_STATE_META_IN_PROGRESS,
-   BRW_STATE_INTERPOLATION_MAP,
    BRW_STATE_PUSH_CONSTANT_ALLOCATION,
    BRW_STATE_NUM_SAMPLES,
    BRW_STATE_TEXTURE_BUFFER,
@@ -303,7 +302,6 @@ enum brw_state_id {
 #define BRW_NEW_ATOMIC_BUFFER           (1ull << BRW_STATE_ATOMIC_BUFFER)
 #define BRW_NEW_IMAGE_UNITS             (1ull << BRW_STATE_IMAGE_UNITS)
 #define BRW_NEW_META_IN_PROGRESS        (1ull << BRW_STATE_META_IN_PROGRESS)
-#define BRW_NEW_INTERPOLATION_MAP       (1ull << BRW_STATE_INTERPOLATION_MAP)
 #define BRW_NEW_PUSH_CONSTANT_ALLOCATION (1ull << 
BRW_STATE_PUSH_CONSTANT_ALLOCATION)
 #define BRW_NEW_NUM_SAMPLES             (1ull << BRW_STATE_NUM_SAMPLES)
 #define BRW_NEW_TEXTURE_BUFFER          (1ull << BRW_STATE_TEXTURE_BUFFER)
@@ -363,6 +361,20 @@ struct brw_fragment_program {
 };
 
 
+struct gen5_fragment_program {
+   struct brw_fragment_program base;
+
+   bool contains_flat_varying;
+   bool contains_noperspective_varying;
+
+   /*
+    * Mapping of varying slots to interpolation modes.
+    * Used Gen4/5 by the clip|sf|wm stages.
+    */
+   unsigned char interp_mode[BRW_VARYING_SLOT_COUNT];
+};
+
+
 /** Subclass of Mesa compute program */
 struct brw_compute_program {
    struct gl_program program;
@@ -385,32 +397,6 @@ struct brw_shader {
     ~VARYING_BIT_POS & ~VARYING_BIT_FACE)
 
 
-/*
- * Mapping of VUE map slots to interpolation modes.
- */
-struct interpolation_mode_map {
-   unsigned char mode[BRW_VARYING_SLOT_COUNT];
-};
-
-static inline bool brw_any_flat_varyings(struct interpolation_mode_map *map)
-{
-   for (int i = 0; i < BRW_VARYING_SLOT_COUNT; i++)
-      if (map->mode[i] == INTERP_MODE_FLAT)
-         return true;
-
-   return false;
-}
-
-static inline bool brw_any_noperspective_varyings(struct 
interpolation_mode_map *map)
-{
-   for (int i = 0; i < BRW_VARYING_SLOT_COUNT; i++)
-      if (map->mode[i] == INTERP_MODE_NOPERSPECTIVE)
-         return true;
-
-   return false;
-}
-
-
 struct brw_sf_prog_data {
    GLuint urb_read_length;
    GLuint total_grf;
@@ -1273,11 +1259,6 @@ struct brw_context
    uint32_t render_target_format[MESA_FORMAT_COUNT];
    bool format_supported_as_render_target[MESA_FORMAT_COUNT];
 
-   /* Interpolation modes, one byte per vue slot.
-    * Used Gen4/5 by the clip|sf|wm stages. Ignored on Gen6+.
-    */
-   struct interpolation_mode_map interpolation_mode;
-
    /* PrimitiveRestart */
    struct {
       bool in_progress;
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp 
b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 1a22fb4..3e0d057 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -6422,14 +6422,14 @@ brw_compile_fs(const struct brw_compiler *compiler, 
void *log_data,
                struct gl_program *prog,
                int shader_time_index8, int shader_time_index16,
                bool allow_spilling,
-               bool use_rep_send,
+               bool use_rep_send, struct brw_vue_map *vue_map,
                unsigned *final_assembly_size,
                char **error_str)
 {
    nir_shader *shader = nir_shader_clone(mem_ctx, src_shader);
    shader = brw_nir_apply_sampler_key(shader, compiler->devinfo, &key->tex,
                                       true);
-   brw_nir_lower_fs_inputs(shader, compiler->devinfo, key);
+   brw_nir_lower_fs_inputs(shader, vue_map, prog, compiler->devinfo, key);
    brw_nir_lower_fs_outputs(shader);
    if (!key->multisample_fbo)
       NIR_PASS_V(shader, demote_sample_qualifiers);
diff --git a/src/mesa/drivers/dri/i965/brw_interpolation_map.c 
b/src/mesa/drivers/dri/i965/brw_interpolation_map.c
index 097987b..cb4deb5 100644
--- a/src/mesa/drivers/dri/i965/brw_interpolation_map.c
+++ b/src/mesa/drivers/dri/i965/brw_interpolation_map.c
@@ -21,7 +21,8 @@
  * IN THE SOFTWARE.
  */
 
-#include "brw_state.h"
+#include "brw_compiler.h"
+#include "brw_context.h"
 #include "compiler/nir/nir.h"
 
 static char const *get_qual_name(int mode)
@@ -38,58 +39,52 @@ static char const *get_qual_name(int mode)
 
 /* Set up interpolation modes for every element in the VUE */
 void
-brw_setup_vue_interpolation(struct brw_context *brw)
+brw_setup_vue_interpolation(struct brw_vue_map *vue_map, nir_shader *nir,
+                            struct gl_program *prog,
+                            const struct gen_device_info *devinfo)
 {
-   const struct gl_fragment_program *fprog = brw->fragment_program;
-   struct brw_vue_map *vue_map = &brw->vue_map_geom_out;
+   struct gen5_fragment_program *fprog = (struct gen5_fragment_program *) prog;
 
-   if (!brw_state_dirty(brw,
-                        _NEW_LIGHT,
-                        BRW_NEW_BLORP |
-                        BRW_NEW_FRAGMENT_PROGRAM |
-                        BRW_NEW_VUE_MAP_GEOM_OUT))
-      return;
-
-   memset(&brw->interpolation_mode, INTERP_MODE_NONE, 
sizeof(brw->interpolation_mode));
-
-   brw->ctx.NewDriverState |= BRW_NEW_INTERPOLATION_MAP;
+   memset(fprog->interp_mode, INTERP_MODE_NONE, sizeof(fprog->interp_mode));
 
-   if (!fprog)
+   if (!vue_map)
       return;
 
-   for (int i = 0; i < vue_map->num_slots; i++) {
-      int varying = vue_map->slot_to_varying[i];
-      if (varying == -1)
-         continue;
+   /* HPOS always wants noperspective. setting it up here allows
+    * us to not need special handling in the SF program.
+    */
+   unsigned pos_slot = vue_map->varying_to_slot[VARYING_SLOT_POS];
+   if (pos_slot != -1) {;
+      fprog->interp_mode[pos_slot] = INTERP_MODE_NOPERSPECTIVE;
+      fprog->contains_noperspective_varying = true;
+   }
 
-      /* HPOS always wants noperspective. setting it up here allows
-       * us to not need special handling in the SF program. */
-      if (varying == VARYING_SLOT_POS) {
-         brw->interpolation_mode.mode[i] = INTERP_MODE_NOPERSPECTIVE;
-         continue;
+   foreach_list_typed(nir_variable, var, node, &nir->inputs) {
+      unsigned location = var->data.location;
+      unsigned slot_count = glsl_count_attribute_slots(var->type, false);
+      unsigned remap_count = 1;
+      if (location == VARYING_SLOT_COL0 || location == VARYING_SLOT_COL1) {
+         remap_count = 2;
       }
 
-      int frag_attrib = varying;
-      if (varying == VARYING_SLOT_BFC0 || varying == VARYING_SLOT_BFC1)
-         frag_attrib = varying - VARYING_SLOT_BFC0 + VARYING_SLOT_COL0;
-
-      if (!(fprog->Base.nir->info->inputs_read & BITFIELD64_BIT(frag_attrib)))
-         continue;
-
-      enum glsl_interp_mode mode = fprog->InterpQualifier[frag_attrib];
-
-      /* If the mode is not specified, the default varies: Color values
-       * follow GL_SHADE_MODEL; everything else is smooth.
-       */
-      if (mode == INTERP_MODE_NONE) {
-         if (frag_attrib == VARYING_SLOT_COL0 || frag_attrib == 
VARYING_SLOT_COL1)
-            mode = brw->ctx.Light.ShadeModel == GL_FLAT
-               ? INTERP_MODE_FLAT : INTERP_MODE_SMOOTH;
-         else
-            mode = INTERP_MODE_SMOOTH;
+      for (unsigned j = 0; j < remap_count; j++) {
+         if (j == 1)
+            location = location + VARYING_SLOT_BFC0 - VARYING_SLOT_COL0;
+
+         for (unsigned k = 0; k < slot_count; k++) {
+            unsigned slot = vue_map->varying_to_slot[location + k];
+            if (slot != -1 && fprog->interp_mode[slot] == INTERP_MODE_NONE) {
+               fprog->interp_mode[slot] = var->data.interpolation;
+
+               if (fprog->interp_mode[slot] == INTERP_MODE_FLAT) {
+                  fprog->contains_flat_varying = true;
+               } else if (fprog->interp_mode[slot] ==
+                          INTERP_MODE_NOPERSPECTIVE) {
+                  fprog->contains_noperspective_varying = true;
+               }
+            }
+         }
       }
-
-      brw->interpolation_mode.mode[i] = mode;
    }
 
    if (unlikely(INTEL_DEBUG & DEBUG_VUE)) {
@@ -103,7 +98,7 @@ brw_setup_vue_interpolation(struct brw_context *brw)
 
          fprintf(stderr, "%d: %d %s ofs %d\n",
                  i, varying,
-                 get_qual_name(brw->interpolation_mode.mode[i]),
+                 get_qual_name(fprog->interp_mode[i]),
                  brw_vue_slot_to_offset(i));
       }
    }
diff --git a/src/mesa/drivers/dri/i965/brw_nir.c 
b/src/mesa/drivers/dri/i965/brw_nir.c
index 3d19691..e6566ba 100644
--- a/src/mesa/drivers/dri/i965/brw_nir.c
+++ b/src/mesa/drivers/dri/i965/brw_nir.c
@@ -280,7 +280,8 @@ brw_nir_lower_tes_inputs(nir_shader *nir, const struct 
brw_vue_map *vue_map)
 }
 
 void
-brw_nir_lower_fs_inputs(nir_shader *nir,
+brw_nir_lower_fs_inputs(nir_shader *nir, struct brw_vue_map *vue_map,
+                        struct gl_program *prog,
                         const struct gen_device_info *devinfo,
                         const struct brw_wm_prog_key *key)
 {
@@ -311,6 +312,10 @@ brw_nir_lower_fs_inputs(nir_shader *nir,
       }
    }
 
+   if (devinfo->gen < 6) {
+      brw_setup_vue_interpolation(vue_map, nir, prog, devinfo);
+   }
+
    nir_lower_io_options lower_io_options = 0;
    if (key->persample_interp)
       lower_io_options |= nir_lower_io_force_sample_interpolation;
diff --git a/src/mesa/drivers/dri/i965/brw_nir.h 
b/src/mesa/drivers/dri/i965/brw_nir.h
index aef5c53..f989026 100644
--- a/src/mesa/drivers/dri/i965/brw_nir.h
+++ b/src/mesa/drivers/dri/i965/brw_nir.h
@@ -105,7 +105,8 @@ void brw_nir_lower_vs_inputs(nir_shader *nir,
 void brw_nir_lower_vue_inputs(nir_shader *nir, bool is_scalar,
                               const struct brw_vue_map *vue_map);
 void brw_nir_lower_tes_inputs(nir_shader *nir, const struct brw_vue_map *vue);
-void brw_nir_lower_fs_inputs(nir_shader *nir,
+void brw_nir_lower_fs_inputs(nir_shader *nir, struct brw_vue_map *vue_map,
+                             struct gl_program *prog,
                              const struct gen_device_info *devinfo,
                              const struct brw_wm_prog_key *key);
 void brw_nir_lower_vue_outputs(nir_shader *nir, bool is_scalar);
diff --git a/src/mesa/drivers/dri/i965/brw_program.c 
b/src/mesa/drivers/dri/i965/brw_program.c
index b94b9b3..b0920a8 100644
--- a/src/mesa/drivers/dri/i965/brw_program.c
+++ b/src/mesa/drivers/dri/i965/brw_program.c
@@ -142,7 +142,15 @@ static struct gl_program *brwNewProgram( struct gl_context 
*ctx,
    }
 
    case GL_FRAGMENT_PROGRAM_ARB: {
-      struct brw_fragment_program *prog = CALLOC_STRUCT(brw_fragment_program);
+      struct brw_fragment_program *prog;
+      if (brw->gen < 6) {
+         struct gen5_fragment_program *g5_prog =
+            CALLOC_STRUCT(gen5_fragment_program);
+         prog = &g5_prog->base;
+      } else {
+         prog = CALLOC_STRUCT(brw_fragment_program);
+      }
+
       if (prog) {
         prog->id = get_new_program_id(brw->screen);
 
diff --git a/src/mesa/drivers/dri/i965/brw_sf.c 
b/src/mesa/drivers/dri/i965/brw_sf.c
index 094260e..308b056 100644
--- a/src/mesa/drivers/dri/i965/brw_sf.c
+++ b/src/mesa/drivers/dri/i965/brw_sf.c
@@ -79,7 +79,6 @@ static void compile_sf_prog( struct brw_context *brw,
 
    c.prog_data.urb_read_length = c.nr_attr_regs;
    c.prog_data.urb_entry_size = c.nr_setup_regs * 2;
-   c.has_flat_shading = brw_any_flat_varyings(&key->interpolation_mode);
 
    /* Which primitive?  Or all three?
     */
@@ -148,7 +147,7 @@ brw_upload_sf_prog(struct brw_context *brw)
                         _NEW_PROGRAM |
                         _NEW_TRANSFORM,
                         BRW_NEW_BLORP |
-                        BRW_NEW_INTERPOLATION_MAP |
+                        BRW_NEW_FRAGMENT_PROGRAM |
                         BRW_NEW_REDUCED_PRIMITIVE |
                         BRW_NEW_VUE_MAP_GEOM_OUT))
       return;
@@ -204,8 +203,15 @@ brw_upload_sf_prog(struct brw_context *brw)
    if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) != render_to_fbo)
       key.sprite_origin_lower_left = true;
 
-   /* BRW_NEW_INTERPOLATION_MAP */
-   key.interpolation_mode = brw->interpolation_mode;
+   const struct gl_fragment_program *fprog = brw->fragment_program;
+   if (fprog) {
+      assert(brw->gen < 6);
+      struct gen5_fragment_program *p = (struct gen5_fragment_program *) fprog;
+
+      /* BRW_NEW_FRAGMENT_PROGRAM */
+      key.contains_flat_varying = p->contains_flat_varying;
+      key.interp_mode = p->interp_mode;
+   }
 
    /* _NEW_LIGHT | _NEW_PROGRAM */
    key.do_twoside_color = ((ctx->Light.Enabled && ctx->Light.Model.TwoSide) ||
diff --git a/src/mesa/drivers/dri/i965/brw_sf.h 
b/src/mesa/drivers/dri/i965/brw_sf.h
index 15102ac..ce4b2e3 100644
--- a/src/mesa/drivers/dri/i965/brw_sf.h
+++ b/src/mesa/drivers/dri/i965/brw_sf.h
@@ -46,7 +46,8 @@
 
 struct brw_sf_prog_key {
    GLbitfield64 attrs;
-   struct interpolation_mode_map interpolation_mode;
+   bool contains_flat_varying;
+   unsigned char *interp_mode;
    uint8_t point_sprite_coord_replace;
    GLuint primitive:2;
    GLuint do_twoside_color:1;
@@ -98,7 +99,6 @@ struct brw_sf_compile {
    unsigned flag_value;
 
    struct brw_vue_map vue_map;
-   bool has_flat_shading;
 };
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c 
b/src/mesa/drivers/dri/i965/brw_sf_emit.c
index fe05d54..5f31fa5 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c
@@ -162,7 +162,7 @@ static void copy_flatshaded_attributes(struct 
brw_sf_compile *c,
    int i;
 
    for (i = 0; i < c->vue_map.num_slots; i++) {
-      if (c->key.interpolation_mode.mode[i] == INTERP_MODE_FLAT) {
+      if (c->key.interp_mode[i] == INTERP_MODE_FLAT) {
          brw_MOV(p,
                  get_vue_slot(c, dst, i),
                  get_vue_slot(c, src, i));
@@ -176,7 +176,7 @@ static int count_flatshaded_attributes(struct 
brw_sf_compile *c)
    int count = 0;
 
    for (i = 0; i < c->vue_map.num_slots; i++)
-      if (c->key.interpolation_mode.mode[i] == INTERP_MODE_FLAT)
+      if (c->key.interp_mode[i] == INTERP_MODE_FLAT)
          count++;
 
    return count;
@@ -342,7 +342,7 @@ calculate_masks(struct brw_sf_compile *c,
    *pc_linear = 0;
    *pc = 0xf;
 
-   interp = c->key.interpolation_mode.mode[vert_reg_to_vue_slot(c, reg, 0)];
+   interp = c->key.interp_mode[vert_reg_to_vue_slot(c, reg, 0)];
    if (interp == INTERP_MODE_SMOOTH) {
       *pc_linear = 0xf;
       *pc_persp = 0xf;
@@ -354,7 +354,7 @@ calculate_masks(struct brw_sf_compile *c,
    if (vert_reg_to_varying(c, reg, 1) != BRW_VARYING_SLOT_COUNT) {
       *pc |= 0xf0;
 
-      interp = c->key.interpolation_mode.mode[vert_reg_to_vue_slot(c, reg, 1)];
+      interp = c->key.interp_mode[vert_reg_to_vue_slot(c, reg, 1)];
       if (interp == INTERP_MODE_SMOOTH) {
          *pc_linear |= 0xf0;
          *pc_persp |= 0xf0;
@@ -428,7 +428,7 @@ void brw_emit_tri_setup(struct brw_sf_compile *c, bool 
allocate)
    if (c->key.do_twoside_color)
       do_twoside_color(c);
 
-   if (c->has_flat_shading)
+   if (c->key.contains_flat_varying)
       do_flatshade_triangle(c);
 
 
@@ -514,7 +514,7 @@ void brw_emit_line_setup(struct brw_sf_compile *c, bool 
allocate)
    invert_det(c);
    copy_z_inv_w(c);
 
-   if (c->has_flat_shading)
+   if (c->key.contains_flat_varying)
       do_flatshade_line(c);
 
    for (i = 0; i < c->nr_setup_regs; i++)
diff --git a/src/mesa/drivers/dri/i965/brw_state.h 
b/src/mesa/drivers/dri/i965/brw_state.h
index b42b9af..8a29ca7 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -34,6 +34,7 @@
 #define BRW_STATE_H
 
 #include "brw_context.h"
+#include "nir.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -396,9 +397,6 @@ void gen7_enable_hw_binding_tables(struct brw_context *brw);
 void gen7_disable_hw_binding_tables(struct brw_context *brw);
 void gen7_reset_hw_bt_pool_offsets(struct brw_context *brw);
 
-/* brw_interpolation_map.c */
-void brw_setup_vue_interpolation(struct brw_context *brw);
-
 /* brw_clip.c */
 void brw_upload_clip_prog(struct brw_context *brw);
 
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c 
b/src/mesa/drivers/dri/i965/brw_state_upload.c
index 17d1b2d..015ea6e 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -640,7 +640,6 @@ static struct dirty_bit_map brw_bits[] = {
    DEFINE_BIT(BRW_NEW_ATOMIC_BUFFER),
    DEFINE_BIT(BRW_NEW_IMAGE_UNITS),
    DEFINE_BIT(BRW_NEW_META_IN_PROGRESS),
-   DEFINE_BIT(BRW_NEW_INTERPOLATION_MAP),
    DEFINE_BIT(BRW_NEW_PUSH_CONSTANT_ALLOCATION),
    DEFINE_BIT(BRW_NEW_NUM_SAMPLES),
    DEFINE_BIT(BRW_NEW_TEXTURE_BUFFER),
@@ -734,13 +733,12 @@ brw_upload_programs(struct brw_context *brw,
             ctx->Const.MaxViewports : 1;
       }
 
+      brw_upload_wm_prog(brw);
+
       if (brw->gen < 6) {
-         brw_setup_vue_interpolation(brw);
          brw_upload_clip_prog(brw);
          brw_upload_sf_prog(brw);
       }
-
-      brw_upload_wm_prog(brw);
    } else if (pipeline == BRW_COMPUTE_PIPELINE) {
       brw_upload_cs_prog(brw);
    }
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c 
b/src/mesa/drivers/dri/i965/brw_wm.c
index e65f77a..53b7d9b 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -77,7 +77,8 @@ bool
 brw_codegen_wm_prog(struct brw_context *brw,
                     struct gl_shader_program *prog,
                     struct brw_fragment_program *fp,
-                    struct brw_wm_prog_key *key)
+                    struct brw_wm_prog_key *key,
+                    struct brw_vue_map *vue_map)
 {
    const struct gen_device_info *devinfo = &brw->screen->devinfo;
    struct gl_context *ctx = &brw->ctx;
@@ -146,8 +147,9 @@ brw_codegen_wm_prog(struct brw_context *brw,
    program = brw_compile_fs(brw->screen->compiler, brw, mem_ctx,
                             key, &prog_data, fp->program.Base.nir,
                             &fp->program.Base, st_index8, st_index16,
-                            true, brw->use_rep_send,
+                            true, brw->use_rep_send, vue_map,
                             &program_size, &error_str);
+
    if (program == NULL) {
       if (prog) {
          prog->LinkStatus = false;
@@ -587,7 +589,8 @@ brw_upload_wm_prog(struct brw_context *brw)
                          &key, sizeof(key),
                          &brw->wm.base.prog_offset,
                          &brw->wm.base.prog_data)) {
-      bool success = brw_codegen_wm_prog(brw, current, fp, &key);
+      bool success = brw_codegen_wm_prog(brw, current, fp, &key,
+                                         &brw->vue_map_geom_out);
       (void) success;
       assert(success);
    }
@@ -641,7 +644,14 @@ brw_fs_precompile(struct gl_context *ctx,
    uint32_t old_prog_offset = brw->wm.base.prog_offset;
    struct brw_stage_prog_data *old_prog_data = brw->wm.base.prog_data;
 
-   bool success = brw_codegen_wm_prog(brw, shader_prog, bfp, &key);
+   struct brw_vue_map vue_map;
+   if (brw->gen < 6) {
+      brw_compute_vue_map(&brw->screen->devinfo, &vue_map,
+                          fp->Base.nir->info->inputs_read | VARYING_BIT_POS,
+                          false);
+   }
+
+   bool success = brw_codegen_wm_prog(brw, shader_prog, bfp, &key, &vue_map);
 
    brw->wm.base.prog_offset = old_prog_offset;
    brw->wm.base.prog_data = old_prog_data;
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h 
b/src/mesa/drivers/dri/i965/brw_wm.h
index 8fa24b1..f4f513b 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -63,7 +63,8 @@ bool brw_color_buffer_write_enabled(struct brw_context *brw);
 bool brw_codegen_wm_prog(struct brw_context *brw,
                          struct gl_shader_program *prog,
                          struct brw_fragment_program *fp,
-                         struct brw_wm_prog_key *key);
+                         struct brw_wm_prog_key *key,
+                         struct brw_vue_map *vue_map);
 void brw_wm_debug_recompile(struct brw_context *brw,
                             struct gl_shader_program *prog,
                             const struct brw_wm_prog_key *key);
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index c8e14c9..6fdb711 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2003,13 +2003,6 @@ struct gl_fragment_program
    enum gl_frag_depth_layout FragDepthLayout;
 
    /**
-    * GLSL interpolation qualifier associated with each fragment shader input.
-    * For inputs that do not have an interpolation qualifier specified in
-    * GLSL, the value is INTERP_MODE_NONE.
-    */
-   enum glsl_interp_mode InterpQualifier[VARYING_SLOT_MAX];
-
-   /**
     * Bitfield indicating, for each fragment shader input, 1 if that input
     * uses centroid interpolation, 0 otherwise.  Unused inputs are 0.
     */
-- 
2.7.4

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to