Mesa (7.11): intel: Fix separate stencil in builtin DRI2 backend

Ian Romanick idr at kemper.freedesktop.org
Sun Nov 27 22:13:44 UTC 2011


Module: Mesa
Branch: 7.11
Commit: 2a45566587e2b180c8c78932802028dee684b988
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2a45566587e2b180c8c78932802028dee684b988

Author: Chad Versace <chad.versace at linux.intel.com>
Date:   Tue Nov 15 07:08:49 2011 -0800

intel: Fix separate stencil in builtin DRI2 backend

intelAllocateBuffer() was oblivious to separate stencil buffers.  This
patch fixes it to allocate a non-tiled stencil buffer with special pitch,
just as the DDX does.

Without this, any app that attempted to create an EGL surface with stencil
bits would crash. Of course, this affected only environments that used the
builtin DRI2 backend, such as Android and Wayland.

Fixes GLBenchmark2.1 on Android on gen7.

Note: This is a candidate for the 7.11 branch.
Tested-by: Louie Tsaie <louie.tsai at intel.com>
Signed-off-by: Chad Versace <chad.versace at linux.intel.com>
(cherry picked from commit 79653c12d6da4d89aaa73e4e8260a84d91f93593)

Conflicts:

	src/mesa/drivers/dri/intel/intel_screen.c

---

 src/mesa/drivers/dri/intel/intel_screen.c |   89 ++++++++++++++++++++++++++---
 1 files changed, 80 insertions(+), 9 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 2a3a601..5ca9b66 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -785,6 +785,54 @@ struct intel_buffer {
    struct intel_region *region;
 };
 
+/**
+ * \brief Get tiling format for a DRI buffer.
+ *
+ * \param attachment is the buffer's attachmet point, such as
+ *        __DRI_BUFFER_DEPTH.
+ * \param out_tiling is the returned tiling format for buffer.
+ * \return false if attachment is unrecognized or is incompatible with screen.
+ */
+static bool
+intel_get_dri_buffer_tiling(struct intel_screen *screen,
+                            uint32_t attachment,
+                            uint32_t *out_tiling)
+{
+   if (screen->gen < 4) {
+      *out_tiling = I915_TILING_X;
+      return true;
+   }
+
+   switch (attachment) {
+   case __DRI_BUFFER_DEPTH:
+   case __DRI_BUFFER_DEPTH_STENCIL:
+   case __DRI_BUFFER_HIZ:
+      *out_tiling = I915_TILING_Y;
+      return true;
+   case __DRI_BUFFER_ACCUM:
+   case __DRI_BUFFER_FRONT_LEFT:
+   case __DRI_BUFFER_FRONT_RIGHT:
+   case __DRI_BUFFER_BACK_LEFT:
+   case __DRI_BUFFER_BACK_RIGHT:
+   case __DRI_BUFFER_FAKE_FRONT_LEFT:
+   case __DRI_BUFFER_FAKE_FRONT_RIGHT:
+      *out_tiling = I915_TILING_X;
+      return true;
+   case __DRI_BUFFER_STENCIL:
+      /* The stencil buffer is W tiled. However, we request from the kernel
+       * a non-tiled buffer because the GTT is incapable of W fencing.
+       */
+      *out_tiling = I915_TILING_NONE;
+      return true;
+   default:
+      if(unlikely(INTEL_DEBUG & DEBUG_DRI)) {
+	 fprintf(stderr, "error: %s: unrecognized DRI buffer attachment 0x%x\n",
+	         __FUNCTION__, attachment);
+      }
+       return false;
+   }
+}
+
 static __DRIbuffer *
 intelAllocateBuffer(__DRIscreen *screen,
 		    unsigned attachment, unsigned format,
@@ -792,22 +840,45 @@ intelAllocateBuffer(__DRIscreen *screen,
 {
    struct intel_buffer *intelBuffer;
    struct intel_screen *intelScreen = screen->private;
+
    uint32_t tiling;
+   uint32_t region_width;
+   uint32_t region_height;
+   uint32_t region_cpp;
+
+   bool ok = true;
+
+   ok = intel_get_dri_buffer_tiling(intelScreen, attachment, &tiling);
+   if (!ok)
+      return NULL;
 
    intelBuffer = CALLOC(sizeof *intelBuffer);
    if (intelBuffer == NULL)
       return NULL;
 
-   if ((attachment == __DRI_BUFFER_DEPTH ||
-	attachment == __DRI_BUFFER_STENCIL ||
-	attachment == __DRI_BUFFER_DEPTH_STENCIL) &&
-       intelScreen->gen >= 4)
-      tiling = I915_TILING_Y;
-   else
-      tiling = I915_TILING_X;
+   if (attachment == __DRI_BUFFER_STENCIL) {
+      /* The stencil buffer has quirky pitch requirements.  From Vol 2a,
+       * 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch":
+       *    The pitch must be set to 2x the value computed based on width, as
+       *    the stencil buffer is stored with two rows interleaved.
+       * To accomplish this, we resort to the nasty hack of doubling the
+       * region's cpp and halving its height.
+       */
+      region_width = ALIGN(width, 64);
+      region_height = ALIGN(ALIGN(height, 2) / 2, 64);
+      region_cpp = format / 4;
+   } else {
+      region_width = width;
+      region_height = height;
+      region_cpp = format / 8;
+   }
 
-   intelBuffer->region = intel_region_alloc(intelScreen, tiling,
-					    format / 8, width, height, GL_TRUE);
+   intelBuffer->region = intel_region_alloc(intelScreen,
+                                            tiling,
+                                            region_cpp,
+                                            region_width,
+                                            region_height,
+                                            true);
    
    if (intelBuffer->region == NULL) {
 	   FREE(intelBuffer);




More information about the mesa-commit mailing list