summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Berry <stereotype441@gmail.com>2013-01-24 10:43:38 -0800
committerPaul Berry <stereotype441@gmail.com>2013-01-24 13:17:07 -0800
commitb50c0feb2ccf3a4e1be8133405347ee3b49b05cf (patch)
treef55a690742aa40111fc8a4bc5bdd9d04ffb6ed9e
parentac158f8ee78fd5902cfeb8712a72cfa4da7ef6f6 (diff)
intel: Fix ReadPixels on buffers whose width >= 32kbytes
When possible, glReadPixels calls are performed using the hardware blitter. However, according to the Ivy Bridge PRM, Vol1 Part4, section 1.2.1.2 (Graphics Data Size Limitations): The BLT engine is capable of transferring very large quantities of graphics data. Any graphics data read from and written to the destination is permitted to represent a number of pixels that occupies up to 65,536 scan lines and up to 32,768 bytes per scan line at the destination. The maximum number of pixels that may be represented per scan line’s worth of graphics data depends on the color depth. With an RGBA32F color buffer (which has 16 bytes per pixel) this imposes a maximum width of 2048 pixels. To make matters worse, if the pitch of the buffer is 32k or greater, intel_miptree_map_blit's call to intelEmitCopyBlit will overflow intelEmitCopyBlit's src_pitch and dst_pitch parameters (which are 16-bit signed integers). We can conveniently avoid both problems by avoiding the readpixels blit path when the miptree's pitch is >= 32k. Fixes gles3conform "half_float" tests when the buffer width is greater than 2048. Reviewed-by: Eric Anholt <eric@anholt.net> Tested-by: Ian Romanick <ian.d.romanick@intel.com>
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index ce03afad68a..a063f87d265 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -1565,10 +1565,30 @@ intel_miptree_map_singlesample(struct intel_context *intel,
intel_miptree_map_etc(intel, mt, map, level, slice);
} else if (mt->stencil_mt) {
intel_miptree_map_depthstencil(intel, mt, map, level, slice);
- } else if (intel->has_llc &&
- !(mode & GL_MAP_WRITE_BIT) &&
- !mt->compressed &&
- mt->region->tiling == I915_TILING_X) {
+ }
+ /* According to the Ivy Bridge PRM, Vol1 Part4, section 1.2.1.2 (Graphics
+ * Data Size Limitations):
+ *
+ * The BLT engine is capable of transferring very large quantities of
+ * graphics data. Any graphics data read from and written to the
+ * destination is permitted to represent a number of pixels that
+ * occupies up to 65,536 scan lines and up to 32,768 bytes per scan line
+ * at the destination. The maximum number of pixels that may be
+ * represented per scan line’s worth of graphics data depends on the
+ * color depth.
+ *
+ * Furthermore, intelEmitCopyBlit (which is called by
+ * intel_miptree_map_blit) uses a signed 16-bit integer to represent buffer
+ * pitch, so it can only handle buffer pitches < 32k.
+ *
+ * As a result of these two limitations, we can only use
+ * intel_miptree_map_blit() when the region's pitsh is less than 32k.
+ */
+ else if (intel->has_llc &&
+ !(mode & GL_MAP_WRITE_BIT) &&
+ !mt->compressed &&
+ mt->region->tiling == I915_TILING_X &&
+ mt->region->pitch < 32768) {
intel_miptree_map_blit(intel, mt, map, level, slice);
} else {
intel_miptree_map_gtt(intel, mt, map, level, slice);