Added PVRTC1 support.

This commit is contained in:
bkaradzic 2013-09-03 20:13:07 -07:00
parent f540cd827b
commit 19ce130464
8 changed files with 258 additions and 49 deletions

View file

@ -302,12 +302,14 @@ namespace bgfx
{
enum Enum
{
BC1, // DXT1
BC2, // DXT3
BC3, // DXT5
BC4, // LATC1/ATI1
BC5, // LATC2/ATI2
ETC1,
BC1, // DXT1
BC2, // DXT3
BC3, // DXT5
BC4, // LATC1/ATI1
BC5, // LATC2/ATI2
ETC1, // ETC1_RGB8
PTC12, // PVRTC1_2BPP_RGBA
PTC14, // PVRTC1_4BPP_RGBA
Unknown,
L8,
BGRX8,

View file

@ -1001,6 +1001,8 @@ namespace bgfx
4, // BC4
8, // BC5
4, // ETC1
2, // PVRTC1_2BPP_RGBA
4, // PVRTC1_2BPP_RGBA
0, // Unknown
8, // L8
32, // BGRX8

View file

@ -9,6 +9,7 @@
#include "image.h"
// DDS
#define DDS_MAGIC BX_MAKEFOURCC('D', 'D', 'S', ' ')
#define DDS_HEADER_SIZE 124
#define DDS_IMAGE_DATA_OFFSET (DDS_HEADER_SIZE + 4)
@ -61,6 +62,7 @@
#define DDSCAPS2_VOLUME 0x00200000
// KTX
#define KTX_MAGIC BX_MAKEFOURCC(0xAB, 'K', 'T', 'X')
#define KTX_HEADER_SIZE 64
@ -87,6 +89,28 @@
#define KTX_RGBA16 0x805B
#define KTX_RGBA16F 0x881A
// PVR3
#define PVR3_MAKE8CC(_a, _b, _c, _d, _e, _f, _g, _h) (uint64_t(BX_MAKEFOURCC(_a, _b, _c, _d) ) | (uint64_t(BX_MAKEFOURCC(_e, _f, _g, _h) )<<32) )
#define PVR3_MAGIC BX_MAKEFOURCC('P', 'V', 'R', 3)
#define PVR3_HEADER_SIZE 52
#define PVR3_PVRTC1_2BPP_RGB 0
#define PVR3_PVRTC1_2BPP_RGBA 1
#define PVR3_PVRTC1_4BPP_RGB 2
#define PVR3_PVRTC1_4BPP_RGBA 3
#define PVR3_ETC1 6
#define PVR3_DXT1 7
#define PVR3_DXT2 8
#define PVR3_DXT3 9
#define PVR3_DXT4 10
#define PVR3_DXT5 11
#define PVR3_BC4 12
#define PVR3_BC5 13
#define PVR3_RGBA16 PVR3_MAKE8CC('r', 'g', 'b', 'a', 16, 16, 16, 16)
#define PVR3_CHANNEL_TYPE_FLOAT 12
namespace bgfx
{
void imageSolid(uint32_t _width, uint32_t _height, uint32_t _solid, void* _dst)
@ -98,7 +122,7 @@ namespace bgfx
}
}
void imageChessboard(uint32_t _width, uint32_t _height, uint32_t _step, uint32_t _0, uint32_t _1, void* _dst)
void imageCheckerboard(uint32_t _width, uint32_t _height, uint32_t _step, uint32_t _0, uint32_t _1, void* _dst)
{
uint32_t* dst = (uint32_t*)_dst;
for (uint32_t yy = 0; yy < _height; ++yy)
@ -738,6 +762,11 @@ namespace bgfx
}
}
break;
default:
// Decompression not implemented... Make ugly red-yellow checkerboard texture.
imageCheckerboard(m_width, m_height, 16, UINT32_C(0xffff0000), UINT32_C(0xffffff00), _dst);
break;
}
}
else
@ -927,10 +956,6 @@ namespace bgfx
bpp = 8;
break;
// type = TextureFormat::A8;
// bpp = 1;
// break;
default:
bpp = 0;
break;
@ -983,29 +1008,29 @@ namespace bgfx
uint32_t glBaseInternalFormat;
bx::readHE(_reader, glBaseInternalFormat, fromLittleEndian);
uint32_t pixelWidth;
bx::readHE(_reader, pixelWidth, fromLittleEndian);
uint32_t width;
bx::readHE(_reader, width, fromLittleEndian);
uint32_t pixelHeight;
bx::readHE(_reader, pixelHeight, fromLittleEndian);
uint32_t height;
bx::readHE(_reader, height, fromLittleEndian);
uint32_t pixelDepth;
bx::readHE(_reader, pixelDepth, fromLittleEndian);
uint32_t depth;
bx::readHE(_reader, depth, fromLittleEndian);
uint32_t numberOfArrayElements;
bx::readHE(_reader, numberOfArrayElements, fromLittleEndian);
uint32_t numberOfFaces;
bx::readHE(_reader, numberOfFaces, fromLittleEndian);
uint32_t numFaces;
bx::readHE(_reader, numFaces, fromLittleEndian);
uint32_t numberOfMipmapLevels;
bx::readHE(_reader, numberOfMipmapLevels, fromLittleEndian);
uint32_t numMips;
bx::readHE(_reader, numMips, fromLittleEndian);
uint32_t bytesOfKeyValueData;
bx::readHE(_reader, bytesOfKeyValueData, fromLittleEndian);
uint32_t metaDataSize;
bx::readHE(_reader, metaDataSize, fromLittleEndian);
// skip meta garbage...
int64_t offset = bx::skip(_reader, bytesOfKeyValueData);
int64_t offset = bx::skip(_reader, metaDataSize);
uint8_t bpp = 0;
uint8_t blockSize = 1;
@ -1014,12 +1039,6 @@ namespace bgfx
switch (glInternalFormat)
{
case KTX_ETC1_RGB8_OES:
type = TextureFormat::ETC1;
bpp = 4;
blockSize = 4*4*bpp/8;
break;
case KTX_COMPRESSED_RGBA_S3TC_DXT1_EXT:
type = TextureFormat::BC1;
bpp = 4;
@ -1050,6 +1069,26 @@ namespace bgfx
blockSize = 4*4*bpp/8;
break;
case KTX_ETC1_RGB8_OES:
type = TextureFormat::ETC1;
bpp = 4;
blockSize = 4*4*bpp/8;
break;
case KTX_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
case KTX_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
type = TextureFormat::PTC12;
bpp = 2;
blockSize = 4*4*bpp/8;
break;
case KTX_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
case KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
type = TextureFormat::PTC14;
bpp = 2;
blockSize = 4*4*bpp/8;
break;
case KTX_RGBA16:
type = TextureFormat::RGBA16;
blockSize = 8;
@ -1072,29 +1111,147 @@ namespace bgfx
case KTX_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case KTX_COMPRESSED_RGBA8_ETC2_EAC:
case KTX_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
case KTX_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
case KTX_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
case KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
case KTX_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
default:
break;
}
_imageContainer.m_type = type;
_imageContainer.m_offset = (uint32_t)offset;
_imageContainer.m_width = pixelWidth;
_imageContainer.m_height = pixelHeight;
_imageContainer.m_depth = pixelDepth;
_imageContainer.m_width = width;
_imageContainer.m_height = height;
_imageContainer.m_depth = depth;
_imageContainer.m_blockSize = blockSize;
_imageContainer.m_numMips = numberOfMipmapLevels;
_imageContainer.m_numMips = numMips;
_imageContainer.m_bpp = bpp;
_imageContainer.m_hasAlpha = hasAlpha;
_imageContainer.m_cubeMap = numberOfFaces > 1;
_imageContainer.m_cubeMap = numFaces > 1;
_imageContainer.m_ktx = true;
return TextureFormat::Unknown != type;
}
bool imageParsePvr3(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)
{
uint32_t flags;
bx::read(_reader, flags);
uint64_t pixelFormat;
bx::read(_reader, pixelFormat);
uint32_t colorSpace;
bx::read(_reader, colorSpace); // 0 - linearRGB, 1 - sRGB
uint32_t channelType;
bx::read(_reader, channelType);
uint32_t height;
bx::read(_reader, height);
uint32_t width;
bx::read(_reader, width);
uint32_t depth;
bx::read(_reader, depth);
uint32_t numSurfaces;
bx::read(_reader, numSurfaces);
uint32_t numFaces;
bx::read(_reader, numFaces);
uint32_t numMips;
bx::read(_reader, numMips);
uint32_t metaDataSize;
bx::read(_reader, metaDataSize);
// skip meta garbage...
int64_t offset = bx::skip(_reader, metaDataSize);
uint8_t bpp = 0;
uint8_t blockSize = 1;
TextureFormat::Enum type = TextureFormat::Unknown;
bool hasAlpha = false;
switch (pixelFormat)
{
case PVR3_PVRTC1_2BPP_RGB:
case PVR3_PVRTC1_2BPP_RGBA:
type = TextureFormat::PTC12;
bpp = 2;
blockSize = 4*4*bpp/8;
break;
case PVR3_PVRTC1_4BPP_RGB:
case PVR3_PVRTC1_4BPP_RGBA:
type = TextureFormat::PTC14;
bpp = 2;
blockSize = 4*4*bpp/8;
break;
case PVR3_ETC1:
type = TextureFormat::ETC1;
bpp = 4;
blockSize = 4*4*bpp/8;
break;
case PVR3_DXT1:
type = TextureFormat::BC1;
bpp = 4;
blockSize = 4*4*bpp/8;
break;
case PVR3_DXT2:
case PVR3_DXT3:
type = TextureFormat::BC2;
bpp = 8;
blockSize = 4*4*bpp/8;
break;
case PVR3_DXT4:
case PVR3_DXT5:
type = TextureFormat::BC3;
bpp = 8;
blockSize = 4*4*bpp/8;
break;
case PVR3_BC4:
type = TextureFormat::BC4;
bpp = 4;
blockSize = 4*4*bpp/8;
break;
case PVR3_BC5:
type = TextureFormat::BC5;
bpp = 8;
blockSize = 4*4*bpp/8;
break;
case PVR3_RGBA16:
type = PVR3_CHANNEL_TYPE_FLOAT == channelType
? TextureFormat::RGBA16F
: TextureFormat::RGBA16
;
blockSize = 8;
bpp = 64;
break;
}
_imageContainer.m_type = type;
_imageContainer.m_offset = (uint32_t)offset;
_imageContainer.m_width = width;
_imageContainer.m_height = height;
_imageContainer.m_depth = depth;
_imageContainer.m_blockSize = blockSize;
_imageContainer.m_numMips = numMips;
_imageContainer.m_bpp = bpp;
_imageContainer.m_hasAlpha = hasAlpha;
_imageContainer.m_cubeMap = numFaces > 1;
_imageContainer.m_ktx = false;
return TextureFormat::Unknown != type;
}
bool imageParse(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)
{
uint32_t magic;
@ -1108,6 +1265,10 @@ namespace bgfx
{
return imageParseKtx(_imageContainer, _reader);
}
else if (PVR3_MAGIC == magic)
{
return imageParsePvr3(_imageContainer, _reader);
}
return false;
}

View file

@ -43,7 +43,7 @@ namespace bgfx
void imageSolid(uint32_t _width, uint32_t _height, uint32_t _solid, void* _dst);
///
void imageChessboard(uint32_t _width, uint32_t _height, uint32_t _step, uint32_t _0, uint32_t _1, void* _dst);
void imageCheckerboard(uint32_t _width, uint32_t _height, uint32_t _step, uint32_t _0, uint32_t _1, void* _dst);
///
void imageRgba8Downsample2x2(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst);

View file

@ -188,7 +188,9 @@ namespace bgfx
{ DXGI_FORMAT_BC3_UNORM },
{ DXGI_FORMAT_BC4_UNORM },
{ DXGI_FORMAT_BC5_UNORM },
{ DXGI_FORMAT_UNKNOWN },
{ DXGI_FORMAT_UNKNOWN }, // ETC1
{ DXGI_FORMAT_UNKNOWN }, // PVRTC1_2BPP_RGBA
{ DXGI_FORMAT_UNKNOWN }, // PVRTC1_4BPP_RGBA
{ DXGI_FORMAT_UNKNOWN },
{ DXGI_FORMAT_R8_UNORM },
{ DXGI_FORMAT_B8G8R8A8_UNORM },
@ -1634,9 +1636,7 @@ namespace bgfx
if (imageParse(imageContainer, _mem->data, _mem->size) )
{
bool decompress = false
|| (TextureFormat::ETC1 == imageContainer.m_type)
;
bool decompress = DXGI_FORMAT_UNKNOWN == s_textureFormat[imageContainer.m_type].m_fmt;
if (imageContainer.m_cubeMap)
{

View file

@ -193,7 +193,9 @@ namespace bgfx
{ D3DFMT_DXT5, 8 },
{ D3DFMT_ATI1, 4 },
{ D3DFMT_ATI2, 8 },
{ D3DFMT_UNKNOWN, 0 },
{ D3DFMT_UNKNOWN, 0 }, // ETC1
{ D3DFMT_UNKNOWN, 0 }, // PVRTC1_2BPP_RGBA
{ D3DFMT_UNKNOWN, 0 }, // PVRTC1_4BPP_RGBA
{ D3DFMT_UNKNOWN, 0 },
{ D3DFMT_L8, 8 },
{ D3DFMT_X8R8G8B8, 32 },
@ -1515,7 +1517,7 @@ namespace bgfx
bool decompress = false
|| (TextureFormat::BC4 == imageContainer.m_type && !s_extendedFormats[ExtendedFormat::Ati1].m_supported)
|| (TextureFormat::BC5 == imageContainer.m_type && !s_extendedFormats[ExtendedFormat::Ati2].m_supported)
|| (TextureFormat::ETC1 == imageContainer.m_type)
|| (D3DFMT_UNKNOWN == tfi.m_fmt)
;
D3DFORMAT format = decompress ? D3DFMT_A8R8G8B8 : tfi.m_fmt;

View file

@ -200,6 +200,8 @@ namespace bgfx
{ GL_COMPRESSED_LUMINANCE_LATC1_EXT, GL_COMPRESSED_LUMINANCE_LATC1_EXT, GL_ZERO, false },
{ GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL_ZERO, false },
{ GL_ETC1_RGB8_OES, GL_ETC1_RGB8_OES, GL_ZERO, false },
{ GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, GL_ZERO, false },
{ GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_ZERO, false },
{ GL_ZERO, GL_ZERO, GL_ZERO, true },
{ GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, true },
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, true },
@ -218,6 +220,7 @@ namespace bgfx
{
ANGLE_instanced_arrays,
ANGLE_translated_shader_source,
APPLE_texture_format_BGRA8888,
ARB_debug_output,
ARB_depth_clamp,
ARB_framebuffer_sRGB,
@ -256,13 +259,16 @@ namespace bgfx
EXT_texture_type_2_10_10_10_REV,
EXT_timer_query,
IMG_multisampled_render_to_texture,
IMG_read_format,
IMG_shader_binary,
IMG_texture_compression_pvrtc,
IMG_texture_compression_pvrtc2,
IMG_texture_format_BGRA8888,
NVX_gpu_memory_info,
OES_compressed_ETC1_RGB8_texture,
OES_depth_texture,
OES_get_program_binary,
OES_read_format,
OES_rgb8_rgba8,
OES_standard_derivatives,
OES_texture_float,
@ -285,6 +291,7 @@ namespace bgfx
{
{ "GL_ANGLE_instanced_arrays", false, true },
{ "GL_ANGLE_translated_shader_source", false, true },
{ "GL_APPLE_texture_format_BGRA8888", false, true },
{ "GL_ARB_debug_output", BGFX_CONFIG_RENDERER_OPENGL >= 43, true },
{ "GL_ARB_depth_clamp", BGFX_CONFIG_RENDERER_OPENGL >= 31, true },
{ "GL_ARB_framebuffer_sRGB", false, true },
@ -323,13 +330,16 @@ namespace bgfx
{ "GL_EXT_texture_type_2_10_10_10_REV", false, true },
{ "GL_EXT_timer_query", false, true },
{ "GL_IMG_multisampled_render_to_texture", false, true },
{ "GL_IMG_read_format", false, true },
{ "GL_IMG_shader_binary", false, true },
{ "GL_IMG_texture_compression_pvrtc", false, true },
{ "GL_IMG_texture_compression_pvrtc2", false, true },
{ "GL_IMG_texture_format_BGRA8888", false, true },
{ "GL_NVX_gpu_memory_info", false, true },
{ "GL_OES_compressed_ETC1_RGB8_texture", false, true },
{ "GL_OES_depth_texture", false, true },
{ "GL_OES_get_program_binary", false, false },
{ "GL_OES_get_program_binary", false, true },
{ "GL_OES_read_format", false, true },
{ "GL_OES_rgb8_rgba8", false, true },
{ "GL_OES_standard_derivatives", false, true },
{ "GL_OES_texture_float", false, true },
@ -2475,8 +2485,14 @@ namespace bgfx
;
s_textureFormat[TextureFormat::BC4].m_supported = bc45Supported;
s_textureFormat[TextureFormat::BC5].m_supported = bc45Supported;
s_textureFormat[TextureFormat::ETC1].m_supported = s_extension[Extension::OES_compressed_ETC1_RGB8_texture].m_supported;
bool pvr1Supported = s_extension[Extension::IMG_texture_compression_pvrtc ].m_supported;
// bool pvr2Supported = s_extension[Extension::IMG_texture_compression_pvrtc2].m_supported;
s_textureFormat[TextureFormat::PTC12].m_supported = pvr1Supported;
s_textureFormat[TextureFormat::PTC14].m_supported = pvr1Supported;
s_renderCtx.m_vaoSupport = !!BGFX_CONFIG_RENDERER_OPENGLES3
|| s_extension[Extension::ARB_vertex_array_object].m_supported
|| s_extension[Extension::OES_vertex_array_object].m_supported
@ -2509,10 +2525,20 @@ namespace bgfx
}
#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
s_renderCtx.m_readPixelsFmt = GL_RGBA;
if (s_extension[Extension::IMG_read_format].m_supported
&& s_extension[Extension::OES_read_format].m_supported)
{
s_renderCtx.m_readPixelsFmt = GL_BGRA_EXT;
}
else
{
s_renderCtx.m_readPixelsFmt = GL_RGBA;
}
if (s_extension[Extension::EXT_texture_format_BGRA8888].m_supported
|| s_extension[Extension::EXT_bgra].m_supported)
|| s_extension[Extension::EXT_bgra].m_supported
|| s_extension[Extension::IMG_texture_format_BGRA8888].m_supported
|| s_extension[Extension::APPLE_texture_format_BGRA8888].m_supported)
{
#if BGFX_CONFIG_RENDERER_OPENGL
s_renderCtx.m_readPixelsFmt = GL_BGRA_EXT;

View file

@ -175,6 +175,22 @@ typedef void (*PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC)(GLuint shader, GLsizei b
# define GL_ETC1_RGB8_OES 0x8D64
# endif // GL_ETC1_RGB8_OES
# ifndef GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG
# define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01
# endif // GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG
# ifndef GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG
# define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03
# endif // GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG
# ifndef GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG
# define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
# endif // GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG
# ifndef GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG
# define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
# endif // GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG
# ifndef GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE
# define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0
# endif // GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE