summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/i965/gen7_hiz.c18
-rw-r--r--src/mesa/drivers/dri/i965/gen7_misc_state.c36
2 files changed, 54 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/gen7_hiz.c b/src/mesa/drivers/dri/i965/gen7_hiz.c
index 4538ec9f203..18272491be8 100644
--- a/src/mesa/drivers/dri/i965/gen7_hiz.c
+++ b/src/mesa/drivers/dri/i965/gen7_hiz.c
@@ -364,6 +364,24 @@ gen7_hiz_exec(struct intel_context *intel,
draw_x & ~tile_mask_x,
draw_y & ~tile_mask_y);
+ /* According to the Sandy Bridge PRM, volume 2 part 1, pp326-327
+ * (3DSTATE_DEPTH_BUFFER dw5), in the documentation for "Depth
+ * Coordinate Offset X/Y":
+ *
+ * "The 3 LSBs of both offsets must be zero to ensure correct
+ * alignment"
+ *
+ * We have no guarantee that tile_x and tile_y are correctly aligned,
+ * since they are determined by the mipmap layout, which is only aligned
+ * to multiples of 4.
+ *
+ * So, to avoid hanging the GPU, just smash the low order 3 bits of
+ * tile_x and tile_y to 0. This is a temporary workaround until we come
+ * up with a better solution.
+ */
+ tile_x &= ~7;
+ tile_y &= ~7;
+
intel_emit_depth_stall_flushes(intel);
BEGIN_BATCH(7);
diff --git a/src/mesa/drivers/dri/i965/gen7_misc_state.c b/src/mesa/drivers/dri/i965/gen7_misc_state.c
index d9beda8f36e..4a5b5a6ae2e 100644
--- a/src/mesa/drivers/dri/i965/gen7_misc_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_misc_state.c
@@ -118,6 +118,24 @@ static void emit_depthbuffer(struct brw_context *brw)
tile_x = draw_x & tile_mask_x;
tile_y = draw_y & tile_mask_y;
+ /* According to the Sandy Bridge PRM, volume 2 part 1, pp326-327
+ * (3DSTATE_DEPTH_BUFFER dw5), in the documentation for "Depth
+ * Coordinate Offset X/Y":
+ *
+ * "The 3 LSBs of both offsets must be zero to ensure correct
+ * alignment"
+ *
+ * We have no guarantee that tile_x and tile_y are correctly aligned,
+ * since they are determined by the mipmap layout, which is only
+ * aligned to multiples of 4.
+ *
+ * So, to avoid hanging the GPU, just smash the low order 3 bits of
+ * tile_x and tile_y to 0. This is a temporary workaround until we
+ * come up with a better solution.
+ */
+ tile_x &= ~7;
+ tile_y &= ~7;
+
/* 3DSTATE_STENCIL_BUFFER inherits surface type and dimensions. */
dw1 |= (BRW_SURFACE_2D << 29);
dw3 = ((srb->Base.Base.Width + tile_x - 1) << 4) |
@@ -142,6 +160,24 @@ static void emit_depthbuffer(struct brw_context *brw)
tile_x = draw_x & tile_mask_x;
tile_y = draw_y & tile_mask_y;
+ /* According to the Sandy Bridge PRM, volume 2 part 1, pp326-327
+ * (3DSTATE_DEPTH_BUFFER dw5), in the documentation for "Depth
+ * Coordinate Offset X/Y":
+ *
+ * "The 3 LSBs of both offsets must be zero to ensure correct
+ * alignment"
+ *
+ * We have no guarantee that tile_x and tile_y are correctly aligned,
+ * since they are determined by the mipmap layout, which is only aligned
+ * to multiples of 4.
+ *
+ * So, to avoid hanging the GPU, just smash the low order 3 bits of
+ * tile_x and tile_y to 0. This is a temporary workaround until we come
+ * up with a better solution.
+ */
+ tile_x &= ~7;
+ tile_y &= ~7;
+
offset = intel_region_get_aligned_offset(region,
draw_x & ~tile_mask_x,
draw_y & ~tile_mask_y);