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())
|
||||
{
|
||||
//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;
|
||||
_dataLen = dataLen - ETC_PKM_HEADER_SIZE;
|
||||
_data = static_cast<unsigned char*>(malloc(_dataLen * sizeof(unsigned char)));
|
||||
|
|
|
@ -61,70 +61,55 @@ namespace {
|
|||
typedef Texture2D::PixelFormatInfoMap::value_type PixelFormatInfoMapValue;
|
||||
static const PixelFormatInfoMapValue TexturePixelFormatInfoTablesValue[] =
|
||||
{
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::BGRA8888, Texture2D::PixelFormatInfo(GL_BGRA, GL_BGRA, GL_UNSIGNED_BYTE, 32, false, true)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::RGBA8888, Texture2D::PixelFormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 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::RGB5A1, Texture2D::PixelFormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 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::RGB888, Texture2D::PixelFormatInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, 24, false, false)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::A8, Texture2D::PixelFormatInfo(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, 8, false, false)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::I8, Texture2D::PixelFormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, 8, false, false)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::AI88, Texture2D::PixelFormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 16, false, true)),
|
||||
#ifndef CC_USE_METAL
|
||||
//OpenGL only
|
||||
#ifdef GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC2, Texture2D::PixelFormatInfo(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, 0xFFFFFFFF, 0xFFFFFFFF, 2, true, false)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC2A, Texture2D::PixelFormatInfo(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, 0xFFFFFFFF, 0xFFFFFFFF, 2, true, true)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC4, Texture2D::PixelFormatInfo(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, 0xFFFFFFFF, 0xFFFFFFFF, 4, true, false)),
|
||||
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
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::BGRA8888, Texture2D::PixelFormatInfo(32, false, true)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::RGBA8888, Texture2D::PixelFormatInfo(32, false, true)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::RGBA4444, Texture2D::PixelFormatInfo(16, false, true)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::RGB5A1, Texture2D::PixelFormatInfo(16, false, true)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::RGB565, Texture2D::PixelFormatInfo(16, false, false)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::RGB888, Texture2D::PixelFormatInfo(24, false, false)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::A8, Texture2D::PixelFormatInfo(8, false, false)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::I8, Texture2D::PixelFormatInfo(8, false, false)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::AI88, Texture2D::PixelFormatInfo(16, false, true)),
|
||||
|
||||
#if defined( GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG) || (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC2, Texture2D::PixelFormatInfo(2, true, false)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC2A, Texture2D::PixelFormatInfo(2, true, true)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC4, Texture2D::PixelFormatInfo(4, true, false)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::PVRTC4A, Texture2D::PixelFormatInfo(4, true, true)),
|
||||
#endif
|
||||
|
||||
#ifdef GL_ETC1_RGB8_OES
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::ETC, Texture2D::PixelFormatInfo(GL_ETC1_RGB8_OES, 0xFFFFFFFF, 0xFFFFFFFF, 4, true, false)),
|
||||
#if defined(GL_ETC1_RGB8_OES) || (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::ETC, Texture2D::PixelFormatInfo(4, true, false)),
|
||||
#endif
|
||||
|
||||
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::S3TC_DXT1, Texture2D::PixelFormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0xFFFFFFFF, 0xFFFFFFFF, 4, true, false)),
|
||||
#if defined(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::S3TC_DXT1, Texture2D::PixelFormatInfo(4, true, false)),
|
||||
#endif
|
||||
|
||||
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::S3TC_DXT3, Texture2D::PixelFormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0xFFFFFFFF, 0xFFFFFFFF, 8, true, false)),
|
||||
#if defined(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::S3TC_DXT3, Texture2D::PixelFormatInfo(8, true, false)),
|
||||
#endif
|
||||
|
||||
#ifdef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::S3TC_DXT5, Texture2D::PixelFormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0xFFFFFFFF, 0xFFFFFFFF, 8, true, false)),
|
||||
#if defined(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::S3TC_DXT5, Texture2D::PixelFormatInfo(8, true, false)),
|
||||
#endif
|
||||
|
||||
#ifdef GL_ATC_RGB_AMD
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::ATC_RGB, Texture2D::PixelFormatInfo(GL_ATC_RGB_AMD,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 4, true, false)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::ATC_RGB, Texture2D::PixelFormatInfo(4, true, false)),
|
||||
#endif
|
||||
|
||||
#ifdef GL_ATC_RGBA_EXPLICIT_ALPHA_AMD
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::ATC_EXPLICIT_ALPHA, Texture2D::PixelFormatInfo(GL_ATC_RGBA_EXPLICIT_ALPHA_AMD,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 8, true, false)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::ATC_EXPLICIT_ALPHA, Texture2D::PixelFormatInfo(8, true, false)),
|
||||
#endif
|
||||
|
||||
#ifdef GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::ATC_INTERPOLATED_ALPHA, Texture2D::PixelFormatInfo(GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 8, true, false)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::ATC_INTERPOLATED_ALPHA, Texture2D::PixelFormatInfo(8, true, false)),
|
||||
#endif
|
||||
//metal formats
|
||||
#ifdef CC_USE_METAL
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::MTL_ABGR4, Texture2D::PixelFormatInfo(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 16, false, true)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::MTL_B5G6R5, Texture2D::PixelFormatInfo(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 16, false, false)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::MTL_BGR5A1, Texture2D::PixelFormatInfo(0xFFFFFFFF,0xFFFFFFFF, 0xFFFFFFFF, 16, false, true)),
|
||||
#endif
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::MTL_ABGR4, Texture2D::PixelFormatInfo(16, false, true)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::MTL_B5G6R5, Texture2D::PixelFormatInfo(16, false, false)),
|
||||
PixelFormatInfoMapValue(backend::PixelFormat::MTL_BGR5A1, Texture2D::PixelFormatInfo(16, false, true)),
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
|
|
@ -74,18 +74,12 @@ class CC_DLL Texture2D : public Ref
|
|||
public:
|
||||
struct PixelFormatInfo {
|
||||
|
||||
PixelFormatInfo(GLenum anInternalFormat, GLenum aFormat, GLenum aType, int aBpp, bool aCompressed, bool anAlpha)
|
||||
: internalFormat(anInternalFormat)
|
||||
, format(aFormat)
|
||||
, type(aType)
|
||||
, bpp(aBpp)
|
||||
PixelFormatInfo(int aBpp, bool aCompressed, bool anAlpha)
|
||||
: bpp(aBpp)
|
||||
, compressed(aCompressed)
|
||||
, alpha(anAlpha)
|
||||
{}
|
||||
|
||||
GLenum internalFormat;
|
||||
GLenum format;
|
||||
GLenum type;
|
||||
|
||||
int bpp;
|
||||
bool compressed;
|
||||
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);
|
||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
|
||||
bool isCompressed = (pixelFormat >= MTLPixelFormatPVRTC_RGB_2BPP &&
|
||||
pixelFormat <= MTLPixelFormatASTC_12x12_LDR);
|
||||
#else
|
||||
bool isCompressed = (pixelFormat >= MTLPixelFormatBC1_RGBA &&
|
||||
pixelFormat <= MTLPixelFormatBC7_RGBAUnorm_sRGB);
|
||||
#endif
|
||||
return isCompressed;
|
||||
uint32_t bytesPerRow = 0;
|
||||
|
||||
if(textureFormat >= PixelFormat::PVRTC2 &&
|
||||
textureFormat <= PixelFormat::PVRTC4A)
|
||||
{
|
||||
bytesPerRow = 0;
|
||||
}
|
||||
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;
|
||||
updateTextureDescriptor(descriptor);
|
||||
_isCompressed = isCompressedFormat(descriptor.textureFormat);
|
||||
}
|
||||
|
||||
TextureMTL::~TextureMTL()
|
||||
|
@ -169,9 +228,7 @@ void TextureMTL::updateSubData(uint32_t xoffset, uint32_t yoffset, uint32_t widt
|
|||
(uint32_t)(width * height),
|
||||
_textureFormat, &convertedData);
|
||||
|
||||
//TODO coulsonwang, it seems that only PVRTC has such limitation.
|
||||
//when pixel format is a compressed one, bytePerRow should be set to ZERO
|
||||
int bytesPerRow = _isCompressed ? 0 : (width * _bitsPerElement / 8);
|
||||
int bytesPerRow = getBytesPerRow(_textureFormat, width, _bitsPerElement);
|
||||
|
||||
[_mtlTexture replaceRegion:region
|
||||
mipmapLevel:level
|
||||
|
|
|
@ -97,6 +97,15 @@ MTLPixelFormat Utils::toMTLPixelFormat(PixelFormat textureFormat)
|
|||
return MTLPixelFormatPVRTC_RGBA_2BPP;
|
||||
case PixelFormat::PVRTC2:
|
||||
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
|
||||
case PixelFormat::RGBA8888:
|
||||
return MTLPixelFormatRGBA8Unorm;
|
||||
|
|
Loading…
Reference in New Issue