summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2014-04-14 16:52:43 -0700
committerEric Anholt <[email protected]>2014-04-15 14:34:47 -0700
commit7ae870211ddc40ef6ed209a322c3a721214bb737 (patch)
tree15352ef563e77d0d669ec3abb239dc686c220a33
parente5b86cb64b2eec6b2d798d80f9abe574825dcb71 (diff)
i965: Fix buffer overruns in MSAA MCS buffer clearing.
This manifested as rendering failures or sometimes GPU hangs in compositors when they accidentally got MSAA visuals due to a bug in the X Server. Today we decided that the problem in compositors was equivalent to a corruption bug we'd noticed recently in resizing MSAA-visual glxgears, and debugging got a lot easier. When we allocate our MCS MT, libdrm takes the size we request, aligns it to Y tile size (blowing it up from 300x300=900000 bytes to 384*320=122880 bytes, 30 pages), then puts it into a power-of-two-sized BO (131072 bytes, 32 pages). Because it's Y tiled, we attach a 384-byte-stride fence to it. When we memset by the BO size in Mesa, between bytes 122880 and 131072 the data gets stored to the first 20 or so scanlines of each of the 3 tiled pages in that row, even though only 2 of those pages were allocated by libdrm. In the glxgears case, the missing 3rd page happened to consistently be the static VBO that got mapped right after the first MCS allocation, so corruption only appeared once window resize made us throw out the old MCS and then allocate the same BO to back the new MCS. Instead, just memset the amount of data we actually asked libdrm to allocate for, which will be smaller (more efficient) and not overrun. Thanks go to Kenneth for doing most of the hard debugging to eliminate a lot of the search space for the bug. Cc: "10.0 10.1" <[email protected]> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=77207 Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/intel_mipmap_tree.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index 5996a1b519d..59700ed8b17 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -1219,7 +1219,7 @@ intel_miptree_alloc_mcs(struct brw_context *brw,
* Note: the clear value for MCS buffers is all 1's, so we memset to 0xff.
*/
void *data = intel_miptree_map_raw(brw, mt->mcs_mt);
- memset(data, 0xff, mt->mcs_mt->region->bo->size);
+ memset(data, 0xff, mt->mcs_mt->region->height * mt->mcs_mt->region->pitch);
intel_miptree_unmap_raw(brw, mt->mcs_mt);
mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_CLEAR;