From ac3db8a8bfc11cb734f8046988c22eeb81f91882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Sat, 20 Feb 2021 18:01:03 +0100 Subject: [PATCH] Utility/PixelFormat: Add preliminary support for SRGB formats (WIP) --- include/Nazara/OpenGLRenderer/Utils.inl | 15 ++++-- include/Nazara/Utility/Enums.hpp | 4 ++ include/Nazara/Utility/PixelFormat.inl | 17 +------ include/Nazara/VulkanRenderer/Utils.inl | 2 + src/Nazara/Utility/PixelFormat.cpp | 55 +++++++++++++++++++-- src/Nazara/VulkanRenderer/VulkanTexture.cpp | 28 ++++------- 6 files changed, 78 insertions(+), 43 deletions(-) diff --git a/include/Nazara/OpenGLRenderer/Utils.inl b/include/Nazara/OpenGLRenderer/Utils.inl index fcae4116a..0887b2e83 100644 --- a/include/Nazara/OpenGLRenderer/Utils.inl +++ b/include/Nazara/OpenGLRenderer/Utils.inl @@ -15,11 +15,16 @@ namespace Nz // TODO: Fill this switch switch (pixelFormat) { - case PixelFormat_A8: return GLTextureFormat { GL_R8, GL_RED, GL_UNSIGNED_BYTE, GL_ZERO, GL_ZERO, GL_ZERO, GL_RED }; - case PixelFormat_BGR8: return GLTextureFormat { GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE, GL_BLUE, GL_GREEN, GL_RED, GL_ONE }; - case PixelFormat_BGRA8: return GLTextureFormat { GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA }; - case PixelFormat_RGB8: return GLTextureFormat { GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE, GL_RED, GL_GREEN, GL_BLUE, GL_ONE }; - case PixelFormat_RGBA8: return GLTextureFormat { GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; + case PixelFormat_A8: return GLTextureFormat{ GL_R8, GL_RED, GL_UNSIGNED_BYTE, GL_ZERO, GL_ZERO, GL_ZERO, GL_RED }; + case PixelFormat_BGR8: return GLTextureFormat{ GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, GL_BLUE, GL_GREEN, GL_RED, GL_ONE }; + case PixelFormat_BGR8_SRGB: return GLTextureFormat{ GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE, GL_BLUE, GL_GREEN, GL_RED, GL_ONE }; + case PixelFormat_BGRA8: return GLTextureFormat{ GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA }; + case PixelFormat_BGRA8_SRGB: return GLTextureFormat{ GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA }; + case PixelFormat_Depth24Stencil8: return GLTextureFormat{ GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_RED, GL_GREEN, GL_ZERO, GL_ZERO }; + case PixelFormat_RGB8: return GLTextureFormat{ GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, GL_RED, GL_GREEN, GL_BLUE, GL_ONE }; + case PixelFormat_RGB8_SRGB: return GLTextureFormat{ GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE, GL_RED, GL_GREEN, GL_BLUE, GL_ONE }; + case PixelFormat_RGBA8: return GLTextureFormat{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; + case PixelFormat_RGBA8_SRGB: return GLTextureFormat{ GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; default: break; } diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index 6f556da16..4112ce48b 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -174,7 +174,9 @@ namespace Nz PixelFormat_A8, // 1*uint8 PixelFormat_BGR8, // 3*uint8 + PixelFormat_BGR8_SRGB, // 3*uint8 PixelFormat_BGRA8, // 4*uint8 + PixelFormat_BGRA8_SRGB, // 4*uint8 PixelFormat_DXT1, PixelFormat_DXT3, PixelFormat_DXT5, @@ -202,6 +204,7 @@ namespace Nz PixelFormat_RG32UI, // 2*uint32 PixelFormat_RGB5A1, // 3*uint5 + alpha bit PixelFormat_RGB8, // 3*uint8 + PixelFormat_RGB8_SRGB, // 3*uint8 PixelFormat_RGB16F, // 3*half PixelFormat_RGB16I, // 4*int16 PixelFormat_RGB16UI, // 4*uint16 @@ -210,6 +213,7 @@ namespace Nz PixelFormat_RGB32UI, // 4*uint32 PixelFormat_RGBA4, // 4*uint4 PixelFormat_RGBA8, // 4*uint8 + PixelFormat_RGBA8_SRGB, // 4*uint8 PixelFormat_RGBA16F, // 4*half PixelFormat_RGBA16I, // 4*int16 PixelFormat_RGBA16UI, // 4*uint16 diff --git a/include/Nazara/Utility/PixelFormat.inl b/include/Nazara/Utility/PixelFormat.inl index 6f0170607..e9b30f0ec 100644 --- a/include/Nazara/Utility/PixelFormat.inl +++ b/include/Nazara/Utility/PixelFormat.inl @@ -185,27 +185,14 @@ namespace Nz } #endif - ConvertFunction func = s_convertFunctions[srcFormat][dstFormat]; - if (!func) - { - NazaraError("Pixel format conversion from " + GetName(srcFormat) + " to " + GetName(dstFormat) + " is not supported"); - return false; - } - - if (!func(reinterpret_cast(src), reinterpret_cast(src) + GetBytesPerPixel(srcFormat), reinterpret_cast(dst))) - { - NazaraError("Pixel format conversion from " + GetName(srcFormat) + " to " + GetName(dstFormat) + " failed"); - return false; - } - - return true; + return Convert(srcFormat, dstFormat, src, static_cast(src) + GetBytesPerPixel(srcFormat), dst); } inline bool PixelFormatInfo::Convert(PixelFormat srcFormat, PixelFormat dstFormat, const void* start, const void* end, void* dst) { if (srcFormat == dstFormat) { - std::memcpy(dst, start, reinterpret_cast(end)-reinterpret_cast(start)); + std::memcpy(dst, start, reinterpret_cast(end) - reinterpret_cast(start)); return true; } diff --git a/include/Nazara/VulkanRenderer/Utils.inl b/include/Nazara/VulkanRenderer/Utils.inl index 90eba6933..a9a872601 100644 --- a/include/Nazara/VulkanRenderer/Utils.inl +++ b/include/Nazara/VulkanRenderer/Utils.inl @@ -15,9 +15,11 @@ namespace Nz switch (format) { case VK_FORMAT_B8G8R8A8_UNORM: return PixelFormat::PixelFormat_BGRA8; + case VK_FORMAT_B8G8R8A8_SRGB: return PixelFormat::PixelFormat_BGRA8_SRGB; case VK_FORMAT_D24_UNORM_S8_UINT: return PixelFormat::PixelFormat_Depth24Stencil8; case VK_FORMAT_D32_SFLOAT: return PixelFormat::PixelFormat_Depth32; case VK_FORMAT_R8G8B8A8_UNORM: return PixelFormat::PixelFormat_RGBA8; + case VK_FORMAT_R8G8B8A8_SRGB: return PixelFormat::PixelFormat_RGBA8_SRGB; default: break; } diff --git a/src/Nazara/Utility/PixelFormat.cpp b/src/Nazara/Utility/PixelFormat.cpp index b169afd4f..d5ecff45e 100644 --- a/src/Nazara/Utility/PixelFormat.cpp +++ b/src/Nazara/Utility/PixelFormat.cpp @@ -157,6 +157,15 @@ namespace Nz return dst; } + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) + { + //FIXME: Not correct + std::size_t count = end - start; + std::memcpy(dst, start, count); + return dst + count; + } + template<> UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { @@ -288,6 +297,15 @@ namespace Nz return dst; } + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) + { + //FIXME: Not correct + std::size_t count = end - start; + std::memcpy(dst, start, count); + return dst + count; + } + template<> UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { @@ -1114,6 +1132,15 @@ namespace Nz return dst; } + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) + { + //FIXME: Not correct + std::size_t count = end - start; + std::memcpy(dst, start, count); + return dst + count; + } + template<> UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { @@ -1261,10 +1288,20 @@ namespace Nz return dst; } - template + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) + { + //FIXME: Not correct + std::size_t count = end - start; + std::memcpy(dst, start, count); + return dst + count; + } + + + template void RegisterConverter() { - PixelFormatInfo::SetConvertFunction(format1, format2, &ConvertPixels); + PixelFormatInfo::SetConvertFunction(Format1, Format2, &ConvertPixels); } } @@ -1386,7 +1423,9 @@ namespace Nz // Setup informations about every pixel format s_pixelFormatInfos[PixelFormat_A8] = PixelFormatDescription("A8", PixelFormatContent_ColorRGBA, 0, 0, 0, 0xFF, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormat_BGR8] = PixelFormatDescription("BGR8", PixelFormatContent_ColorRGBA, 0x0000FF, 0x00FF00, 0xFF0000, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormat_BGR8_SRGB] = PixelFormatDescription("BGR8_SRGB", PixelFormatContent_ColorRGBA, 0x0000FF, 0x00FF00, 0xFF0000, 0, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormat_BGRA8] = PixelFormatDescription("BGRA8", PixelFormatContent_ColorRGBA, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormat_BGRA8_SRGB] = PixelFormatDescription("BGRA8_SRGB", PixelFormatContent_ColorRGBA, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormat_DXT1] = PixelFormatDescription("DXT1", PixelFormatContent_ColorRGBA, 8, PixelFormatSubType_Compressed); s_pixelFormatInfos[PixelFormat_DXT3] = PixelFormatDescription("DXT3", PixelFormatContent_ColorRGBA, 16, PixelFormatSubType_Compressed); s_pixelFormatInfos[PixelFormat_DXT5] = PixelFormatDescription("DXT5", PixelFormatContent_ColorRGBA, 16, PixelFormatSubType_Compressed); @@ -1413,6 +1452,7 @@ namespace Nz s_pixelFormatInfos[PixelFormat_RG32I] = PixelFormatDescription("RG32I", PixelFormatContent_ColorRGBA, 0xFFFFFFFF00000000, 0x00000000FFFFFFFF, 0, 0, PixelFormatSubType_Int); s_pixelFormatInfos[PixelFormat_RG32UI] = PixelFormatDescription("RG32UI", PixelFormatContent_ColorRGBA, 0xFFFFFFFF00000000, 0x00000000FFFFFFFF, 0, 0, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormat_RGB8] = PixelFormatDescription("RGB8", PixelFormatContent_ColorRGBA, 0xFF000000, 0x00FF0000, 0x0000FF00, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormat_RGB8_SRGB] = PixelFormatDescription("RGB8_SRGB", PixelFormatContent_ColorRGBA, 0xFF000000, 0x00FF0000, 0x0000FF00, 0, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormat_RGB16F] = PixelFormatDescription("RGB16F", PixelFormatContent_ColorRGBA, 0xFFFF00000000, 0x0000FFFF0000, 0x00000000FFFF, 0, PixelFormatSubType_Half); s_pixelFormatInfos[PixelFormat_RGB16I] = PixelFormatDescription("RGB16I", PixelFormatContent_ColorRGBA, 0xFFFF00000000, 0x0000FFFF0000, 0x00000000FFFF, 0, PixelFormatSubType_Int); s_pixelFormatInfos[PixelFormat_RGB16UI] = PixelFormatDescription("RGB16UI", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0, PixelFormatSubType_Unsigned); @@ -1422,16 +1462,17 @@ namespace Nz s_pixelFormatInfos[PixelFormat_RGBA4] = PixelFormatDescription("RGBA4", PixelFormatContent_ColorRGBA, 0xF000, 0x0F00, 0x00F0, 0x000F, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormat_RGB5A1] = PixelFormatDescription("RGB5A1", PixelFormatContent_ColorRGBA, 0xF800, 0x07C0, 0x003E, 0x0001, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormat_RGBA8] = PixelFormatDescription("RGBA8", PixelFormatContent_ColorRGBA, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormat_RGBA8_SRGB] = PixelFormatDescription("RGBA8_SRGB", PixelFormatContent_ColorRGBA, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormat_RGBA16F] = PixelFormatDescription("RGBA16F", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x000000000000FFFF, PixelFormatSubType_Half); s_pixelFormatInfos[PixelFormat_RGBA16I] = PixelFormatDescription("RGBA16I", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x000000000000FFFF, PixelFormatSubType_Int); s_pixelFormatInfos[PixelFormat_RGBA16UI] = PixelFormatDescription("RGBA16UI", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x000000000000FFFF, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormat_RGBA32F] = PixelFormatDescription("RGBA32F", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, b32 >> 96, PixelFormatSubType_Float); s_pixelFormatInfos[PixelFormat_RGBA32I] = PixelFormatDescription("RGBA32I", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, b32 >> 96, PixelFormatSubType_Int); s_pixelFormatInfos[PixelFormat_RGBA32UI] = PixelFormatDescription("RGBA32UI", PixelFormatContent_ColorRGBA, b32, b32 >> 32, b32 >> 64, b32 >> 96, PixelFormatSubType_Unsigned); - s_pixelFormatInfos[PixelFormat_Depth16] = PixelFormatDescription("Depth16", PixelFormatContent_DepthStencil, 0xFFFF, 0, 0, 0, PixelFormatSubType_Unsigned); - s_pixelFormatInfos[PixelFormat_Depth24] = PixelFormatDescription("Depth24", PixelFormatContent_DepthStencil, 0xFFFFFF, 0, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormat_Depth16] = PixelFormatDescription("Depth16", PixelFormatContent_Depth, 0xFFFF, 0, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormat_Depth24] = PixelFormatDescription("Depth24", PixelFormatContent_Depth, 0xFFFFFF, 0, 0, 0, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormat_Depth24Stencil8] = PixelFormatDescription("Depth24Stencil8", PixelFormatContent_DepthStencil, 0xFFFFFF00, 0x000000FF, 0, 0, PixelFormatSubType_Unsigned); - s_pixelFormatInfos[PixelFormat_Depth32] = PixelFormatDescription("Depth32", PixelFormatContent_DepthStencil, 0xFFFFFFFF, 0, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormat_Depth32] = PixelFormatDescription("Depth32", PixelFormatContent_Depth, 0xFFFFFFFF, 0, 0, 0, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormat_Stencil1] = PixelFormatDescription("Stencil1", PixelFormatContent_Stencil, 0x1, 0, 0, 0, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormat_Stencil4] = PixelFormatDescription("Stencil4", PixelFormatContent_Stencil, 0xF, 0, 0, 0, PixelFormatSubType_Unsigned); s_pixelFormatInfos[PixelFormat_Stencil8] = PixelFormatDescription("Stencil8", PixelFormatContent_Stencil, 0xFF, 0, 0, 0, PixelFormatSubType_Unsigned); @@ -1454,6 +1495,7 @@ namespace Nz RegisterConverter(); /**********************************BGR8***********************************/ + RegisterConverter(); RegisterConverter(); RegisterConverter(); RegisterConverter();/* @@ -1473,6 +1515,7 @@ namespace Nz /**********************************BGRA8**********************************/ RegisterConverter(); RegisterConverter(); + RegisterConverter(); RegisterConverter(); RegisterConverter();/* RegisterConverter(); @@ -1642,6 +1685,7 @@ namespace Nz RegisterConverter(); RegisterConverter();*/ RegisterConverter(); + RegisterConverter(); RegisterConverter(); RegisterConverter(); @@ -1662,6 +1706,7 @@ namespace Nz RegisterConverter(); RegisterConverter(); RegisterConverter(); + RegisterConverter(); return true; } diff --git a/src/Nazara/VulkanRenderer/VulkanTexture.cpp b/src/Nazara/VulkanRenderer/VulkanTexture.cpp index 5574bb755..377370946 100644 --- a/src/Nazara/VulkanRenderer/VulkanTexture.cpp +++ b/src/Nazara/VulkanRenderer/VulkanTexture.cpp @@ -231,13 +231,19 @@ namespace Nz switch (pixelFormat) { case PixelFormat_BGR8: + case PixelFormat_BGR8_SRGB: + case PixelFormat_BGRA8: + case PixelFormat_BGRA8_SRGB: + case PixelFormat_RGB8: + case PixelFormat_RGB8_SRGB: + case PixelFormat_RGBA8: + case PixelFormat_RGBA8_SRGB: { - createImage.format = VK_FORMAT_B8G8R8_SRGB; + createImage.format = ToVulkan(pixelFormat); createImageView.format = createImage.format; break; } - case PixelFormat_BGRA8: { createImage.format = VK_FORMAT_B8G8R8A8_SRGB; createImageView.format = createImage.format; @@ -246,7 +252,7 @@ namespace Nz case PixelFormat_L8: { - createImage.format = VK_FORMAT_R8_SRGB; + createImage.format = VK_FORMAT_R8_UNORM; createImageView.format = createImage.format; createImageView.components = { VK_COMPONENT_SWIZZLE_R, @@ -259,7 +265,7 @@ namespace Nz case PixelFormat_LA8: { - createImage.format = VK_FORMAT_R8G8_SRGB; + createImage.format = VK_FORMAT_R8G8_UNORM; createImageView.format = createImage.format; createImageView.components = { VK_COMPONENT_SWIZZLE_R, @@ -270,20 +276,6 @@ namespace Nz break; } - case PixelFormat_RGB8: - { - createImage.format = VK_FORMAT_R8G8B8_SRGB; - createImageView.format = createImage.format; - break; - } - - case PixelFormat_RGBA8: - { - createImage.format = VK_FORMAT_R8G8B8A8_SRGB; - createImageView.format = createImage.format; - break; - } - default: throw std::runtime_error("Unsupported pixel format " + PixelFormatInfo::GetName(pixelFormat)); }