swrast: Make a teximage's stored RowStride be in terms of bytes per row.
authorEric Anholt <eric@anholt.net>
Fri, 19 Apr 2013 21:00:22 +0000 (14:00 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 30 Apr 2013 17:40:44 +0000 (10:40 -0700)
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).

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Brian Paul <brianp@vmware.com>
src/mesa/swrast/s_context.h
src/mesa/swrast/s_texfetch.c
src/mesa/swrast/s_texfetch_tmp.h
src/mesa/swrast/s_texfilter.c
src/mesa/swrast/s_texture.c
src/mesa/swrast/s_triangle.c

index 7b3c740c1caeee7ac767fb1a0535f2672b2188b8..38015483597f8dc15b5da0fecd40c8980b82159b 100644 (file)
@@ -138,8 +138,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 */
index a9bc3fad0a2a7c70bf2f1351205bbc9309c568fa..f6c269d8bafecc5ec3e674af32086aa579732774 100644 (file)
@@ -98,8 +98,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);
 }
 
index 4cd42c06dfe9a79bf91b0ae06988266dc2713427..c9991cd84d9cb089467dc13a31d115c6a5a72658 100644 (file)
 
 #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
 
index ee3d737e26ccd5b8fceadd510abdebc2d9a13898..c8ea26adae8e2d48a0e8f9a7476574b570af3a6f 100644 (file)
@@ -1505,7 +1505,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);
index b0990a8cc304a0c52b6d1bd295b804a796bf173d..1783d9c477fd046fd244e9c50927cb8d8150d84f 100644 (file)
@@ -104,7 +104,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;
index eceac83f719c7b97e0649fdc7cbf892344036a94..ffe99832bce497f91a3a7b212d8055e0ae43c661 100644 (file)
@@ -1079,7 +1079,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