i965: Perform program state upload outside of atom handling
authorCarl Worth <cworth@cworth.org>
Wed, 11 Feb 2015 21:53:31 +0000 (13:53 -0800)
committerCarl Worth <cworth@cworth.org>
Mon, 23 Feb 2015 22:54:15 +0000 (14:54 -0800)
Across the board of the various generations, the intial few atoms in
all of the atom lists are basically the same, (performing uploads for
the various programs). The only difference is that prior to gen6
there's an ff_gs upload in place of the later gs upload.

In this commit, instead of using the atom lists for this program state
upload, we add a new function brw_upload_programs that calls into the
per-stage upload functions which in turn check dirty bits and return
immediately if nothing needs to be done.

This commit is intended to have no functional change. The motivation
is that future code, (such as the shader cache), wants to have a
single function within which to perform various operations before and
after program upload, (with some local variables holding state across
the upload).

It may be worth looking at whether some of the other functionality
currently handled via atoms might also be more cleanly handled in a
similar fashion.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_ff_gs.c
src/mesa/drivers/dri/i965/brw_ff_gs.h
src/mesa/drivers/dri/i965/brw_gs.c
src/mesa/drivers/dri/i965/brw_gs.h
src/mesa/drivers/dri/i965/brw_state.h
src/mesa/drivers/dri/i965/brw_state_upload.c
src/mesa/drivers/dri/i965/brw_vs.c
src/mesa/drivers/dri/i965/brw_vs.h
src/mesa/drivers/dri/i965/brw_wm.c
src/mesa/drivers/dri/i965/brw_wm.h

index 653c4b6deb3957f37babfa554e8c167ae63df28c..828e383bbd4e91256be01c61ef33b96bda5e4758 100644 (file)
@@ -221,10 +221,18 @@ static void populate_key(struct brw_context *brw,
 
 /* Calculate interpolants for triangle and line rasterization.
  */
-static void
+void
 brw_upload_ff_gs_prog(struct brw_context *brw)
 {
    struct brw_ff_gs_prog_key key;
+
+   if (!brw_state_dirty(brw,
+                        _NEW_LIGHT,
+                        BRW_NEW_PRIMITIVE |
+                        BRW_NEW_TRANSFORM_FEEDBACK |
+                        BRW_NEW_VS_PROG_DATA))
+      return;
+
    /* Populate the key:
     */
    populate_key(brw, &key);
@@ -247,13 +255,3 @@ void gen6_brw_upload_ff_gs_prog(struct brw_context *brw)
 {
    brw_upload_ff_gs_prog(brw);
 }
-
-const struct brw_tracked_state brw_ff_gs_prog = {
-   .dirty = {
-      .mesa  = _NEW_LIGHT,
-      .brw   = BRW_NEW_PRIMITIVE |
-               BRW_NEW_TRANSFORM_FEEDBACK |
-               BRW_NEW_VS_PROG_DATA,
-   },
-   .emit = brw_upload_ff_gs_prog
-};
index a538948e9ac6aebdc4b1515ab61c384142061059..e4afdab65990589216aa0938bc61c9eaf4200d7c 100644 (file)
@@ -112,4 +112,7 @@ void gen6_sol_program(struct brw_ff_gs_compile *c,
                       unsigned num_verts, bool check_edge_flag);
 void gen6_brw_upload_ff_gs_prog(struct brw_context *brw);
 
+void
+brw_upload_ff_gs_prog(struct brw_context *brw);
+
 #endif
index c7ebe5f89f80194f7fe348d611e9036b21a5c64b..1fba76a68afb28153e7e482f603c10691fa1b609 100644 (file)
@@ -292,8 +292,7 @@ do_gs_prog(struct brw_context *brw,
    return true;
 }
 
-
-static void
+void
 brw_upload_gs_prog(struct brw_context *brw)
 {
    struct gl_context *ctx = &brw->ctx;
@@ -303,6 +302,13 @@ brw_upload_gs_prog(struct brw_context *brw)
    struct brw_geometry_program *gp =
       (struct brw_geometry_program *) brw->geometry_program;
 
+   if (!brw_state_dirty(brw,
+                        _NEW_TEXTURE,
+                        BRW_NEW_GEOMETRY_PROGRAM |
+                        BRW_NEW_TRANSFORM_FEEDBACK |
+                        BRW_NEW_VUE_MAP_VS))
+      return;
+
    if (gp == NULL) {
       /* No geometry shader.  Vertex data just passes straight through. */
       if (brw->state.dirty.brw & BRW_NEW_VUE_MAP_VS) {
@@ -358,18 +364,6 @@ brw_upload_gs_prog(struct brw_context *brw)
    }
 }
 
-
-const struct brw_tracked_state brw_gs_prog = {
-   .dirty = {
-      .mesa  = _NEW_TEXTURE,
-      .brw   = BRW_NEW_GEOMETRY_PROGRAM |
-               BRW_NEW_TRANSFORM_FEEDBACK |
-               BRW_NEW_VUE_MAP_VS,
-   },
-   .emit = brw_upload_gs_prog
-};
-
-
 bool
 brw_gs_precompile(struct gl_context *ctx,
                   struct gl_shader_program *shader_prog,
index 5a15fa92018f04c1ec80b78996071ad4ac244473..5f7c437b3112b607ddfc14ef5b536fb9847ffd3d 100644 (file)
@@ -26,6 +26,8 @@
 
 #include <stdbool.h>
 
+#include "brw_context.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -36,6 +38,9 @@ struct gl_program;
 
 bool brw_gs_prog_data_compare(const void *a, const void *b);
 
+void
+brw_upload_gs_prog(struct brw_context *brw);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index f195407e88279d8b41a732a4e4752798f9a837e0..71210b9410c01e8d9a52d89653505f276a7cb3b5 100644 (file)
@@ -152,6 +152,13 @@ extern const struct brw_tracked_state gen8_vertices;
 extern const struct brw_tracked_state gen8_vf_topology;
 extern const struct brw_tracked_state gen8_vs_state;
 
+static inline bool
+brw_state_dirty(struct brw_context *brw, GLuint mesa_flags, uint64_t brw_flags)
+{
+   return ((brw->state.dirty.mesa & mesa_flags) |
+           (brw->state.dirty.brw & brw_flags)) != 0;
+}
+
 /* brw_misc_state.c */
 void brw_upload_invariant_state(struct brw_context *brw);
 uint32_t
index 84e5c104bf3ba8d6ccd77ed8a1e65949f4628bd6..1b848593de654ba9fb22788abcf7ee165a7e1418 100644 (file)
 #include "drivers/common/meta.h"
 #include "intel_batchbuffer.h"
 #include "intel_buffers.h"
+#include "brw_vs.h"
+#include "brw_ff_gs.h"
+#include "brw_gs.h"
+#include "brw_wm.h"
 
 static const struct brw_tracked_state *gen4_atoms[] =
 {
-   &brw_vs_prog, /* must do before GS prog, state base address. */
-   &brw_ff_gs_prog, /* must do before state base address */
-
    &brw_interpolation_map,
 
    &brw_clip_prog, /* must do before state base address */
    &brw_sf_prog, /* must do before state base address */
-   &brw_wm_prog, /* must do before state base address */
 
    /* Once all the programs are done, we know how large urb entry
     * sizes need to be and can decide if we need to change the urb
@@ -107,10 +107,6 @@ static const struct brw_tracked_state *gen4_atoms[] =
 
 static const struct brw_tracked_state *gen6_atoms[] =
 {
-   &brw_vs_prog, /* must do before state base address */
-   &brw_gs_prog, /* must do before state base address */
-   &brw_wm_prog, /* must do before state base address */
-
    &gen6_clip_vp,
    &gen6_sf_vp,
 
@@ -180,10 +176,6 @@ static const struct brw_tracked_state *gen6_atoms[] =
 
 static const struct brw_tracked_state *gen7_atoms[] =
 {
-   &brw_vs_prog,
-   &brw_gs_prog,
-   &brw_wm_prog,
-
    /* Command packets: */
 
    /* must do before binding table pointers, cc state ptrs */
@@ -256,10 +248,6 @@ static const struct brw_tracked_state *gen7_atoms[] =
 
 static const struct brw_tracked_state *gen8_atoms[] =
 {
-   &brw_vs_prog,
-   &brw_gs_prog,
-   &brw_wm_prog,
-
    /* Command packets: */
    &gen8_state_base_address,
 
@@ -565,6 +553,19 @@ brw_print_dirty_count(struct dirty_bit_map *bit_map)
    }
 }
 
+static void
+brw_upload_programs(struct brw_context *brw)
+{
+   brw_upload_vs_prog(brw);
+
+   if (brw->gen < 6)
+      brw_upload_ff_gs_prog(brw);
+   else
+      brw_upload_gs_prog(brw);
+
+   brw_upload_wm_prog(brw);
+}
+
 /***********************************************************************
  * Emit all state:
  */
@@ -619,6 +620,8 @@ void brw_upload_state(struct brw_context *brw)
    if (brw->gen == 6)
       intel_emit_post_sync_nonzero_flush(brw);
 
+   brw_upload_programs(brw);
+
    if (unlikely(INTEL_DEBUG)) {
       /* Debug version which enforces various sanity checks on the
        * state flags which are generated and checked to help ensure
index 2d56b749ea3caba8ac97e14caed1dc77709eae09..2aefd35832c335e011abbbd9e6e191de777942b2 100644 (file)
@@ -409,8 +409,8 @@ brw_setup_vue_key_clip_info(struct brw_context *brw,
    }
 }
 
-
-static void brw_upload_vs_prog(struct brw_context *brw)
+void
+brw_upload_vs_prog(struct brw_context *brw)
 {
    struct gl_context *ctx = &brw->ctx;
    struct brw_vs_prog_key key;
@@ -420,6 +420,17 @@ static void brw_upload_vs_prog(struct brw_context *brw)
    struct gl_program *prog = (struct gl_program *) brw->vertex_program;
    int i;
 
+   if (!brw_state_dirty(brw,
+                        _NEW_BUFFERS |
+                        _NEW_LIGHT |
+                        _NEW_POINT |
+                        _NEW_POLYGON |
+                        _NEW_TEXTURE |
+                        _NEW_TRANSFORM,
+                        BRW_NEW_VERTEX_PROGRAM |
+                        BRW_NEW_VS_ATTRIB_WORKAROUNDS))
+      return;
+
    memset(&key, 0, sizeof(key));
 
    /* Just upload the program verbatim for now.  Always send it all
@@ -482,22 +493,6 @@ static void brw_upload_vs_prog(struct brw_context *brw)
    }
 }
 
-/* See brw_vs.c:
- */
-const struct brw_tracked_state brw_vs_prog = {
-   .dirty = {
-      .mesa  = _NEW_BUFFERS |
-               _NEW_LIGHT |
-               _NEW_POINT |
-               _NEW_POLYGON |
-               _NEW_TEXTURE |
-               _NEW_TRANSFORM,
-      .brw   = BRW_NEW_VERTEX_PROGRAM |
-               BRW_NEW_VS_ATTRIB_WORKAROUNDS,
-   },
-   .emit = brw_upload_vs_prog
-};
-
 bool
 brw_vs_precompile(struct gl_context *ctx,
                   struct gl_shader_program *shader_prog,
index 93c5389a737d00b24f3d239b548f163ec0b8495a..bad0f070236402305e30a2c16e49394e641716d2 100644 (file)
@@ -72,6 +72,9 @@ 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);
 
+void
+brw_upload_vs_prog(struct brw_context *brw);
+
 #ifdef __cplusplus
 } /* extern "C" */
 
index e7939f097cb628e789e142e3e742ba198c0564e3..a0eda3a8b94537247abc54f4caf26e9f5bf1cd7d 100644 (file)
@@ -582,8 +582,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
    key->program_string_id = fp->id;
 }
 
-
-static void
+void
 brw_upload_wm_prog(struct brw_context *brw)
 {
    struct gl_context *ctx = &brw->ctx;
@@ -591,6 +590,24 @@ brw_upload_wm_prog(struct brw_context *brw)
    struct brw_fragment_program *fp = (struct brw_fragment_program *)
       brw->fragment_program;
 
+   if (!brw_state_dirty(brw,
+                        _NEW_BUFFERS |
+                        _NEW_COLOR |
+                        _NEW_DEPTH |
+                        _NEW_FRAG_CLAMP |
+                        _NEW_HINT |
+                        _NEW_LIGHT |
+                        _NEW_LINE |
+                        _NEW_MULTISAMPLE |
+                        _NEW_POLYGON |
+                        _NEW_STENCIL |
+                        _NEW_TEXTURE,
+                        BRW_NEW_FRAGMENT_PROGRAM |
+                        BRW_NEW_REDUCED_PRIMITIVE |
+                        BRW_NEW_STATS_WM |
+                        BRW_NEW_VUE_MAP_GEOM_OUT))
+      return;
+
    brw_wm_populate_key(brw, &key);
 
    if (!brw_search_cache(&brw->cache, BRW_CACHE_FS_PROG,
@@ -603,26 +620,3 @@ brw_upload_wm_prog(struct brw_context *brw)
    }
    brw->wm.base.prog_data = &brw->wm.prog_data->base;
 }
-
-
-const struct brw_tracked_state brw_wm_prog = {
-   .dirty = {
-      .mesa  = _NEW_BUFFERS |
-               _NEW_COLOR |
-               _NEW_DEPTH |
-               _NEW_FRAG_CLAMP |
-               _NEW_HINT |
-               _NEW_LIGHT |
-               _NEW_LINE |
-               _NEW_MULTISAMPLE |
-               _NEW_POLYGON |
-               _NEW_STENCIL |
-               _NEW_TEXTURE,
-      .brw   = BRW_NEW_FRAGMENT_PROGRAM |
-               BRW_NEW_REDUCED_PRIMITIVE |
-               BRW_NEW_STATS_WM |
-               BRW_NEW_VUE_MAP_GEOM_OUT,
-   },
-   .emit = brw_upload_wm_prog
-};
-
index a12c7d40a0b3042a383edc92f9b363dc9228825a..f54530f370bd07330b1c72892748ba4b0a62ac31 100644 (file)
@@ -83,4 +83,7 @@ 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);
 
+void
+brw_upload_wm_prog(struct brw_context *brw);
+
 #endif