diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_misc_state.c | 36 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/gen6_hiz.c | 18 |
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; |