[Mesa-dev] [RFC: PATCH 4/4] i965: Refactor all upload_<stage>_prog functions up into brw_upload_programs

Carl Worth cworth at cworth.org
Fri Mar 20 17:49:09 PDT 2015


This completes the refactoring being prepared for in the previous
commits. The function bodies of all brw_upadload_<stage>_prog
functions are pulled up into brw_upload_programs where there are
unified with loops and switch statements.

The purpose of this refactoring is to allow for new code to
be added after all programs have been queried from the in-memory
cache, but before any programs have been recompiled. It's exactly at
that point that we want to add the check of the on-disk cache.

(Previously, there was no such single point in the
execution---instead, for each stage there was a point in
brw_upload_<stage>_prog after the in-memory-cache query and before the
recompile.)

This commit is intended to have no functional change, but whether that
is actually achieved is not as clearly obvious as in the previous few
commits.
---

On this patch in particular, I would appreciate some review.

This may be entirely broken, (or a freak failure happened which
aborted the test run I tried---I'm not sure which). I'm only sending
this out ine spite of the inconclusive testing because I'm about to be
gone on vacation for a week, and I could use some input here.

With this patch, it would be possible to have the new code act 100%
identical to the code before, but I don't think that would be
useful. Keeping all of the ordering, etc. exactly the same would
complicate the code more than necesary, (especially when the final
results don't actually depend on the order, etc.).

But since I'm not the most familiar with this code and all of its side
effects, I could use some input from others who might know it
better. So if you've got any high-level input on how you think the
code should look, I'd like to hear it.

Most of the state complexity is dealing with the fixed-function GS
stuff. Take a look if you can.

Thanks,

-Carl

 src/mesa/drivers/dri/i965/brw_ff_gs.c        |  39 +----
 src/mesa/drivers/dri/i965/brw_ff_gs.h        |  11 +-
 src/mesa/drivers/dri/i965/brw_gs.c           |  62 +------
 src/mesa/drivers/dri/i965/brw_gs.h           |  13 +-
 src/mesa/drivers/dri/i965/brw_state_upload.c | 251 ++++++++++++++++++++++++++-
 src/mesa/drivers/dri/i965/brw_vs.c           |  45 +----
 src/mesa/drivers/dri/i965/brw_vs.h           |  12 +-
 src/mesa/drivers/dri/i965/brw_wm.c           |  32 +---
 src/mesa/drivers/dri/i965/brw_wm.h           |   6 +-
 9 files changed, 295 insertions(+), 176 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_ff_gs.c b/src/mesa/drivers/dri/i965/brw_ff_gs.c
index 8bc0a1c..6ae7ffa 100644
--- a/src/mesa/drivers/dri/i965/brw_ff_gs.c
+++ b/src/mesa/drivers/dri/i965/brw_ff_gs.c
@@ -45,7 +45,7 @@
 
 #include "util/ralloc.h"
 
-static void
+void
 brw_ff_gs_compile(struct brw_context *brw,
 		  struct brw_ff_gs_prog_key *key)
 {
@@ -148,7 +148,7 @@ brw_ff_gs_compile(struct brw_context *brw,
    ralloc_free(mem_ctx);
 }
 
-static bool
+bool
 brw_ff_gs_state_dirty(struct brw_context *brw)
 {
    return brw_state_dirty(brw,
@@ -158,7 +158,7 @@ brw_ff_gs_state_dirty(struct brw_context *brw)
 			  BRW_NEW_VS_PROG_DATA);
 }
 
-static void
+void
 brw_ff_gs_populate_key(struct brw_context *brw,
 		       struct brw_ff_gs_prog_key *key)
 {
@@ -230,36 +230,3 @@ brw_ff_gs_populate_key(struct brw_context *brw,
                            brw->primitive == _3DPRIM_LINELOOP);
    }
 }
-
-/* Calculate interpolants for triangle and line rasterization.
- */
-void
-brw_upload_ff_gs_prog(struct brw_context *brw)
-{
-   struct brw_ff_gs_prog_key key;
-
-   if (!brw_ff_gs_state_dirty(brw))
-      return;
-
-   /* Populate the key:
-    */
-   brw_ff_gs_populate_key(brw, &key);
-
-   if (brw->ff_gs.prog_active != key.need_gs_prog) {
-      brw->state.dirty.brw |= BRW_NEW_FF_GS_PROG_DATA;
-      brw->ff_gs.prog_active = key.need_gs_prog;
-   }
-
-   if (brw->ff_gs.prog_active) {
-      if (!brw_search_cache(&brw->cache, BRW_CACHE_FF_GS_PROG,
-			    &key, sizeof(key),
-			    &brw->ff_gs.prog_offset, &brw->ff_gs.prog_data)) {
-	 brw_ff_gs_compile(brw, &key);
-      }
-   }
-}
-
-void gen6_brw_upload_ff_gs_prog(struct brw_context *brw)
-{
-   brw_upload_ff_gs_prog(brw);
-}
diff --git a/src/mesa/drivers/dri/i965/brw_ff_gs.h b/src/mesa/drivers/dri/i965/brw_ff_gs.h
index e4afdab..1f831a2 100644
--- a/src/mesa/drivers/dri/i965/brw_ff_gs.h
+++ b/src/mesa/drivers/dri/i965/brw_ff_gs.h
@@ -110,9 +110,16 @@ void brw_ff_gs_lines(struct brw_ff_gs_compile *c);
 void gen6_sol_program(struct brw_ff_gs_compile *c,
                       struct brw_ff_gs_prog_key *key,
                       unsigned num_verts, bool check_edge_flag);
-void gen6_brw_upload_ff_gs_prog(struct brw_context *brw);
+
+bool
+brw_ff_gs_state_dirty(struct brw_context *brw);
+
+void
+brw_ff_gs_populate_key(struct brw_context *brw,
+		       struct brw_ff_gs_prog_key *key);
 
 void
-brw_upload_ff_gs_prog(struct brw_context *brw);
+brw_ff_gs_compile(struct brw_context *brw,
+		  struct brw_ff_gs_prog_key *key);
 
 #endif
diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c
index a0da919..15da587 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.c
+++ b/src/mesa/drivers/dri/i965/brw_gs.c
@@ -33,8 +33,7 @@
 #include "brw_state.h"
 #include "brw_ff_gs.h"
 
-
-static bool
+bool
 brw_gs_compile(struct brw_context *brw,
 	       struct gl_shader_program *prog,
 	       struct brw_geometry_program *gp,
@@ -288,7 +287,7 @@ brw_gs_compile(struct brw_context *brw,
    return true;
 }
 
-static bool
+bool
 brw_gs_state_dirty(struct brw_context *brw)
 {
    return brw_state_dirty(brw,
@@ -298,7 +297,7 @@ brw_gs_state_dirty(struct brw_context *brw)
 			  BRW_NEW_VUE_MAP_VS);
 }
 
-static void
+void
 brw_gs_populate_key(struct brw_context *brw,
 		    struct brw_gs_prog_key *key)
 {
@@ -322,61 +321,6 @@ brw_gs_populate_key(struct brw_context *brw,
    key->input_varyings = brw->vue_map_vs.slots_valid;
 }
 
-void
-brw_upload_gs_prog(struct brw_context *brw)
-{
-   struct gl_context *ctx = &brw->ctx;
-   struct brw_stage_state *stage_state = &brw->gs.base;
-   struct brw_gs_prog_key key;
-   /* BRW_NEW_GEOMETRY_PROGRAM */
-   struct brw_geometry_program *gp =
-      (struct brw_geometry_program *) brw->geometry_program;
-
-   if (!brw_gs_state_dirty(brw))
-      return;
-
-   if (gp == NULL) {
-      /* No geometry shader.  Vertex data just passes straight through. */
-      if (brw->state.dirty.brw & BRW_NEW_VUE_MAP_VS) {
-         brw->vue_map_geom_out = brw->vue_map_vs;
-         brw->state.dirty.brw |= BRW_NEW_VUE_MAP_GEOM_OUT;
-      }
-
-      if (brw->gen == 6 &&
-          (brw->state.dirty.brw & BRW_NEW_TRANSFORM_FEEDBACK)) {
-         gen6_brw_upload_ff_gs_prog(brw);
-         return;
-      }
-
-      /* Other state atoms had better not try to access prog_data, since
-       * there's no GS program.
-       */
-      brw->gs.prog_data = NULL;
-      brw->gs.base.prog_data = NULL;
-
-      return;
-   }
-
-   brw_gs_populate_key(brw, &key);
-
-   if (!brw_search_cache(&brw->cache, BRW_CACHE_GS_PROG,
-                         &key, sizeof(key),
-                         &stage_state->prog_offset, &brw->gs.prog_data)) {
-      bool success =
-         brw_gs_compile(brw, ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY],
-			gp, &key);
-      assert(success);
-      (void)success;
-   }
-   brw->gs.base.prog_data = &brw->gs.prog_data->base.base;
-
-   if (memcmp(&brw->gs.prog_data->base.vue_map, &brw->vue_map_geom_out,
-              sizeof(brw->vue_map_geom_out)) != 0) {
-      brw->vue_map_geom_out = brw->gs.prog_data->base.vue_map;
-      brw->state.dirty.brw |= BRW_NEW_VUE_MAP_GEOM_OUT;
-   }
-}
-
 bool
 brw_gs_precompile(struct gl_context *ctx,
                   struct gl_shader_program *shader_prog,
diff --git a/src/mesa/drivers/dri/i965/brw_gs.h b/src/mesa/drivers/dri/i965/brw_gs.h
index 5f7c437..922b321 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.h
+++ b/src/mesa/drivers/dri/i965/brw_gs.h
@@ -27,6 +27,7 @@
 #include <stdbool.h>
 
 #include "brw_context.h"
+#include "brw_program.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -38,8 +39,18 @@ struct gl_program;
 
 bool brw_gs_prog_data_compare(const void *a, const void *b);
 
+bool
+brw_gs_state_dirty(struct brw_context *brw);
+
 void
-brw_upload_gs_prog(struct brw_context *brw);
+brw_gs_populate_key(struct brw_context *brw,
+		    struct brw_gs_prog_key *key);
+
+bool
+brw_gs_compile(struct brw_context *brw,
+	       struct gl_shader_program *prog,
+	       struct brw_geometry_program *gp,
+	       struct brw_gs_prog_key *key);
 
 #ifdef __cplusplus
 } /* extern "C" */
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index 1b84859..d5ded74 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -553,17 +553,256 @@ brw_print_dirty_count(struct dirty_bit_map *bit_map)
    }
 }
 
+struct key_block
+{
+   struct brw_vs_prog_key vs_key;
+   struct brw_ff_gs_prog_key ff_gs_key;
+   struct brw_gs_prog_key gs_key;
+   struct brw_wm_prog_key wm_key;
+};
+
+/* All of the following "per_stage" functions expect only one of four
+ * possible values for 'stage'.
+ */
+static inline bool
+per_stage_valid(enum brw_cache_id stage)
+{
+   return (stage == BRW_CACHE_VS_PROG ||
+	   stage == BRW_CACHE_FF_GS_PROG ||
+	   stage == BRW_CACHE_GS_PROG ||
+	   stage == BRW_CACHE_FS_PROG);
+}
+
+static bool
+per_stage_state_dirty(struct brw_context *brw,
+		      enum brw_cache_id stage)
+{
+   switch (stage) {
+   case BRW_CACHE_VS_PROG:
+      return brw_vs_state_dirty(brw);
+   case BRW_CACHE_FF_GS_PROG:
+      return brw_ff_gs_state_dirty(brw);
+   case BRW_CACHE_GS_PROG:
+      return brw_gs_state_dirty(brw);
+   case BRW_CACHE_FS_PROG:
+      return brw_wm_state_dirty(brw);
+   default:
+      unreachable("not reached");
+   }
+}
+
+static void
+per_stage_populate_key(struct brw_context *brw,
+		       enum brw_cache_id stage,
+		       struct key_block *key_block,
+		       void **key_ret,
+		       size_t *key_size_ret,
+		       uint32_t **prog_offset_ret,
+		       void **prog_data_ret)
+{
+   switch (stage) {
+   case BRW_CACHE_VS_PROG:
+      brw_vs_populate_key(brw, &key_block->vs_key);
+      *key_ret = &key_block->vs_key;
+      *key_size_ret = sizeof(key_block->vs_key);
+      *prog_offset_ret = &brw->vs.base.prog_offset;
+      *prog_data_ret = &brw->vs.prog_data;
+      break;
+   case BRW_CACHE_FF_GS_PROG:
+      brw_ff_gs_populate_key(brw, &key_block->ff_gs_key);
+      *key_ret = &key_block->ff_gs_key;
+      *key_size_ret = sizeof(key_block->ff_gs_key);
+      *prog_offset_ret = &brw->ff_gs.prog_offset;
+      *prog_data_ret = &brw->ff_gs.prog_data;
+      break;
+   case BRW_CACHE_GS_PROG:
+      brw_gs_populate_key(brw, &key_block->gs_key);
+      *key_ret = &key_block->gs_key;
+      *key_size_ret = sizeof(key_block->gs_key);
+      *prog_offset_ret = &brw->gs.base.prog_offset;
+      *prog_data_ret = &brw->gs.prog_data;
+      break;
+   case BRW_CACHE_FS_PROG:
+      brw_wm_populate_key(brw, &key_block->wm_key);
+      *key_ret = &key_block->wm_key;
+      *key_size_ret = sizeof(key_block->wm_key);
+      *prog_offset_ret = &brw->wm.base.prog_offset;
+      *prog_data_ret = &brw->wm.prog_data;
+      break;
+   default:
+      unreachable("not reached");
+      break;
+   }
+}
+
+static bool
+per_stage_compile(struct brw_context *brw,
+		  enum brw_cache_id stage,
+		  struct key_block *key_block)
+{
+   struct gl_context *ctx = &brw->ctx;
+   struct brw_vertex_program *vp =
+      (struct brw_vertex_program *) brw->vertex_program;
+   struct brw_geometry_program *gp =
+      (struct brw_geometry_program *) brw->geometry_program;
+   struct brw_fragment_program *fp =
+      (struct brw_fragment_program *) brw->fragment_program;
+
+   switch (stage) {
+   case BRW_CACHE_VS_PROG:
+      return brw_vs_compile(brw,
+			    ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX],
+			    vp, &key_block->vs_key);
+   case BRW_CACHE_FF_GS_PROG:
+      brw_ff_gs_compile(brw, &key_block->ff_gs_key);
+      return true;
+   case BRW_CACHE_GS_PROG:
+      return brw_gs_compile(brw,
+			    ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY],
+			    gp, &key_block->gs_key);
+   case BRW_CACHE_FS_PROG:
+      return brw_wm_compile(brw, ctx->_Shader->_CurrentFragmentProgram,
+			    fp, &key_block->wm_key);
+   default:
+      unreachable("not reached");
+      break;
+   }
+}
+
+static void
+per_stage_update_prog_data_and_vue_map(struct brw_context *brw,
+				       enum brw_cache_id stage)
+{
+   struct brw_geometry_program *gp =
+      (struct brw_geometry_program *) brw->geometry_program;
+
+   switch (stage) {
+   case BRW_CACHE_VS_PROG:
+      brw->vs.base.prog_data = &brw->vs.prog_data->base.base;
+
+      if (memcmp(&brw->vs.prog_data->base.vue_map, &brw->vue_map_geom_out,
+		 sizeof(brw->vue_map_geom_out)) != 0) {
+	 brw->vue_map_vs = brw->vs.prog_data->base.vue_map;
+	 brw->state.dirty.brw |= BRW_NEW_VUE_MAP_VS;
+	 if (brw->gen < 6 || gp == NULL) {
+	    /* No geometry shader support, so the VS VUE map is the VUE map for
+	     * the output of the "geometry" portion of the pipeline.
+	     */
+	    brw->vue_map_geom_out = brw->vue_map_vs;
+	    brw->state.dirty.brw |= BRW_NEW_VUE_MAP_GEOM_OUT;
+	 }
+      }
+      break;
+   case BRW_CACHE_FF_GS_PROG:
+      break;
+   case BRW_CACHE_GS_PROG:
+      brw->gs.base.prog_data = &brw->gs.prog_data->base.base;
+      if (memcmp(&brw->gs.prog_data->base.vue_map, &brw->vue_map_geom_out,
+		 sizeof(brw->vue_map_geom_out)) != 0) {
+	 brw->vue_map_geom_out = brw->gs.prog_data->base.vue_map;
+	 brw->state.dirty.brw |= BRW_NEW_VUE_MAP_GEOM_OUT;
+      }
+      break;
+   case BRW_CACHE_FS_PROG:
+      brw->wm.base.prog_data = &brw->wm.prog_data->base;
+      break;
+   default:
+      unreachable("not reached");
+   }
+}
+
 static void
 brw_upload_programs(struct brw_context *brw)
 {
-   brw_upload_vs_prog(brw);
+   bool need_new_program[BRW_MAX_CACHE];
+   struct key_block key_block;
+   struct brw_geometry_program *gp =
+      (struct brw_geometry_program *) brw->geometry_program;
+   void *key;
+   size_t key_size;
+   uint32_t *prog_offset;
+   void *prog_data;
+   enum brw_cache_id stage;
+   bool fixed_function_gs;
+
+   /* Clear all of our bools before beginning. */
+   for (stage = 0; stage < BRW_MAX_CACHE; stage++) {
+      need_new_program[stage] = false;
+   }
+
+   /* Decide up front whether to use fixed-function GS support */
+   fixed_function_gs = (brw->gen < 6);
+
+   /* Check dirty bits for each stage. */
+   for (stage = 0; stage < BRW_MAX_CACHE; stage++) {
+      if (!per_stage_valid(stage))
+	  continue;
+
+      /* We'll use either FF_GS or GS, but not both. */
+      if (fixed_function_gs) {
+	 if (stage == BRW_CACHE_GS_PROG)
+	    continue;
+      } else {
+	 if (stage == BRW_CACHE_FF_GS_PROG)
+	    continue;
+      }
+
+      need_new_program[stage] = per_stage_state_dirty(brw, stage);
+   }
 
-   if (brw->gen < 6)
-      brw_upload_ff_gs_prog(brw);
-   else
-      brw_upload_gs_prog(brw);
+   /* As a special case, supply the fixed-function GS program if a GS
+    * program is needed but has not been rovided.
+    */
+   if (need_new_program[BRW_CACHE_GS_PROG] && gp == NULL)
+   {
+      if (brw->gen == 6 &&
+	  (brw->state.dirty.brw & BRW_NEW_TRANSFORM_FEEDBACK))
+      {
+	 fixed_function_gs = true;
+	 need_new_program[BRW_CACHE_FF_GS_PROG] =
+	    per_stage_state_dirty(brw, BRW_CACHE_FF_GS_PROG);
+      }
+   }
+   if (fixed_function_gs) {
+      if (brw->ff_gs.prog_active != key_block.ff_gs_key.need_gs_prog) {
+	 brw->state.dirty.brw |= BRW_NEW_FF_GS_PROG_DATA;
+	 brw->ff_gs.prog_active = key_block.ff_gs_key.need_gs_prog;
+	 need_new_program[BRW_CACHE_FF_GS_PROG] = false;
+      }
+   } else {
+      if (gp == NULL) {
+	 /* Other state atoms had better not try to access prog_data, since
+	  * there's no GS program.
+	  */
+	 brw->gs.prog_data = NULL;
+	 brw->gs.base.prog_data = NULL;
+	 need_new_program[BRW_CACHE_GS_PROG] = false;
+      }
+   }
+
+   /* For each stage where a new program is needed, either find it in
+    * the in-meory cache or else compile it.
+    */
+   for (stage = 0; stage < BRW_MAX_CACHE; stage++) {
+      if (!per_stage_valid(stage))
+	 continue;
+
+      if (!need_new_program[stage])
+	 continue;
+
+      per_stage_populate_key(brw, stage, &key_block, &key, &key_size,
+			     &prog_offset, &prog_data);
+
+      if (!brw_search_cache(&brw->cache, stage, key, key_size,
+			    prog_offset, prog_data))
+      {
+	 bool success = per_stage_compile(brw, stage, &key_block);
+	 (void) success;
+	 assert(success);
+      }
 
-   brw_upload_wm_prog(brw);
+      per_stage_update_prog_data_and_vue_map(brw, stage);
+   }
 }
 
 /***********************************************************************
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index e5a55a7..068ce07 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -187,7 +187,7 @@ brw_vs_prog_data_compare(const void *in_a, const void *in_b)
    return true;
 }
 
-static bool
+bool
 brw_vs_compile(struct brw_context *brw,
 	       struct gl_shader_program *prog,
 	       struct brw_vertex_program *vp,
@@ -401,7 +401,7 @@ brw_setup_vue_key_clip_info(struct brw_context *brw,
    }
 }
 
-static bool
+bool
 brw_vs_state_dirty(struct brw_context *brw)
 {
    return brw_state_dirty(brw,
@@ -415,7 +415,7 @@ brw_vs_state_dirty(struct brw_context *brw)
 			  BRW_NEW_VS_ATTRIB_WORKAROUNDS);
 }
 
-static void
+void
 brw_vs_populate_key(struct brw_context *brw,
                     struct brw_vs_prog_key *key)
 {
@@ -464,45 +464,6 @@ brw_vs_populate_key(struct brw_context *brw,
           sizeof(brw->vb.attrib_wa_flags));
 }
 
-void
-brw_upload_vs_prog(struct brw_context *brw)
-{
-   struct gl_context *ctx = &brw->ctx;
-   struct brw_vs_prog_key key;
-   /* BRW_NEW_VERTEX_PROGRAM */
-   struct brw_vertex_program *vp =
-      (struct brw_vertex_program *)brw->vertex_program;
-
-   if (!brw_vs_state_dirty(brw))
-      return;
-
-   brw_vs_populate_key(brw, &key);
-
-   if (!brw_search_cache(&brw->cache, BRW_CACHE_VS_PROG,
-			 &key, sizeof(key),
-			 &brw->vs.base.prog_offset, &brw->vs.prog_data)) {
-      bool success =
-         brw_vs_compile(brw,ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX],
-			vp, &key);
-      (void) success;
-      assert(success);
-   }
-   brw->vs.base.prog_data = &brw->vs.prog_data->base.base;
-
-   if (memcmp(&brw->vs.prog_data->base.vue_map, &brw->vue_map_geom_out,
-              sizeof(brw->vue_map_geom_out)) != 0) {
-      brw->vue_map_vs = brw->vs.prog_data->base.vue_map;
-      brw->state.dirty.brw |= BRW_NEW_VUE_MAP_VS;
-      if (brw->gen < 6) {
-         /* No geometry shader support, so the VS VUE map is the VUE map for
-          * the output of the "geometry" portion of the pipeline.
-          */
-         brw->vue_map_geom_out = brw->vue_map_vs;
-         brw->state.dirty.brw |= BRW_NEW_VUE_MAP_GEOM_OUT;
-      }
-   }
-}
-
 bool
 brw_vs_precompile(struct gl_context *ctx,
                   struct gl_shader_program *shader_prog,
diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h
index bad0f07..d93ee1b 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.h
+++ b/src/mesa/drivers/dri/i965/brw_vs.h
@@ -72,8 +72,18 @@ void brw_vs_debug_recompile(struct brw_context *brw,
                             const struct brw_vs_prog_key *key);
 bool brw_vs_prog_data_compare(const void *a, const void *b);
 
+bool
+brw_vs_state_dirty(struct brw_context *brw);
+
 void
-brw_upload_vs_prog(struct brw_context *brw);
+brw_vs_populate_key(struct brw_context *brw,
+                    struct brw_vs_prog_key *key);
+
+bool
+brw_vs_compile(struct brw_context *brw,
+	       struct gl_shader_program *prog,
+	       struct brw_vertex_program *vp,
+	       struct brw_vs_prog_key *key);
 
 #ifdef __cplusplus
 } /* extern "C" */
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 15cd6aa..054937b 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -422,7 +422,7 @@ brw_populate_sampler_prog_key_data(struct gl_context *ctx,
    }
 }
 
-static bool
+bool
 brw_wm_state_dirty (struct brw_context *brw)
 {
    return brw_state_dirty(brw,
@@ -443,8 +443,9 @@ brw_wm_state_dirty (struct brw_context *brw)
 			  BRW_NEW_VUE_MAP_GEOM_OUT);
 }
 
-static void brw_wm_populate_key( struct brw_context *brw,
-				 struct brw_wm_prog_key *key )
+void
+brw_wm_populate_key( struct brw_context *brw,
+		     struct brw_wm_prog_key *key )
 {
    struct gl_context *ctx = &brw->ctx;
    /* BRW_NEW_FRAGMENT_PROGRAM */
@@ -603,28 +604,3 @@ static void brw_wm_populate_key( struct brw_context *brw,
    /* The unique fragment program ID */
    key->program_string_id = fp->id;
 }
-
-void
-brw_upload_wm_prog(struct brw_context *brw)
-{
-   struct gl_context *ctx = &brw->ctx;
-   struct brw_wm_prog_key key;
-   struct brw_fragment_program *fp = (struct brw_fragment_program *)
-      brw->fragment_program;
-
-   if (!brw_wm_state_dirty(brw))
-      return;
-
-   brw_wm_populate_key(brw, &key);
-
-   if (!brw_search_cache(&brw->cache, BRW_CACHE_FS_PROG,
-			 &key, sizeof(key),
-			 &brw->wm.base.prog_offset, &brw->wm.prog_data)) {
-      bool success =
-	 brw_wm_compile(brw, ctx->_Shader->_CurrentFragmentProgram,
-			fp, &key);
-      (void) success;
-      assert(success);
-   }
-   brw->wm.base.prog_data = &brw->wm.prog_data->base;
-}
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index ea7abe3..0344ccc 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -87,8 +87,12 @@ void brw_wm_debug_recompile(struct brw_context *brw,
                             const struct brw_wm_prog_key *key);
 bool brw_wm_prog_data_compare(const void *a, const void *b);
 
+bool
+brw_wm_state_dirty (struct brw_context *brw);
+
 void
-brw_upload_wm_prog(struct brw_context *brw);
+brw_wm_populate_key( struct brw_context *brw,
+		     struct brw_wm_prog_key *key );
 
 #ifdef __cplusplus
 } // extern "C"
-- 
2.1.4



More information about the mesa-dev mailing list