i965: Implement the actual tables for texture alignment units [v2]
authorKenneth Graunke <kenneth@whitecape.org>
Mon, 7 Nov 2011 23:58:43 +0000 (15:58 -0800)
committerChad Versace <chad.versace@linux.intel.com>
Tue, 22 Nov 2011 18:50:52 +0000 (10:50 -0800)
I implemented functions for horizontal/vertical alignment units separately
because I find it easier to read that way...especially with all the
corner-cases.

[chad] Corrected the vertical alignment calculation by checking for
depthstencil formats.

v2:
   - Fix typos in intel_horizontal_texture_alignment_unit():
     s/height/width/ and s/VALIGN/HALIGN.
   - Remove special case for compressed formats in
     intel_get_texture_alignment unit(). Compressed formats are already
     handled in the halign and valign functions.
   - Replace check ``_mesa_is_depth_format(...) ||
     _mesa_is_depthstencil_format(...)`` with explcitit checks against
     GL_DEPTH_COMPONENT and GL_DEPTH_STENCIL.

Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
src/mesa/drivers/dri/intel/intel_mipmap_tree.c
src/mesa/drivers/dri/intel/intel_tex_layout.c
src/mesa/drivers/dri/intel/intel_tex_layout.h

index 2c326f9096b0a58b4e0b886d1524c776dad902b3..f875edb973090c7983098304bfadfaa44c0053e0 100644 (file)
@@ -89,7 +89,8 @@ intel_miptree_create_internal(struct intel_context *intel,
    mt->compressed = compress_byte ? 1 : 0;
    mt->refcount = 1; 
 
-   intel_get_texture_alignment_unit(format, &mt->align_w, &mt->align_h);
+   intel_get_texture_alignment_unit(intel, format,
+                                   &mt->align_w, &mt->align_h);
 
    if (target == GL_TEXTURE_CUBE_MAP) {
       assert(depth0 == 1);
index a428d56a23bc971a553fb2a740c10ca1fcdf44b3..65645bc46a4d4e255bd5c97bc9cc1c9d5f5f081c 100644 (file)
 #include "intel_mipmap_tree.h"
 #include "intel_tex_layout.h"
 #include "intel_context.h"
+
+#include "main/image.h"
 #include "main/macros.h"
 
+static 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 width  ("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 HALIGN_4 or HALIGN_8.
+    */
+    if (_mesa_is_format_compressed(format)) {
+       /* The hardware alignment requirements for compressed textures
+        * happen to match the block boundaries.
+        */
+      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;
+}
+
+static 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 | N/A |  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;
+
+   GLenum base_format = _mesa_get_format_base_format(format);
+
+   if (intel->gen >= 6 &&
+       (base_format == GL_DEPTH_COMPONENT ||
+       base_format == GL_DEPTH_STENCIL)) {
+      return 4;
+   }
+
+   return 2;
+}
+
 void
-intel_get_texture_alignment_unit(gl_format format,
+intel_get_texture_alignment_unit(struct intel_context *intel,
+                                gl_format format,
                                 unsigned int *w, unsigned int *h)
 {
-   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;
-   }
+   *w = intel_horizontal_texture_alignment_unit(intel, format);
+   *h = intel_vertical_texture_alignment_unit(intel, format);
 }
 
 void i945_miptree_layout_2d(struct intel_mipmap_tree *mt)
index c6c865d2c8070bbd6cb22e0e418515ae41fb357e..12ed16d82166683ab609e2ee8d760f1d14fb0b2d 100644 (file)
@@ -39,5 +39,8 @@ static INLINE GLuint minify( GLuint d )
 }
 
 extern void i945_miptree_layout_2d(struct intel_mipmap_tree *mt);
-void intel_get_texture_alignment_unit(gl_format format,
-                                     unsigned int *w, unsigned int *h);
+
+void
+intel_get_texture_alignment_unit(struct intel_context *intel,
+                                gl_format format,
+                                unsigned int *w, unsigned int *h);