swr: [rasterizer memory] minify original sizes for block formats

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>
This commit is contained in:
Ilia Mirkin 2016-11-12 03:01:15 -05:00
parent bf75ef3f92
commit c5a654786b
1 changed files with 25 additions and 11 deletions

View 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;
}
}
}