340 lines
9.2 KiB
C++
Raw Normal View History

2020-07-31 11:31:32 +08:00
//===============================================================================
// Copyright (c) 2007-2016 Advanced Micro Devices, Inc. All rights reserved.
// Copyright (c) 2004-2006 ATI Technologies Inc.
//===============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//
// File Name: Codec.cpp
// Description: Implementation of the CCodec class
//
//////////////////////////////////////////////////////////////////////////////
#include "Common.h"
#include "Codec.h"
#include "Codec_ATI1N.h"
#include "Codec_ATI2N.h"
#include "Codec_ATI2N_DXT5.h"
#include "Codec_DXT1.h"
#include "Codec_DXT3.h"
#include "Codec_DXT5.h"
#include "Codec_DXT5_xGBR.h"
#include "Codec_DXT5_RxBG.h"
#include "Codec_DXT5_RBxG.h"
#include "Codec_DXT5_xRBG.h"
#include "Codec_DXT5_RGxB.h"
#include "Codec_DXT5_xGxR.h"
#include "Codec_ATC_RGB.h"
#include "Codec_ATC_RGBA_Explicit.h"
#include "Codec_ATC_RGBA_Interpolated.h"
#include "Codec_ETC_RGB.h"
#include "Codec_ETC2_RGB.h"
#include "Codec_ETC2_RGBA.h"
#include "Codec_ETC2_RGBA1.h"
#include "Codec_BC6H.h"
#include "Codec_BC7.h"
#include "ASTC/Codec_ASTC.h"
#ifdef _WIN32 //GT only enabled for win build now
#include "Codec_GT.h"
#ifdef USE_BASIS
#include "Codec_BASIS.h"
#endif
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CCodec::CCodec(CodecType codecType)
{
m_CodecType = codecType;
}
CCodec::~CCodec()
{
}
bool CCodec::SetParameter(const CMP_CHAR* /*pszParamName*/, CMP_CHAR* /*dwValue*/)
{
return false;
}
bool CCodec::SetParameter(const CMP_CHAR* /*pszParamName*/, CMP_DWORD /*dwValue*/)
{
return false;
}
bool CCodec::GetParameter(const CMP_CHAR* /*pszParamName*/, CMP_DWORD& /*dwValue*/)
{
return false;
}
bool CCodec::SetParameter(const CMP_CHAR* /*pszParamName*/, CODECFLOAT /*fValue*/)
{
return false;
}
bool CCodec::GetParameter(const CMP_CHAR* /*pszParamName*/, CODECFLOAT& /*fValue*/)
{
return false;
}
#ifdef _WIN32
#include <intrin.h>
// Windows
#define cpuid(info, x) __cpuidex(info, x, 0)
#else
// GCC Intrinsics
#include <cpuid.h>
void cpuid(int info[4], int InfoType)
{
__cpuid_count(InfoType, 0, info[0], info[1], info[2], info[3]);
}
#endif
bool SupportsSSE()
{
#if defined(USE_SSE)
int info[4];
cpuid(info, 0);
int nIds = info[0];
if (nIds >= 1)
{
return ((info[3] & ((int)1 << 25)) != 0);
}
#endif
return false;
}
bool SupportsSSE2()
{
#if defined(USE_SSE2) && defined(_WIN32)
int info[4];
cpuid(info, 0);
int nIds = info[0];
if (nIds >= 1)
{
return ((info[3] & ((int)1 << 26)) != 0);
}
#endif
return false;
}
CCodec* CreateCodec(CodecType nCodecType)
{
#ifdef USE_DBGTRACE
DbgTrace(("nCodecType %d", nCodecType));
#endif
switch (nCodecType)
{
case CT_DXT1:
return new CCodec_DXT1;
case CT_DXT3:
return new CCodec_DXT3;
case CT_DXT5:
return new CCodec_DXT5;
case CT_DXT5_xGBR:
return new CCodec_DXT5_xGBR;
case CT_DXT5_RxBG:
return new CCodec_DXT5_RxBG;
case CT_DXT5_RBxG:
return new CCodec_DXT5_RBxG;
case CT_DXT5_xRBG:
return new CCodec_DXT5_xRBG;
case CT_DXT5_RGxB:
return new CCodec_DXT5_RGxB;
case CT_DXT5_xGxR:
return new CCodec_DXT5_xGxR;
case CT_ATI1N:
return new CCodec_ATI1N;
case CT_ATI2N:
return new CCodec_ATI2N;
case CT_ATI2N_XY:
return new CCodec_ATI2N(CT_ATI2N_XY);
case CT_ATI2N_DXT5:
return new CCodec_ATI2N_DXT5;
case CT_ATC_RGB:
return new CCodec_ATC_RGB;
case CT_ATC_RGBA_Explicit:
return new CCodec_ATC_RGBA_Explicit;
case CT_ATC_RGBA_Interpolated:
return new CCodec_ATC_RGBA_Interpolated;
case CT_ETC_RGB:
return new CCodec_ETC_RGB;
case CT_ETC2_RGB:
case CT_ETC2_SRGB:
return new CCodec_ETC2_RGB(nCodecType);
case CT_ETC2_RGBA:
case CT_ETC2_SRGBA:
return new CCodec_ETC2_RGBA(nCodecType);
case CT_ETC2_RGBA1:
case CT_ETC2_SRGBA1:
return new CCodec_ETC2_RGBA1(nCodecType);
case CT_BC6H:
case CT_BC6H_SF:
return new CCodec_BC6H(nCodecType);
case CT_BC7:
return new CCodec_BC7;
case CT_ASTC:
return new CCodec_ASTC;
#ifdef _WIN32
case CT_GTC:
return new CCodec_GTC;
#ifdef USE_BASIS
case CT_BASIS:
return new CCodec_BASIS;
#endif
#endif
case CT_Unknown:
default:
assert(0);
return NULL;
}
}
CMP_DWORD CalcBufferSize(CodecType nCodecType, CMP_DWORD dwWidth, CMP_DWORD dwHeight, CMP_BYTE nBlockWidth, CMP_BYTE nBlockHeight)
{
#ifdef USE_DBGTRACE
DbgTrace(("IN: nCodecType %d, dwWidth %d, dwHeight %d", nCodecType, dwWidth, dwHeight));
#endif
CMP_DWORD dwChannels;
CMP_DWORD dwBitsPerChannel;
CMP_DWORD buffsize = 0;
switch (nCodecType)
{
// Block size is 4x4 and 64 bits per block
case CT_DXT1:
case CT_ATI1N:
case CT_ATC_RGB:
case CT_ETC_RGB:
case CT_ETC2_RGB:
case CT_ETC2_SRGB:
case CT_ETC2_RGBA1:
case CT_ETC2_SRGBA1:
dwChannels = 1;
dwBitsPerChannel = 4;
dwWidth = ((dwWidth + 3) / 4) * 4;
dwHeight = ((dwHeight + 3) / 4) * 4;
buffsize = (dwWidth * dwHeight * dwChannels * dwBitsPerChannel) / 8;
break;
// Block size is 4x4 and 128 bits per block
case CT_ETC2_RGBA:
case CT_ETC2_SRGBA:
// dwChannels = 2;
// dwBitsPerChannel = 4;
// dwWidth = ((dwWidth + 3) / 4) * 4;
// dwHeight = ((dwHeight + 3) / 4) * 4;
// buffsize = (dwWidth * dwHeight * dwChannels * dwBitsPerChannel) / 8;
dwWidth = ((dwWidth + 3) / 4) * 4;
dwHeight = ((dwHeight + 3) / 4) * 4;
buffsize = dwWidth * dwHeight;
if (buffsize < BC_BLOCK_PIXELS)
buffsize = BC_BLOCK_PIXELS;
break;
// Block size is 4x4 and 128 bits per block
case CT_DXT3:
case CT_DXT5:
case CT_DXT5_xGBR:
case CT_DXT5_RxBG:
case CT_DXT5_RBxG:
case CT_DXT5_xRBG:
case CT_DXT5_RGxB:
case CT_DXT5_xGxR:
case CT_ATI2N:
case CT_ATI2N_XY:
case CT_ATI2N_DXT5:
case CT_ATC_RGBA_Explicit:
case CT_ATC_RGBA_Interpolated:
dwChannels = 2;
dwBitsPerChannel = 4;
dwWidth = ((dwWidth + 3) / 4) * 4;
dwHeight = ((dwHeight + 3) / 4) * 4;
buffsize = (dwWidth * dwHeight * dwChannels * dwBitsPerChannel) / 8;
break;
// Block size is 4x4 and 128 bits per block
case CT_BC6H:
case CT_BC6H_SF:
dwWidth = ((dwWidth + 3) / 4) * 4;
dwHeight = ((dwHeight + 3) / 4) * 4;
buffsize = dwWidth * dwHeight;
if (buffsize < BC6H_BLOCK_PIXELS)
buffsize = BC6H_BLOCK_PIXELS;
break;
// Block size is 4x4 and 128 bits per block
case CT_BC7:
dwWidth = ((dwWidth + 3) / 4) * 4;
dwHeight = ((dwHeight + 3) / 4) * 4;
buffsize = dwWidth * dwHeight;
if (buffsize < BC7_BLOCK_PIXELS)
buffsize = BC7_BLOCK_PIXELS;
break;
// Block size ranges from 4x4 to 12x12 and 128 bits per block
case CT_ASTC:
dwWidth = ((dwWidth + nBlockWidth - 1) / nBlockWidth) * 4;
dwHeight = ((dwHeight + nBlockHeight - 1) / nBlockHeight) * 4;
buffsize = dwWidth * dwHeight;
break;
#ifdef _WIN32
// Block size is 4x4 and 128 bits per block. in future releases its will vary in Block Sizes and bits per block may change to 256
case CT_GTC:
dwWidth = ((dwWidth + 3) / 4) * 4;
dwHeight = ((dwHeight + 3) / 4) * 4;
buffsize = dwWidth * dwHeight;
if (buffsize < (4 * 4))
buffsize = 4 * 4;
break;
#ifdef USE_BASIS
// Block size is 4x4 and 128 bits per block, needs conformation!!
case CT_BASIS:
dwWidth = ((dwWidth + 3) / 4) * 4;
dwHeight = ((dwHeight + 3) / 4) * 4;
buffsize = dwWidth * dwHeight;
if (buffsize < (4 * 4))
buffsize = 4 * 4;
break;
#endif
#endif
default:
return 0;
}
#ifdef USE_DBGTRACE
DbgTrace(("OUT: %d", buffsize));
#endif
return buffsize;
}