i965: Skip recalculating URB allocations if the entry size didn't change.
authorEric Anholt <eric@anholt.net>
Tue, 6 May 2014 23:37:05 +0000 (16:37 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Sat, 25 Oct 2014 06:17:14 +0000 (23:17 -0700)
We only get here if the VS/GS compiled programs change, but we can even
skip it if the VS/GS size didn't change.

Affects cairo runtime on glamor by -1.26471% +/- 0.674335% (n=234)

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_context.c
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/gen6_urb.c
src/mesa/drivers/dri/i965/gen7_urb.c

index 8b3f45b68d8c08d869ef70ff738e0c7d58a6b462..e1a994a6ddefd04c766022e15abf0494f653f7cf 100644 (file)
@@ -814,7 +814,7 @@ brwCreateContext(gl_api api,
    brw->max_gtt_map_object_size = gtt_size / 4;
 
    if (brw->gen == 6)
-      brw->urb.gen6_gs_previously_active = false;
+      brw->urb.gs_present = false;
 
    brw->prim_restart.in_progress = false;
    brw->prim_restart.enable_cut_index = false;
index 45d72d2ced49a25ea1c0cb72097b1c7743f55023..eb37e750f6db9762d65ec7ba8a36882c92c59a25 100644 (file)
@@ -1169,6 +1169,7 @@ struct brw_context
     */
    struct {
       GLuint vsize;            /* vertex size plus header in urb registers */
+      GLuint gsize;            /* GS output size in urb registers */
       GLuint csize;            /* constant buffer size in urb registers */
       GLuint sfsize;           /* setup data size in urb registers */
 
@@ -1191,10 +1192,10 @@ struct brw_context
       GLuint cs_start;
       GLuint size; /* Hardware URB size, in KB. */
 
-      /* gen6: True if the most recently sent _3DSTATE_URB message allocated
+      /* True if the most recently sent _3DSTATE_URB message allocated
        * URB space for the GS.
        */
-      bool gen6_gs_previously_active;
+      bool gs_present;
    } urb;
 
 
index 7af1f37bad8fa28061256bd3a3569d6744caeb28..46cc4cc2976668445f5ed9145ae4c9695ee2a8dc 100644 (file)
@@ -119,9 +119,9 @@ gen6_upload_urb( struct brw_context *brw )
     * doesn't exist on Gen6).  So for now we just do a full pipeline flush as
     * a workaround.
     */
-   if (brw->urb.gen6_gs_previously_active && !gs_present)
+   if (brw->urb.gs_present && !gs_present)
       intel_batchbuffer_emit_mi_flush(brw);
-   brw->urb.gen6_gs_previously_active = gs_present;
+   brw->urb.gs_present = gs_present;
 }
 
 const struct brw_tracked_state gen6_urb = {
index 190d6f07493424f461e2e938aef10f49ece77b3e..eb3784a846bd41bd63e2f177ddaf62a714604362 100644 (file)
@@ -150,6 +150,19 @@ gen7_upload_urb(struct brw_context *brw)
    unsigned gs_size = gs_present ? brw->gs.prog_data->base.urb_entry_size : 1;
    unsigned gs_entry_size_bytes = gs_size * 64;
 
+   /* If we're just switching between programs with the same URB requirements,
+    * skip the rest of the logic.
+    */
+   if (!(brw->state.dirty.brw & BRW_NEW_CONTEXT) &&
+       brw->urb.vsize == vs_size &&
+       brw->urb.gs_present == gs_present &&
+       brw->urb.gsize == gs_size) {
+      return;
+   }
+   brw->urb.vsize = vs_size;
+   brw->urb.gs_present = gs_present;
+   brw->urb.gsize = gs_size;
+
    /* From p35 of the Ivy Bridge PRM (section 1.7.1: 3DSTATE_URB_GS):
     *
     *     VS Number of URB Entries must be divisible by 8 if the VS URB Entry