summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965/gen7_urb.c
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2012-01-11 11:44:02 -0800
committerKenneth Graunke <kenneth@whitecape.org>2012-01-11 12:13:49 -0800
commit28cfa1fa213fe7ba6e5b57e61da663a6c3bf0c13 (patch)
tree58d5dfd1e22faee199976d3d5d2e77df72333dcf /src/mesa/drivers/dri/i965/gen7_urb.c
parent10a6fde333f0170fbac70924581c647e531aba3e (diff)
downloadexternal_mesa3d-28cfa1fa213fe7ba6e5b57e61da663a6c3bf0c13.zip
external_mesa3d-28cfa1fa213fe7ba6e5b57e61da663a6c3bf0c13.tar.gz
external_mesa3d-28cfa1fa213fe7ba6e5b57e61da663a6c3bf0c13.tar.bz2
i965: Don't reallocate push constant URB space on new VS programs.
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>
Diffstat (limited to 'src/mesa/drivers/dri/i965/gen7_urb.c')
-rw-r--r--src/mesa/drivers/dri/i965/gen7_urb.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/src/mesa/drivers/dri/i965/gen7_urb.c b/src/mesa/drivers/dri/i965/gen7_urb.c
index e53fcb7..e6cf1eb 100644
--- a/src/mesa/drivers/dri/i965/gen7_urb.c
+++ b/src/mesa/drivers/dri/i965/gen7_urb.c
@@ -51,6 +51,30 @@
* 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)
{
struct intel_context *intel = &brw->intel;
@@ -76,16 +100,6 @@ gen7_upload_urb(struct brw_context *brw)
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 |
((brw->urb.vs_size - 1) << GEN7_URB_ENTRY_SIZE_SHIFT) |