mirror of https://github.com/axmolengine/axmol.git
add compressed format for metal (#19762)
This commit is contained in:
parent
10b2799051
commit
89ba801628
|
@ -1634,7 +1634,7 @@ bool Image::initWithETCData(const unsigned char * data, ssize_t dataLen)
|
||||||
if (Configuration::getInstance()->supportsETC())
|
if (Configuration::getInstance()->supportsETC())
|
||||||
{
|
{
|
||||||
//old opengl version has no define for GL_ETC1_RGB8_OES, add macro to make compiler happy.
|
//old opengl version has no define for GL_ETC1_RGB8_OES, add macro to make compiler happy.
|
||||||
#ifdef GL_ETC1_RGB8_OES
|
#if defined(GL_ETC1_RGB8_OES) || defined(CC_USE_METAL)
|
||||||
_pixelFormat = backend::PixelFormat::ETC;
|
_pixelFormat = backend::PixelFormat::ETC;
|
||||||
_dataLen = dataLen - ETC_PKM_HEADER_SIZE;
|
_dataLen = dataLen - ETC_PKM_HEADER_SIZE;
|
||||||
_data = static_cast<unsigned char*>(malloc(_dataLen * sizeof(unsigned char)));
|
_data = static_cast<unsigned char*>(malloc(_dataLen * sizeof(unsigned char)));
|
||||||
|
|
|
@ -61,70 +61,55 @@ namespace {
|
||||||
typedef Texture2D::PixelFormatInfoMap::value_type PixelFormatInfoMapValue;
|
typedef Texture2D::PixelFormatInfoMap::value_type PixelFormatInfoMapValue;
|
||||||
static const PixelFormatInfoMapValue TexturePixelFormatInfoTablesValue[] =
|
static const PixelFormatInfoMapValue TexturePixelFormatInfoTablesValue[] =
|
||||||
{
|
{
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::BGRA8888, Texture2D::PixelFormatInfo(GL_BGRA, GL_BGRA, GL_UNSIGNED_BYTE, 32, false, true)),
|
PixelFormatInfoMapValue(backend::PixelFormat::BGRA8888, Texture2D::PixelFormatInfo(32, false, true)),
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::RGBA8888, Texture2D::PixelFormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 32, false, true)),
|
PixelFormatInfoMapValue(backend::PixelFormat::RGBA8888, Texture2D::PixelFormatInfo(32, false, true)),
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::RGBA4444, Texture2D::PixelFormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 16, false, true)),
|
PixelFormatInfoMapValue(backend::PixelFormat::RGBA4444, Texture2D::PixelFormatInfo(16, false, true)),
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::RGB5A1, Texture2D::PixelFormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 16, false, true)),
|
PixelFormatInfoMapValue(backend::PixelFormat::RGB5A1, Texture2D::PixelFormatInfo(16, false, true)),
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::RGB565, Texture2D::PixelFormatInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 16, false, false)),
|
PixelFormatInfoMapValue(backend::PixelFormat::RGB565, Texture2D::PixelFormatInfo(16, false, false)),
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::RGB888, Texture2D::PixelFormatInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, 24, false, false)),
|
PixelFormatInfoMapValue(backend::PixelFormat::RGB888, Texture2D::PixelFormatInfo(24, false, false)),
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::A8, Texture2D::PixelFormatInfo(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, 8, false, false)),
|
PixelFormatInfoMapValue(backend::PixelFormat::A8, Texture2D::PixelFormatInfo(8, false, false)),
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::I8, Texture2D::PixelFormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, 8, false, false)),
|
PixelFormatInfoMapValue(backend::PixelFormat::I8, Texture2D::PixelFormatInfo(8, false, false)),
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::AI88, Texture2D::PixelFormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 16, false, true)),
|
PixelFormatInfoMapValue(backend::PixelFormat::AI88, Texture2D::PixelFormatInfo(16, false, true)),
|
||||||
#ifndef CC_USE_METAL
|
|
||||||
//OpenGL only
|
#if defined( GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG) || (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||||
#ifdef GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG
|
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC2, Texture2D::PixelFormatInfo(2, true, false)),
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC2, Texture2D::PixelFormatInfo(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, 0xFFFFFFFF, 0xFFFFFFFF, 2, true, false)),
|
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC2A, Texture2D::PixelFormatInfo(2, true, true)),
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC2A, Texture2D::PixelFormatInfo(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, 0xFFFFFFFF, 0xFFFFFFFF, 2, true, true)),
|
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC4, Texture2D::PixelFormatInfo(4, true, false)),
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC4, Texture2D::PixelFormatInfo(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, 0xFFFFFFFF, 0xFFFFFFFF, 4, true, false)),
|
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC4A, Texture2D::PixelFormatInfo(4, true, true)),
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC4A, Texture2D::PixelFormatInfo(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, 0xFFFFFFFF, 0xFFFFFFFF, 4, true, true)),
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
//Metal && iOS
|
|
||||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC2, Texture2D::PixelFormatInfo(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 2, true, false)),
|
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC2A, Texture2D::PixelFormatInfo(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 2, true, true)),
|
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC4, Texture2D::PixelFormatInfo(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 4, true, false)),
|
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC4A, Texture2D::PixelFormatInfo(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 4, true, true)),
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GL_ETC1_RGB8_OES
|
#if defined(GL_ETC1_RGB8_OES) || (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::ETC, Texture2D::PixelFormatInfo(GL_ETC1_RGB8_OES, 0xFFFFFFFF, 0xFFFFFFFF, 4, true, false)),
|
PixelFormatInfoMapValue(backend::PixelFormat::ETC, Texture2D::PixelFormatInfo(4, true, false)),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
|
#if defined(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::S3TC_DXT1, Texture2D::PixelFormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0xFFFFFFFF, 0xFFFFFFFF, 4, true, false)),
|
PixelFormatInfoMapValue(backend::PixelFormat::S3TC_DXT1, Texture2D::PixelFormatInfo(4, true, false)),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
|
#if defined(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::S3TC_DXT3, Texture2D::PixelFormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0xFFFFFFFF, 0xFFFFFFFF, 8, true, false)),
|
PixelFormatInfoMapValue(backend::PixelFormat::S3TC_DXT3, Texture2D::PixelFormatInfo(8, true, false)),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
|
#if defined(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::S3TC_DXT5, Texture2D::PixelFormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0xFFFFFFFF, 0xFFFFFFFF, 8, true, false)),
|
PixelFormatInfoMapValue(backend::PixelFormat::S3TC_DXT5, Texture2D::PixelFormatInfo(8, true, false)),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GL_ATC_RGB_AMD
|
#ifdef GL_ATC_RGB_AMD
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::ATC_RGB, Texture2D::PixelFormatInfo(GL_ATC_RGB_AMD,
|
PixelFormatInfoMapValue(backend::PixelFormat::ATC_RGB, Texture2D::PixelFormatInfo(4, true, false)),
|
||||||
0xFFFFFFFF, 0xFFFFFFFF, 4, true, false)),
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GL_ATC_RGBA_EXPLICIT_ALPHA_AMD
|
#ifdef GL_ATC_RGBA_EXPLICIT_ALPHA_AMD
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::ATC_EXPLICIT_ALPHA, Texture2D::PixelFormatInfo(GL_ATC_RGBA_EXPLICIT_ALPHA_AMD,
|
PixelFormatInfoMapValue(backend::PixelFormat::ATC_EXPLICIT_ALPHA, Texture2D::PixelFormatInfo(8, true, false)),
|
||||||
0xFFFFFFFF, 0xFFFFFFFF, 8, true, false)),
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD
|
#ifdef GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::ATC_INTERPOLATED_ALPHA, Texture2D::PixelFormatInfo(GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD,
|
PixelFormatInfoMapValue(backend::PixelFormat::ATC_INTERPOLATED_ALPHA, Texture2D::PixelFormatInfo(8, true, false)),
|
||||||
0xFFFFFFFF, 0xFFFFFFFF, 8, true, false)),
|
|
||||||
#endif
|
#endif
|
||||||
//metal formats
|
//metal formats
|
||||||
#ifdef CC_USE_METAL
|
|
||||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::MTL_ABGR4, Texture2D::PixelFormatInfo(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 16, false, true)),
|
PixelFormatInfoMapValue(backend::PixelFormat::MTL_ABGR4, Texture2D::PixelFormatInfo(16, false, true)),
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::MTL_B5G6R5, Texture2D::PixelFormatInfo(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 16, false, false)),
|
PixelFormatInfoMapValue(backend::PixelFormat::MTL_B5G6R5, Texture2D::PixelFormatInfo(16, false, false)),
|
||||||
PixelFormatInfoMapValue(backend::PixelFormat::MTL_BGR5A1, Texture2D::PixelFormatInfo(0xFFFFFFFF,0xFFFFFFFF, 0xFFFFFFFF, 16, false, true)),
|
PixelFormatInfoMapValue(backend::PixelFormat::MTL_BGR5A1, Texture2D::PixelFormatInfo(16, false, true)),
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,18 +74,12 @@ class CC_DLL Texture2D : public Ref
|
||||||
public:
|
public:
|
||||||
struct PixelFormatInfo {
|
struct PixelFormatInfo {
|
||||||
|
|
||||||
PixelFormatInfo(GLenum anInternalFormat, GLenum aFormat, GLenum aType, int aBpp, bool aCompressed, bool anAlpha)
|
PixelFormatInfo(int aBpp, bool aCompressed, bool anAlpha)
|
||||||
: internalFormat(anInternalFormat)
|
: bpp(aBpp)
|
||||||
, format(aFormat)
|
|
||||||
, type(aType)
|
|
||||||
, bpp(aBpp)
|
|
||||||
, compressed(aCompressed)
|
, compressed(aCompressed)
|
||||||
, alpha(anAlpha)
|
, alpha(anAlpha)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
GLenum internalFormat;
|
|
||||||
GLenum format;
|
|
||||||
GLenum type;
|
|
||||||
int bpp;
|
int bpp;
|
||||||
bool compressed;
|
bool compressed;
|
||||||
bool alpha;
|
bool alpha;
|
||||||
|
|
|
@ -105,17 +105,77 @@ namespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isCompressedFormat(PixelFormat textureFormat)
|
uint32_t getBytesPerRowETC(MTLPixelFormat pixleFormat, uint32_t width)
|
||||||
|
{
|
||||||
|
uint32_t bytesPerRow = 0;
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||||
|
uint32_t bytesPerBlock = 0, blockWidth = 4;
|
||||||
|
switch (pixleFormat) {
|
||||||
|
case MTLPixelFormatETC2_RGB8:
|
||||||
|
case MTLPixelFormatETC2_RGB8A1:
|
||||||
|
case MTLPixelFormatEAC_R11Unorm:
|
||||||
|
bytesPerBlock = 8;
|
||||||
|
break;
|
||||||
|
case MTLPixelFormatEAC_RGBA8:
|
||||||
|
case MTLPixelFormatEAC_RG11Unorm:
|
||||||
|
bytesPerBlock = 16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false); //TODO coulsonwang
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto blocksPerRow = (width + (blockWidth - 1)) / blockWidth;
|
||||||
|
bytesPerRow = blocksPerRow * bytesPerBlock;
|
||||||
|
#endif
|
||||||
|
return bytesPerRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getBytesPerRowS3TC(MTLPixelFormat pixleFormat, uint32_t width)
|
||||||
|
{
|
||||||
|
uint32_t bytesPerRow = 0;
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||||
|
uint32_t bytesPerBlock = 0, blockWidth = 4;
|
||||||
|
switch (pixleFormat) {
|
||||||
|
case MTLPixelFormatBC1_RGBA:
|
||||||
|
bytesPerBlock = 8;
|
||||||
|
break;
|
||||||
|
case MTLPixelFormatBC2_RGBA:
|
||||||
|
case MTLPixelFormatBC3_RGBA:
|
||||||
|
bytesPerBlock = 16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto blocksPerRow = (width + (blockWidth - 1)) / blockWidth;
|
||||||
|
bytesPerRow = blocksPerRow * bytesPerBlock;
|
||||||
|
#endif
|
||||||
|
return bytesPerRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getBytesPerRow(PixelFormat textureFormat, uint32_t width, uint32_t bitsPerElement)
|
||||||
{
|
{
|
||||||
MTLPixelFormat pixelFormat = Utils::toMTLPixelFormat(textureFormat);
|
MTLPixelFormat pixelFormat = Utils::toMTLPixelFormat(textureFormat);
|
||||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
uint32_t bytesPerRow = 0;
|
||||||
bool isCompressed = (pixelFormat >= MTLPixelFormatPVRTC_RGB_2BPP &&
|
|
||||||
pixelFormat <= MTLPixelFormatASTC_12x12_LDR);
|
if(textureFormat >= PixelFormat::PVRTC2 &&
|
||||||
#else
|
textureFormat <= PixelFormat::PVRTC4A)
|
||||||
bool isCompressed = (pixelFormat >= MTLPixelFormatBC1_RGBA &&
|
{
|
||||||
pixelFormat <= MTLPixelFormatBC7_RGBAUnorm_sRGB);
|
bytesPerRow = 0;
|
||||||
#endif
|
}
|
||||||
return isCompressed;
|
else if (textureFormat == PixelFormat::ETC)
|
||||||
|
{
|
||||||
|
bytesPerRow = getBytesPerRowETC(pixelFormat, width);
|
||||||
|
}
|
||||||
|
else if(textureFormat >= PixelFormat::S3TC_DXT1 &&
|
||||||
|
textureFormat <= PixelFormat::S3TC_DXT5)
|
||||||
|
{
|
||||||
|
bytesPerRow = getBytesPerRowS3TC(pixelFormat, width);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bytesPerRow = width * bitsPerElement / 8;
|
||||||
|
}
|
||||||
|
return bytesPerRow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +184,6 @@ TextureMTL::TextureMTL(id<MTLDevice> mtlDevice, const TextureDescriptor& descrip
|
||||||
{
|
{
|
||||||
_mtlDevice = mtlDevice;
|
_mtlDevice = mtlDevice;
|
||||||
updateTextureDescriptor(descriptor);
|
updateTextureDescriptor(descriptor);
|
||||||
_isCompressed = isCompressedFormat(descriptor.textureFormat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureMTL::~TextureMTL()
|
TextureMTL::~TextureMTL()
|
||||||
|
@ -169,9 +228,7 @@ void TextureMTL::updateSubData(uint32_t xoffset, uint32_t yoffset, uint32_t widt
|
||||||
(uint32_t)(width * height),
|
(uint32_t)(width * height),
|
||||||
_textureFormat, &convertedData);
|
_textureFormat, &convertedData);
|
||||||
|
|
||||||
//TODO coulsonwang, it seems that only PVRTC has such limitation.
|
int bytesPerRow = getBytesPerRow(_textureFormat, width, _bitsPerElement);
|
||||||
//when pixel format is a compressed one, bytePerRow should be set to ZERO
|
|
||||||
int bytesPerRow = _isCompressed ? 0 : (width * _bitsPerElement / 8);
|
|
||||||
|
|
||||||
[_mtlTexture replaceRegion:region
|
[_mtlTexture replaceRegion:region
|
||||||
mipmapLevel:level
|
mipmapLevel:level
|
||||||
|
|
|
@ -97,6 +97,15 @@ MTLPixelFormat Utils::toMTLPixelFormat(PixelFormat textureFormat)
|
||||||
return MTLPixelFormatPVRTC_RGBA_2BPP;
|
return MTLPixelFormatPVRTC_RGBA_2BPP;
|
||||||
case PixelFormat::PVRTC2:
|
case PixelFormat::PVRTC2:
|
||||||
return MTLPixelFormatPVRTC_RGB_2BPP;
|
return MTLPixelFormatPVRTC_RGB_2BPP;
|
||||||
|
case TextureFormat::ETC1:
|
||||||
|
return MTLPixelFormatETC2_RGB8;
|
||||||
|
#else
|
||||||
|
case PixelFormat::S3TC_DXT1:
|
||||||
|
return MTLPixelFormatBC1_RGBA;
|
||||||
|
case PixelFormat::S3TC_DXT3:
|
||||||
|
return MTLPixelFormatBC2_RGBA;
|
||||||
|
case PixelFormat::S3TC_DXT5:
|
||||||
|
return MTLPixelFormatBC3_RGBA;
|
||||||
#endif
|
#endif
|
||||||
case PixelFormat::RGBA8888:
|
case PixelFormat::RGBA8888:
|
||||||
return MTLPixelFormatRGBA8Unorm;
|
return MTLPixelFormatRGBA8Unorm;
|
||||||
|
|
Loading…
Reference in New Issue