i965: Add functions for comparing two brw_wm/vs_prog_data structs.
authorEric Anholt <eric@anholt.net>
Mon, 27 Aug 2012 04:19:05 +0000 (21:19 -0700)
committerEric Anholt <eric@anholt.net>
Fri, 7 Sep 2012 15:29:48 +0000 (08:29 -0700)
Currently, this just avoids comparing all unused parts of param[] and
pull_param[], but it's a step toward getting rid of those giant statically
sized arrays.

v2: Actually use the new function instead of just looking at its
    address.  This required changing the args to const pointers.
    (review by Kenneth)

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_state_cache.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 71cd0f4ed8711816fec590549e930889d9cd7e30..12b28bd3352a9e3b5fc361e08fcc96bd745d586b 100644 (file)
@@ -288,7 +288,10 @@ struct brw_shader_program {
 /* Data about a particular attempt to compile a program.  Note that
  * there can be many of these, each in a different GL state
  * corresponding to a different brw_wm_prog_key struct, with different
- * compiled programs:
+ * compiled programs.
+ *
+ * Note: brw_wm_prog_data_compare() must be updated when adding fields to this
+ * struct!
  */
 struct brw_wm_prog_data {
    GLuint curb_read_length;
@@ -313,8 +316,11 @@ struct brw_wm_prog_data {
     */
    uint32_t barycentric_interp_modes;
 
-   /* Pointer to tracked values (only valid once
+   /* Pointers to tracked values (only valid once
     * _mesa_load_state_parameters has been called at runtime).
+    *
+    * These must be the last fields of the struct (see
+    * brw_wm_prog_data_compare()).
     */
    const float *param[MAX_UNIFORMS * 4]; /* should be: BRW_MAX_CURBE */
    const float *pull_param[MAX_UNIFORMS * 4];
@@ -426,6 +432,9 @@ struct brw_gs_prog_data {
    unsigned svbi_postincrement_value;
 };
 
+/* Note: brw_vs_prog_data_compare() must be updated when adding fields to this
+ * struct!
+ */
 struct brw_vs_prog_data {
    struct brw_vue_map vue_map;
 
@@ -443,14 +452,15 @@ struct brw_vs_prog_data {
     */
    GLuint urb_entry_size;
 
-   const float *param[MAX_UNIFORMS * 4]; /* should be: BRW_MAX_CURBE */
-   const float *pull_param[MAX_UNIFORMS * 4];
-
    bool uses_new_param_layout;
    bool uses_vertexid;
    bool userclip;
 
    int num_surfaces;
+
+   /* These pointers must appear last.  See brw_vs_prog_data_compare(). */
+   const float *param[MAX_UNIFORMS * 4]; /* should be: BRW_MAX_CURBE */
+   const float *pull_param[MAX_UNIFORMS * 4];
 };
 
 
@@ -619,6 +629,8 @@ struct brw_cache_item {
 };   
 
 
+typedef bool (*cache_aux_compare_func)(const void *a, const void *b,
+                                       int aux_size, const void *key);
 
 struct brw_cache {
    struct brw_context *brw;
@@ -629,6 +641,13 @@ struct brw_cache {
 
    uint32_t next_offset;
    bool bo_used_by_gpu;
+
+   /**
+    * Optional functions used in determining whether the prog_data for a new
+    * cache item matches an existing cache item (in case there's relevant data
+    * outside of the prog_data).  If NULL, a plain memcmp is done.
+    */
+   cache_aux_compare_func aux_compare[BRW_MAX_CACHE];
 };
 
 
index d9cc520b62a884d5e855b0e26b1a2a53e522187f..92b81c7ad174099a2c26f9f9491e43fbe95c82fa 100644 (file)
@@ -47,6 +47,8 @@
 #include "main/imports.h"
 #include "intel_batchbuffer.h"
 #include "brw_state.h"
+#include "brw_vs.h"
+#include "brw_wm.h"
 
 #define FILE_DEBUG_FLAG DEBUG_STATE
 
@@ -211,7 +213,12 @@ brw_try_upload_using_copy(struct brw_cache *cache,
            continue;
         }
 
-        if (memcmp(item_aux, aux, item->aux_size) != 0) {
+         if (cache->aux_compare[result_item->cache_id]) {
+            if (!cache->aux_compare[result_item->cache_id](item_aux, aux,
+                                                           item->aux_size,
+                                                           item->key))
+               continue;
+         } else if (memcmp(item_aux, aux, item->aux_size) != 0) {
            continue;
         }
 
@@ -333,6 +340,9 @@ brw_init_caches(struct brw_context *brw)
    cache->bo = drm_intel_bo_alloc(intel->bufmgr,
                                  "program cache",
                                  4096, 64);
+
+   cache->aux_compare[BRW_VS_PROG] = brw_vs_prog_data_compare;
+   cache->aux_compare[BRW_WM_PROG] = brw_wm_prog_data_compare;
 }
 
 static void
index 710ffe858c6381e4e0acf623cd49c519fa80e7c7..1b111743aaf4a0c76dec9c08e08583b402c3baae 100644 (file)
@@ -186,6 +186,25 @@ gl_clip_plane *brw_select_clip_planes(struct gl_context *ctx)
    }
 }
 
+bool
+brw_vs_prog_data_compare(const void *in_a, const void *in_b,
+                         int aux_size, const void *in_key)
+{
+   const struct brw_vs_prog_data *a = in_a;
+   const struct brw_vs_prog_data *b = in_b;
+
+   /* Compare all the struct up to the pointers. */
+   if (memcmp(a, b, offsetof(struct brw_vs_prog_data, param)))
+      return false;
+
+   if (memcmp(a->param, b->param, a->nr_params * sizeof(void *)))
+      return false;
+
+   if (memcmp(a->pull_param, b->pull_param, a->nr_pull_params * sizeof(void *)))
+      return false;
+
+   return true;
+}
 
 static bool
 do_vs_prog(struct brw_context *brw,
index a68a620b1f2bf999cf900f6784999236ed691592..e69a713d08de1874e15d9c9252083c8f9dcbdbbb 100644 (file)
@@ -123,5 +123,7 @@ bool brw_vs_precompile(struct gl_context *ctx, struct gl_shader_program *prog);
 void brw_vs_debug_recompile(struct brw_context *brw,
                             struct gl_shader_program *prog,
                             const struct brw_vs_prog_key *key);
+bool brw_vs_prog_data_compare(const void *a, const void *b,
+                              int aux_size, const void *key);
 
 #endif
index 7ba13375a6915e6709439f34efbfa4f0b9cca04d..6ef8cc28372facc41fd2e46f506055d6b1f763d8 100644 (file)
@@ -253,6 +253,26 @@ brw_wm_payload_setup(struct brw_context *brw,
    }
 }
 
+bool
+brw_wm_prog_data_compare(const void *in_a, const void *in_b,
+                         int aux_size, const void *in_key)
+{
+   const struct brw_wm_prog_data *a = in_a;
+   const struct brw_wm_prog_data *b = in_b;
+
+   /* Compare all the struct up to the pointers. */
+   if (memcmp(a, b, offsetof(struct brw_wm_prog_data, param)))
+      return false;
+
+   if (memcmp(a->param, b->param, a->nr_params * sizeof(void *)))
+      return false;
+
+   if (memcmp(a->pull_param, b->pull_param, a->nr_pull_params * sizeof(void *)))
+      return false;
+
+   return true;
+}
+
 /**
  * All Mesa program -> GPU code generation goes through this function.
  * Depending on the instructions used (i.e. flow control instructions)
index 293844990995fa6758691e34695fb85ba66dde5f..d2936c21449de832cc60cbd525302f9cb03dd705 100644 (file)
@@ -484,5 +484,7 @@ bool do_wm_prog(struct brw_context *brw,
 void brw_wm_debug_recompile(struct brw_context *brw,
                             struct gl_shader_program *prog,
                             const struct brw_wm_prog_key *key);
+bool brw_wm_prog_data_compare(const void *a, const void *b,
+                              int aux_size, const void *key);
 
 #endif