[Mesa-dev] [PATCH 09/17] swrast: Make a teximage's stored RowStride be in terms of bytes per row.

Eric Anholt eric at anholt.net
Mon Apr 22 09:14:50 PDT 2013


For hardware drivers with pitch alignment requirements, a
non-power-of-two-sized texture format won't end up being an integer number
of pixels per row.  Also, avoids having to change our units between
MapTextureImage's rowStride and swrast's RowStride.

This doesn't fully convert the compressed texel fetch path, but does make
sure we don't drop any bits (not that we'd expect to).
---
 src/mesa/swrast/s_context.h      |   12 ++++++++++--
 src/mesa/swrast/s_texfetch.c     |   10 +++++++++-
 src/mesa/swrast/s_texfetch_tmp.h |    7 ++++---
 src/mesa/swrast/s_texfilter.c    |    4 +++-
 src/mesa/swrast/s_texture.c      |    3 ++-
 src/mesa/swrast/s_triangle.c     |    3 ++-
 6 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h
index c9a8ee5..509759e 100644
--- a/src/mesa/swrast/s_context.h
+++ b/src/mesa/swrast/s_context.h
@@ -137,8 +137,16 @@ struct swrast_texture_image
    /** used for mipmap LOD computation */
    GLfloat WidthScale, HeightScale, DepthScale;
 
-   /** These fields only valid when texture memory is mapped */
-   GLint RowStride;		/**< Padded width in units of texels */
+   /**
+    * Byte stride between rows in ImageSlices.
+    *
+    * For compressed textures, this is the byte stride between one row of
+    * blocks and the next row of blocks.
+    *
+    * Only valid while one of the ImageSlices is mapped, and must be the same
+    * between all slices.
+    */
+   GLint RowStride;
    void **ImageSlices;          /**< if 3D texture: array [Depth] of offsets to
                                      each 2D slice in 'Data', in texels */
    GLubyte *Map;		/**< Pointer to mapped image memory */
diff --git a/src/mesa/swrast/s_texfetch.c b/src/mesa/swrast/s_texfetch.c
index fd9a93e..8438823 100644
--- a/src/mesa/swrast/s_texfetch.c
+++ b/src/mesa/swrast/s_texfetch.c
@@ -97,8 +97,16 @@ static void
 fetch_compressed(const struct swrast_texture_image *swImage,
                  GLint i, GLint j, GLint k, GLfloat *texel)
 {
+   /* The FetchCompressedTexel function takes an integer pixel rowstride,
+    * while the image's rowstride is bytes per row of blocks.
+    */
+   GLuint bw, bh;
+   GLuint texelBytes = _mesa_get_format_bytes(swImage->Base.TexFormat);
+   _mesa_get_format_block_size(swImage->Base.TexFormat, &bw, &bh);
+   assert(swImage->RowStride * bw % texelBytes == 0);
+
    swImage->FetchCompressedTexel(swImage->ImageSlices[k],
-                                 swImage->RowStride,
+                                 swImage->RowStride * bw / texelBytes,
                                  i, j, texel);
 }
 
diff --git a/src/mesa/swrast/s_texfetch_tmp.h b/src/mesa/swrast/s_texfetch_tmp.h
index c2fdb89..2bf8042 100644
--- a/src/mesa/swrast/s_texfetch_tmp.h
+++ b/src/mesa/swrast/s_texfetch_tmp.h
@@ -51,15 +51,16 @@
 
 #define TEXEL_ADDR( type, image, i, j, k, size )			\
 	((void) (k),							\
-	 ((type *)(image)->ImageSlices[0] + ((image)->RowStride * (j) + (i)) * (size)))
+	 ((type *)((image)->ImageSlices[0] + (image)->RowStride * (j)) + \
+          (i) * (size)))
 
 #define FETCH(x) fetch_texel_2d_##x
 
 #elif DIM == 3
 
 #define TEXEL_ADDR( type, image, i, j, k, size )			\
-	((type *)(image)->ImageSlices[k] +				\
-         ((image)->RowStride * (j) + (i)) * (size))
+	((type *)((image)->ImageSlices[k] +				\
+                  (image)->RowStride * (j)) + (i) * (size))
 
 #define FETCH(x) fetch_texel_3d_##x
 
diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c
index 9c28bfe..4c34d8d 100644
--- a/src/mesa/swrast/s_texfilter.c
+++ b/src/mesa/swrast/s_texfilter.c
@@ -1504,7 +1504,9 @@ sample_lambda_2d(struct gl_context *ctx,
 
    const GLboolean repeatNoBorderPOT = (samp->WrapS == GL_REPEAT)
       && (samp->WrapT == GL_REPEAT)
-      && (tImg->Border == 0 && (tImg->Width == swImg->RowStride))
+      && (tImg->Border == 0)
+      && (_mesa_format_row_stride(tImg->TexFormat, tImg->Width) ==
+          swImg->RowStride)
       && swImg->_IsPowerOfTwo;
 
    ASSERT(lambda != NULL);
diff --git a/src/mesa/swrast/s_texture.c b/src/mesa/swrast/s_texture.c
index f6e0aa4..bfc2e9d 100644
--- a/src/mesa/swrast/s_texture.c
+++ b/src/mesa/swrast/s_texture.c
@@ -95,7 +95,8 @@ _swrast_alloc_texture_image_buffer(struct gl_context *ctx,
       return GL_FALSE;
 
    /* RowStride and ImageSlices[] describe how to address texels in 'Data' */
-   swImg->RowStride = texImage->Width;
+   swImg->RowStride = _mesa_format_row_stride(texImage->TexFormat,
+                                              texImage->Width);
 
    for (i = 0; i < slices; i++) {
       swImg->ImageSlices[i] = swImg->Buffer + bytesPerSlice * i;
diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c
index 761c42d..dce5568 100644
--- a/src/mesa/swrast/s_triangle.c
+++ b/src/mesa/swrast/s_triangle.c
@@ -1078,7 +1078,8 @@ _swrast_choose_triangle( struct gl_context *ctx )
              && texObj2D->_Swizzle == SWIZZLE_NOOP
              && swImg->_IsPowerOfTwo
              && texImg->Border == 0
-             && texImg->Width == swImg->RowStride
+             && (_mesa_format_row_stride(format, texImg->Width) ==
+                 swImg->RowStride)
              && (format == MESA_FORMAT_RGB888 || format == MESA_FORMAT_RGBA8888)
              && minFilter == magFilter
              && ctx->Light.Model.ColorControl == GL_SINGLE_COLOR
-- 
1.7.10.4



More information about the mesa-dev mailing list