Przeglądaj źródła

Added ETC2 and PVRTC2.

bkaradzic 12 lat temu
rodzic
commit
8cdc2a1d15
8 zmienionych plików z 418 dodań i 404 usunięć
  1. 1 0
      README.md
  2. 15 8
      include/bgfx.h
  3. 1 28
      src/bgfx.cpp
  4. 258 311
      src/image.cpp
  5. 24 17
      src/renderer_d3d11.cpp
  6. 24 17
      src/renderer_d3d9.cpp
  7. 75 23
      src/renderer_gl.cpp
  8. 20 0
      src/renderer_gl.h

+ 1 - 0
README.md

@@ -292,6 +292,7 @@ Todo
  - Occlusion queries.
  - DX11: MSAA.
  - Fullscreen mode.
+ - ETC2, PVRTC1/2 decoding fallback for targets that don't support it natively.
 
 Contact
 -------

+ 15 - 8
include/bgfx.h

@@ -302,14 +302,21 @@ namespace bgfx
 	{
 		enum Enum
 		{
-			BC1,   // DXT1
-			BC2,   // DXT3
-			BC3,   // DXT5
-			BC4,   // LATC1/ATI1
-			BC5,   // LATC2/ATI2
-			ETC1,  // ETC1_RGB8
-			PTC12, // PVRTC1_2BPP_RGBA
-			PTC14, // PVRTC1_4BPP_RGBA
+			BC1,    // DXT1
+			BC2,    // DXT3
+			BC3,    // DXT5
+			BC4,    // LATC1/ATI1
+			BC5,    // LATC2/ATI2
+			ETC1,   // ETC1 RGB8
+			ETC2,   // ETC2 RGB8
+			ETC2A,  // ETC2 RGBA8
+			ETC2A1, // ETC2 RGB8A1
+			PTC12,  // PVRTC1 RGB 2BPP
+			PTC14,  // PVRTC1 RGB 4BPP
+			PTC14A, // PVRTC1 RGBA 4BPP
+			PTC12A, // PVRTC1 RGBA 2BPP
+			PTC22,  // PVRTC2 RGBA 2BPP
+			PTC24,  // PVRTC2 RGBA 4BPP
 			Unknown,
 			L8,
 			BGRX8,

+ 1 - 28
src/bgfx.cpp

@@ -993,33 +993,6 @@ namespace bgfx
 		s_ctx.destroyProgram(_handle);
 	}
 
-	static const uint32_t s_bitsPerPixel[TextureFormat::Count] =
-	{
-		4,  // BC1
-		8,  // BC2
-		8,  // BC3
-		4,  // BC4
-		8,  // BC5
-		4,  // ETC1
-		2,  // PVRTC1_2BPP_RGBA
-		4,  // PVRTC1_2BPP_RGBA
-		0,  // Unknown
-		8,  // L8
-		32, // BGRX8
-		32, // BGRA8
-		64, // RGBA16
-		64, // RGBA16F
-		16, // R5G6B5
-		16, // RGBA4
-		16, // RGB5A1
-		32, // RGB10A2
-	};
-
-	uint32_t getBitsPerPixel(TextureFormat::Enum _format)
-	{
-		return s_bitsPerPixel[_format];
-	}
-
 	void calcTextureSize(TextureInfo& _info, uint16_t _width, uint16_t _height, uint16_t _depth, uint8_t _numMips, TextureFormat::Enum _format)
 	{
 		_width   = bx::uint32_max(1, _width);
@@ -1031,7 +1004,7 @@ namespace bgfx
 		uint32_t height = _height;
 		uint32_t depth = _depth;
 
-		uint32_t bpp = s_bitsPerPixel[_format];
+		uint32_t bpp = getBitsPerPixel(_format);
 		uint32_t size = 0;
 
 		for (uint32_t lod = 0; lod < _numMips; ++lod)

+ 258 - 311
src/image.cpp

@@ -9,110 +9,42 @@
 
 #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)
-
-#define DDS_DXT1 BX_MAKEFOURCC('D', 'X', 'T', '1')
-#define DDS_DXT2 BX_MAKEFOURCC('D', 'X', 'T', '2')
-#define DDS_DXT3 BX_MAKEFOURCC('D', 'X', 'T', '3')
-#define DDS_DXT4 BX_MAKEFOURCC('D', 'X', 'T', '4')
-#define DDS_DXT5 BX_MAKEFOURCC('D', 'X', 'T', '5')
-#define DDS_ATI1 BX_MAKEFOURCC('A', 'T', 'I', '1')
-#define DDS_BC4U BX_MAKEFOURCC('B', 'C', '4', 'U')
-#define DDS_ATI2 BX_MAKEFOURCC('A', 'T', 'I', '2')
-#define DDS_BC5U BX_MAKEFOURCC('B', 'C', '5', 'U')
-
-#define D3DFMT_A16B16G16R16  36
-#define D3DFMT_A16B16G16R16F 113
-
-#define DDSD_CAPS                   0x00000001
-#define DDSD_HEIGHT                 0x00000002
-#define DDSD_WIDTH                  0x00000004
-#define DDSD_PITCH                  0x00000008
-#define DDSD_PIXELFORMAT            0x00001000
-#define DDSD_MIPMAPCOUNT            0x00020000
-#define DDSD_LINEARSIZE             0x00080000
-#define DDSD_DEPTH                  0x00800000
-
-#define DDPF_ALPHAPIXELS            0x00000001
-#define DDPF_ALPHA                  0x00000002
-#define DDPF_FOURCC                 0x00000004
-#define DDPF_INDEXED                0x00000020
-#define DDPF_RGB                    0x00000040
-#define DDPF_YUV                    0x00000200
-#define DDPF_LUMINANCE              0x00020000
-
-#define DDSCAPS_COMPLEX             0x00000008
-#define DDSCAPS_TEXTURE             0x00001000
-#define DDSCAPS_MIPMAP              0x00400000
-
-#define DDSCAPS2_CUBEMAP            0x00000200
-#define DDSCAPS2_CUBEMAP_POSITIVEX  0x00000400
-#define DDSCAPS2_CUBEMAP_NEGATIVEX  0x00000800
-#define DDSCAPS2_CUBEMAP_POSITIVEY  0x00001000
-#define DDSCAPS2_CUBEMAP_NEGATIVEY  0x00002000
-#define DDSCAPS2_CUBEMAP_POSITIVEZ  0x00004000
-#define DDSCAPS2_CUBEMAP_NEGATIVEZ  0x00008000
-
-#define DDS_CUBEMAP_ALLFACES (DDSCAPS2_CUBEMAP_POSITIVEX|DDSCAPS2_CUBEMAP_NEGATIVEX \
-							 |DDSCAPS2_CUBEMAP_POSITIVEY|DDSCAPS2_CUBEMAP_NEGATIVEY \
-							 |DDSCAPS2_CUBEMAP_POSITIVEZ|DDSCAPS2_CUBEMAP_NEGATIVEZ)
-
-#define DDSCAPS2_VOLUME             0x00200000
-
-// KTX
-#define KTX_MAGIC       BX_MAKEFOURCC(0xAB, 'K', 'T', 'X')
-#define KTX_HEADER_SIZE 64
-
-#define KTX_ETC1_RGB8_OES                             0x8D64
-#define KTX_COMPRESSED_R11_EAC                        0x9270
-#define KTX_COMPRESSED_SIGNED_R11_EAC                 0x9271
-#define KTX_COMPRESSED_RG11_EAC                       0x9272
-#define KTX_COMPRESSED_SIGNED_RG11_EAC                0x9273
-#define KTX_COMPRESSED_RGB8_ETC2                      0x9274
-#define KTX_COMPRESSED_SRGB8_ETC2                     0x9275
-#define KTX_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2  0x9276
-#define KTX_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
-#define KTX_COMPRESSED_RGBA8_ETC2_EAC                 0x9278
-#define KTX_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC          0x9279
-#define KTX_COMPRESSED_RGB_PVRTC_4BPPV1_IMG           0x8C00
-#define KTX_COMPRESSED_RGB_PVRTC_2BPPV1_IMG           0x8C01
-#define KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG          0x8C02
-#define KTX_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG          0x8C03
-#define KTX_COMPRESSED_RGBA_S3TC_DXT1_EXT             0x83F1
-#define KTX_COMPRESSED_RGBA_S3TC_DXT3_EXT             0x83F2
-#define KTX_COMPRESSED_RGBA_S3TC_DXT5_EXT             0x83F3
-#define KTX_COMPRESSED_LUMINANCE_LATC1_EXT            0x8C70
-#define KTX_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT      0x8C72
-#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
 {
+	static const uint32_t s_bitsPerPixel[TextureFormat::Count] =
+	{
+		4,  // BC1
+		8,  // BC2
+		8,  // BC3
+		4,  // BC4
+		8,  // BC5
+		4,  // ETC1
+		4,  // ETC2
+		4,  // ETC2A
+		4,  // ETC2A1
+		2,  // PTC12
+		4,  // PTC14
+		2,  // PTC12A
+		4,  // PTC14A
+		2,  // PTC22
+		4,  // PTC24
+		0,  // Unknown
+		8,  // L8
+		32, // BGRX8
+		32, // BGRA8
+		64, // RGBA16
+		64, // RGBA16F
+		16, // R5G6B5
+		16, // RGBA4
+		16, // RGB5A1
+		32, // RGB10A2
+	};
+
+	uint32_t getBitsPerPixel(TextureFormat::Enum _format)
+	{
+		return s_bitsPerPixel[_format];
+	}
+
 	void imageSolid(uint32_t _width, uint32_t _height, uint32_t _solid, void* _dst)
 	{
 		uint32_t* dst = (uint32_t*)_dst;
@@ -800,6 +732,84 @@ namespace bgfx
 		}
 	}
 
+// DDS
+#define DDS_MAGIC             BX_MAKEFOURCC('D', 'D', 'S', ' ')
+#define DDS_HEADER_SIZE       124
+#define DDS_IMAGE_DATA_OFFSET (DDS_HEADER_SIZE + 4)
+
+#define DDS_DXT1 BX_MAKEFOURCC('D', 'X', 'T', '1')
+#define DDS_DXT2 BX_MAKEFOURCC('D', 'X', 'T', '2')
+#define DDS_DXT3 BX_MAKEFOURCC('D', 'X', 'T', '3')
+#define DDS_DXT4 BX_MAKEFOURCC('D', 'X', 'T', '4')
+#define DDS_DXT5 BX_MAKEFOURCC('D', 'X', 'T', '5')
+#define DDS_ATI1 BX_MAKEFOURCC('A', 'T', 'I', '1')
+#define DDS_BC4U BX_MAKEFOURCC('B', 'C', '4', 'U')
+#define DDS_ATI2 BX_MAKEFOURCC('A', 'T', 'I', '2')
+#define DDS_BC5U BX_MAKEFOURCC('B', 'C', '5', 'U')
+
+#define D3DFMT_A16B16G16R16  36
+#define D3DFMT_A16B16G16R16F 113
+
+#define DDSD_CAPS                   0x00000001
+#define DDSD_HEIGHT                 0x00000002
+#define DDSD_WIDTH                  0x00000004
+#define DDSD_PITCH                  0x00000008
+#define DDSD_PIXELFORMAT            0x00001000
+#define DDSD_MIPMAPCOUNT            0x00020000
+#define DDSD_LINEARSIZE             0x00080000
+#define DDSD_DEPTH                  0x00800000
+
+#define DDPF_ALPHAPIXELS            0x00000001
+#define DDPF_ALPHA                  0x00000002
+#define DDPF_FOURCC                 0x00000004
+#define DDPF_INDEXED                0x00000020
+#define DDPF_RGB                    0x00000040
+#define DDPF_YUV                    0x00000200
+#define DDPF_LUMINANCE              0x00020000
+
+#define DDSCAPS_COMPLEX             0x00000008
+#define DDSCAPS_TEXTURE             0x00001000
+#define DDSCAPS_MIPMAP              0x00400000
+
+#define DDSCAPS2_CUBEMAP            0x00000200
+#define DDSCAPS2_CUBEMAP_POSITIVEX  0x00000400
+#define DDSCAPS2_CUBEMAP_NEGATIVEX  0x00000800
+#define DDSCAPS2_CUBEMAP_POSITIVEY  0x00001000
+#define DDSCAPS2_CUBEMAP_NEGATIVEY  0x00002000
+#define DDSCAPS2_CUBEMAP_POSITIVEZ  0x00004000
+#define DDSCAPS2_CUBEMAP_NEGATIVEZ  0x00008000
+
+#define DDS_CUBEMAP_ALLFACES (DDSCAPS2_CUBEMAP_POSITIVEX|DDSCAPS2_CUBEMAP_NEGATIVEX \
+							 |DDSCAPS2_CUBEMAP_POSITIVEY|DDSCAPS2_CUBEMAP_NEGATIVEY \
+							 |DDSCAPS2_CUBEMAP_POSITIVEZ|DDSCAPS2_CUBEMAP_NEGATIVEZ)
+
+#define DDSCAPS2_VOLUME             0x00200000
+
+	static struct TranslateDdsFormat
+	{
+		uint32_t m_format;
+		TextureFormat::Enum m_textureFormat;
+
+	} s_translateDdsFormat[] =
+	{
+		{ DDS_DXT1,                                       TextureFormat::BC1     },
+		{ DDS_DXT2,                                       TextureFormat::BC2     },
+		{ DDS_DXT3,                                       TextureFormat::BC2     },
+		{ DDS_DXT4,                                       TextureFormat::BC3     },
+		{ DDS_DXT5,                                       TextureFormat::BC3     },
+		{ DDS_ATI1,                                       TextureFormat::BC4     },
+		{ DDS_BC4U,                                       TextureFormat::BC4     },
+		{ DDS_ATI2,                                       TextureFormat::BC5     },
+		{ DDS_BC5U,                                       TextureFormat::BC5     },
+		{ D3DFMT_A16B16G16R16,                            TextureFormat::RGBA16  },
+		{ D3DFMT_A16B16G16R16F,                           TextureFormat::RGBA16F },
+		{ DDPF_RGB,                                       TextureFormat::BGRX8   },
+		{ DDPF_RGB|DDPF_ALPHAPIXELS,                      TextureFormat::BGRA8   },
+		{ DDPF_INDEXED,                                   TextureFormat::L8      },
+		{ DDPF_LUMINANCE,                                 TextureFormat::L8      },
+		{ DDPF_ALPHA,                                     TextureFormat::L8      },
+	};
+
 	bool imageParseDds(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)
 	{
 		uint32_t headerSize;
@@ -882,85 +892,22 @@ namespace bgfx
 		TextureFormat::Enum type = TextureFormat::Unknown;
 		bool hasAlpha = pixelFlags & DDPF_ALPHAPIXELS;
 
-		if (pixelFlags & DDPF_FOURCC)
+		uint32_t format = pixelFlags & DDPF_FOURCC ? fourcc : pixelFlags;
+		for (uint32_t ii = 0; ii < BX_COUNTOF(s_translateDdsFormat); ++ii)
 		{
-			switch (fourcc)
+			if (s_translateDdsFormat[ii].m_format == format)
 			{
-			case DDS_DXT1:
-				type = TextureFormat::BC1;
-				bpp = 4;
-				blockSize = 4*4*bpp/8;
-				break;
-
-			case DDS_DXT2:
-			case DDS_DXT3:
-				type = TextureFormat::BC2;
-				bpp = 8;
-				blockSize = 4*4*bpp/8;
-				break;
-
-			case DDS_DXT4:
-			case DDS_DXT5:
-				type = TextureFormat::BC3;
-				bpp = 8;
-				blockSize = 4*4*bpp/8;
-				break;
-
-			case DDS_ATI1:
-			case DDS_BC4U:
-				type = TextureFormat::BC4;
-				bpp = 4;
-				blockSize = 4*4*bpp/8;
-				break;
-
-			case DDS_ATI2:
-			case DDS_BC5U:
-				type = TextureFormat::BC5;
-				bpp = 8;
-				blockSize = 4*4*bpp/8;
-				break;
-
-			case D3DFMT_A16B16G16R16:
-				type = TextureFormat::RGBA16;
-				blockSize = 8;
-				bpp = 64;
-				break;
-
-			case D3DFMT_A16B16G16R16F:
-				type = TextureFormat::RGBA16F;
-				blockSize = 8;
-				bpp = 64;
+				type = s_translateDdsFormat[ii].m_textureFormat;
 				break;
 			}
 		}
-		else
-		{
-			switch (pixelFlags)
-			{
-			case DDPF_RGB:
-				type = TextureFormat::BGRX8;
-				blockSize = 3;
-				bpp = 24;
-				break;
-
-			case DDPF_RGB|DDPF_ALPHAPIXELS:
-				type = TextureFormat::BGRA8;
-				blockSize = 4;
-				bpp = 32;
-				break;
-
-			case DDPF_INDEXED:
-			case DDPF_LUMINANCE:
-			case DDPF_ALPHA:
-				type = TextureFormat::L8;
-				bpp = 8;
-				break;
 
-			default:
-				bpp = 0;
-				break;
-			}
-		}
+		bpp = TextureFormat::BGRX8 == type // special case to force conversion to 32-bpp.
+			? 24
+			: getBitsPerPixel(type)
+			;
+		blockSize = type < TextureFormat::Unknown ? 4*4 : 1;
+		blockSize = blockSize*bpp/8;
 
 		_imageContainer.m_type = type;
 		_imageContainer.m_offset = DDS_IMAGE_DATA_OFFSET;
@@ -977,6 +924,68 @@ namespace bgfx
 		return TextureFormat::Unknown != type;
 	}
 
+// KTX
+#define KTX_MAGIC       BX_MAKEFOURCC(0xAB, 'K', 'T', 'X')
+#define KTX_HEADER_SIZE 64
+
+#define KTX_ETC1_RGB8_OES                             0x8D64
+#define KTX_COMPRESSED_R11_EAC                        0x9270
+#define KTX_COMPRESSED_SIGNED_R11_EAC                 0x9271
+#define KTX_COMPRESSED_RG11_EAC                       0x9272
+#define KTX_COMPRESSED_SIGNED_RG11_EAC                0x9273
+#define KTX_COMPRESSED_RGB8_ETC2                      0x9274
+#define KTX_COMPRESSED_SRGB8_ETC2                     0x9275
+#define KTX_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2  0x9276
+#define KTX_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define KTX_COMPRESSED_RGBA8_ETC2_EAC                 0x9278
+#define KTX_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC          0x9279
+#define KTX_COMPRESSED_RGB_PVRTC_4BPPV1_IMG           0x8C00
+#define KTX_COMPRESSED_RGB_PVRTC_2BPPV1_IMG           0x8C01
+#define KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG          0x8C02
+#define KTX_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG          0x8C03
+#define KTX_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG          0x9137
+#define KTX_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG          0x9138
+#define KTX_COMPRESSED_RGBA_S3TC_DXT1_EXT             0x83F1
+#define KTX_COMPRESSED_RGBA_S3TC_DXT3_EXT             0x83F2
+#define KTX_COMPRESSED_RGBA_S3TC_DXT5_EXT             0x83F3
+#define KTX_COMPRESSED_LUMINANCE_LATC1_EXT            0x8C70
+#define KTX_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT      0x8C72
+#define KTX_RGBA16                                    0x805B
+#define KTX_RGBA16F                                   0x881A
+
+	static struct TranslateKtxFormat
+	{
+		uint32_t m_format;
+		TextureFormat::Enum m_textureFormat;
+
+	} s_translateKtxFormat[] =
+	{
+		{ KTX_COMPRESSED_RGBA_S3TC_DXT1_EXT,              TextureFormat::BC1     },
+		{ KTX_COMPRESSED_RGBA_S3TC_DXT3_EXT,              TextureFormat::BC2     },
+		{ KTX_COMPRESSED_RGBA_S3TC_DXT5_EXT,              TextureFormat::BC3     },
+		{ KTX_COMPRESSED_LUMINANCE_LATC1_EXT,             TextureFormat::BC4     },
+		{ KTX_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT,       TextureFormat::BC5     },
+		{ KTX_ETC1_RGB8_OES,                              TextureFormat::ETC1    },
+		{ KTX_COMPRESSED_RGB8_ETC2,                       TextureFormat::ETC2    },
+		{ KTX_COMPRESSED_RGBA8_ETC2_EAC,                  TextureFormat::ETC2A   },
+		{ KTX_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,   TextureFormat::ETC2A1  },
+		{ KTX_COMPRESSED_RGB_PVRTC_2BPPV1_IMG,            TextureFormat::PTC12   },
+		{ KTX_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG,           TextureFormat::PTC12A  },
+		{ KTX_COMPRESSED_RGB_PVRTC_4BPPV1_IMG,            TextureFormat::PTC14   },
+		{ KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG,           TextureFormat::PTC14A  },
+		{ KTX_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG,           TextureFormat::PTC22   },
+		{ KTX_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG,           TextureFormat::PTC24   },
+		{ KTX_RGBA16,                                     TextureFormat::RGBA16  },
+		{ KTX_RGBA16F,                                    TextureFormat::RGBA16F },
+		{ KTX_COMPRESSED_R11_EAC,                         TextureFormat::Unknown },
+		{ KTX_COMPRESSED_SIGNED_R11_EAC,                  TextureFormat::Unknown },
+		{ KTX_COMPRESSED_RG11_EAC,                        TextureFormat::Unknown },
+		{ KTX_COMPRESSED_SIGNED_RG11_EAC,                 TextureFormat::Unknown },
+		{ KTX_COMPRESSED_SRGB8_ETC2,                      TextureFormat::Unknown },
+		{ KTX_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,  TextureFormat::Unknown },
+		{ KTX_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,           TextureFormat::Unknown },
+	};
+
 	bool imageParseKtx(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)
 	{
 		uint8_t identifier[8];
@@ -1037,84 +1046,22 @@ namespace bgfx
 		TextureFormat::Enum type = TextureFormat::Unknown;
 		bool hasAlpha = false;
 
-		switch (glInternalFormat)
+		for (uint32_t ii = 0; ii < BX_COUNTOF(s_translateKtxFormat); ++ii)
 		{
-		case KTX_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-			type = TextureFormat::BC1;
-			bpp = 4;
-			blockSize = 4*4*bpp/8;
-			break;
-
-		case KTX_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-			type = TextureFormat::BC2;
-			bpp = 8;
-			blockSize = 4*4*bpp/8;
-			break;
-
-		case KTX_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-			type = TextureFormat::BC3;
-			bpp = 8;
-			blockSize = 4*4*bpp/8;
-			break;
-
-		case KTX_COMPRESSED_LUMINANCE_LATC1_EXT:
-			type = TextureFormat::BC4;
-			bpp = 4;
-			blockSize = 4*4*bpp/8;
-			break;
-
-		case KTX_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
-			type = TextureFormat::BC5;
-			bpp = 8;
-			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;
-			bpp = 64;
-			break;
-
-		case KTX_RGBA16F:
-			type = TextureFormat::RGBA16F;
-			blockSize = 8;
-			bpp = 64;
-			break;
-
-		case KTX_COMPRESSED_R11_EAC:
-		case KTX_COMPRESSED_SIGNED_R11_EAC:
-		case KTX_COMPRESSED_RG11_EAC:
-		case KTX_COMPRESSED_SIGNED_RG11_EAC:
-		case KTX_COMPRESSED_RGB8_ETC2:
-		case KTX_COMPRESSED_SRGB8_ETC2:
-		case KTX_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-		case KTX_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-		case KTX_COMPRESSED_RGBA8_ETC2_EAC:
-		case KTX_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
-		default:
-			break;
+			if (s_translateKtxFormat[ii].m_format == glInternalFormat)
+			{
+				type = s_translateKtxFormat[ii].m_textureFormat;
+				break;
+			}
 		}
 
+		bpp = TextureFormat::BGRX8 == type // special case to force conversion to 32-bpp.
+			? 24
+			: getBitsPerPixel(type)
+			;
+		blockSize = type < TextureFormat::Unknown ? 4*4 : 1;
+		blockSize = blockSize*bpp/8;
+
 		_imageContainer.m_type = type;
 		_imageContainer.m_offset = (uint32_t)offset;
 		_imageContainer.m_width = width;
@@ -1130,6 +1077,53 @@ namespace bgfx
 		return TextureFormat::Unknown != type;
 	}
 
+// 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_ANY   UINT32_MAX
+#define PVR3_CHANNEL_TYPE_FLOAT UINT32_C(12)
+
+	static struct TranslatePvr3Format
+	{
+		uint64_t m_format;
+		uint32_t m_channelTypeMask;
+		TextureFormat::Enum m_textureFormat;
+
+	} s_translatePvr3Format[] =
+	{
+		{ PVR3_PVRTC1_2BPP_RGB,  PVR3_CHANNEL_TYPE_ANY,   TextureFormat::PTC12   },
+		{ PVR3_PVRTC1_2BPP_RGBA, PVR3_CHANNEL_TYPE_ANY,   TextureFormat::PTC12   },
+		{ PVR3_PVRTC1_4BPP_RGB,  PVR3_CHANNEL_TYPE_ANY,   TextureFormat::PTC14   },
+		{ PVR3_PVRTC1_4BPP_RGBA, PVR3_CHANNEL_TYPE_ANY,   TextureFormat::PTC14   },
+		{ PVR3_ETC1,             PVR3_CHANNEL_TYPE_ANY,   TextureFormat::ETC1    },
+		{ PVR3_DXT1,             PVR3_CHANNEL_TYPE_ANY,   TextureFormat::BC1     },
+		{ PVR3_DXT2,             PVR3_CHANNEL_TYPE_ANY,   TextureFormat::BC2     },
+		{ PVR3_DXT3,             PVR3_CHANNEL_TYPE_ANY,   TextureFormat::BC2     },
+		{ PVR3_DXT4,             PVR3_CHANNEL_TYPE_ANY,   TextureFormat::BC3     },
+		{ PVR3_DXT5,             PVR3_CHANNEL_TYPE_ANY,   TextureFormat::BC3     },
+		{ PVR3_BC4,              PVR3_CHANNEL_TYPE_ANY,   TextureFormat::BC4     },
+		{ PVR3_BC5,              PVR3_CHANNEL_TYPE_ANY,   TextureFormat::BC5     },
+		{ PVR3_RGBA16,           PVR3_CHANNEL_TYPE_FLOAT, TextureFormat::RGBA16F },
+		{ PVR3_RGBA16,           PVR3_CHANNEL_TYPE_ANY,   TextureFormat::RGBA16  },
+	};
+
 	bool imageParsePvr3(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)
 	{
 		uint32_t flags;
@@ -1173,70 +1167,23 @@ namespace bgfx
 		TextureFormat::Enum type = TextureFormat::Unknown;
 		bool hasAlpha = false;
 
-		switch (pixelFormat)
+		for (uint32_t ii = 0; ii < BX_COUNTOF(s_translatePvr3Format); ++ii)
 		{
-		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;
+			if (s_translatePvr3Format[ii].m_format == pixelFormat
+			&&  channelType == (s_translatePvr3Format[ii].m_channelTypeMask & channelType) )
+			{
+				type = s_translatePvr3Format[ii].m_textureFormat;
+				break;
+			}
 		}
 
+		bpp = TextureFormat::BGRX8 == type // special case to force conversion to 32-bpp.
+			? 24
+			: getBitsPerPixel(type)
+			;
+		blockSize = type < TextureFormat::Unknown ? 4*4 : 1;
+		blockSize = blockSize*bpp/8;
+
 		_imageContainer.m_type = type;
 		_imageContainer.m_offset = (uint32_t)offset;
 		_imageContainer.m_width = width;

+ 24 - 17
src/renderer_d3d11.cpp

@@ -183,24 +183,31 @@ namespace bgfx
 
 	static const TextureFormatInfo s_textureFormat[TextureFormat::Count] =
 	{
-		{ DXGI_FORMAT_BC1_UNORM          },
-		{ DXGI_FORMAT_BC2_UNORM          },
-		{ DXGI_FORMAT_BC3_UNORM          },
-		{ DXGI_FORMAT_BC4_UNORM          },
-		{ DXGI_FORMAT_BC5_UNORM          },
+		{ DXGI_FORMAT_BC1_UNORM          }, // BC1 
+		{ DXGI_FORMAT_BC2_UNORM          }, // BC2
+		{ DXGI_FORMAT_BC3_UNORM          }, // BC3
+		{ DXGI_FORMAT_BC4_UNORM          }, // BC4
+		{ DXGI_FORMAT_BC5_UNORM          }, // BC5
 		{ 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     },
-		{ DXGI_FORMAT_B8G8R8A8_UNORM     },
-		{ DXGI_FORMAT_R16G16B16A16_UNORM },
-		{ DXGI_FORMAT_R16G16B16A16_FLOAT },
-		{ DXGI_FORMAT_B5G6R5_UNORM       },
-		{ DXGI_FORMAT_B4G4R4A4_UNORM     },
-		{ DXGI_FORMAT_B5G5R5A1_UNORM     },
-		{ DXGI_FORMAT_R10G10B10A2_UNORM  },
+		{ DXGI_FORMAT_UNKNOWN            }, // ETC2
+		{ DXGI_FORMAT_UNKNOWN            }, // ETC2A
+		{ DXGI_FORMAT_UNKNOWN            }, // ETC2A1
+		{ DXGI_FORMAT_UNKNOWN            }, // PTC12
+		{ DXGI_FORMAT_UNKNOWN            }, // PTC14
+		{ DXGI_FORMAT_UNKNOWN            }, // PTC12A
+		{ DXGI_FORMAT_UNKNOWN            }, // PTC14A
+		{ DXGI_FORMAT_UNKNOWN            }, // PTC22
+		{ DXGI_FORMAT_UNKNOWN            }, // PTC24
+		{ DXGI_FORMAT_UNKNOWN            }, // Unknown
+		{ DXGI_FORMAT_R8_UNORM           }, // L8
+		{ DXGI_FORMAT_B8G8R8A8_UNORM     }, // BGRX8
+		{ DXGI_FORMAT_B8G8R8A8_UNORM     }, // BGRA8
+		{ DXGI_FORMAT_R16G16B16A16_UNORM }, // RGBA16
+		{ DXGI_FORMAT_R16G16B16A16_FLOAT }, // RGBA16F
+		{ DXGI_FORMAT_B5G6R5_UNORM       }, // R5G6B5
+		{ DXGI_FORMAT_B4G4R4A4_UNORM     }, // RGBA4
+		{ DXGI_FORMAT_B5G5R5A1_UNORM     }, // RGB5A1
+		{ DXGI_FORMAT_R10G10B10A2_UNORM  }, // RGB10A2
 	};
 
 	static const D3D11_INPUT_ELEMENT_DESC s_attrib[Attrib::Count] =

+ 24 - 17
src/renderer_d3d9.cpp

@@ -188,24 +188,31 @@ namespace bgfx
 
 	static const TextureFormatInfo s_textureFormat[TextureFormat::Count] =
 	{
-		{ D3DFMT_DXT1,           4 },
-		{ D3DFMT_DXT3,           8 },
-		{ D3DFMT_DXT5,           8 },
-		{ D3DFMT_ATI1,           4 },
-		{ D3DFMT_ATI2,           8 },
+		{ D3DFMT_DXT1,           4 }, // BC1 
+		{ D3DFMT_DXT3,           8 }, // BC2
+		{ D3DFMT_DXT5,           8 }, // BC3
+		{ D3DFMT_ATI1,           4 }, // BC4
+		{ D3DFMT_ATI2,           8 }, // BC5
 		{ 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 },
-		{ D3DFMT_A8R8G8B8,      32 },
-		{ D3DFMT_A16B16G16R16,  64 },
-		{ D3DFMT_A16B16G16R16F, 64 },
-		{ D3DFMT_R5G6B5,        16 },
-		{ D3DFMT_A4R4G4B4,      16 },
-		{ D3DFMT_A1R5G5B5,      16 },
-		{ D3DFMT_A2B10G10R10,   32 },
+		{ D3DFMT_UNKNOWN,        0 }, // ETC2
+		{ D3DFMT_UNKNOWN,        0 }, // ETC2A
+		{ D3DFMT_UNKNOWN,        0 }, // ETC2A1
+		{ D3DFMT_UNKNOWN,        0 }, // PTC12
+		{ D3DFMT_UNKNOWN,        0 }, // PTC14
+		{ D3DFMT_UNKNOWN,        0 }, // PTC12A
+		{ D3DFMT_UNKNOWN,        0 }, // PTC14A
+		{ D3DFMT_UNKNOWN,        0 }, // PTC22
+		{ D3DFMT_UNKNOWN,        0 }, // PTC24
+		{ D3DFMT_UNKNOWN,        0 }, // Unknown
+		{ D3DFMT_L8,             8 }, // L8
+		{ D3DFMT_X8R8G8B8,      32 }, // BGRX8
+		{ D3DFMT_A8R8G8B8,      32 }, // BGRA8
+		{ D3DFMT_A16B16G16R16,  64 }, // RGBA16
+		{ D3DFMT_A16B16G16R16F, 64 }, // RGBA16F
+		{ D3DFMT_R5G6B5,        16 }, // R5G6B5
+		{ D3DFMT_A4R4G4B4,      16 }, // RGBA4
+		{ D3DFMT_A1R5G5B5,      16 }, // RGB5A1
+		{ D3DFMT_A2B10G10R10,   32 }, // RGB10A2
 	};
 
 	static ExtendedFormat s_extendedFormats[ExtendedFormat::Count] =

+ 75 - 23
src/renderer_gl.cpp

@@ -194,24 +194,31 @@ namespace bgfx
 
 	static TextureFormatInfo s_textureFormat[TextureFormat::Count] =
 	{
-		{ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,        GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,        GL_ZERO,                        false },
-		{ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,        GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,        GL_ZERO,                        false },
-		{ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,        GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,        GL_ZERO,                        false },
-		{ 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  },
-		{ GL_RGBA,                                 GL_RGBA,                                 GL_UNSIGNED_BYTE,               true  },
-		{ GL_RGBA16,                               GL_RGBA,                                 GL_UNSIGNED_BYTE,               true  },
-		{ GL_RGBA16F,                              GL_RGBA,                                 GL_HALF_FLOAT,                  true  },
-		{ GL_RGB565,                               GL_RGB,                                  GL_UNSIGNED_SHORT_5_6_5,        true  },
-		{ GL_RGBA4,                                GL_RGBA,                                 GL_UNSIGNED_SHORT_4_4_4_4,      true  },
-		{ GL_RGB5_A1,                              GL_RGBA,                                 GL_UNSIGNED_SHORT_5_5_5_1,      true  },
-		{ GL_RGB10_A2,                             GL_RGBA,                                 GL_UNSIGNED_INT_2_10_10_10_REV, true  },
+		{ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,            GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,            GL_ZERO,                        false },
+		{ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,            GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,            GL_ZERO,                        false },
+		{ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,            GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,            GL_ZERO,                        false },
+		{ 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_RGB8_ETC2,                     GL_COMPRESSED_RGB8_ETC2,                     GL_ZERO,                        false },
+		{ GL_COMPRESSED_RGBA8_ETC2_EAC,                GL_COMPRESSED_RGBA8_ETC2_EAC,                GL_ZERO,                        false },
+		{ GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_ZERO,                        false },
+		{ GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG,          GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG,          GL_ZERO,                        false },
+		{ GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG,          GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG,          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_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG,         GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG,         GL_ZERO,                        false },
+		{ GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG,         GL_COMPRESSED_RGBA_PVRTC_4BPPV2_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  },
+		{ GL_RGBA,                                     GL_RGBA,                                     GL_UNSIGNED_BYTE,               true  },
+		{ GL_RGBA16,                                   GL_RGBA,                                     GL_UNSIGNED_BYTE,               true  },
+		{ GL_RGBA16F,                                  GL_RGBA,                                     GL_HALF_FLOAT,                  true  },
+		{ GL_RGB565,                                   GL_RGB,                                      GL_UNSIGNED_SHORT_5_6_5,        true  },
+		{ GL_RGBA4,                                    GL_RGBA,                                     GL_UNSIGNED_SHORT_4_4_4_4,      true  },
+		{ GL_RGB5_A1,                                  GL_RGBA,                                     GL_UNSIGNED_SHORT_5_5_5_1,      true  },
+		{ GL_RGB10_A2,                                 GL_RGBA,                                     GL_UNSIGNED_INT_2_10_10_10_REV, true  },
 	};
 
 	struct Extension
@@ -223,6 +230,7 @@ namespace bgfx
 			APPLE_texture_format_BGRA8888,
 			ARB_debug_output,
 			ARB_depth_clamp,
+			ARB_ES3_compatibility,
 			ARB_framebuffer_sRGB,
 			ARB_get_program_binary,
 			ARB_half_float_vertex,
@@ -294,6 +302,7 @@ namespace bgfx
 		{ "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_ES3_compatibility",              BGFX_CONFIG_RENDERER_OPENGL >= 43, true  },
 		{ "GL_ARB_framebuffer_sRGB",               false,                             true  },
 		{ "GL_ARB_get_program_binary",             BGFX_CONFIG_RENDERER_OPENGL >= 41, true  },
 		{ "GL_ARB_half_float_vertex",              false,                             true  },
@@ -2376,12 +2385,43 @@ namespace bgfx
 
 		if (0 < numCmpFormats)
 		{
+			static const char* s_textureFormatName[TextureFormat::Unknown+1] =
+			{
+				"BC1",
+				"BC2",
+				"BC3",
+				"BC4",
+				"BC5",
+				"ETC1",
+				"ETC2",
+				"ETC2A",
+				"ETC2A1",
+				"PTC12",
+				"PTC14",
+				"PTC12A",
+				"PTC14A",
+				"PTC22",
+				"PTC24",
+				"",
+				// TextureFormat::Count
+			};
+
 			GLint* formats = (GLint*)alloca(sizeof(GLint)*numCmpFormats);
 			GL_CHECK(glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats) );
 
 			for (GLint ii = 0; ii < numCmpFormats; ++ii)
 			{
-				BX_TRACE("  %3d: %8x", ii, formats[ii]);
+				GLint internalFmt = formats[ii];
+				uint32_t fmt = uint32_t(TextureFormat::Unknown);
+				for (uint32_t jj = 0; jj < fmt; ++jj)
+				{
+					if (s_textureFormat[jj].m_internalFmt == internalFmt)
+					{
+						fmt = jj;
+					}
+				}
+
+				BX_TRACE("  %3d: %8x %s", ii, internalFmt, s_textureFormatName[fmt]);
 			}
 		}
 
@@ -2488,10 +2528,22 @@ namespace bgfx
 
 		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;
+		bool etc2Supported = !!BGFX_CONFIG_RENDERER_OPENGLES3
+			|| s_extension[Extension::ARB_ES3_compatibility].m_supported
+			;
+		s_textureFormat[TextureFormat::ETC2  ].m_supported = etc2Supported;
+		s_textureFormat[TextureFormat::ETC2A ].m_supported = etc2Supported;
+		s_textureFormat[TextureFormat::ETC2A1].m_supported = etc2Supported;
+
+		bool ptc1Supported = s_extension[Extension::IMG_texture_compression_pvrtc ].m_supported;
+		s_textureFormat[TextureFormat::PTC12].m_supported  = ptc1Supported;
+		s_textureFormat[TextureFormat::PTC14].m_supported  = ptc1Supported;
+		s_textureFormat[TextureFormat::PTC12A].m_supported = ptc1Supported;
+		s_textureFormat[TextureFormat::PTC14A].m_supported = ptc1Supported;
+
+		bool ptc2Supported = s_extension[Extension::IMG_texture_compression_pvrtc2].m_supported;
+		s_textureFormat[TextureFormat::PTC22].m_supported  = ptc2Supported;
+		s_textureFormat[TextureFormat::PTC24].m_supported  = ptc2Supported;
 
 		s_renderCtx.m_vaoSupport = !!BGFX_CONFIG_RENDERER_OPENGLES3
 			|| s_extension[Extension::ARB_vertex_array_object].m_supported

+ 20 - 0
src/renderer_gl.h

@@ -175,6 +175,18 @@ typedef void (*PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC)(GLuint shader, GLsizei b
 #		define GL_ETC1_RGB8_OES 0x8D64
 #	endif // GL_ETC1_RGB8_OES
 
+#	ifndef GL_COMPRESSED_RGB8_ETC2
+#		define GL_COMPRESSED_RGB8_ETC2 0x9274
+#	endif // GL_COMPRESSED_RGB8_ETC2
+
+#	ifndef GL_COMPRESSED_RGBA8_ETC2_EAC
+#		define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#	endif // GL_COMPRESSED_RGBA8_ETC2_EAC
+
+#	ifndef GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
+#		define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#	endif // GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
+
 #	ifndef GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG
 #		define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01
 #	endif // GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG
@@ -191,6 +203,14 @@ typedef void (*PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC)(GLuint shader, GLsizei b
 #		define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
 #	endif // GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG
 
+#	ifndef GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG
+#		define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137
+#	endif // GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG
+
+#	ifndef GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG
+#		define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138
+#	endif // GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG
+
 #	ifndef GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE
 #		define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0
 #	endif // GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE