swr: [rasterizer memory] minify original sizes for block formats
authorIlia Mirkin <imirkin@alum.mit.edu>
Sat, 12 Nov 2016 08:01:15 +0000 (03:01 -0500)
committerIlia Mirkin <imirkin@alum.mit.edu>
Tue, 22 Nov 2016 02:11:26 +0000 (21:11 -0500)
There's no guarantee that mip width/height will be a multiple of the
compressed block size. Doing a divide by the block size first yields
different results than GL expects, so we do the divide at the end.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Tim Rowley <timothy.o.rowley@intel.com>
src/gallium/drivers/swr/rasterizer/memory/TilingFunctions.h

index 0694a99808f6351ca106f58d4710e7ef060325a4..11ed4518f2efb012ca4e9ab3881253b7fce1e0bc 100644 (file)
@@ -274,9 +274,12 @@ INLINE void ComputeLODOffset1D(
     else
     {
         uint32_t curWidth = baseWidth;
-        // translate mip width from pixels to blocks for block compressed formats
-        // @note hAlign is already in blocks for compressed formats so no need to convert
-        if (info.isBC) curWidth /= info.bcWidth;
+        // @note hAlign is already in blocks for compressed formats so upconvert
+        //       so that we have the desired alignment post-divide.
+        if (info.isBC)
+        {
+            hAlign *= info.bcWidth;
+        }
 
         offset = GFX_ALIGN(curWidth, hAlign);
         for (uint32_t l = 1; l < lod; ++l)
@@ -285,7 +288,7 @@ INLINE void ComputeLODOffset1D(
             offset += curWidth;
         }
 
-        if (info.isSubsampled)
+        if (info.isSubsampled || info.isBC)
         {
             offset /= info.bcWidth;
         }
@@ -312,14 +315,17 @@ INLINE void ComputeLODOffsetX(
     else
     {
         uint32_t curWidth = baseWidth;
-        // convert mip width from pixels to blocks for block compressed formats
-        // @note hAlign is already in blocks for compressed formats so no need to convert
-        if (info.isBC) curWidth /= info.bcWidth;
+        // @note hAlign is already in blocks for compressed formats so upconvert
+        //       so that we have the desired alignment post-divide.
+        if (info.isBC)
+        {
+            hAlign *= info.bcWidth;
+        }
 
         curWidth = std::max<uint32_t>(curWidth >> 1, 1U);
         curWidth = GFX_ALIGN(curWidth, hAlign);
 
-        if (info.isSubsampled)
+        if (info.isSubsampled || info.isBC)
         {
             curWidth /= info.bcWidth;
         }
@@ -350,9 +356,12 @@ INLINE void ComputeLODOffsetY(
         offset = 0;
         uint32_t mipHeight = baseHeight;
 
-        // translate mip height from pixels to blocks for block compressed formats
-        // @note VAlign is already in blocks for compressed formats so no need to convert
-        if (info.isBC) mipHeight /= info.bcHeight;
+        // @note vAlign is already in blocks for compressed formats so upconvert
+        //       so that we have the desired alignment post-divide.
+        if (info.isBC)
+        {
+            vAlign *= info.bcHeight;
+        }
 
         for (uint32_t l = 1; l <= lod; ++l)
         {
@@ -360,6 +369,11 @@ INLINE void ComputeLODOffsetY(
             offset += ((l != 2) ? alignedMipHeight : 0);
             mipHeight = std::max<uint32_t>(mipHeight >> 1, 1U);
         }
+
+        if (info.isBC)
+        {
+            offset /= info.bcHeight;
+        }
     }
 }