[Mesa-dev] [RFC PATCH 1/2] i965: Implement the actual tables for texture alignment units.

Kenneth Graunke kenneth at whitecape.org
Mon Aug 15 12:21:06 PDT 2011


I implemented functions for horizontal/vertical alignment units separately
because I find it easier to read that way...especially with all the
corner-cases.

Regresses piglit test "fbo-generatemipmap-formats GL_ARB_depth_texture"
on Sandybridge: the 1x1 quad is 0.0 rather than 0.5.  This is caused by
changing the vertical alignment to 4 instead of 2 for depth formats.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/mesa/drivers/dri/i965/brw_tex_layout.c     |    2 +-
 src/mesa/drivers/dri/intel/intel_mipmap_tree.c |    6 +-
 src/mesa/drivers/dri/intel/intel_tex_layout.c  |   97 ++++++++++++++++++++++--
 src/mesa/drivers/dri/intel/intel_tex_layout.h  |   13 +++-
 4 files changed, 104 insertions(+), 14 deletions(-)

Oddly, implementing all these rules from the HW docs only seems to break
this one test on Sandybridge (I haven't tried Ironlake).  Ivybridge is
unaffected.  Nothing is actually fixed AFAIK.

About the fbo-generatemipmap-formats failure...SURFACE_STATE has a
VALIGN_2/VALIGN_4 setting, which we're currently always leaving at 2.
I tried setting it to 4 for depth formats, but that had no effect (assuming
I did it correctly).  Very strange.

diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index 46a417a..d868e9f 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -88,7 +88,7 @@ GLboolean brw_miptree_layout(struct intel_context *intel,
       GLuint align_w = 4;
 
       mt->total_height = 0;
-      intel_get_texture_alignment_unit(mt->format, &align_w, &align_h);
+      intel_texture_alignment_units(intel, mt->format, &align_w, &align_h);
 
       if (mt->compressed) {
           mt->total_width = ALIGN(width, align_w);
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index 4e711de..fa3d744 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -394,7 +394,7 @@ intel_miptree_image_data(struct intel_context *intel,
       if (dst->compressed) {
 	 unsigned int align_w, align_h;
 
-	 intel_get_texture_alignment_unit(dst->format, &align_w, &align_h);
+	 intel_texture_alignment_units(intel, dst->format, &align_w, &align_h);
 	 height = (height + align_h - 1) / align_h;
 	 width = ALIGN(width, align_w);
       }
@@ -434,9 +434,9 @@ intel_miptree_image_copy(struct intel_context *intel,
    GLboolean success;
 
    if (dst->compressed) {
-       GLuint align_w, align_h;
+      unsigned int align_w =
+	 intel_horizontal_texture_alignment_unit(intel, dst->format);
 
-       intel_get_texture_alignment_unit(dst->format, &align_w, &align_h);
        height = (height + 3) / 4;
        width = ALIGN(width, align_w);
    }
diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c
index 9d81523..b6c3fcf 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_layout.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c
@@ -34,20 +34,101 @@
 #include "intel_tex_layout.h"
 #include "intel_context.h"
 #include "main/macros.h"
+#include "main/image.h"
 
-void
-intel_get_texture_alignment_unit(gl_format format,
-				 unsigned int *w, unsigned int *h)
+unsigned int
+intel_horizontal_texture_alignment_unit(struct intel_context *intel,
+					gl_format format)
 {
+   /**
+    * From the "Alignment Unit Size" section of various specs, namely:
+    * - Gen3 Spec: "Memory Data Formats" Volume,         Section 1.20.1.4
+    * - i965 and G45 PRMs:             Volume 1,         Section 6.17.3.4.
+    * - Ironlake and Sandybridge PRMs: Volume 1, Part 1, Section 7.18.3.4
+    * - BSpec (for Ivybridge and slight variations in separate stencil)
+    *
+    * +----------------------------------------------------------------------+
+    * |                                        | alignment unit height ("i") |
+    * | Surface Property                       |-----------------------------|
+    * |                                        | 915 | 965 | ILK | SNB | IVB |
+    * +----------------------------------------------------------------------+
+    * | YUV 4:2:2 format                       |  8  |  4  |  4  |  4  |  4  |
+    * | BC1-5 compressed format (DXTn/S3TC)    |  4  |  4  |  4  |  4  |  4  |
+    * | FXT1  compressed format                |  8  |  8  |  8  |  8  |  8  |
+    * | Depth Buffer (16-bit)                  |  4  |  4  |  4  |  4  |  8  |
+    * | Depth Buffer (other)                   |  4  |  4  |  4  |  4  |  4  |
+    * | Separate Stencil Buffer                | N/A | N/A |  8  |  8  |  8  |
+    * | All Others                             |  4  |  4  |  4  |  4  |  4  |
+    * +----------------------------------------------------------------------+
+    *
+    * On IVB+, non-special cases can be overridden by setting the SURFACE_STATE
+    * "Surface Horizontal Alignment" field to VALIGN_4 or VALIGN_8.
+    */
    if (_mesa_is_format_compressed(format)) {
       /* The hardware alignment requirements for compressed textures
        * happen to match the block boundaries.
        */
-      _mesa_get_format_block_size(format, w, h);
-   } else {
-      *w = 4;
-      *h = 2;
+      unsigned int i, j;
+      _mesa_get_format_block_size(format, &i, &j);
+      return i;
    }
+
+   if (format == MESA_FORMAT_S8)
+      return 8;
+
+   if (intel->gen >= 7 && format == MESA_FORMAT_Z16)
+      return 8;
+
+   return 4;
+}
+
+unsigned int
+intel_vertical_texture_alignment_unit(struct intel_context *intel,
+				      gl_format format)
+{
+   /**
+    * From the "Alignment Unit Size" section of various specs, namely:
+    * - Gen3 Spec: "Memory Data Formats" Volume,         Section 1.20.1.4
+    * - i965 and G45 PRMs:             Volume 1,         Section 6.17.3.4.
+    * - Ironlake and Sandybridge PRMs: Volume 1, Part 1, Section 7.18.3.4
+    * - BSpec (for Ivybridge and slight variations in separate stencil)
+    *
+    * +----------------------------------------------------------------------+
+    * |                                        | alignment unit height ("j") |
+    * | Surface Property                       |-----------------------------|
+    * |                                        | 915 | 965 | ILK | SNB | IVB |
+    * +----------------------------------------------------------------------+
+    * | BC1-5 compressed format (DXTn/S3TC)    |  4  |  4  |  4  |  4  |  4  |
+    * | FXT1  compressed format                |  4  |  4  |  4  |  4  |  4  |
+    * | Depth Buffer                           |  2  |  2  |  2  |  4  |  4  |
+    * | Separate Stencil Buffer                | N/A | N/A |  4  |  4  |  8  |
+    * | Multisampled (4x or 8x) render target  | N/A | N/A | N/A |  4  |  4  |
+    * | All Others                             |  2  |  2  |  2  |  2  |  2  |
+    * +----------------------------------------------------------------------+
+    *
+    * On SNB+, non-special cases can be overridden by setting the SURFACE_STATE
+    * "Surface Vertical Alignment" field to VALIGN_2 or VALIGN_4.
+    *
+    * We currently don't support multisampling.
+    */
+   if (_mesa_is_format_compressed(format))
+      return 4;
+
+   if (format == MESA_FORMAT_S8)
+      return intel->gen >= 7 ? 8 : 4;
+
+   if (intel->gen >= 6 && _mesa_is_depth_format(_mesa_get_format_base_format(format)))
+      return 4;
+
+   return 2;
+}
+
+void
+intel_texture_alignment_units(struct intel_context *intel, gl_format format,
+			      unsigned int *w, unsigned int *h)
+{
+   *w = intel_horizontal_texture_alignment_unit(intel, format);
+   *h = intel_vertical_texture_alignment_unit(intel, format);
 }
 
 void i945_miptree_layout_2d(struct intel_context *intel,
@@ -62,7 +143,7 @@ void i945_miptree_layout_2d(struct intel_context *intel,
    GLuint height = mt->height0;
 
    mt->total_width = mt->width0;
-   intel_get_texture_alignment_unit(mt->format, &align_w, &align_h);
+   intel_texture_alignment_units(intel, mt->format, &align_w, &align_h);
 
    if (mt->compressed) {
        mt->total_width = ALIGN(mt->width0, align_w);
diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h
index b52e5a4..145d6c2 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_layout.h
+++ b/src/mesa/drivers/dri/intel/intel_tex_layout.h
@@ -41,5 +41,14 @@ static INLINE GLuint minify( GLuint d )
 extern void i945_miptree_layout_2d(struct intel_context *intel,
 				   struct intel_mipmap_tree *mt,
 				   uint32_t tiling, int nr_images);
-void intel_get_texture_alignment_unit(gl_format format,
-				      unsigned int *w, unsigned int *h);
+unsigned int
+intel_horizontal_texture_alignment_unit(struct intel_context *intel,
+				        gl_format format);
+unsigned int
+intel_vertical_texture_alignment_unit(struct intel_context *intel,
+				      gl_format format);
+
+void
+intel_texture_alignment_units(struct intel_context *intel,
+			      gl_format format,
+			      unsigned int *w, unsigned int *h);
-- 
1.7.6



More information about the mesa-dev mailing list