From 88fa8a44be8ba079f175d4e696cf337d57985ff8 Mon Sep 17 00:00:00 2001 From: Ivan Avdeev Date: Thu, 21 Dec 2023 15:49:37 -0500 Subject: [PATCH] Add BC7_SRGB format support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tracked alongside regular BC7 for the most part, with simple conversion from/to external BC7 UNORM/SRGB format enums. No actual SRGB↔linear colorspace conversion is introduced. Fixes #277 --- applications/_plugins/cimage/dds/dds_dx10.cpp | 9 ++++++++- applications/_plugins/cimage/ktx/ktx1.cpp | 1 + applications/_plugins/cimage/ktx2/ktx2.cpp | 7 +++++++ applications/_plugins/common/atiformats.cpp | 7 +++++++ applications/_plugins/common/cmdline.cpp | 8 +++++--- applications/_plugins/common/texture.h | 1 + applications/_plugins/common/textureio.cpp | 1 + cmp_compressonatorlib/bc7/codec_bc7.cpp | 2 +- cmp_compressonatorlib/bc7/codec_bc7.h | 2 +- cmp_compressonatorlib/common.h | 1 + cmp_compressonatorlib/common/codec.cpp | 4 +++- cmp_compressonatorlib/compress.cpp | 4 ++++ cmp_compressonatorlib/compressonator.cpp | 1 + cmp_compressonatorlib/compressonator.h | 1 + cmp_framework/compute_base.cpp | 3 +++ 15 files changed, 45 insertions(+), 7 deletions(-) diff --git a/applications/_plugins/cimage/dds/dds_dx10.cpp b/applications/_plugins/cimage/dds/dds_dx10.cpp index 2fbc1451a..a83447753 100644 --- a/applications/_plugins/cimage/dds/dds_dx10.cpp +++ b/applications/_plugins/cimage/dds/dds_dx10.cpp @@ -234,10 +234,14 @@ TC_PluginError LoadDDS_DX10(FILE* pFile, DDSD2* pDDSD, MipSet* pMipSet) { case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: pMipSet->m_compressed = true; pMipSet->m_format = CMP_FORMAT_BC7; err = LoadDDS_DX10_FourCC(pFile, pDDSD, pMipSet, CMP_FOURCC_DX10); + + case DXGI_FORMAT_BC7_UNORM_SRGB: + pMipSet->m_compressed = true; + pMipSet->m_format = CMP_FORMAT_BC7_SRGB; + err = LoadDDS_DX10_FourCC(pFile, pDDSD, pMipSet, CMP_FOURCC_DX10); break; // case DXGI_FORMAT_???: @@ -371,6 +375,8 @@ DXGI_FORMAT GetDXGIFormat(const MipSet* pMipSet) { return DXGI_FORMAT_BC5_UNORM; case CMP_FORMAT_BC7: return DXGI_FORMAT_BC7_UNORM; + case CMP_FORMAT_BC7_SRGB: + return DXGI_FORMAT_BC7_UNORM_SRGB; // case CMP_FORMAT_ASTC: return DXGI_FORMAT_????; Not yet supported as of Jun 24 2015 } } else @@ -444,6 +450,7 @@ TC_PluginError SaveDDS_DX10(FILE* pFile, const MipSet* pMipSet) { ddsd2.lPitch = ddsd2.dwWidth * 4; break; case CMP_FORMAT_BC7: + case CMP_FORMAT_BC7_SRGB: default: ddsd2.lPitch = ddsd2.dwWidth * 4; break; diff --git a/applications/_plugins/cimage/ktx/ktx1.cpp b/applications/_plugins/cimage/ktx/ktx1.cpp index f198a8715..0f3465c46 100644 --- a/applications/_plugins/cimage/ktx/ktx1.cpp +++ b/applications/_plugins/cimage/ktx/ktx1.cpp @@ -1068,6 +1068,7 @@ int Plugin_KTX::TC_PluginFileSaveTexture(const char* pszFilename, MipSet* pMipSe case CMP_FORMAT_BC6H: case CMP_FORMAT_BC6H_SF: case CMP_FORMAT_BC7 : + case CMP_FORMAT_BC7_SRGB : case CMP_FORMAT_DXT1 : case CMP_FORMAT_DXT3 : case CMP_FORMAT_DXT5 : diff --git a/applications/_plugins/cimage/ktx2/ktx2.cpp b/applications/_plugins/cimage/ktx2/ktx2.cpp index dfeeee443..0bc90dbb6 100644 --- a/applications/_plugins/cimage/ktx2/ktx2.cpp +++ b/applications/_plugins/cimage/ktx2/ktx2.cpp @@ -218,6 +218,9 @@ int Plugin_KTX2::TC_PluginFileLoadTexture(const char* pszFilename, MipSet* pMipS case VK_FORMAT_BC7_UNORM_BLOCK: pMipSet->m_format = CMP_FORMAT_BC7; break; + case VK_FORMAT_BC7_SRGB_BLOCK: + pMipSet->m_format = CMP_FORMAT_BC7_SRGB; + break; case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: pMipSet->m_format = CMP_FORMAT_ETC2_RGB; // Skip ETC as ETC2 is backward comp break; @@ -857,6 +860,10 @@ int Plugin_KTX2::TC_PluginFileSaveTexture(const char* pszFilename, MipSet* pMipS // RGB_BP_UNorm; textureCreateInfo.vkFormat = VK_FORMAT_BC7_UNORM_BLOCK; break; + case CMP_FORMAT_BC7_SRGB: + // RGB_BP_UNorm; + textureCreateInfo.vkFormat = VK_FORMAT_BC7_SRGB_BLOCK; + break; //case CMP_FORMAT_ATI1N: // // COMPRESSED_FORMAT_ATI1N_UNorm_TMP; // textureCreateInfo.vkFormat = VK_FORMAT_BC4_UNORM_BLOCK; diff --git a/applications/_plugins/common/atiformats.cpp b/applications/_plugins/common/atiformats.cpp index 66f0b897b..0d8efb544 100644 --- a/applications/_plugins/common/atiformats.cpp +++ b/applications/_plugins/common/atiformats.cpp @@ -103,6 +103,7 @@ CMP_FormatDesc g_FormatDesc[] = { {CMP_FORMAT_BC6H, "BC6H"}, {CMP_FORMAT_BC6H_SF, "BC6H_SF" }, {CMP_FORMAT_BC7, "BC7"}, + {CMP_FORMAT_BC7_SRGB, "BC7_SRGB"}, {CMP_FORMAT_DXT1, "DXT1"}, @@ -323,6 +324,9 @@ void CMP_API CMP_Format2FourCC(CMP_FORMAT format, MipSet *pMipSet) { case CMP_FORMAT_BC7: pMipSet->m_dwFourCC = CMP_FOURCC_DX10; break; + case CMP_FORMAT_BC7_SRGB: + pMipSet->m_dwFourCC = CMP_FOURCC_DX10; + break; #if (OPTION_BUILD_ASTC == 1) case CMP_FORMAT_ASTC: pMipSet->m_dwFourCC = CMP_FOURCC_DX10; @@ -470,6 +474,7 @@ CMP_BOOL CMP_API CMP_IsCompressedFormat(CMP_FORMAT format) { case CMP_FORMAT_BC6H: case CMP_FORMAT_BC6H_SF: case CMP_FORMAT_BC7: + case CMP_FORMAT_BC7_SRGB: case CMP_FORMAT_DXT1: case CMP_FORMAT_DXT3: case CMP_FORMAT_DXT5: @@ -609,6 +614,7 @@ CMP_BOOL CMP_API CMP_IsValidFormat(CMP_FORMAT InFormat) case CMP_FORMAT_BC6H : case CMP_FORMAT_BC6H_SF : case CMP_FORMAT_BC7 : + case CMP_FORMAT_BC7_SRGB : case CMP_FORMAT_ATI1N : case CMP_FORMAT_ATI2N : case CMP_FORMAT_ATI2N_XY : @@ -765,6 +771,7 @@ static CMP_FORMAT GetFormat(CMP_DWORD dwFourCC) { case CMP_FOURCC_BC5S: return CMP_FORMAT_BC5_S; case CMP_FOURCC_BC6H: return CMP_FORMAT_BC6H; case CMP_FOURCC_BC7: return CMP_FORMAT_BC7; + case CMP_FOURCC_BC7_SRGB: return CMP_FORMAT_BC7_SRGB; #if (OPTION_BUILD_ASTC == 1) case CMP_FOURCC_ASTC: return CMP_FORMAT_ASTC; #endif diff --git a/applications/_plugins/common/cmdline.cpp b/applications/_plugins/common/cmdline.cpp index 963237502..0a8a456c8 100644 --- a/applications/_plugins/common/cmdline.cpp +++ b/applications/_plugins/common/cmdline.cpp @@ -2076,6 +2076,7 @@ bool SVMInitCodec(KernelOptions* options) case CMP_FORMAT_BC1: case CMP_FORMAT_DXT1: case CMP_FORMAT_BC7: + case CMP_FORMAT_BC7_SRGB: #if (OPTION_BUILD_ASTC == 1) case CMP_FORMAT_ASTC: #endif @@ -3089,7 +3090,7 @@ int ProcessCMDLine(CMP_Feedback_Proc pFeedbackProc, MipSet* p_userMipSetIn) if ((g_CmdPrams.CompressOptions.fquality > 0.00f) && (g_CmdPrams.CompressOptions.fquality < 0.01f)) { // set default max quality for fast processing codecs - if ((destFormat != CMP_FORMAT_BC7) && (destFormat != CMP_FORMAT_BC6H) && (destFormat != CMP_FORMAT_BC6H_SF)) + if ((destFormat != CMP_FORMAT_BC7_SRGB) && (destFormat != CMP_FORMAT_BC7) && (destFormat != CMP_FORMAT_BC6H) && (destFormat != CMP_FORMAT_BC6H_SF)) { g_CmdPrams.CompressOptions.fquality = 1.0f; } @@ -3282,12 +3283,13 @@ int ProcessCMDLine(CMP_Feedback_Proc pFeedbackProc, MipSet* p_userMipSetIn) g_MipSetIn.m_format == CMP_FORMAT_BC3 || g_MipSetIn.m_format == CMP_FORMAT_BC4 || g_MipSetIn.m_format == CMP_FORMAT_BC4_S || g_MipSetIn.m_format == CMP_FORMAT_BC5 || g_MipSetIn.m_format == CMP_FORMAT_BC5_S || g_MipSetIn.m_format == CMP_FORMAT_BC6H || - g_MipSetIn.m_format == CMP_FORMAT_BC6H_SF || g_MipSetIn.m_format == CMP_FORMAT_BC7; + g_MipSetIn.m_format == CMP_FORMAT_BC6H_SF || g_MipSetIn.m_format == CMP_FORMAT_BC7 || + g_MipSetIn.m_format == CMP_FORMAT_BC7_SRGB; bool DestFormatIsBCN = destFormat == CMP_FORMAT_BC1 || destFormat == CMP_FORMAT_BC2 || destFormat == CMP_FORMAT_BC3 || destFormat == CMP_FORMAT_BC4 || destFormat == CMP_FORMAT_BC4_S || destFormat == CMP_FORMAT_BC5 || destFormat == CMP_FORMAT_BC5_S || destFormat == CMP_FORMAT_BC6H || destFormat == CMP_FORMAT_BC6H_SF || - destFormat == CMP_FORMAT_BC7; + destFormat == CMP_FORMAT_BC7 || destFormat == CMP_FORMAT_BC7_SRGB; if (SourceFormatIsBCN && DestFormatIsBCN && (g_MipSetIn.m_format != destFormat)) { diff --git a/applications/_plugins/common/texture.h b/applications/_plugins/common/texture.h index 60e196bef..1a687523a 100644 --- a/applications/_plugins/common/texture.h +++ b/applications/_plugins/common/texture.h @@ -107,6 +107,7 @@ extern "C" { #define CMP_FOURCC_BC6H CMP_MAKEFOURCC('B', 'C', '6', 'H') #define CMP_FOURCC_BC7 CMP_MAKEFOURCC('B', 'C', '7', 'x') +#define CMP_FOURCC_BC7_SRGB CMP_MAKEFOURCC('B', 'C', '7', 's') #if (OPTION_BUILD_ASTC == 1) #define CMP_FOURCC_ASTC CMP_MAKEFOURCC('A', 'S', 'T', 'C') #endif diff --git a/applications/_plugins/common/textureio.cpp b/applications/_plugins/common/textureio.cpp index c39b1e2c2..ac37b5aaa 100644 --- a/applications/_plugins/common/textureio.cpp +++ b/applications/_plugins/common/textureio.cpp @@ -721,6 +721,7 @@ int AMDSaveMIPSTextureImage(const char *DestFile, MipSet *MipSetIn, bool use_OCV case CMP_FORMAT_ASTC: #endif case CMP_FORMAT_BC7: + case CMP_FORMAT_BC7_SRGB: case CMP_FORMAT_BC6H: case CMP_FORMAT_BC6H_SF: case CMP_FORMAT_ETC_RGB: diff --git a/cmp_compressonatorlib/bc7/codec_bc7.cpp b/cmp_compressonatorlib/bc7/codec_bc7.cpp index c1cb13d2c..3d70e550e 100644 --- a/cmp_compressonatorlib/bc7/codec_bc7.cpp +++ b/cmp_compressonatorlib/bc7/codec_bc7.cpp @@ -81,7 +81,7 @@ unsigned int BC7ThreadProcEncode(void* param) { // Construction/Destruction ////////////////////////////////////////////////////////////////////////////// -CCodec_BC7::CCodec_BC7() : CCodec_DXTC(CT_BC7) { +CCodec_BC7::CCodec_BC7(CodecType codecType) : CCodec_DXTC(codecType) { m_LibraryInitialized = false; m_Use_MultiThreading = true; diff --git a/cmp_compressonatorlib/bc7/codec_bc7.h b/cmp_compressonatorlib/bc7/codec_bc7.h index f7c379357..e30e8f357 100644 --- a/cmp_compressonatorlib/bc7/codec_bc7.h +++ b/cmp_compressonatorlib/bc7/codec_bc7.h @@ -54,7 +54,7 @@ struct BC7EncodeThreadParam { class CCodec_BC7 : public CCodec_DXTC { public: - CCodec_BC7(); + CCodec_BC7(CodecType codecType); ~CCodec_BC7(); virtual bool SetParameter(const CMP_CHAR* pszParamName, CMP_CHAR* sValue); diff --git a/cmp_compressonatorlib/common.h b/cmp_compressonatorlib/common.h index 4f7d054e1..e09c7765f 100644 --- a/cmp_compressonatorlib/common.h +++ b/cmp_compressonatorlib/common.h @@ -252,6 +252,7 @@ typedef enum _CodecType CT_BC6H, CT_BC6H_SF, CT_BC7, + CT_BC7_SRGB, #if (OPTION_BUILD_ASTC == 1) CT_ASTC, #endif diff --git a/cmp_compressonatorlib/common/codec.cpp b/cmp_compressonatorlib/common/codec.cpp index 9a7440951..c149a9988 100644 --- a/cmp_compressonatorlib/common/codec.cpp +++ b/cmp_compressonatorlib/common/codec.cpp @@ -211,7 +211,8 @@ CCodec* CreateCodec(CodecType nCodecType) { case CT_BC6H_SF: return new CCodec_BC6H(nCodecType); case CT_BC7: - return new CCodec_BC7; + case CT_BC7_SRGB: + return new CCodec_BC7(nCodecType); #if (OPTION_BUILD_ASTC == 1) case CT_ASTC: return new CCodec_ASTC; @@ -320,6 +321,7 @@ CMP_DWORD CalcBufferSize(CodecType nCodecType, CMP_DWORD dwWidth, CMP_DWORD dwHe // Block size is 4x4 and 128 bits per block case CT_BC7: + case CT_BC7_SRGB: dwWidth = ((dwWidth + 3) / 4) * 4; dwHeight = ((dwHeight + 3) / 4) * 4; buffsize = dwWidth * dwHeight; diff --git a/cmp_compressonatorlib/compress.cpp b/cmp_compressonatorlib/compress.cpp index f7a6cd41b..eae4266fb 100644 --- a/cmp_compressonatorlib/compress.cpp +++ b/cmp_compressonatorlib/compress.cpp @@ -151,6 +151,8 @@ CodecType GetCodecType(CMP_FORMAT format) { return CT_BC6H_SF; case CMP_FORMAT_BC7: return CT_BC7; + case CMP_FORMAT_BC7_SRGB: + return CT_BC7_SRGB; #if (OPTION_BUILD_ASTC == 1) case CMP_FORMAT_ASTC: return CT_ASTC; @@ -326,6 +328,7 @@ CMP_ERROR CompressTexture(const CMP_Texture* pSourceTexture, CMP_Texture* pDestT switch(destType) { case CT_BC7: + case CT_BC7_SRGB: pCodec->SetParameter("MultiThreading", (CMP_DWORD) !pOptions->bDisableMultiThreading); if (!pOptions->bDisableMultiThreading) @@ -477,6 +480,7 @@ void ThreadedCompressProc(void *lpParameter) { CMP_ERROR ThreadedCompressTexture(const CMP_Texture* pSourceTexture, CMP_Texture* pDestTexture, const CMP_CompressOptions* pOptions, CMP_Feedback_Proc pFeedbackProc, CodecType destType) { // Note function should not be called for the following Codecs.... if (destType == CT_BC7) return CMP_ABORTED; + if (destType == CT_BC7_SRGB) return CMP_ABORTED; #ifdef USE_APC if (destType == CT_APC) return CMP_ABORTED; diff --git a/cmp_compressonatorlib/compressonator.cpp b/cmp_compressonatorlib/compressonator.cpp index b976f986b..af1296aa5 100644 --- a/cmp_compressonatorlib/compressonator.cpp +++ b/cmp_compressonatorlib/compressonator.cpp @@ -589,6 +589,7 @@ CMP_ERROR CMP_API CMP_ConvertTexture(CMP_Texture* pSourceTexture, (destType != CT_ASTC) && #endif (destType != CT_BC7) && + (destType != CT_BC7_SRGB) && (destType != CT_BC6H) && (destType != CT_BC6H_SF) #ifdef USE_APC && (destType != CT_APC) diff --git a/cmp_compressonatorlib/compressonator.h b/cmp_compressonatorlib/compressonator.h index c68d7e954..f2035f289 100644 --- a/cmp_compressonatorlib/compressonator.h +++ b/cmp_compressonatorlib/compressonator.h @@ -152,6 +152,7 @@ typedef enum { CMP_FORMAT_BC6H = 0x0061, // DXGI_FORMAT_BC6H_UF16 VK_FORMAT_BC6H_UFLOAT_BLOCK GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT BC6H compressed texture format (UF) CMP_FORMAT_BC6H_SF = 0x1061, // DXGI_FORMAT_BC6H_SF16 VK_FORMAT_BC6H_SFLOAT_BLOCK GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT BC6H compressed texture format (SF) CMP_FORMAT_BC7 = 0x0071, // DXGI_FORMAT_BC7_UNORM VK_FORMAT_BC7_UNORM_BLOCK GL_COMPRESSED_RGBA_BPTC_UNORM BC7 compressed texture format + CMP_FORMAT_BC7_SRGB = 0x0072, // DXGI_FORMAT_BC7_UNORM_SRGB VK_FORMAT_BC7_SRGB_BLOCK GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM BC7 compressed texture format CMP_FORMAT_ATI1N = 0x0141, // DXGI_FORMAT_BC4_UNORM VK_FORMAT_BC4_UNORM_BLOCK GL_COMPRESSED_RED_RGTC1 Single component compression format using the same technique as DXT5 alpha. Four bits per pixel. CMP_FORMAT_ATI2N = 0x0151, // DXGI_FORMAT_BC5_UNORM VK_FORMAT_BC5_UNORM_BLOCK GL_COMPRESSED_RG_RGTC2 Two component compression format using the same technique as DXT5 alpha. Designed for compression of tangent space normal maps. Eight bits per pixel. diff --git a/cmp_framework/compute_base.cpp b/cmp_framework/compute_base.cpp index 65c241118..03671644f 100644 --- a/cmp_framework/compute_base.cpp +++ b/cmp_framework/compute_base.cpp @@ -445,6 +445,8 @@ CodecType GetCodecType2(CMP_FORMAT format) { return CT_BC6H_SF; case CMP_FORMAT_BC7: return CT_BC7; + case CMP_FORMAT_BC7_SRGB: + return CT_BC7_SRGB; #if (OPTION_BUILD_ASTC == 1) case CMP_FORMAT_ASTC: return CT_ASTC; @@ -567,6 +569,7 @@ CMP_DWORD CalcBufferSizeCT(CodecType nCodecType, CMP_DWORD dwWidth, CMP_DWORD dw // Block size is 4x4 and 128 bits per block case CT_BC7: + case CT_BC7_SRGB: dwWidth = ((dwWidth + 3) / 4) * 4; dwHeight = ((dwHeight + 3) / 4) * 4; buffsize = dwWidth * dwHeight;