From aea8722729550ef8487d0ef5bc3cce72a3a959a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 5 Apr 2021 13:42:52 +0200 Subject: [PATCH] Add generic depth/stencil PixelFormat values. The 32-bit float depth be needed for the upcoming OpenEXR plugin, added also the remaining ones that will be eventually supported by KTX and DDS plugins. --- doc/changelog.dox | 8 ++ src/Magnum/DebugTools/CompareImage.cpp | 43 ++++++-- src/Magnum/DebugTools/CompareImage.h | 6 +- .../DebugTools/Test/CompareImageTest.cpp | 16 +++ .../GL/Implementation/pixelFormatMapping.hpp | 28 +++++ .../Implementation/pixelFormatMapping.hpp | 7 ++ src/Magnum/PixelFormat.cpp | 7 ++ src/Magnum/PixelFormat.h | 103 +++++++++++++++++- .../Vk/Implementation/pixelFormatMapping.hpp | 7 ++ 9 files changed, 214 insertions(+), 11 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index b94e6c63d..0e656a333 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -41,6 +41,14 @@ See also: @subsection changelog-latest-new New features - New @ref NoAllocate constructor tag, to be used by the @ref Vk library +- New @ref PixelFormat::Depth16Unorm, @relativeref{PixelFormat,Depth24Unorm}, + @relativeref{PixelFormat,Depth32F}, @relativeref{PixelFormat,Stencil8UI}, + @relativeref{PixelFormat,Depth16UnormStencil8UI}, + @relativeref{PixelFormat,Depth24UnormStencil8UI}, + @relativeref{PixelFormat,Depth32FStencil8UI} generic pixel formats, + including mapping to @ref GL::PixelFormat / @ref GL::PixelType, + @ref GL::TextureFormat and @ref Vk::PixelFormat and (partial) support in + @ref DebugTools::CompareImage @subsubsection changelog-latest-new-debugtools DebugTools library diff --git a/src/Magnum/DebugTools/CompareImage.cpp b/src/Magnum/DebugTools/CompareImage.cpp index ea0d30227..9a79fae4d 100644 --- a/src/Magnum/DebugTools/CompareImage.cpp +++ b/src/Magnum/DebugTools/CompareImage.cpp @@ -132,8 +132,17 @@ std::tuple, Float, Float> calculateImageDelta(const Pix Containers::arrayCast<2, const Math::Vector>(actualPixels), \ expected.pixels>(), delta); \ break; + #define _f(first, second, third, fourth, size, T) \ + case PixelFormat::first: \ + case PixelFormat::second: \ + case PixelFormat::third: \ + case PixelFormat::fourth: \ + max = calculateImageDelta( \ + Containers::arrayCast<2, const Math::Vector>(actualPixels), \ + expected.pixels>(), delta); \ + break; /* LCOV_EXCL_START */ - _e(R8Unorm, R8Srgb, R8UI, 1, UnsignedByte) + _f(R8Unorm, R8Srgb, R8UI, Stencil8UI, 1, UnsignedByte) _e(RG8Unorm, RG8Srgb, RG8UI, 2, UnsignedByte) _e(RGB8Unorm, RGB8Srgb, RGB8UI, 3, UnsignedByte) _e(RGBA8Unorm, RGBA8Srgb, RGBA8UI, 4, UnsignedByte) @@ -141,7 +150,7 @@ std::tuple, Float, Float> calculateImageDelta(const Pix _d(RG8Snorm, RG8I, 2, Byte) _d(RGB8Snorm, RGB8I, 3, Byte) _d(RGBA8Snorm, RGBA8I, 4, Byte) - _d(R16Unorm, R16UI, 1, UnsignedShort) + _e(R16Unorm, R16UI, Depth16Unorm, 1, UnsignedShort) _d(RG16Unorm, RG16UI, 2, UnsignedShort) _d(RGB16Unorm, RGB16UI, 3, UnsignedShort) _d(RGBA16Unorm, RGBA16UI, 4, UnsignedShort) @@ -149,7 +158,7 @@ std::tuple, Float, Float> calculateImageDelta(const Pix _d(RG16Snorm, RG16I, 2, Short) _d(RGB16Snorm, RGB16I, 3, Short) _d(RGBA16Snorm, RGBA16I, 4, Short) - _c(R32UI, 1, UnsignedInt) + _d(R32UI, Depth24Unorm, 1, UnsignedInt) _c(RG32UI, 2, UnsignedInt) _c(RGB32UI, 3, UnsignedInt) _c(RGBA32UI, 4, UnsignedInt) @@ -157,11 +166,12 @@ std::tuple, Float, Float> calculateImageDelta(const Pix _c(RG32I, 2, Int) _c(RGB32I, 3, Int) _c(RGBA32I, 4, Int) - _c(R32F, 1, Float) + _d(R32F, Depth32F, 1, Float) _c(RG32F, 2, Float) _c(RGB32F, 3, Float) _c(RGBA32F, 4, Float) /* LCOV_EXCL_STOP */ + #undef _f #undef _e #undef _d #undef _c @@ -171,6 +181,10 @@ std::tuple, Float, Float> calculateImageDelta(const Pix case PixelFormat::RGB16F: case PixelFormat::RGBA16F: CORRADE_ASSERT_UNREACHABLE("DebugTools::CompareImage: half-float formats are not supported yet", {}); + case PixelFormat::Depth16UnormStencil8UI: + case PixelFormat::Depth24UnormStencil8UI: + case PixelFormat::Depth32FStencil8UI: + CORRADE_ASSERT_UNREACHABLE("DebugTools::CompareImage: packed depth/stencil formats are not supported yet", {}); } #ifdef __GNUC__ #pragma GCC diagnostic pop @@ -261,11 +275,18 @@ void printPixelAt(Debug& out, const Containers::StridedArrayView3D& #define _e(first, second, third, size, T) \ case PixelFormat::first: \ case PixelFormat::second: \ - case PixelFormat::third: \ + case PixelFormat::third: \ + out << *reinterpret_cast*>(pixel); \ + break; + #define _f(first, second, third, fourth, size, T) \ + case PixelFormat::first: \ + case PixelFormat::second: \ + case PixelFormat::third: \ + case PixelFormat::fourth: \ out << *reinterpret_cast*>(pixel); \ break; /* LCOV_EXCL_START */ - _e(R8Unorm, R8Srgb, R8UI, 1, UnsignedByte) + _f(R8Unorm, R8Srgb, R8UI, Stencil8UI, 1, UnsignedByte) _e(RG8Unorm, RG8Srgb, RG8UI, 2, UnsignedByte) _c(RGB8UI, 3, UnsignedByte) _c(RGBA8UI, 4, UnsignedByte) @@ -274,7 +295,7 @@ void printPixelAt(Debug& out, const Containers::StridedArrayView3D& _d(RG8Snorm, RG8I, 2, Byte) _d(RGB8Snorm, RGB8I, 3, Byte) _d(RGBA8Snorm, RGBA8I, 4, Byte) - _d(R16Unorm, R16UI, 1, UnsignedShort) + _e(R16Unorm, R16UI, Depth16Unorm, 1, UnsignedShort) _d(RG16Unorm, RG16UI, 2, UnsignedShort) _d(RGB16Unorm, RGB16UI, 3, UnsignedShort) _d(RGBA16Unorm, RGBA16UI, 4, UnsignedShort) @@ -282,7 +303,7 @@ void printPixelAt(Debug& out, const Containers::StridedArrayView3D& _d(RG16Snorm, RG16I, 2, Short) _d(RGB16Snorm, RGB16I, 3, Short) _d(RGBA16Snorm, RGBA16I, 4, Short) - _c(R32UI, 1, UnsignedInt) + _d(R32UI, Depth24Unorm, 1, UnsignedInt) _c(RG32UI, 2, UnsignedInt) _c(RGB32UI, 3, UnsignedInt) _c(RGBA32UI, 4, UnsignedInt) @@ -290,11 +311,12 @@ void printPixelAt(Debug& out, const Containers::StridedArrayView3D& _c(RG32I, 2, Int) _c(RGB32I, 3, Int) _c(RGBA32I, 4, Int) - _c(R32F, 1, Float) + _d(R32F, Depth32F, 1, Float) _c(RG32F, 2, Float) _c(RGB32F, 3, Float) _c(RGBA32F, 4, Float) /* LCOV_EXCL_STOP */ + #undef _f #undef _e #undef _d #undef _c @@ -313,6 +335,9 @@ void printPixelAt(Debug& out, const Containers::StridedArrayView3D& case PixelFormat::RG16F: case PixelFormat::RGB16F: case PixelFormat::RGBA16F: + case PixelFormat::Depth16UnormStencil8UI: + case PixelFormat::Depth24UnormStencil8UI: + case PixelFormat::Depth32FStencil8UI: /* Already handled by a printing assert before */ CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ } diff --git a/src/Magnum/DebugTools/CompareImage.h b/src/Magnum/DebugTools/CompareImage.h index 546d8e43c..690402944 100644 --- a/src/Magnum/DebugTools/CompareImage.h +++ b/src/Magnum/DebugTools/CompareImage.h @@ -227,7 +227,11 @@ Supports the following formats: - @ref PixelFormat::RGBA32F and its one-/two-/three-component versions @ref PixelFormat::RGBA16F and other half-float formats are not supported at the -moment. Implementation-specific pixel formats can't be supported. +moment. Packed depth/stencil formats are not supported at the moment, +however you can work around that by making separate depth/stencil pixel +views and @ref DebugTools-CompareImage-pixels "comparing those" to a +depth/stencil-only ground truth images. Implementation-specific pixel +formats can't be supported. Supports all @ref PixelStorage parameters. The images don't need to have the same pixel storage parameters, meaning you are able to compare different diff --git a/src/Magnum/DebugTools/Test/CompareImageTest.cpp b/src/Magnum/DebugTools/Test/CompareImageTest.cpp index e2809d700..29df8251a 100644 --- a/src/Magnum/DebugTools/Test/CompareImageTest.cpp +++ b/src/Magnum/DebugTools/Test/CompareImageTest.cpp @@ -54,6 +54,7 @@ struct CompareImageTest: TestSuite::Tester { void formatUnknown(); void formatHalf(); + void formatPackedDepthStencil(); void formatImplementationSpecific(); void calculateDelta(); @@ -125,6 +126,7 @@ struct CompareImageTest: TestSuite::Tester { CompareImageTest::CompareImageTest() { addTests({&CompareImageTest::formatUnknown, &CompareImageTest::formatHalf, + &CompareImageTest::formatPackedDepthStencil, &CompareImageTest::formatImplementationSpecific, &CompareImageTest::calculateDelta, @@ -265,6 +267,20 @@ void CompareImageTest::formatHalf() { CORRADE_COMPARE(out.str(), "DebugTools::CompareImage: half-float formats are not supported yet\n"); } +void CompareImageTest::formatPackedDepthStencil() { + #ifdef CORRADE_NO_ASSERT + CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); + #endif + + std::ostringstream out; + Error redirectError{&out}; + + ImageView2D image{PixelFormat::Depth24UnormStencil8UI, {}}; + Implementation::calculateImageDelta(image.format(), image.pixels(), image); + + CORRADE_COMPARE(out.str(), "DebugTools::CompareImage: packed depth/stencil formats are not supported yet\n"); +} + void CompareImageTest::formatImplementationSpecific() { #ifdef CORRADE_NO_ASSERT CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); diff --git a/src/Magnum/GL/Implementation/pixelFormatMapping.hpp b/src/Magnum/GL/Implementation/pixelFormatMapping.hpp index 0d487f6b4..8a0c14111 100644 --- a/src/Magnum/GL/Implementation/pixelFormatMapping.hpp +++ b/src/Magnum/GL/Implementation/pixelFormatMapping.hpp @@ -183,4 +183,32 @@ _n(RG32F, LuminanceAlpha, Float) _n(RGB32F, RGB, Float) _n(RGBA32F, RGBA, Float) #endif +#ifndef MAGNUM_TARGET_GLES2 +_c(Depth16Unorm, DepthComponent, UnsignedShort, DepthComponent16) +_c(Depth24Unorm, DepthComponent, UnsignedInt, DepthComponent24) +#else +_n(Depth16Unorm, DepthComponent, UnsignedShort) +_n(Depth24Unorm, DepthComponent, UnsignedInt) +#endif +#ifndef MAGNUM_TARGET_GLES2 +_c(Depth32F, DepthComponent, Float, DepthComponent32F) +#else +_s(Depth32F) +#endif +#ifndef MAGNUM_TARGET_WEBGL +_c(Stencil8UI, StencilIndex, UnsignedByte, StencilIndex8) +#else +_s(Stencil8UI) +#endif +_s(Depth16UnormStencil8UI) +#ifndef MAGNUM_TARGET_GLES2 +_c(Depth24UnormStencil8UI, DepthStencil, UnsignedInt248, Depth24Stencil8) +#else +_n(Depth24UnormStencil8UI, DepthStencil, UnsignedInt248) +#endif +#ifndef MAGNUM_TARGET_GLES2 +_c(Depth32FStencil8UI, DepthStencil, Float32UnsignedInt248Rev, Depth32FStencil8) +#else +_s(Depth32FStencil8UI) +#endif #endif diff --git a/src/Magnum/Implementation/pixelFormatMapping.hpp b/src/Magnum/Implementation/pixelFormatMapping.hpp index c9495f39e..67360a28f 100644 --- a/src/Magnum/Implementation/pixelFormatMapping.hpp +++ b/src/Magnum/Implementation/pixelFormatMapping.hpp @@ -77,4 +77,11 @@ _c(R32F) _c(RG32F) _c(RGB32F) _c(RGBA32F) +_c(Depth16Unorm) +_c(Depth24Unorm) +_c(Depth32F) +_c(Stencil8UI) +_c(Depth16UnormStencil8UI) +_c(Depth24UnormStencil8UI) +_c(Depth32FStencil8UI) #endif diff --git a/src/Magnum/PixelFormat.cpp b/src/Magnum/PixelFormat.cpp index 6aee8b921..3b38a15aa 100644 --- a/src/Magnum/PixelFormat.cpp +++ b/src/Magnum/PixelFormat.cpp @@ -48,6 +48,7 @@ UnsignedInt pixelSize(const PixelFormat format) { case PixelFormat::R8Srgb: case PixelFormat::R8UI: case PixelFormat::R8I: + case PixelFormat::Stencil8UI: return 1; case PixelFormat::RG8Unorm: case PixelFormat::RG8Snorm: @@ -59,6 +60,7 @@ UnsignedInt pixelSize(const PixelFormat format) { case PixelFormat::R16UI: case PixelFormat::R16I: case PixelFormat::R16F: + case PixelFormat::Depth16Unorm: return 2; case PixelFormat::RGB8Unorm: case PixelFormat::RGB8Snorm: @@ -79,6 +81,10 @@ UnsignedInt pixelSize(const PixelFormat format) { case PixelFormat::R32UI: case PixelFormat::R32I: case PixelFormat::R32F: + case PixelFormat::Depth24Unorm: + case PixelFormat::Depth32F: + case PixelFormat::Depth16UnormStencil8UI: + case PixelFormat::Depth24UnormStencil8UI: return 4; case PixelFormat::RGB16Unorm: case PixelFormat::RGB16Snorm: @@ -94,6 +100,7 @@ UnsignedInt pixelSize(const PixelFormat format) { case PixelFormat::RG32UI: case PixelFormat::RG32I: case PixelFormat::RG32F: + case PixelFormat::Depth32FStencil8UI: return 8; case PixelFormat::RGB32UI: case PixelFormat::RGB32I: diff --git a/src/Magnum/PixelFormat.h b/src/Magnum/PixelFormat.h index 50e0f468a..62bf70d67 100644 --- a/src/Magnum/PixelFormat.h +++ b/src/Magnum/PixelFormat.h @@ -663,7 +663,108 @@ enum class PixelFormat: UnsignedInt { * or @m_class{m-doc-external} [MTLPixelFormatRGBA32Float](https://developer.apple.com/documentation/metal/mtlpixelformat/mtlpixelformatrgba32float?language=objc). * @m_keywords{DXGI_FORMAT_R32G32B32A32_FLOAT MTLPixelFormatRGBA32Float} */ - RGBA32F + RGBA32F, + + /** + * 16-bit unsigned normalized depth. + * + * Corresponds to @ref GL::PixelFormat::DepthComponent and + * @ref GL::PixelType::UnsignedShort, + * @ref GL::TextureFormat::DepthComponent16; + * @ref Vk::PixelFormat::Depth16Unorm; + * @m_class{m-doc-external} [DXGI_FORMAT_D16_UNORM](https://docs.microsoft.com/en-us/windows/win32/api/dxgiformat/ne-dxgiformat-dxgi_format) + * or @m_class{m-doc-external} [MTLPixelFormatDepth16Unorm](https://developer.apple.com/documentation/metal/mtlpixelformat/mtlpixelformatdepth16unorm?language=objc). + * @m_keywords{DXGI_FORMAT_D16_UNORM MTLPixelFormatDepth16Unorm} + * @m_since_latest + */ + Depth16Unorm, + + /** + * 24-bit unsigned normalized depth. Data layout consistent with the + * [KTX2 specification](http://github.khronos.org/KTX-Specification/#_depth_and_stencil_formats) + * --- aligned to 32 bits with the 8 most significant bits unused. + * + * Corresponds to @ref GL::PixelFormat::DepthComponent and + * @ref GL::PixelType::UnsignedInt, + * @ref GL::TextureFormat::DepthComponent24; + * @ref Vk::PixelFormat::Depth24Unorm. No direct 24-bit D3D or Metal + * equivalent. + * @m_since_latest + * @todo wait, how GL interprets this? does it discard the top 8 bits? or + * should I use UnsignedInt248 instead? + */ + Depth24Unorm, + + /** + * 32-bit float depth. + * + * Corresponds to @ref GL::PixelFormat::DepthComponent and + * @ref GL::PixelType::Float, @ref GL::TextureFormat::DepthComponent32F; + * @ref Vk::PixelFormat::Depth32F; + * @m_class{m-doc-external} [DXGI_FORMAT_D32_FLOAT](https://docs.microsoft.com/en-us/windows/win32/api/dxgiformat/ne-dxgiformat-dxgi_format) + * or @m_class{m-doc-external} [MTLPixelFormatDepth32Float](https://developer.apple.com/documentation/metal/mtlpixelformat/mtlpixelformatdepth32float?language=objc). + * @m_keywords{DXGI_FORMAT_D32_FLOAT MTLPixelFormatDepth32Float} + * @m_since_latest + */ + Depth32F, + + /** + * 8-bit unsigned integral stencil. + * + * Corresponds to @ref GL::PixelFormat::StencilIndex and + * @ref GL::PixelType::UnsignedByte, @ref GL::TextureFormat::StencilIndex8; + * @ref Vk::PixelFormat::Stencil8UI + * or @m_class{m-doc-external} [MTLPixelFormatStencil8](https://developer.apple.com/documentation/metal/mtlpixelformat/mtlpixelformatstencil8?language=objc). No direct 8-bit D3D equivalent. + * @m_keywords{MTLPixelFormatStencil8} + * @m_since_latest + */ + Stencil8UI, + + /** + * 16-bit unsigned normalized depth with 8-bit unsigned integral stencil. + * Data layout consistent with the [KTX2 specification](http://github.khronos.org/KTX-Specification/#_depth_and_stencil_formats) + * --- aligned to 32 bits with depth in the 16 least significant bits and + * the 8 most significant bits unused. + * + * Corresponds to @ref Vk::PixelFormat::Depth16UnormStencil8UI. No direct + * 32-bit GL, D3D or Metal equivalent. + * @m_since_latest + */ + Depth16UnormStencil8UI, + + /** + * 24-bit unsigned normalized depth with 8-bit unsigned integral stencil. + * Data layout consistent with the [KTX2 specification](http://github.khronos.org/KTX-Specification/#_depth_and_stencil_formats) + * --- packed to 32 bits with depth in the 24 least significant bits + * and stencil being in the 8 most significant bits. + * + * Corresponds to @ref GL::PixelFormat::DepthStencil and + * @ref GL::PixelType::UnsignedInt248, + * @ref GL::TextureFormat::Depth24Stencil8; + * @ref Vk::PixelFormat::Depth24UnormStencil8UI; + * @m_class{m-doc-external} [DXGI_FORMAT_D24_UNORM_S8_UINT](https://docs.microsoft.com/en-us/windows/win32/api/dxgiformat/ne-dxgiformat-dxgi_format) + * or @m_class{m-doc-external} [MTLPixelFormatDepth24Unorm_Stencil8](https://developer.apple.com/documentation/metal/mtlpixelformat/mtlpixelformatdepth24unorm_stencil8?language=objc). + * @m_keywords{DXGI_FORMAT_D24_UNORM_S8_UINT MTLPixelFormatDepth24Unorm_Stencil8} + * @m_since_latest + */ + Depth24UnormStencil8UI, + + /** + * 32-bit float depth with 8-bit unsigned integral stencil. Data layout + * consistent with the [KTX2 specification](http://github.khronos.org/KTX-Specification/#_depth_and_stencil_formats) + * --- packed to 64 bits with the depth in the 32 least significant + * bits and the 24 most significant bits unused. + * + * Corresponds to @ref GL::PixelFormat::DepthStencil and + * @ref GL::PixelType::Float32UnsignedInt248Rev, + * @ref GL::TextureFormat::Depth32FStencil8; + * @ref Vk::PixelFormat::Depth32FStencil8UI; + * @m_class{m-doc-external} [DXGI_FORMAT_D32_FLOAT_S8X24_UINT](https://docs.microsoft.com/en-us/windows/win32/api/dxgiformat/ne-dxgiformat-dxgi_format) + * or @m_class{m-doc-external} [MTLPixelFormatDepth32Float_Stencil8](https://developer.apple.com/documentation/metal/mtlpixelformat/mtlpixelformatdepth32float_stencil8?language=objc). + * @m_keywords{DXGI_FORMAT_D32_FLOAT_S8X24_UINT MTLPixelFormatDepth32Float_Stencil8} + * @m_since_latest + */ + Depth32FStencil8UI }; /** diff --git a/src/Magnum/Vk/Implementation/pixelFormatMapping.hpp b/src/Magnum/Vk/Implementation/pixelFormatMapping.hpp index 9e2d7986d..51a7e490c 100644 --- a/src/Magnum/Vk/Implementation/pixelFormatMapping.hpp +++ b/src/Magnum/Vk/Implementation/pixelFormatMapping.hpp @@ -77,4 +77,11 @@ _c(R32F) _c(RG32F) _c(RGB32F) _c(RGBA32F) +_c(Depth16Unorm) +_c(Depth24Unorm) +_c(Depth32F) +_c(Stencil8UI) +_c(Depth16UnormStencil8UI) +_c(Depth24UnormStencil8UI) +_c(Depth32FStencil8UI) #endif