From 21ca0c4319dfd5a161c5f2a0c406e8f60194ea6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dar=C3=ADo?= Date: Wed, 7 Aug 2024 14:47:25 -0300 Subject: [PATCH] Reimplement get_offset to account for mipmaps with sizes that are not aligned to the format's block size. Fixes #6. (#7) --- ddspp.h | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/ddspp.h b/ddspp.h index b395f6d..fa264f7 100644 --- a/ddspp.h +++ b/ddspp.h @@ -1005,15 +1005,15 @@ namespace ddspp if (desc.type == Texture3D) { - for (unsigned int m = 0; m < mip; ++m) + for (unsigned int m = 0; m <= mip; ++m) { - unsigned long long mipSize = mip0Size >> 2 * m; - offset += mipSize * desc.numMips; + unsigned int mipWidth = (desc.width >> m) > 1 ? (desc.width >> m) : 1; + unsigned int mipHeight = (desc.height >> m) > 1 ? (desc.height >> m) : 1; + unsigned int mipBlocksWidth = (mipWidth + desc.blockWidth - 1) / desc.blockWidth; + unsigned int mipBlocksHeight = (mipHeight + desc.blockHeight - 1) / desc.blockHeight; + unsigned long long mipSize = mipBlocksWidth * mipBlocksHeight * desc.bitsPerPixelOrBlock; + offset += mipSize * ((m == mip) ? slice : desc.numMips); } - - unsigned long long lastMip = mip0Size >> 2 * mip; - - offset += lastMip * slice; } else { @@ -1021,16 +1021,22 @@ namespace ddspp for (unsigned int m = 0; m < desc.numMips; ++m) { - unsigned long long mipSize = mip0Size >> 2 * m; // Divide by 2 in width and height - mipChainSize += mipSize > desc.bitsPerPixelOrBlock ? mipSize : desc.bitsPerPixelOrBlock; + unsigned int mipWidth = (desc.width >> m) > 1 ? (desc.width >> m) : 1; + unsigned int mipHeight = (desc.height >> m) > 1 ? (desc.height >> m) : 1; + unsigned int mipBlocksWidth = (mipWidth + desc.blockWidth - 1) / desc.blockWidth; + unsigned int mipBlocksHeight = (mipHeight + desc.blockHeight - 1) / desc.blockHeight; + mipChainSize += mipBlocksWidth * mipBlocksHeight * desc.bitsPerPixelOrBlock; } offset += mipChainSize * slice; for (unsigned int m = 0; m < mip; ++m) { - unsigned long long mipSize = mip0Size >> 2 * m; // Divide by 2 in width and height - offset += mipSize > desc.bitsPerPixelOrBlock ? mipSize : desc.bitsPerPixelOrBlock; + unsigned int mipWidth = (desc.width >> m) > 1 ? (desc.width >> m) : 1; + unsigned int mipHeight = (desc.height >> m) > 1 ? (desc.height >> m) : 1; + unsigned int mipBlocksWidth = (mipWidth + desc.blockWidth - 1) / desc.blockWidth; + unsigned int mipBlocksHeight = (mipHeight + desc.blockHeight - 1) / desc.blockHeight; + offset += mipBlocksWidth * mipBlocksHeight * desc.bitsPerPixelOrBlock; } }