i965: Don't reallocate push constant URB space on new VS programs.
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 11 Jan 2012 19:44:02 +0000 (11:44 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Wed, 11 Jan 2012 20:13:49 +0000 (12:13 -0800)
The gen7_urb atom depends on CACHE_NEW_VS_PROG and CACHE_NEW_GS_PROG,
causing gen7_upload_urb() to be called when switching to a new VS
program.

In addition to partitioning the URB space between the VS and GS,
gen7_upload_urb() also allocated space for VS and PS push constants.
Unfortunately, this meant that whenever CACHE_NEW_VS was flagged, we'd
reallocate the space for the PS push constants.  According to the BSpec,
after sending 3DSTATE_PUSH_CONSTANT_ALLOC_PS, we must reprogram
3DSTATE_CONSTANT_PS prior to the next 3DPRIMITIVE.

Since our URB allocation for push constants is entirely static, it makes
sense to split it out into its own atom that only subscribes to
BRW_NEW_CONTEXT.  This avoids reallocating the space and trashing
constants.

Fixes a rendering artifact in Extreme Tuxracer, where instead of a snow
trail, you'd get a bright red streak (affectionately known as the
"bloody penguin bug").

This also explains why adding VS-related dirty bits to gen7_ps_state
made the problem disappear: it made 3DSTATE_CONSTANT_PS be emitted after
every 3DSTATE_PUSH_CONSTANT_ALLOC_PS packet.

NOTE: This is a candidate for the 7.11 branch.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38868
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
src/mesa/drivers/dri/i965/brw_state.h
src/mesa/drivers/dri/i965/brw_state_upload.c
src/mesa/drivers/dri/i965/gen7_urb.c

index fcfe79f4aa0f0605899e2295399dfdaf522e2bdc..2dd566538ee9167c6e103e04f2c055cdbfbe0c7a 100644 (file)
@@ -110,6 +110,7 @@ extern const struct brw_tracked_state gen7_clip_state;
 extern const struct brw_tracked_state gen7_depth_stencil_state_pointer;
 extern const struct brw_tracked_state gen7_disable_stages;
 extern const struct brw_tracked_state gen7_ps_state;
+extern const struct brw_tracked_state gen7_push_constant_alloc;
 extern const struct brw_tracked_state gen7_samplers;
 extern const struct brw_tracked_state gen7_sbe_state;
 extern const struct brw_tracked_state gen7_sf_clip_viewport;
index c7b796c68b69ae5845919dfa6ee76c864cc19ffb..d071f87693f50ce7a6d8db8d7551a17878347988 100644 (file)
@@ -188,6 +188,7 @@ const struct brw_tracked_state *gen7_atoms[] =
 
    /* Command packets: */
    &brw_invariant_state,
+   &gen7_push_constant_alloc,
 
    /* must do before binding table pointers, cc state ptrs */
    &brw_state_base_address,
index e53fcb77356dc5e57638db2b084d8f8d9e4ae81b..e6cf1ebdff2deafd3f262f237643eb8a671a4d22 100644 (file)
  *
  * See "Volume 2a: 3D Pipeline," section 1.8.
  */
+static void
+gen7_allocate_push_constants(struct brw_context *brw)
+{
+   struct intel_context *intel = &brw->intel;
+   BEGIN_BATCH(2);
+   OUT_BATCH(_3DSTATE_PUSH_CONSTANT_ALLOC_VS << 16 | (2 - 2));
+   OUT_BATCH(8);
+   ADVANCE_BATCH();
+
+   BEGIN_BATCH(2);
+   OUT_BATCH(_3DSTATE_PUSH_CONSTANT_ALLOC_PS << 16 | (2 - 2));
+   OUT_BATCH(8 | 8 << GEN7_PUSH_CONSTANT_BUFFER_OFFSET_SHIFT);
+   ADVANCE_BATCH();
+}
+
+const struct brw_tracked_state gen7_push_constant_alloc = {
+   .dirty = {
+      .mesa = 0,
+      .brw = BRW_NEW_CONTEXT,
+      .cache = 0,
+   },
+   .emit = gen7_allocate_push_constants,
+};
+
 static void
 gen7_upload_urb(struct brw_context *brw)
 {
@@ -75,16 +99,6 @@ gen7_upload_urb(struct brw_context *brw)
    /* GS requirement */
    assert(!brw->gs.prog_active);
 
-   BEGIN_BATCH(2);
-   OUT_BATCH(_3DSTATE_PUSH_CONSTANT_ALLOC_VS << 16 | (2 - 2));
-   OUT_BATCH(8);
-   ADVANCE_BATCH();
-
-   BEGIN_BATCH(2);
-   OUT_BATCH(_3DSTATE_PUSH_CONSTANT_ALLOC_PS << 16 | (2 - 2));
-   OUT_BATCH(8 | 8 << GEN7_PUSH_CONSTANT_BUFFER_OFFSET_SHIFT);
-   ADVANCE_BATCH();
-
    BEGIN_BATCH(2);
    OUT_BATCH(_3DSTATE_URB_VS << 16 | (2 - 2));
    OUT_BATCH(brw->urb.nr_vs_entries |