[Mesa-dev] [PATCH 1/3] intel: Fix span functions for stencil buffer

Chad Versace chad at chad-versace.us
Sat Jul 9 08:56:01 PDT 2011


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 <chad at 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



More information about the mesa-dev mailing list