From 410441791c6cd8bd99aadb61198ea6be1944901b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 1 Jun 2023 18:09:05 +0200 Subject: [PATCH] Math: implement BC2 flipping as well. It's a weird format nobody uses, but since I have the full context in my head now, it's easy to do. --- src/Magnum/Math/ColorBatch.cpp | 38 ++++++++++++++++++ src/Magnum/Math/ColorBatch.h | 19 ++++++++- src/Magnum/Math/Test/CMakeLists.txt | 1 + src/Magnum/Math/Test/ColorBatchTest.cpp | 25 ++++++++++++ .../Math/Test/ColorBatchTestFiles/bc2.png | Bin 0 -> 206 bytes src/Magnum/PixelFormat.h | 6 ++- 6 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 src/Magnum/Math/Test/ColorBatchTestFiles/bc2.png diff --git a/src/Magnum/Math/ColorBatch.cpp b/src/Magnum/Math/ColorBatch.cpp index edffbbb2c..89ebc69dd 100644 --- a/src/Magnum/Math/ColorBatch.cpp +++ b/src/Magnum/Math/ColorBatch.cpp @@ -60,6 +60,36 @@ inline void yFlipBc1BlockInPlace(char* const data) { } } +inline void yFlipBc2BlockInPlace(char* data) { + /* The 128-bit block is laid out as follows: + + - 8 bytes for 4x4 4-bit alpha values, same order as BC1 + - 2 bytes for first endpoint color + - 2 bytes for second endpoint color + - 4 bytes for 4x4 2-bit color indices, same order as BC1 + + Which means, swapping the alphas and then doing the same as with BC1 + for the color indices in the second half. + https://learn.microsoft.com/cs-cz/windows/win32/direct3d10/d3d10-graphics-programming-guide-resources-block-compression#bc2 */ + { + char tmp1 = data[0]; + char tmp2 = data[1]; + data[0] = data[6]; + data[1] = data[7]; + data[6] = tmp1; + data[7] = tmp2; + } { + char tmp1 = data[2]; + char tmp2 = data[3]; + data[2] = data[4]; + data[3] = data[5]; + data[4] = tmp1; + data[5] = tmp2; + } + + yFlipBc1BlockInPlace(data + 8); +} + inline void yFlipBc4BlockInPlace(char* data) { /* The 64-bit block is laid out as follows: @@ -173,6 +203,14 @@ void yFlipBc1InPlace(const Containers::StridedArrayView4D& blocks) { ); } +void yFlipBc2InPlace(const Containers::StridedArrayView4D& blocks) { + yFlipBlocksInPlace<16, yFlipBc2BlockInPlace>(blocks + #ifndef CORRADE_NO_ASSERT + , "Math::yFlipBc2InPlace():" + #endif + ); +} + void yFlipBc3InPlace(const Containers::StridedArrayView4D& blocks) { yFlipBlocksInPlace<16, yFlipBc3BlockInPlace>(blocks #ifndef CORRADE_NO_ASSERT diff --git a/src/Magnum/Math/ColorBatch.h b/src/Magnum/Math/ColorBatch.h index 98ffa82ff..749c2e31b 100644 --- a/src/Magnum/Math/ColorBatch.h +++ b/src/Magnum/Math/ColorBatch.h @@ -57,7 +57,24 @@ expected to be contiguous with size of 8. */ MAGNUM_EXPORT void yFlipBc1InPlace(const Corrade::Containers::StridedArrayView4D& blocks); -/** @todo BC2, if used at all for anything */ +/** +@brief Y-flip BC2 texture blocks in-place +@m_since_latest + +Performs a Y flip of given 3D image by flipping block order and modifying +internal block representation to encode the same information, just upside down. +No decoding or re-encoding of the block data is performed, thus the operation +is lossless. However note that this operation flips full blocks --- if size of +the actual image isn't whole blocks, the flipped image will be shifted compared +to the original, possibly with garbage data appearing in the first few rows. + +First dimension is expected to be image slices, second block rows, third +2D blocks, fourth the 128-bit 4x4 block data, i.e. the last dimension is +expected to be contiguous with size of 16. +@see @ref CompressedPixelFormat::Bc2RGBAUnorm, + @ref CompressedPixelFormat::Bc2RGBASrgb +*/ +MAGNUM_EXPORT void yFlipBc2InPlace(const Corrade::Containers::StridedArrayView4D& blocks); /** @brief Y-flip BC3 texture blocks in-place diff --git a/src/Magnum/Math/Test/CMakeLists.txt b/src/Magnum/Math/Test/CMakeLists.txt index 1849d8eca..e1c9294bc 100644 --- a/src/Magnum/Math/Test/CMakeLists.txt +++ b/src/Magnum/Math/Test/CMakeLists.txt @@ -50,6 +50,7 @@ corrade_add_test(MathColorBatchTest ColorBatchTest.cpp LIBRARIES MagnumMathTestLib MagnumDebugTools FILES ColorBatchTestFiles/bc1.png + ColorBatchTestFiles/bc2.png ColorBatchTestFiles/bc3.png ColorBatchTestFiles/bc4.png ColorBatchTestFiles/bc5.png diff --git a/src/Magnum/Math/Test/ColorBatchTest.cpp b/src/Magnum/Math/Test/ColorBatchTest.cpp index 2136f9a29..8c99691b3 100644 --- a/src/Magnum/Math/Test/ColorBatchTest.cpp +++ b/src/Magnum/Math/Test/ColorBatchTest.cpp @@ -192,6 +192,31 @@ const struct { '\xdd', '\xff', '\xa8', '\x6b', '\x09', '\x25', '\x95', '\x55', '\x79', '\xd6', '\xa7', '\x39', '\x35', '\xd5', '\x55', '\x5c' }}}, + {"BC2", CompressedPixelFormat::Bc2RGBAUnorm, {1, 4}, {InPlaceInit, { + /* ./extract-interesting-blocks.py testcard_bc2.dds bc2.png --offset 88 + (image taken from the bcdec repository test files) */ + /* [7, 52], 2.427 */ + '\xf8', '\xff', '\x91', '\xff', '\x20', '\xfa', '\x00', '\xc4', + '\xff', '\xff', '\x0f', '\xb3', '\x55', '\x55', '\x54', '\x50', + /* [6, 51], 2.427 */ + '\x90', '\xff', '\x20', '\xfb', '\x00', '\xd4', '\x00', '\x60', + '\xff', '\xff', '\x0f', '\xb3', '\x54', '\x54', '\x50', '\x40', + /* [53, 8], 2.412 */ + '\x6d', '\x00', '\xdf', '\x06', '\xff', '\x7e', '\xff', '\xff', + '\xff', '\xff', '\xf6', '\x63', '\x05', '\x15', '\x55', '\x55', + /* [10, 8], 2.412 */ + '\x00', '\xd6', '\x60', '\xfd', '\xe7', '\xff', '\xff', '\xff', + '\xff', '\xff', '\xf6', '\x63', '\x50', '\x54', '\x55', '\x55', + }}, yFlipBc2InPlace, "bc2.png", {InPlaceInit, { + '\xff', '\xff', '\xe7', '\xff', '\x60', '\xfd', '\x00', '\xd6', + '\xff', '\xff', '\xf6', '\x63', '\x55', '\x55', '\x54', '\x50', + '\xff', '\xff', '\xff', '\x7e', '\xdf', '\x06', '\x6d', '\x00', + '\xff', '\xff', '\xf6', '\x63', '\x55', '\x55', '\x15', '\x05', + '\x00', '\x60', '\x00', '\xd4', '\x20', '\xfb', '\x90', '\xff', + '\xff', '\xff', '\x0f', '\xb3', '\x40', '\x50', '\x54', '\x54', + '\x00', '\xc4', '\x20', '\xfa', '\x91', '\xff', '\xf8', '\xff', + '\xff', '\xff', '\x0f', '\xb3', '\x50', '\x54', '\x55', '\x55' + }}}, {"BC3", CompressedPixelFormat::Bc3RGBAUnorm, {1, 4}, {InPlaceInit, { /* ./extract-interesting-blocks.py dice_bc3.dds bc3.png --offset 148 (image taken from the bcdec repository test files) */ diff --git a/src/Magnum/Math/Test/ColorBatchTestFiles/bc2.png b/src/Magnum/Math/Test/ColorBatchTestFiles/bc2.png new file mode 100644 index 0000000000000000000000000000000000000000..12d312d7ce01f56bcbb41444c890a486a76f8897 GIT binary patch literal 206 zcmV;<05SiGP)+$P6tU6~6k8V%Oe+?)E+AOAKo$^UVIt92y}S4B zhYKe2Q>8T_W+)pYx?K*}Xl;*WTj3e*gdg07*qo IM6N<$g1&T5Jpcdz literal 0 HcmV?d00001 diff --git a/src/Magnum/PixelFormat.h b/src/Magnum/PixelFormat.h index 2f0fce02a..a1779e446 100644 --- a/src/Magnum/PixelFormat.h +++ b/src/Magnum/PixelFormat.h @@ -1078,7 +1078,8 @@ enum class CompressedPixelFormat: UnsignedInt { * @ref Vk::PixelFormat::CompressedBc2RGBAUnorm; * @m_class{m-doc-external} [DXGI_FORMAT_BC2_UNORM](https://docs.microsoft.com/en-us/windows/win32/api/dxgiformat/ne-dxgiformat-dxgi_format) * or @m_class{m-doc-external} [MTLPixelFormatBC2_RGBA](https://developer.apple.com/documentation/metal/mtlpixelformat/mtlpixelformatbc2_rgba?language=objc). - * @see @relativeref{Trade,BcDecImageConverter} + * @see @ref Math::yFlipBc2InPlace(), + * @relativeref{Trade,BcDecImageConverter} * @m_keywords{DXGI_FORMAT_BC2_UNORM MTLPixelFormatBC2_RGBA} */ Bc2RGBAUnorm, @@ -1094,7 +1095,8 @@ enum class CompressedPixelFormat: UnsignedInt { * @ref Vk::PixelFormat::CompressedBc2RGBASrgb; * @m_class{m-doc-external} [DXGI_FORMAT_BC2_UNORM_SRGB](https://docs.microsoft.com/en-us/windows/win32/api/dxgiformat/ne-dxgiformat-dxgi_format) * or @m_class{m-doc-external} [MTLPixelFormatBC2_RGBA_sRGB](https://developer.apple.com/documentation/metal/mtlpixelformat/mtlpixelformatbc2_rgba_srgb?language=objc). - * @see @relativeref{Trade,BcDecImageConverter} + * @see @ref Math::yFlipBc2InPlace(), + * @relativeref{Trade,BcDecImageConverter} * @m_keywords{DXGI_FORMAT_BC2_UNORM_SRGB MTLPixelFormatBC2_RGBA_sRGB} * @m_since{2019,10} */