i965: rewrite brw_setup_vue_interpolation()
authorTimothy Arceri <timothy.arceri@collabora.com>
Wed, 19 Oct 2016 22:59:00 +0000 (09:59 +1100)
committerTimothy Arceri <timothy.arceri@collabora.com>
Wed, 26 Oct 2016 03:29:36 +0000 (14:29 +1100)
Here brw_setup_vue_interpolation() is rewritten not to use the InterpQualifier
array in gl_fragment_program which will allow 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.

V2: Don't remove BRW_NEW_INTERPOLATION_MAP from dirty_bit_map until the following
patch to fix build error.

V3 - Suggestions by Jason:
- name struct gen4_fragment_program rather than gen5_fragment_program
- don't use enum with memset()
- create interp mode set helper and simplify logic to call it
- add assert when calling function to show prog will never be NULL for
 gen4/5 i.e. no Vulkan

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
22 files changed:
src/intel/blorp/blorp.c
src/intel/vulkan/anv_pipeline.c
src/mesa/drivers/dri/i965/brw_clip.c
src/mesa/drivers/dri/i965/brw_clip.h
src/mesa/drivers/dri/i965/brw_clip_line.c
src/mesa/drivers/dri/i965/brw_clip_tri.c
src/mesa/drivers/dri/i965/brw_clip_unfilled.c
src/mesa/drivers/dri/i965/brw_clip_util.c
src/mesa/drivers/dri/i965/brw_compiler.h
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_interpolation_map.c
src/mesa/drivers/dri/i965/brw_nir.c
src/mesa/drivers/dri/i965/brw_nir.h
src/mesa/drivers/dri/i965/brw_program.c
src/mesa/drivers/dri/i965/brw_sf.c
src/mesa/drivers/dri/i965/brw_sf.h
src/mesa/drivers/dri/i965/brw_sf_emit.c
src/mesa/drivers/dri/i965/brw_state.h
src/mesa/drivers/dri/i965/brw_state_upload.c
src/mesa/drivers/dri/i965/brw_wm.c
src/mesa/drivers/dri/i965/brw_wm.h

index 5209ee23dea7235f2b67add5e4f92509f932efae..8905cfa387357181ff45a600eb02cebf62a0ffb4 100644 (file)
@@ -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;
index 72f0643bd706da4e70ca3a11f68d3e6702b983c9..0aac71153433662440b15b7216f9c8d0ee9f5f68 100644 (file)
@@ -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);
index 1134fa43878ee0919892726ceb3c6a79e2c0889f..8646b9e0154de33c1b5d5ca3e0aa11090bd8c33b 100644 (file)
@@ -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 gen4_fragment_program *p = (struct gen4_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;
index 54c76822e224772a1bd148219e77686ce0d202ca..355ae64eefeb87bc229b2985a790324fd4fe3f6c 100644 (file)
@@ -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;
 };
 
 /**
index 2c7f85a0e60c6e72f612bc97e4c75b8af2213657..f9cabd2f98dcd41178ac6a5cf76564d1959fd1a4 100644 (file)
@@ -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
index 4caa8f5aa077da40a93bdb54248ccd17a388a3ea..52402e30bcf6324efef436aedbb28c83e48783d5 100644 (file)
@@ -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) ||
index d333d10d2998ae6234499c7b5b97acc83c1197e6..7c06857ff615fc2f75b70076d7c60669d2b19327 100644 (file)
@@ -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);
index f5d0a5ad946abf65db1ea15ab8c603cce7e30cab..4f1b0fd9fc9d834810c949eb7d20c8362bff038f 100644 (file)
@@ -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)));
index 447d05b8198115573d1527cac934cb133f0b5ccf..772c11ee170a0dbca2a3f98bf4b7dfe79c5fa143 100644 (file)
@@ -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);
 
index e190d531c80d6e29e8b24c2ece0a6aa65fbcaa0f..a40ba86d231eda5913d88997f0a339f054520765 100644 (file)
@@ -363,6 +363,20 @@ struct brw_fragment_program {
 };
 
 
+struct gen4_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 +399,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 +1261,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;
index ea8c2e67d545c4fa6533be5b2f37d20f78c936d0..f839d368f3c8a0185566a6d3928d0cdd2cb9a222 100644 (file)
@@ -6415,14 +6415,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);
index 097987b4684540956a202fc9a0f98959bb9c3d98..fe14ea33f45bc5dec41fad5fc1af311c9ecf0df3 100644 (file)
@@ -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)
@@ -35,61 +36,61 @@ static char const *get_qual_name(int mode)
    }
 }
 
+static void
+gen4_frag_prog_set_interp_modes(struct gen4_fragment_program *prog,
+                                struct brw_vue_map *vue_map,
+                                unsigned location, unsigned slot_count,
+                                enum glsl_interp_mode interp)
+{
+   for (unsigned k = 0; k < slot_count; k++) {
+      unsigned slot = vue_map->varying_to_slot[location + k];
+      if (slot != -1 && prog->interp_mode[slot] == INTERP_MODE_NONE) {
+         prog->interp_mode[slot] = interp;
+
+         if (prog->interp_mode[slot] == INTERP_MODE_FLAT) {
+            prog->contains_flat_varying = true;
+         } else if (prog->interp_mode[slot] == INTERP_MODE_NOPERSPECTIVE) {
+            prog->contains_noperspective_varying = true;
+         }
+      }
+   }
+}
 
 /* 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;
-
-   if (!brw_state_dirty(brw,
-                        _NEW_LIGHT,
-                        BRW_NEW_BLORP |
-                        BRW_NEW_FRAGMENT_PROGRAM |
-                        BRW_NEW_VUE_MAP_GEOM_OUT))
-      return;
+   struct gen4_fragment_program *fprog = (struct gen4_fragment_program *) prog;
 
-   memset(&brw->interpolation_mode, INTERP_MODE_NONE, sizeof(brw->interpolation_mode));
+   /* Initialise interp_mode. INTERP_MODE_NONE == 0 */
+   memset(fprog->interp_mode, 0, sizeof(fprog->interp_mode));
 
-   brw->ctx.NewDriverState |= BRW_NEW_INTERPOLATION_MAP;
-
-   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. */
-      if (varying == VARYING_SLOT_POS) {
-         brw->interpolation_mode.mode[i] = INTERP_MODE_NOPERSPECTIVE;
-         continue;
-      }
-
-      int frag_attrib = varying;
-      if (varying == VARYING_SLOT_BFC0 || varying == VARYING_SLOT_BFC1)
-         frag_attrib = varying - VARYING_SLOT_BFC0 + VARYING_SLOT_COL0;
+   /* 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;
+   }
 
-      if (!(fprog->Base.nir->info->inputs_read & BITFIELD64_BIT(frag_attrib)))
-         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);
 
-      enum glsl_interp_mode mode = fprog->InterpQualifier[frag_attrib];
+      gen4_frag_prog_set_interp_modes(fprog, vue_map, location, slot_count,
+                                      var->data.interpolation);
 
-      /* 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;
+      if (location == VARYING_SLOT_COL0 || location == VARYING_SLOT_COL1) {
+         location = location + VARYING_SLOT_BFC0 - VARYING_SLOT_COL0;
+         gen4_frag_prog_set_interp_modes(fprog, vue_map, location,
+                                         slot_count, var->data.interpolation);
       }
-
-      brw->interpolation_mode.mode[i] = mode;
    }
 
    if (unlikely(INTEL_DEBUG & DEBUG_VUE)) {
@@ -103,7 +104,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));
       }
    }
index 7334f68db3de4dad7f02e0c7310980f2a756e42f..ec48da9f2f8de951cfd5984a8d38ff2a42c57caa 100644 (file)
@@ -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,11 @@ brw_nir_lower_fs_inputs(nir_shader *nir,
       }
    }
 
+   if (devinfo->gen < 6) {
+      assert(prog); /* prog will be NULL when called from Vulkan */
+      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;
index 645a818c4e500de570644dffba991607ad0080d0..3c774d040334a63d4673fc7cffec23a7db3b699c 100644 (file)
@@ -104,7 +104,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);
index 7516baf1e1f830485956115c658f43edc05b1d9e..3176dc4ef284582a868fe498a4b6b41a444e704f 100644 (file)
@@ -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 gen4_fragment_program *g4_prog =
+            CALLOC_STRUCT(gen4_fragment_program);
+         prog = &g4_prog->base;
+      } else {
+         prog = CALLOC_STRUCT(brw_fragment_program);
+      }
+
       if (prog) {
         prog->id = get_new_program_id(brw->screen);
 
index 094260e2a1ff63f1e889f9183b80a7705f08bd5a..b0ed712f0a35eb1210881eab04815496bf95f359 100644 (file)
@@ -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 gen4_fragment_program *p = (struct gen4_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) ||
index 15102ac6119fb9926ddcac9ac8bd7396611562c4..ce4b2e36a8cd584d9eebb5c7f9d439ce0f5d914f 100644 (file)
@@ -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;
 };
 
 
index fe05d547fbcd28fe8842ff56ec2a8812ef415479..5f31fa51602dd59e26b9031e70365ee587eaba5a 100644 (file)
@@ -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++)
index b42b9af40738fe123ae7c88e4309b761da1266bd..1420aaba59eb00c0931ef6fe23b4a1b4f5121e25 100644 (file)
@@ -396,9 +396,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);
 
index 17d1b2df59935185fd1b46291ebf9f0657b23917..17befe37defc73fde9fbf2272a14b3b5154312ef 100644 (file)
@@ -734,13 +734,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);
    }
index e65f77a8c43ed97fd5609656e1d7f161a016beb7..53b7d9bd91e080d7cb613b613afeab0855aa93f5 100644 (file)
@@ -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;
index 8fa24b1ae4833d265dd91f9663b09ece8b1fd93b..f4f513bef0a214256b5f3eb72d6575747680c6b3 100644 (file)
@@ -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);