<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Oct 20, 2016 at 8:23 PM, Timothy Arceri <span dir="ltr"><<a href="mailto:timothy.arceri@collabora.com" target="_blank">timothy.arceri@collabora.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">Here brw_setup_vue_interpolation() is rewritten not to use the InterpQualifier<br>
array in gl_fragment_program which will allow us to remove it.<br>
<br>
This change also makes the code which is only used by gen4/5 more self contained<br>
as it now has its own gen5_fragment_program struct rather than storing the map<br>
in brw_context. This means the interpolation map will only get processed once<br>
and will get stored in the in memory cache rather than being processed everytime<br>
the fs changes.<br>
<br>
Also by calling this from the fs compile code rather than from the upload code<br>
and using the interpolation assigned there we can get rid of the<br>
BRW_NEW_INTERPOLATION_MAP flag.<br>
<br>
It might not seem ideal to add a gen5_fragment_program struct however by the end<br>
of this series we will have gotten rid of all the brw_{shader_stage}_program<br>
structs and replaced them with a generic brw_program struct so there will only<br>
be two program structs which is better than what we have now.<br>
<br>
</span>V2: Don't remove BRW_NEW_INTERPOLATION_MAP from dirty_bit_map until the following<br>
patch to fix build error.<br>
<span class="">---<br>
 src/intel/blorp/blorp.c                           |  6 +-<br>
 src/intel/vulkan/anv_pipeline.<wbr>c                   |  2 +-<br>
 src/mesa/drivers/dri/i965/brw_<wbr>clip.c              | 19 ++---<br>
 src/mesa/drivers/dri/i965/brw_<wbr>clip.h              |  7 +-<br>
 src/mesa/drivers/dri/i965/brw_<wbr>clip_line.c         |  2 +-<br>
 src/mesa/drivers/dri/i965/brw_<wbr>clip_tri.c          |  2 +-<br>
 src/mesa/drivers/dri/i965/brw_<wbr>clip_unfilled.c     |  2 +-<br>
 src/mesa/drivers/dri/i965/brw_<wbr>clip_util.c         | 10 +--<br>
 src/mesa/drivers/dri/i965/brw_<wbr>compiler.h          |  8 ++-<br>
 src/mesa/drivers/dri/i965/brw_<wbr>context.h           | 45 ++++--------<br>
 src/mesa/drivers/dri/i965/brw_<wbr>fs.cpp              |  4 +-<br>
 src/mesa/drivers/dri/i965/brw_<wbr>interpolation_map.c | 85 +++++++++++------------<br>
 src/mesa/drivers/dri/i965/brw_<wbr>nir.c               |  7 +-<br>
 src/mesa/drivers/dri/i965/brw_<wbr>nir.h               |  3 +-<br>
 src/mesa/drivers/dri/i965/brw_<wbr>program.c           | 10 ++-<br>
 src/mesa/drivers/dri/i965/brw_<wbr>sf.c                | 14 ++--<br>
 src/mesa/drivers/dri/i965/brw_<wbr>sf.h                |  4 +-<br>
 src/mesa/drivers/dri/i965/brw_<wbr>sf_emit.c           | 12 ++--<br>
 src/mesa/drivers/dri/i965/brw_<wbr>state.h             |  3 -<br>
</span> src/mesa/drivers/dri/i965/brw_<wbr>state_upload.c      |  5 +-<br>
<span class=""> src/mesa/drivers/dri/i965/brw_<wbr>wm.c                | 18 +++--<br>
 src/mesa/drivers/dri/i965/brw_<wbr>wm.h                |  3 +-<br>
</span> 22 files changed, 142 insertions(+), 129 deletions(-)<br>
<div><div class="h5"><br>
diff --git a/src/intel/blorp/blorp.c b/src/intel/blorp/blorp.c<br>
index 5209ee2..8905cfa 100644<br>
--- a/src/intel/blorp/blorp.c<br>
+++ b/src/intel/blorp/blorp.c<br>
@@ -211,9 +211,9 @@ brw_blorp_compile_nir_shader(<wbr>struct blorp_context *blorp, struct nir_shader *nir<br>
    nir_lower_io(nir, nir_var_uniform, nir_uniform_type_size, 0);<br>
<br>
    const unsigned *program =<br>
-      brw_compile_fs(compiler, blorp->driver_ctx, mem_ctx,<br>
-                     wm_key, &wm_prog_data, nir,<br>
-                     NULL, -1, -1, false, use_repclear, program_size, NULL);<br>
+      brw_compile_fs(compiler, blorp->driver_ctx, mem_ctx, wm_key,<br>
+                     &wm_prog_data, nir, NULL, -1, -1, false, use_repclear,<br>
+                     NULL, program_size, NULL);<br>
<br>
    /* Copy the relavent bits of wm_prog_data over into the blorp prog data */<br>
    prog_data->dispatch_8 = wm_prog_data.dispatch_8;<br>
diff --git a/src/intel/vulkan/anv_<wbr>pipeline.c b/src/intel/vulkan/anv_<wbr>pipeline.c<br>
index 72f0643..0aac711 100644<br>
--- a/src/intel/vulkan/anv_<wbr>pipeline.c<br>
+++ b/src/intel/vulkan/anv_<wbr>pipeline.c<br>
@@ -678,7 +678,7 @@ anv_pipeline_compile_fs(struct anv_pipeline *pipeline,<br>
       unsigned code_size;<br>
       const unsigned *shader_code =<br>
          brw_compile_fs(compiler, NULL, mem_ctx, &key, &prog_data, nir,<br>
-                        NULL, -1, -1, true, false, &code_size, NULL);<br>
+                        NULL, -1, -1, true, false, NULL, &code_size, NULL);<br>
       if (shader_code == NULL) {<br>
          ralloc_free(mem_ctx);<br>
          return vk_error(VK_ERROR_OUT_OF_HOST_<wbr>MEMORY);<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_clip.c b/src/mesa/drivers/dri/i965/<wbr>brw_clip.c<br>
index 1134fa4..06650b6 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_clip.c<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_clip.c<br>
@@ -68,11 +68,6 @@ static void compile_clip_prog( struct brw_context *brw,<br>
    c.key = *key;<br>
    c.vue_map = brw->vue_map_geom_out;<br>
<br>
-   c.has_flat_shading =<br>
-      brw_any_flat_varyings(&key-><wbr>interpolation_mode);<br>
-   c.has_noperspective_shading =<br>
-      brw_any_noperspective_<wbr>varyings(&key->interpolation_<wbr>mode);<br>
-<br>
    /* nr_regs is the number of registers filled by reading data from the VUE.<br>
     * This program accesses the entire VUE, so nr_regs needs to be the size of<br>
     * the VUE (measured in pairs, since two slots are stored in each<br>
@@ -144,7 +139,7 @@ brw_upload_clip_prog(struct brw_context *brw)<br>
                         _NEW_POLYGON |<br>
                         _NEW_TRANSFORM,<br>
                         BRW_NEW_BLORP |<br>
-                        BRW_NEW_INTERPOLATION_MAP |<br>
+                        BRW_NEW_FRAGMENT_PROGRAM |<br>
                         BRW_NEW_REDUCED_PRIMITIVE |<br>
                         BRW_NEW_VUE_MAP_GEOM_OUT))<br>
       return;<br>
@@ -154,8 +149,16 @@ brw_upload_clip_prog(struct brw_context *brw)<br>
    /* Populate the key:<br>
     */<br>
<br>
-   /* BRW_NEW_INTERPOLATION_MAP */<br>
-   key.interpolation_mode = brw->interpolation_mode;<br>
+   const struct gl_fragment_program *fprog = brw->fragment_program;<br>
+   if (fprog) {<br>
+      assert(brw->gen < 6);<br>
+      struct gen5_fragment_program *p = (struct gen5_fragment_program *) fprog;<br>
+<br>
+      /* BRW_NEW_FRAGMENT_PROGRAM */<br>
+      key.contains_flat_varying = p->contains_flat_varying;<br>
+      key.contains_noperspective_<wbr>varying = p->contains_noperspective_<wbr>varying;<br>
+      key.interp_mode = p->interp_mode;<br>
+   }<br>
<br>
    /* BRW_NEW_REDUCED_PRIMITIVE */<br>
    key.primitive = brw->reduced_primitive;<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_clip.h b/src/mesa/drivers/dri/i965/<wbr>brw_clip.h<br>
index 54c7682..355ae64 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_clip.h<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_clip.h<br>
@@ -47,7 +47,9 @@<br>
  */<br>
 struct brw_clip_prog_key {<br>
    GLbitfield64 attrs;<br>
-   struct interpolation_mode_map interpolation_mode;<br>
+   bool contains_flat_varying;<br>
+   bool contains_noperspective_<wbr>varying;<br>
+   unsigned char *interp_mode;<br>
    GLuint primitive:4;<br>
    GLuint nr_userclip:4;<br>
    GLuint pv_first:1;<br>
@@ -128,9 +130,6 @@ struct brw_clip_compile {<br>
    bool need_direction;<br>
<br>
    struct brw_vue_map vue_map;<br>
-<br>
-   bool has_flat_shading;<br>
-   bool has_noperspective_shading;<br>
 };<br>
<br>
 /**<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_clip_line.c b/src/mesa/drivers/dri/i965/<wbr>brw_clip_line.c<br>
index 2c7f85a..f9cabd2 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_clip_line.c<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_clip_line.c<br>
@@ -302,7 +302,7 @@ void brw_emit_line_clip( struct brw_clip_compile *c )<br>
    brw_clip_line_alloc_regs(c);<br>
    brw_clip_init_ff_sync(c);<br>
<br>
-   if (c->has_flat_shading) {<br>
+   if (c->key.contains_flat_varying) {<br>
       if (c->key.pv_first)<br>
          brw_clip_copy_flatshaded_<wbr>attributes(c, 1, 0);<br>
       else<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_clip_tri.c b/src/mesa/drivers/dri/i965/<wbr>brw_clip_tri.c<br>
index 4caa8f5..52402e3 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_clip_tri.c<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_clip_tri.c<br>
@@ -650,7 +650,7 @@ void brw_emit_tri_clip( struct brw_clip_compile *c )<br>
     * flatshading, need to apply the flatshade here because we don't<br>
     * respect the PV when converting to trifan for emit:<br>
     */<br>
-   if (c->has_flat_shading)<br>
+   if (c->key.contains_flat_varying)<br>
       brw_clip_tri_flat_shade(c);<br>
<br>
    if ((c->key.clip_mode == BRW_CLIPMODE_NORMAL) ||<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_clip_unfilled.c b/src/mesa/drivers/dri/i965/<wbr>brw_clip_unfilled.c<br>
index d333d10..7c06857 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_clip_unfilled.c<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_clip_unfilled.c<br>
@@ -519,7 +519,7 @@ void brw_emit_unfilled_clip( struct brw_clip_compile *c )<br>
<br>
    /* Need to do this whether we clip or not:<br>
     */<br>
-   if (c->has_flat_shading)<br>
+   if (c->key.contains_flat_varying)<br>
       brw_clip_tri_flat_shade(c);<br>
<br>
    brw_clip_init_clipmask(c);<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_clip_util.c b/src/mesa/drivers/dri/i965/<wbr>brw_clip_util.c<br>
index f5d0a5a..4f1b0fd 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_clip_util.c<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_clip_util.c<br>
@@ -157,7 +157,7 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,<br>
     */<br>
<br>
    /* Take a copy of the v0 NDC coordinates, in case dest == v0. */<br>
-   if (c->has_noperspective_shading) {<br>
+   if (c->key.contains_<wbr>noperspective_varying) {<br>
       GLuint offset = brw_varying_to_offset(&c->vue_<wbr>map,<br>
                                                  BRW_VARYING_SLOT_NDC);<br>
       v0_ndc_copy = get_tmp(c);<br>
@@ -183,7 +183,7 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,<br>
    /* If we have noperspective attributes,<br>
     * we need to compute the screen-space t<br>
     */<br>
-   if (c->has_noperspective_shading) {<br>
+   if (c->key.contains_<wbr>noperspective_varying) {<br>
       GLuint delta = brw_varying_to_offset(&c->vue_<wbr>map,<br>
                                                 BRW_VARYING_SLOT_NDC);<br>
       struct brw_reg tmp = get_tmp(c);<br>
@@ -272,7 +272,7 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,<br>
           * Unless the attribute is flat shaded -- in which case just copy<br>
           * from one of the sources (doesn't matter which; already copied from pv)<br>
          */<br>
-         GLuint interp = c->key.interpolation_mode.<wbr>mode[slot];<br>
+         GLuint interp = c->key.interp_mode[slot];<br>
<br>
          if (interp != INTERP_MODE_FLAT) {<br>
             struct brw_reg tmp = get_tmp(c);<br>
@@ -310,7 +310,7 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,<br>
       brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0));<br>
    }<br>
<br>
-   if (c->has_noperspective_shading)<br>
+   if (c->key.contains_<wbr>noperspective_varying)<br>
       release_tmp(c, t_nopersp);<br>
 }<br>
<br>
@@ -406,7 +406,7 @@ void brw_clip_copy_flatshaded_<wbr>attributes( struct brw_clip_compile *c,<br>
    struct brw_codegen *p = &c->func;<br>
<br>
    for (int i = 0; i < c->vue_map.num_slots; i++) {<br>
-      if (c->key.interpolation_mode.<wbr>mode[i] == INTERP_MODE_FLAT) {<br>
+      if (c->key.interp_mode[i] == INTERP_MODE_FLAT) {<br>
          brw_MOV(p,<br>
                  byte_offset(c->reg.vertex[to], brw_vue_slot_to_offset(i)),<br>
                  byte_offset(c->reg.vertex[<wbr>from], brw_vue_slot_to_offset(i)));<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_compiler.h b/src/mesa/drivers/dri/i965/<wbr>brw_compiler.h<br>
index 447d05b..772c11e 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_compiler.h<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_compiler.h<br>
@@ -575,6 +575,12 @@ void brw_compute_tess_vue_map(<wbr>struct brw_vue_map *const vue_map,<br>
                               const GLbitfield64 slots_valid,<br>
                               const GLbitfield is_patch);<br>
<br>
+/* brw_interpolation_map.c */<br>
+void brw_setup_vue_interpolation(<wbr>struct brw_vue_map *vue_map,<br>
+                                 struct nir_shader *nir,<br>
+                                 struct gl_program *prog,<br>
+                                 const struct gen_device_info *devinfo);<br>
+<br>
 enum shader_dispatch_mode {<br>
    DISPATCH_MODE_4X1_SINGLE = 0,<br>
    DISPATCH_MODE_4X2_DUAL_<wbr>INSTANCE = 1,<br>
@@ -834,7 +840,7 @@ brw_compile_fs(const struct brw_compiler *compiler, void *log_data,<br>
                int shader_time_index8,<br>
                int shader_time_index16,<br>
                bool allow_spilling,<br>
-               bool use_rep_send,<br>
+               bool use_rep_send, struct brw_vue_map *vue_map,<br>
                unsigned *final_assembly_size,<br>
                char **error_str);<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_context.h b/src/mesa/drivers/dri/i965/<wbr>brw_context.h<br>
index e190d53..ba8b254 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_context.h<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_context.h<br>
@@ -363,6 +363,20 @@ struct brw_fragment_program {<br>
 };<br>
<br>
<br>
+struct gen5_fragment_program {<br>
+   struct brw_fragment_program base;<br>
+<br>
+   bool contains_flat_varying;<br>
+   bool contains_noperspective_<wbr>varying;<br>
+<br>
+   /*<br>
+    * Mapping of varying slots to interpolation modes.<br>
+    * Used Gen4/5 by the clip|sf|wm stages.<br>
+    */<br>
+   unsigned char interp_mode[BRW_VARYING_SLOT_<wbr>COUNT];<br>
+};<br>
+<br>
+<br>
 /** Subclass of Mesa compute program */<br>
 struct brw_compute_program {<br>
    struct gl_program program;<br>
@@ -385,32 +399,6 @@ struct brw_shader {<br>
     ~VARYING_BIT_POS & ~VARYING_BIT_FACE)<br>
<br>
<br>
-/*<br>
- * Mapping of VUE map slots to interpolation modes.<br>
- */<br>
-struct interpolation_mode_map {<br>
-   unsigned char mode[BRW_VARYING_SLOT_COUNT];<br>
-};<br>
-<br>
-static inline bool brw_any_flat_varyings(struct interpolation_mode_map *map)<br>
-{<br>
-   for (int i = 0; i < BRW_VARYING_SLOT_COUNT; i++)<br>
-      if (map->mode[i] == INTERP_MODE_FLAT)<br>
-         return true;<br>
-<br>
-   return false;<br>
-}<br>
-<br>
-static inline bool brw_any_noperspective_<wbr>varyings(struct interpolation_mode_map *map)<br>
-{<br>
-   for (int i = 0; i < BRW_VARYING_SLOT_COUNT; i++)<br>
-      if (map->mode[i] == INTERP_MODE_NOPERSPECTIVE)<br>
-         return true;<br>
-<br>
-   return false;<br>
-}<br>
-<br>
-<br>
 struct brw_sf_prog_data {<br>
    GLuint urb_read_length;<br>
    GLuint total_grf;<br>
@@ -1273,11 +1261,6 @@ struct brw_context<br>
    uint32_t render_target_format[MESA_<wbr>FORMAT_COUNT];<br>
    bool format_supported_as_render_<wbr>target[MESA_FORMAT_COUNT];<br>
<br>
-   /* Interpolation modes, one byte per vue slot.<br>
-    * Used Gen4/5 by the clip|sf|wm stages. Ignored on Gen6+.<br>
-    */<br>
-   struct interpolation_mode_map interpolation_mode;<br>
-<br>
    /* PrimitiveRestart */<br>
    struct {<br>
       bool in_progress;<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_fs.cpp b/src/mesa/drivers/dri/i965/<wbr>brw_fs.cpp<br>
index 1a22fb4..3e0d057 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_fs.cpp<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_fs.cpp<br>
@@ -6422,14 +6422,14 @@ brw_compile_fs(const struct brw_compiler *compiler, void *log_data,<br>
                struct gl_program *prog,<br>
                int shader_time_index8, int shader_time_index16,<br>
                bool allow_spilling,<br>
-               bool use_rep_send,<br>
+               bool use_rep_send, struct brw_vue_map *vue_map,<br>
                unsigned *final_assembly_size,<br>
                char **error_str)<br>
 {<br>
    nir_shader *shader = nir_shader_clone(mem_ctx, src_shader);<br>
    shader = brw_nir_apply_sampler_key(<wbr>shader, compiler->devinfo, &key->tex,<br>
                                       true);<br>
-   brw_nir_lower_fs_inputs(<wbr>shader, compiler->devinfo, key);<br>
+   brw_nir_lower_fs_inputs(<wbr>shader, vue_map, prog, compiler->devinfo, key);<br>
    brw_nir_lower_fs_outputs(<wbr>shader);<br>
    if (!key->multisample_fbo)<br>
       NIR_PASS_V(shader, demote_sample_qualifiers);<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_interpolation_map.c b/src/mesa/drivers/dri/i965/<wbr>brw_interpolation_map.c<br>
index 097987b..cb4deb5 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_interpolation_map.c<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_interpolation_map.c<br>
@@ -21,7 +21,8 @@<br>
  * IN THE SOFTWARE.<br>
  */<br>
<br>
-#include "brw_state.h"<br>
+#include "brw_compiler.h"<br>
+#include "brw_context.h"<br>
 #include "compiler/nir/nir.h"<br>
<br>
 static char const *get_qual_name(int mode)<br>
@@ -38,58 +39,52 @@ static char const *get_qual_name(int mode)<br>
<br>
 /* Set up interpolation modes for every element in the VUE */<br>
 void<br>
-brw_setup_vue_interpolation(<wbr>struct brw_context *brw)<br>
+brw_setup_vue_interpolation(<wbr>struct brw_vue_map *vue_map, nir_shader *nir,<br>
+                            struct gl_program *prog,<br>
+                            const struct gen_device_info *devinfo)<br>
 {<br>
-   const struct gl_fragment_program *fprog = brw->fragment_program;<br>
-   struct brw_vue_map *vue_map = &brw->vue_map_geom_out;<br>
+   struct gen5_fragment_program *fprog = (struct gen5_fragment_program *) prog;<br></div></div></blockquote><div><br></div><div>Why are we calling this gen5_fragment_program and not gen4_fragment_program?  Generally, we use the lowest gen that applies.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
-   if (!brw_state_dirty(brw,<br>
-                        _NEW_LIGHT,<br>
-                        BRW_NEW_BLORP |<br>
-                        BRW_NEW_FRAGMENT_PROGRAM |<br>
-                        BRW_NEW_VUE_MAP_GEOM_OUT))<br>
-      return;<br>
-<br>
-   memset(&brw->interpolation_<wbr>mode, INTERP_MODE_NONE, sizeof(brw->interpolation_<wbr>mode));<br>
-<br>
-   brw->ctx.NewDriverState |= BRW_NEW_INTERPOLATION_MAP;<br>
+   memset(fprog->interp_mode, INTERP_MODE_NONE, sizeof(fprog->interp_mode));<br></div></div></blockquote><div><br></div><div>Please, no.  This does not do what it looks like it does.  Most enums (unless declared as packed) aren't compiled down to 8-bit types so the only reason why this works is because INTERP_MODE_NONE happens to be 0.  If it was anything else, this line wouldn't work.  Memset to 0 with a comment or use a for loop; don't memset to an enum value.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
<br>
-   if (!fprog)<br>
+   if (!vue_map)<br>
       return;<br>
<br>
-   for (int i = 0; i < vue_map->num_slots; i++) {<br>
-      int varying = vue_map->slot_to_varying[i];<br>
-      if (varying == -1)<br>
-         continue;<br>
+   /* HPOS always wants noperspective. setting it up here allows<br>
+    * us to not need special handling in the SF program.<br>
+    */<br>
+   unsigned pos_slot = vue_map->varying_to_slot[<wbr>VARYING_SLOT_POS];<br>
+   if (pos_slot != -1) {;<br>
+      fprog->interp_mode[pos_slot] = INTERP_MODE_NOPERSPECTIVE;<br>
+      fprog->contains_noperspective_<wbr>varying = true;<br>
+   }<br>
<br>
-      /* HPOS always wants noperspective. setting it up here allows<br>
-       * us to not need special handling in the SF program. */<br>
-      if (varying == VARYING_SLOT_POS) {<br>
-         brw->interpolation_mode.mode[<wbr>i] = INTERP_MODE_NOPERSPECTIVE;<br>
-         continue;<br>
+   foreach_list_typed(nir_<wbr>variable, var, node, &nir->inputs) {<br>
+      unsigned location = var->data.location;<br>
+      unsigned slot_count = glsl_count_attribute_slots(<wbr>var->type, false);<br>
+      unsigned remap_count = 1;<br>
+      if (location == VARYING_SLOT_COL0 || location == VARYING_SLOT_COL1) {<br>
+         remap_count = 2;<br>
       }<br>
<br>
-      int frag_attrib = varying;<br>
-      if (varying == VARYING_SLOT_BFC0 || varying == VARYING_SLOT_BFC1)<br>
-         frag_attrib = varying - VARYING_SLOT_BFC0 + VARYING_SLOT_COL0;<br>
-<br>
-      if (!(fprog->Base.nir->info-><wbr>inputs_read & BITFIELD64_BIT(frag_attrib)))<br>
-         continue;<br>
-<br>
-      enum glsl_interp_mode mode = fprog->InterpQualifier[frag_<wbr>attrib];<br>
-<br>
-      /* If the mode is not specified, the default varies: Color values<br>
-       * follow GL_SHADE_MODEL; everything else is smooth.<br>
-       */<br>
-      if (mode == INTERP_MODE_NONE) {<br>
-         if (frag_attrib == VARYING_SLOT_COL0 || frag_attrib == VARYING_SLOT_COL1)<br>
-            mode = brw->ctx.Light.ShadeModel == GL_FLAT<br>
-               ? INTERP_MODE_FLAT : INTERP_MODE_SMOOTH;<br>
-         else<br>
-            mode = INTERP_MODE_SMOOTH;<br></div></div></blockquote><div><br></div><div>Uh... Where did this logic go?  Oh, it's already in nir_lower_fs_inputs...<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
+      for (unsigned j = 0; j < remap_count; j++) {<br></div></div></blockquote><div><br></div><div>This remap thing is really confusing.  Maybe it would be better to have a helper<br><br></div><div>gen5_fragment_prog_set_interp_modes(prog, vue_map, location, slot_count, interp_mode)<br><br></div><div>And then, you can explicitly call it twice for colors and once for other things.  I believe your logic here is correct, it's just horribly confusing.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
+         if (j == 1)<br>
+            location = location + VARYING_SLOT_BFC0 - VARYING_SLOT_COL0;<br>
+<br>
+         for (unsigned k = 0; k < slot_count; k++) {<br>
+            unsigned slot = vue_map->varying_to_slot[<wbr>location + k];<br>
+            if (slot != -1 && fprog->interp_mode[slot] == INTERP_MODE_NONE) {<br>
+               fprog->interp_mode[slot] = var->data.interpolation;<br>
+<br>
+               if (fprog->interp_mode[slot] == INTERP_MODE_FLAT) {<br>
+                  fprog->contains_flat_varying = true;<br>
+               } else if (fprog->interp_mode[slot] ==<br>
+                          INTERP_MODE_NOPERSPECTIVE) {<br>
+                  fprog->contains_noperspective_<wbr>varying = true;<br>
+               }<br>
+            }<br>
+         }<br>
       }<br>
-<br>
-      brw->interpolation_mode.mode[<wbr>i] = mode;<br>
    }<br>
<br>
    if (unlikely(INTEL_DEBUG & DEBUG_VUE)) {<br>
@@ -103,7 +98,7 @@ brw_setup_vue_interpolation(<wbr>struct brw_context *brw)<br>
<br>
          fprintf(stderr, "%d: %d %s ofs %d\n",<br>
                  i, varying,<br>
-                 get_qual_name(brw-><wbr>interpolation_mode.mode[i]),<br>
+                 get_qual_name(fprog->interp_<wbr>mode[i]),<br>
                  brw_vue_slot_to_offset(i));<br>
       }<br>
    }<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_nir.c b/src/mesa/drivers/dri/i965/<wbr>brw_nir.c<br>
index 3d19691..e6566ba 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_nir.c<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_nir.c<br>
@@ -280,7 +280,8 @@ brw_nir_lower_tes_inputs(nir_<wbr>shader *nir, const struct brw_vue_map *vue_map)<br>
 }<br>
<br>
 void<br>
-brw_nir_lower_fs_inputs(nir_<wbr>shader *nir,<br>
+brw_nir_lower_fs_inputs(nir_<wbr>shader *nir, struct brw_vue_map *vue_map,<br>
+                        struct gl_program *prog,<br>
                         const struct gen_device_info *devinfo,<br>
                         const struct brw_wm_prog_key *key)<br>
 {<br>
@@ -311,6 +312,10 @@ brw_nir_lower_fs_inputs(nir_<wbr>shader *nir,<br>
       }<br>
    }<br>
<br>
+   if (devinfo->gen < 6) {<br></div></div></blockquote><div><br></div><div>This is a lie.  It really needs to be (devinfo->gen < 6 && prog).  Or, you could assert prog.  Something to indicate that prog can't be null here.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
+      brw_setup_vue_interpolation(<wbr>vue_map, nir, prog, devinfo);<br>
+   }<br>
+<br>
    nir_lower_io_options lower_io_options = 0;<br>
    if (key->persample_interp)<br>
       lower_io_options |= nir_lower_io_force_sample_<wbr>interpolation;<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_nir.h b/src/mesa/drivers/dri/i965/<wbr>brw_nir.h<br>
index aef5c53..f989026 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_nir.h<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_nir.h<br>
@@ -105,7 +105,8 @@ void brw_nir_lower_vs_inputs(nir_<wbr>shader *nir,<br>
 void brw_nir_lower_vue_inputs(nir_<wbr>shader *nir, bool is_scalar,<br>
                               const struct brw_vue_map *vue_map);<br>
 void brw_nir_lower_tes_inputs(nir_<wbr>shader *nir, const struct brw_vue_map *vue);<br>
-void brw_nir_lower_fs_inputs(nir_<wbr>shader *nir,<br>
+void brw_nir_lower_fs_inputs(nir_<wbr>shader *nir, struct brw_vue_map *vue_map,<br>
+                             struct gl_program *prog,<br>
                              const struct gen_device_info *devinfo,<br>
                              const struct brw_wm_prog_key *key);<br>
 void brw_nir_lower_vue_outputs(nir_<wbr>shader *nir, bool is_scalar);<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_program.c b/src/mesa/drivers/dri/i965/<wbr>brw_program.c<br>
index 7516baf..957c5b5 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_program.c<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_program.c<br>
@@ -142,7 +142,15 @@ static struct gl_program *brwNewProgram( struct gl_context *ctx,<br>
    }<br>
<br>
    case GL_FRAGMENT_PROGRAM_ARB: {<br>
-      struct brw_fragment_program *prog = CALLOC_STRUCT(brw_fragment_<wbr>program);<br>
+      struct brw_fragment_program *prog;<br>
+      if (brw->gen < 6) {<br>
+         struct gen5_fragment_program *g5_prog =<br>
+            CALLOC_STRUCT(gen5_fragment_<wbr>program);<br>
+         prog = &g5_prog->base;<br>
+      } else {<br>
+         prog = CALLOC_STRUCT(brw_fragment_<wbr>program);<br>
+      }<br>
+<br>
       if (prog) {<br>
         prog->id = get_new_program_id(brw-><wbr>screen);<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_sf.c b/src/mesa/drivers/dri/i965/<wbr>brw_sf.c<br>
index 094260e..308b056 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_sf.c<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_sf.c<br>
@@ -79,7 +79,6 @@ static void compile_sf_prog( struct brw_context *brw,<br>
<br>
    c.prog_data.urb_read_length = c.nr_attr_regs;<br>
    c.prog_data.urb_entry_size = c.nr_setup_regs * 2;<br>
-   c.has_flat_shading = brw_any_flat_varyings(&key-><wbr>interpolation_mode);<br>
<br>
    /* Which primitive?  Or all three?<br>
     */<br>
@@ -148,7 +147,7 @@ brw_upload_sf_prog(struct brw_context *brw)<br>
                         _NEW_PROGRAM |<br>
                         _NEW_TRANSFORM,<br>
                         BRW_NEW_BLORP |<br>
-                        BRW_NEW_INTERPOLATION_MAP |<br>
+                        BRW_NEW_FRAGMENT_PROGRAM |<br>
                         BRW_NEW_REDUCED_PRIMITIVE |<br>
                         BRW_NEW_VUE_MAP_GEOM_OUT))<br>
       return;<br>
@@ -204,8 +203,15 @@ brw_upload_sf_prog(struct brw_context *brw)<br>
    if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) != render_to_fbo)<br>
       key.sprite_origin_lower_left = true;<br>
<br>
-   /* BRW_NEW_INTERPOLATION_MAP */<br>
-   key.interpolation_mode = brw->interpolation_mode;<br>
+   const struct gl_fragment_program *fprog = brw->fragment_program;<br>
+   if (fprog) {<br>
+      assert(brw->gen < 6);<br>
+      struct gen5_fragment_program *p = (struct gen5_fragment_program *) fprog;<br>
+<br>
+      /* BRW_NEW_FRAGMENT_PROGRAM */<br>
+      key.contains_flat_varying = p->contains_flat_varying;<br>
+      key.interp_mode = p->interp_mode;<br>
+   }<br>
<br>
    /* _NEW_LIGHT | _NEW_PROGRAM */<br>
    key.do_twoside_color = ((ctx->Light.Enabled && ctx->Light.Model.TwoSide) ||<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_sf.h b/src/mesa/drivers/dri/i965/<wbr>brw_sf.h<br>
index 15102ac..ce4b2e3 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_sf.h<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_sf.h<br>
@@ -46,7 +46,8 @@<br>
<br>
 struct brw_sf_prog_key {<br>
    GLbitfield64 attrs;<br>
-   struct interpolation_mode_map interpolation_mode;<br>
+   bool contains_flat_varying;<br>
+   unsigned char *interp_mode;<br>
    uint8_t point_sprite_coord_replace;<br>
    GLuint primitive:2;<br>
    GLuint do_twoside_color:1;<br>
@@ -98,7 +99,6 @@ struct brw_sf_compile {<br>
    unsigned flag_value;<br>
<br>
    struct brw_vue_map vue_map;<br>
-   bool has_flat_shading;<br>
 };<br>
<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_sf_emit.c b/src/mesa/drivers/dri/i965/<wbr>brw_sf_emit.c<br>
index fe05d54..5f31fa5 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_sf_emit.c<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_sf_emit.c<br>
@@ -162,7 +162,7 @@ static void copy_flatshaded_attributes(<wbr>struct brw_sf_compile *c,<br>
    int i;<br>
<br>
    for (i = 0; i < c->vue_map.num_slots; i++) {<br>
-      if (c->key.interpolation_mode.<wbr>mode[i] == INTERP_MODE_FLAT) {<br>
+      if (c->key.interp_mode[i] == INTERP_MODE_FLAT) {<br>
          brw_MOV(p,<br>
                  get_vue_slot(c, dst, i),<br>
                  get_vue_slot(c, src, i));<br>
@@ -176,7 +176,7 @@ static int count_flatshaded_attributes(<wbr>struct brw_sf_compile *c)<br>
    int count = 0;<br>
<br>
    for (i = 0; i < c->vue_map.num_slots; i++)<br>
-      if (c->key.interpolation_mode.<wbr>mode[i] == INTERP_MODE_FLAT)<br>
+      if (c->key.interp_mode[i] == INTERP_MODE_FLAT)<br>
          count++;<br>
<br>
    return count;<br>
@@ -342,7 +342,7 @@ calculate_masks(struct brw_sf_compile *c,<br>
    *pc_linear = 0;<br>
    *pc = 0xf;<br>
<br>
-   interp = c->key.interpolation_mode.<wbr>mode[vert_reg_to_vue_slot(c, reg, 0)];<br>
+   interp = c->key.interp_mode[vert_reg_<wbr>to_vue_slot(c, reg, 0)];<br>
    if (interp == INTERP_MODE_SMOOTH) {<br>
       *pc_linear = 0xf;<br>
       *pc_persp = 0xf;<br>
@@ -354,7 +354,7 @@ calculate_masks(struct brw_sf_compile *c,<br>
    if (vert_reg_to_varying(c, reg, 1) != BRW_VARYING_SLOT_COUNT) {<br>
       *pc |= 0xf0;<br>
<br>
-      interp = c->key.interpolation_mode.<wbr>mode[vert_reg_to_vue_slot(c, reg, 1)];<br>
+      interp = c->key.interp_mode[vert_reg_<wbr>to_vue_slot(c, reg, 1)];<br>
       if (interp == INTERP_MODE_SMOOTH) {<br>
          *pc_linear |= 0xf0;<br>
          *pc_persp |= 0xf0;<br>
@@ -428,7 +428,7 @@ void brw_emit_tri_setup(struct brw_sf_compile *c, bool allocate)<br>
    if (c->key.do_twoside_color)<br>
       do_twoside_color(c);<br>
<br>
-   if (c->has_flat_shading)<br>
+   if (c->key.contains_flat_varying)<br>
       do_flatshade_triangle(c);<br>
<br>
<br>
@@ -514,7 +514,7 @@ void brw_emit_line_setup(struct brw_sf_compile *c, bool allocate)<br>
    invert_det(c);<br>
    copy_z_inv_w(c);<br>
<br>
-   if (c->has_flat_shading)<br>
+   if (c->key.contains_flat_varying)<br>
       do_flatshade_line(c);<br>
<br>
    for (i = 0; i < c->nr_setup_regs; i++)<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_state.h b/src/mesa/drivers/dri/i965/<wbr>brw_state.h<br>
index b42b9af..1420aab 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_state.h<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_state.h<br>
@@ -396,9 +396,6 @@ void gen7_enable_hw_binding_tables(<wbr>struct brw_context *brw);<br>
 void gen7_disable_hw_binding_<wbr>tables(struct brw_context *brw);<br>
 void gen7_reset_hw_bt_pool_offsets(<wbr>struct brw_context *brw);<br>
<br>
-/* brw_interpolation_map.c */<br>
-void brw_setup_vue_interpolation(<wbr>struct brw_context *brw);<br>
-<br>
 /* brw_clip.c */<br>
 void brw_upload_clip_prog(struct brw_context *brw);<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_state_upload.c b/src/mesa/drivers/dri/i965/<wbr>brw_state_upload.c<br>
</div></div>index 17d1b2d..17befe3 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_state_upload.c<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_state_upload.c<br>
@@ -734,13 +734,12 @@ brw_upload_programs(struct brw_context *brw,<br>
<div class="HOEnZb"><div class="h5">             ctx->Const.MaxViewports : 1;<br>
       }<br>
<br>
+      brw_upload_wm_prog(brw);<br>
+<br>
       if (brw->gen < 6) {<br>
-         brw_setup_vue_interpolation(<wbr>brw);<br>
          brw_upload_clip_prog(brw);<br>
          brw_upload_sf_prog(brw);<br>
       }<br>
-<br>
-      brw_upload_wm_prog(brw);<br>
    } else if (pipeline == BRW_COMPUTE_PIPELINE) {<br>
       brw_upload_cs_prog(brw);<br>
    }<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_wm.c b/src/mesa/drivers/dri/i965/<wbr>brw_wm.c<br>
index e65f77a..53b7d9b 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_wm.c<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_wm.c<br>
@@ -77,7 +77,8 @@ bool<br>
 brw_codegen_wm_prog(struct brw_context *brw,<br>
                     struct gl_shader_program *prog,<br>
                     struct brw_fragment_program *fp,<br>
-                    struct brw_wm_prog_key *key)<br>
+                    struct brw_wm_prog_key *key,<br>
+                    struct brw_vue_map *vue_map)<br>
 {<br>
    const struct gen_device_info *devinfo = &brw->screen->devinfo;<br>
    struct gl_context *ctx = &brw->ctx;<br>
@@ -146,8 +147,9 @@ brw_codegen_wm_prog(struct brw_context *brw,<br>
    program = brw_compile_fs(brw->screen-><wbr>compiler, brw, mem_ctx,<br>
                             key, &prog_data, fp->program.Base.nir,<br>
                             &fp->program.Base, st_index8, st_index16,<br>
-                            true, brw->use_rep_send,<br>
+                            true, brw->use_rep_send, vue_map,<br>
                             &program_size, &error_str);<br>
+<br>
    if (program == NULL) {<br>
       if (prog) {<br>
          prog->LinkStatus = false;<br>
@@ -587,7 +589,8 @@ brw_upload_wm_prog(struct brw_context *brw)<br>
                          &key, sizeof(key),<br>
                          &brw->wm.base.prog_offset,<br>
                          &brw->wm.base.prog_data)) {<br>
-      bool success = brw_codegen_wm_prog(brw, current, fp, &key);<br>
+      bool success = brw_codegen_wm_prog(brw, current, fp, &key,<br>
+                                         &brw->vue_map_geom_out);<br>
       (void) success;<br>
       assert(success);<br>
    }<br>
@@ -641,7 +644,14 @@ brw_fs_precompile(struct gl_context *ctx,<br>
    uint32_t old_prog_offset = brw->wm.base.prog_offset;<br>
    struct brw_stage_prog_data *old_prog_data = brw->wm.base.prog_data;<br>
<br>
-   bool success = brw_codegen_wm_prog(brw, shader_prog, bfp, &key);<br>
+   struct brw_vue_map vue_map;<br>
+   if (brw->gen < 6) {<br>
+      brw_compute_vue_map(&brw-><wbr>screen->devinfo, &vue_map,<br>
+                          fp->Base.nir->info->inputs_<wbr>read | VARYING_BIT_POS,<br>
+                          false);<br>
+   }<br>
+<br>
+   bool success = brw_codegen_wm_prog(brw, shader_prog, bfp, &key, &vue_map);<br>
<br>
    brw->wm.base.prog_offset = old_prog_offset;<br>
    brw->wm.base.prog_data = old_prog_data;<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_wm.h b/src/mesa/drivers/dri/i965/<wbr>brw_wm.h<br>
index 8fa24b1..f4f513b 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_wm.h<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_wm.h<br>
@@ -63,7 +63,8 @@ bool brw_color_buffer_write_<wbr>enabled(struct brw_context *brw);<br>
 bool brw_codegen_wm_prog(struct brw_context *brw,<br>
                          struct gl_shader_program *prog,<br>
                          struct brw_fragment_program *fp,<br>
-                         struct brw_wm_prog_key *key);<br>
+                         struct brw_wm_prog_key *key,<br>
+                         struct brw_vue_map *vue_map);<br>
 void brw_wm_debug_recompile(struct brw_context *brw,<br>
                             struct gl_shader_program *prog,<br>
                             const struct brw_wm_prog_key *key);<br>
--<br>
2.7.4<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</div></div></blockquote></div><br></div></div>