Mesa (9.0): i965/gen6+: Adjust stencil buffer size after computing miptree layout.

Paul Berry stereotype441 at kemper.freedesktop.org
Fri Sep 28 18:30:36 UTC 2012


Module: Mesa
Branch: 9.0
Commit: 5db1deab5118a986167ea6e8f8c7c196c74457c1
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5db1deab5118a986167ea6e8f8c7c196c74457c1

Author: Paul Berry <stereotype441 at gmail.com>
Date:   Tue Sep  4 07:57:37 2012 -0700

i965/gen6+: Adjust stencil buffer size after computing miptree layout.

Since Gen6+ stencil buffers use W-tiling (a tiling arrangement which
drm and the kernel are not aware of) we need to round up the width and
height of a stencil buffer to multiples of the W-tile size (64x64)
before allocating a stencil buffer.  Previously, we rounded up the
size of the base miplevel, and then computed the miptree layout based
on the rounded up size.  This was incorrect, because it meant that the
total size of the miptree would not be properly W-tile aligned, and
therefore we would not always allocate enough pages.

(Note: even though the GL API doesn't allow creation of mipmapped
stencil textures, it does allow mipmapping of a combined depth/stencil
texture, and on Gen6+, a combined depth/stencil texture is internally
implemented as a pair of separate depth and stencil buffers.)

For example, on Sandy Bridge, when allocating a mipmapped stencil
texture of size 128x128, we would first round up to the nearest
multiple of 64x64 (causing no change to the size), and then compute
the miptree layout (whose size worked out to 128x196).  Then we would
request an allocation of 128*196 bytes (6.125 pages), causing 7 pages
to be allocated to the texture.  However, the texture needs 8 pages,
since each W-tile occupies a page, and it takes 2 W-tiles to cover a
width of 128 and 4 W-tiles to cover a height of 196.

This patch changes the order of operations so that the miptree layout
is computed first and then the total size of the miptree is rounded up
to be W-tile aligned.

NOTE: This is a candidate for the 8.0 release branch.

Reviewed-by: Eric Anholt <eric at anholt.net>
(cherry picked from commit bde833c9d014ad8aebfab0d2285184d7e6d5896d)

---

 src/mesa/drivers/dri/intel/intel_mipmap_tree.c |   28 +++++++++++++----------
 1 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index 24cd9e9..dbfddc8 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -200,6 +200,7 @@ intel_miptree_create(struct intel_context *intel,
    uint32_t tiling = I915_TILING_NONE;
    GLenum base_format;
    bool wraps_etc1 = false;
+   GLuint total_width, total_height;
 
    if (format == MESA_FORMAT_ETC1_RGB8) {
       format = MESA_FORMAT_RGBX8888_REV;
@@ -231,16 +232,6 @@ intel_miptree_create(struct intel_context *intel,
 	 tiling = I915_TILING_X;
    }
 
-   if (format == MESA_FORMAT_S8) {
-      /* The stencil buffer is W tiled. However, we request from the kernel a
-       * non-tiled buffer because the GTT is incapable of W fencing.  So round
-       * up the width and height to match the size of W tiles (64x64).
-       */
-      tiling = I915_TILING_NONE;
-      width0 = ALIGN(width0, 64);
-      height0 = ALIGN(height0, 64);
-   }
-
    mt = intel_miptree_create_internal(intel, target, format,
 				      first_level, last_level, width0,
 				      height0, depth0,
@@ -253,12 +244,25 @@ intel_miptree_create(struct intel_context *intel,
       return NULL;
    }
 
+   total_width = mt->total_width;
+   total_height = mt->total_height;
+
+   if (format == MESA_FORMAT_S8) {
+      /* The stencil buffer is W tiled. However, we request from the kernel a
+       * non-tiled buffer because the GTT is incapable of W fencing.  So round
+       * up the width and height to match the size of W tiles (64x64).
+       */
+      tiling = I915_TILING_NONE;
+      total_width = ALIGN(total_width, 64);
+      total_height = ALIGN(total_height, 64);
+   }
+
    mt->wraps_etc1 = wraps_etc1;
    mt->region = intel_region_alloc(intel->intelScreen,
 				   tiling,
 				   mt->cpp,
-				   mt->total_width,
-				   mt->total_height,
+				   total_width,
+				   total_height,
 				   expect_accelerated_upload);
    mt->offset = 0;
 




More information about the mesa-commit mailing list