Up until this point, we incorrectly believed that the stencil buffer is Y-tiled. In fact, it is W tiled. From PRM Vol 1 Part 2 Section 4.5.2.1 W-Major Tile Format: "W-Major Tile Format is used for separate stencil."
Since the stencil buffer is allocated with I915_TILING_Y, the span functions must decode W tiling through a Y tiled fence. On gen5 with intel_screen.hw_must_use_separate_stencil enabled, Fixes-Piglit-test: stencil-drawpixels Fixes-Piglit-test: stencil-scissor-clear Fixes-Piglit-test: readpixels-24_8 Note: This is a candidate for the 7.11 branch Signed-off-by: Chad Versace <c...@chad-versace.us> --- src/mesa/drivers/dri/intel/intel_span.c | 52 +++++++++++++++++++++---------- 1 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c index 153803f..f39c008 100644 --- a/src/mesa/drivers/dri/intel/intel_span.c +++ b/src/mesa/drivers/dri/intel/intel_span.c @@ -141,28 +141,46 @@ intel_set_span_functions(struct intel_context *intel, /** * \brief Get pointer offset into stencil buffer. * - * The stencil buffer interleaves two rows into one. Yay for crazy hardware. - * The table below demonstrates how the pointer arithmetic behaves for a buffer - * with positive stride (s=stride). - * - * x | y | byte offset - * -------------------------- - * 0 | 0 | 0 - * 0 | 1 | 1 - * 1 | 0 | 2 - * 1 | 1 | 3 - * ... | ... | ... - * 0 | 2 | s - * 0 | 3 | s + 1 - * 1 | 2 | s + 2 - * 1 | 3 | s + 3 - * + * The stencil buffer is W-tiled, yet the drm buffer is allocated with + * I915_TILING_Y. So here we must decode the W tiling through a Y fence. * + * From PRM Vol 1 Part 2 Section 4.5.2.1 W-Major Tile Format: + * "W-Major Tile Format is used for separate stencil." */ static inline intptr_t intel_offset_S8(int stride, GLint x, GLint y) { - return 2 * ((y / 2) * stride + x) + y % 2; + /* f: (x, y) -> (fx, fy) */ + int fx = x / 8; + int fy = y / 4; + + /* e: (x, y) -> (ex, 0) */ + int ex = (x % 8) / 4; + + /* d: (x, y) -> (dx, dy) */ + int dx = (x % 4) / 2; + int dy = (y % 4) / 2; + + /* c: (x, y) -> (cx, cy) */ + int cx = x % 2; + int cy = y % 2; + + int s = stride; + intptr_t o = 0; + + if (s > 0) { + /*f*/ o += 16 * fx + 4 * s * fy; + /*e*/ o += 2 * s * ex; + /*d*/ o += 4 * dx + 8 * dy; + /*c*/ o += cx + 2 * cy; + } else { + /*f*/ o += 16 * fx + 4 * s * fy; + /*e*/ o += 2 * s * (1 - ex); + /*d*/ o += 4 * dx + 8 * (1 - dy); + /*c*/ o += cx + 2 * (1 - cy); + } + + return o; } #define WRITE_STENCIL(x, y, src) buf[intel_offset_S8(stride, x, y)] = src; -- 1.7.5.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev