340 lines
9.2 KiB
C++
340 lines
9.2 KiB
C++
|
//===============================================================================
|
||
|
// 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;
|
||
|
}
|