summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/i965/brw_misc_state.c36
-rw-r--r--src/mesa/drivers/dri/i965/gen6_hiz.c18
2 files changed, 54 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index 7a0f5a31ac0..0c0389f8bdf 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -398,6 +398,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;
+
BEGIN_BATCH(len);
OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (len - 2));
OUT_BATCH((BRW_DEPTHFORMAT_D32_FLOAT << 18) |
@@ -436,6 +454,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);
diff --git a/src/mesa/drivers/dri/i965/gen6_hiz.c b/src/mesa/drivers/dri/i965/gen6_hiz.c
index d9b547c3964..67d6bdb7ea9 100644
--- a/src/mesa/drivers/dri/i965/gen6_hiz.c
+++ b/src/mesa/drivers/dri/i965/gen6_hiz.c
@@ -487,6 +487,24 @@ gen6_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;
+
uint32_t format;
switch (mt->format) {
case MESA_FORMAT_Z16: format = BRW_DEPTHFORMAT_D16_UNORM; break;