Archives

August 2012 の記事

圧縮テクスチャフォーマットの wiki を更新しました。

圧縮 Texture


関連ページ
Texture File Format


OpenGL と Direct3D は Texture の RGB の並びが違っています。
Vista の D3D10 で一度 OpenGL の並び順に統一されましたが
Windows 7 以降、D3D11 で元の Windows 配列が復活しました。

DDS 形式のデータはデフォルトで Windows 順の配列になっています。

Windows : B8 G8 R8 A8
OpenGL  : R8 G8 B8 A8

OpenGL ES 2.0 では BGRA は定義されておらず、Texture Swizzle も
ないので DDS の Texture を読み込む場合は色の並び順を反転させる
必要があります。

並びの違いについて詳しくは下記の記事を参照してください。

OpenGLES2.0 DDS テクスチャを読み込む

ですが結局 GPU としては OpenGL/D3D 両方に対応するものがほとんど
なので、この両者にそれほど違いはありません。
どちらかに決めてしまえばシェーダーでも入れ替えできます。
下記のデータを見ても、PowerVR, Adreno, Tegra は
GL_EXT_texture_format_BGRA8888 に対応していることがわかります。

OpenGL ES Extension (Mobile GPU)

同じ PowerVR でも iOS の場合は GL_EXT_texture_format_BGRA8888
ではなく GL_APPLE_texture_format_BGRA8888 になっています。
どちらも DirectX の Windows 配列のピクセルをそのまま glTexImage2D() に
渡せる点は同じです。でも使い方が少し違います。

Extension        InternalFormat  Format        Type
---------------------------------------------------------------
EXT   BGRA8888   GL_BGRA_EXT     GL_BGRA_EXT   GL_UNSIGNED_BYTE
APPLE BGRA8888   GL_RGBA         GL_BGRA_EXT   GL_UNSIGNED_BYTE

おそらく内部で RGBA 並びに統一した方が効率的にアクセスできるのでしょう。
PowerVR は lowp の swizzle が苦手ということもありますし、
結局ロード時に自分で byte 並びを入れ替えても変わらないかもしれません。

Mali-400MP は GL_EXT_texture_format_BGRA8888 に対応していません。
Extension として GL_ARM_rgba8 がありますが、こちらは Texture ではなく
フレームバッファの並び順です。


関連エントリ
OpenGLES2.0 DDS テクスチャを読み込む


昨日の記事に書いたように OpenGL / OpenGL ES の場合 KTX 形式の
テクスチャ読み込みが非常に簡単に出来ます。
ところが OpenGL ES 3.0 / OpenGL 4.3 の場合、ETC1 の読み込みに
問題がありました。

KTX のロード時に、ヘッダに GL_ETC1_RGB8_OES があれば
GL_COMPRESSED_RGB8_ETC2 に置き換える必要があります。
これは GPU が ETC2 に対応している場合だけです。


OpenGL ES 3.0 / OpenGL 4.3 で採用された ETC2 形式は ETC1 と
完全に上位互換性があります。
フォーマットも同一で、ETC1 は ETC2 の一部になりました。
そのため OpenGL ES 3.0 では事実上 ETC1 が無くなっています。

実際に Emulator (ES3 compatibility) で
glGetIntegerv( GL_COMPRESSED_TEXTURE_FORMATS, lists )
を列挙すると↓ ETC1 が含まれていないことがわかります。

tc[00]=83f0  GL_COMPRESSED_RGB_S3TC_DXT1_EXT
tc[01]=83f2  GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
tc[02]=83f3  GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
tc[03]=8b90  GL_PALETTE4_RGB8
tc[04]=8b91  GL_PALETTE4_RGBA8
tc[05]=8b92  GL_PALETTE4_R5_G6_B5
tc[06]=8b93  GL_PALETTE4_RGBA4
tc[07]=8b94  GL_PALETTE4_RGB5_A1
tc[08]=8b95  GL_PALETTE8_RGB8
tc[09]=8b96  GL_PALETTE8_RGBA8
tc[10]=8b97  GL_PALETTE8_R5_G6_B5
tc[11]=8b98  GL_PALETTE8_RGBA4
tc[12]=8b99  GL_PALETTE8_RGB5_A1
tc[13]=9274  GL_COMPRESSED_RGB8_ETC2
tc[14]=9275  GL_COMPRESSED_SRGB8_ETC2
tc[15]=9276  GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
tc[16]=9277  GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
tc[17]=9278  GL_COMPRESSED_RGBA8_ETC2_EAC
tc[18]=9279  GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
tc[19]=9270  GL_COMPRESSED_R11_EAC
tc[20]=9271  GL_COMPRESSED_SIGNED_R11_EAC
tc[21]=9272  GL_COMPRESSED_RG11_EAC
tc[22]=9273  GL_COMPRESSED_SIGNED_RG11_EAC

ドキュメントによれば ETC1 画像を読み込む場合 API に
GL_COMPRESSED_RGB8_ETC2 を渡すことになっています。
そのため KTX に ETC1 が含まれている場合、OpenGL 4.3 / OpenGL ES 3.0
ではヘッダの値をそのまま使うとエラーになります。

bool HasFormat( GLenum format )
{
  GLint numformat= 0;
  glGetIntegerv( GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numformat );
  const int	MAX_TLISTBUFFER= 128;
  GLint lists[MAX_TLISTBUFFER];
  glGetIntegerv( GL_COMPRESSED_TEXTURE_FORMATS, lists );
  for( int fi= 0 ; fi< numformat ; fi++ ){
    if( lists[fi] == format ){
      return  true;
    }
  }
  return  false;
}


GLuint KTX_Loader_Compressed( const void* memory, size_t memory_size )
{
  const KTX_Header*  hp= reinterpret_cast<const KTX_Header*>( memory );
  const void*        image_data= address_add( memory, sizeof(KTX_Header) + hp->bytesOfKeyValueData );

  unsigned int  image_size= *reinterpret_cast<const int32_t*>( image_data );
  image_data= address_add( image_data, sizeof(int32_t) );

  GLuint  texid= 0;
  glGenTextures( 1, &texid );
  glBindTexture( GL_TEXTURE_2D, texid );

  GLenum  cformat= dp->glInternalFormat;
  if( cformat == GL_ETC1_RGB8_OES && HasFormat( GL_COMPRESSED_RGB8_ETC2 ) ){
    // **** ここで ETC2 に置き換える ****
    cformat= GL_COMPRESSED_RGB8_ETC2;
  }

  glCompressedTexImage2D( GL_TEXTURE_2D, 0,
           cformat,
           hp->pixelWidth,
           hp->pixelHeight,
	   0,
	   image_size,
	   image_data );

  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

  return  texid;
}


関連エントリ
OpenGL / OpenGL ES KTX Texture の読み込み方


OpenGL / OpenGL ES の場合 KTX 形式のテクスチャの読み込みは簡単です。
ファイルを全部メモリに読み込んだと仮定して

const void* address_add( const void* a, uintptr_t b )
{
  return  reinterpret_cast<const void*>( reinterpret_cast<uintptr_t>( a ) + b );
}


GLuint KTX_Loader( const void* memory, size_t memory_size )
{
  const KTX_Header*  hp= reinterpret_cast<const KTX_Header*>( memory );
  const void*        image_data= address_add( memory, sizeof(KTX_Header) + hp->bytesOfKeyValueData );

  image_data= address_add( image_data, sizeof(int32_t) );

  GLuint  texid= 0;
  glGenTextures( 1, &texid );
  glBindTexture( GL_TEXTURE_2D, texid );

  glTexImage2D( GL_TEXTURE_2D, 0,
           hp->glInternalFormat,
           hp->pixelWidth,
           hp->pixelHeight,
	   0,
           hp->glBaseInternalFormat,
           hp->glType,
	   image_data );

  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

  return  texid;
}

このように、API に渡す必要な情報が全部ヘッダに入っています。
ヘッダの構造は下記を参照してください。

KTX File Format Specification

圧縮テクスチャの場合も簡単です。glType が 0 なら圧縮テクスチャです。

GLuint KTX_Loader_Compressed( const void* memory, size_t memory_size )
{
  const KTX_Header*  hp= reinterpret_cast<const KTX_Header*>( memory );
  const void*        image_data= address_add( memory, sizeof(KTX_Header) + hp->bytesOfKeyValueData );

  unsigned int  image_size= *reinterpret_cast<const int32_t*>( image_data );
  image_data= address_add( image_data, sizeof(int32_t) );

  GLuint  texid= 0;
  glGenTextures( 1, &texid );
  glBindTexture( GL_TEXTURE_2D, texid );

  glCompressedTexImage2D( GL_TEXTURE_2D, 0,
           hp->glInternalFormat,
           hp->pixelWidth,
           hp->pixelHeight,
	   0,
	   image_size,
	   image_data );

  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

  return  texid;
}

上の例はそのまま API に渡しているので、GPU が対応していない圧縮形式の場合
エラーが発生する可能性があります。

厳密には CPU とファイルの endian が一致していないケースを考慮しなければなりません。
ヘッダの endiannness を見て必要に応じて byte swap します。
データ作成環境と実行環境が一致していればあまり問題はないと思います。

KTX の注意点は DDS とデータの並びが異なっていることです。
例えば cubemap の場合、DDS は face 毎に mipmap が並びますが、
KTX は同じ mip level の face が先に来ます。

DDS             KTX
--------------------------
[X+ 32x32]      [X+ 32x32]
[X+ 16x16]      [X- 32x32]
[X+ 8x8]        [Y+ 32x32]
[X+ 4x4]        [Y- 32x32]
[X+ 2x2]        [Z+ 32x32]
[X+ 1x1]        [Z- 32x32]
[X- 32x32]      [X+ 16x16]
[X- 16x16]      [X- 16x16]
[X- 8x8]        [Y+ 16x16]
[X- 4x4]        [Y- 16x16]
[X- 2x2]        [Z+ 16x16]
[X- 1x1]        [Z- 16x16]
[Y+ 32x32]      [X+ 8x8]
[Y+ 16x16]      [X- 8x8]
[Y+ 8x8]        [Y+ 8x8]
[Y+ 4x4]        [Y- 8x8]
[Y+ 2x2]        [Z+ 8x8]
[Y+ 1x1]        [Z- 8x8]
:               :

↑このようにデータの順番が異なっています。
wiki にも追記しましたが、データの入れ子構造の詳細は下記の通りです。

DDS :  ( ( ( ( width * height ) * volume_depth ) * mip ) * cube_face ) * array
KTX :  ( ( ( ( width * height ) * volume_depth ) * cube_face ) * array ) * mip

DDS の利点は、2D のテクスチャを 6 個並べるだけで cubemap ができること。
KTX の利点は同じサイズのサーフェースを出来るだけ一度に並べようとしていることです。

KTX の画像は下記のように 32bit のデータサイズが挿入されます。

int32 imageSize; // 32x32
[X+ 32x32]
[X- 32x32]
[Y+ 32x32]
[Y- 32x32]
[Z+ 32x32]
[Z- 32x32]
int32 imageSize; // 16x16
[X+ 16x16]
[X- 16x16]
[Y+ 16x16]
[Y- 16x16]
[Z+ 16x16]
[Z- 16x16]
int32 imageSize; // 8x8
[X+ 8x8]
[X- 8x8]
[Y+ 8x8]
[Y- 8x8]
[Z+ 8x8]
[Z- 8x8]
int32 imageSize; // 4x4
~

imageSize は 1画像分の byte 数で、同じサイズのサーフェースが
並んでいるためアドレス計算が簡単になります。
glCompressedTexImage2D() にそのまま渡すことができます。
mipmap に対応するとこんな感じです。

GLuint KTX_Loader_Mipmap( const void* memory, size_t memory_size )
{
  const KTX_Header*  hp= reinterpret_cast<const KTX_Header*>( memory );
  const void*        image_data= address_add( memory, sizeof(KTX_Header) + hp->bytesOfKeyValueData );

  GLuint  texid= 0;
  glGenTextures( 1, &texid );
  glBindTexture( GL_TEXTURE_2D, texid );

  unsigned int  mip_level= hp->numberOfMipmapLevels > 0 ? dp->numberOfMipmapLevels : 1;
  unsigned int  width=  hp->pixelWidth;
  unsigned int  height= hp->pixelHeight;

  for( unsigned int mip= 0 ; mip < mip_level ; mip++ ){

    unsigned int   image_size= *reinterpret_cast<const int32_t*>( image_data );
    image_data= address_add( image_data, sizeof(int32_t) );

    glTexImage2D( GL_TEXTURE_2D, mip, hp->glInternalFormat, width, height,
                0, hp->glBaseInternalFormat, hp->glType, image_data );

    width=  int_max( width>>1, 1 );
    height= int_max( height>>1, 1 );
    image_data= address_add( image_data, (image_size+ 3) & ~3 );
  }

  if( mip_level > 1 ){
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
  }else{
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  }
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

  return  texid;
}

これで mip + 圧縮テクスチャ や cubemap への対応も容易にできます。

KTX の一番の問題はデータの作成方法にあるようです。
ツールが絶望的に揃っていない状況で、まだあまり安定もしていません。
ARM の Texture Compression Tool は 64bit 環境でうまく動かず、
PVR の TexTool で ktx に出力すると PVRTC 以外は正しいヘッダ値が入りませんでした。


関連ページ
Texture File Format

関連エントリ
OpenGL / OpenGL ES テクスチャファイルフォーマット KTX と DDS


DXT テクスチャの格納や cubemap, 3D Texture, HDR 形式など、
DDS は非常に便利なファイルフォーマットでした。

ところが DirectX は仕様自体に圧縮テクスチャが含まれているため
DXT,BC 以外のフォーマットが定義されていません。
ATITC や ETC1 など、独自の FourCC で対応しているツールもあります。

同時に PVRTC/PVRTC2、ETC2/EAC や ASTC など、DDS に格納できない
データも増えています。

KTX 形式は OpenGL の値をそのまま格納するので、Extension など
GLenum 値が決まればどんな形式も格納することができます。

今後 PVRTC2, ETC2/EAC, ASTC が出てくることを考えると ktx への
対応をきちんと考えておいた方が良さそうです。

テクスチャのファイルフォーマットについて下記のページにまとめました。
取り敢えず dds, ktx, pvr, pkm の 4 種類。

Texture File Format


関連エントリ
Android OpenGL ES 2.0 の圧縮テクスチャ
Direct3D10 と DDS テクスチャフォーマット
DirectX SDK November 2007 Gather と 新DDS フォーマット


サンコーの Android スティック ANDHDM2S を触る機会がありました。

Androidスティック with DUALCORE

とりあえず dual core であることを確認。
CPU は NEON 使用可能で GPU は PowerVR SGX530 でした。

-------------------
CPU
-------------------
Processor	: ARMv7 Processor rev 2 (v7l)
processor	: 0
BogoMIPS	: 1061.68

processor	: 1
BogoMIPS	: 1064.96

Features	: swp half thumb fastmult vfp edsp neon vfpv3 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x1
CPU part	: 0xc09
CPU revision	: 2

Hardware	: EMXX
Revision	: 0420
Serial		: 0000000000000000


-------------------
GPU
-------------------
GL_VERSION: OpenGL ES 2.0
GL_RENDERER: PowerVR SGX 530
GL_VENDOR: Imagination Technologies
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 1.00

pconst=64 vconst=128 vin=16 vout=8 ptex=8 vtex=8 combotex=8 maxrender=2048 maxtexsize=2048 cubetexsize=2048 viewdims=2048

Extension:
GL_OES_rgb8_rgba8
GL_OES_depth24
GL_OES_vertex_half_float
GL_OES_texture_float
GL_OES_texture_half_float
GL_OES_element_index_uint
GL_OES_mapbuffer
GL_OES_fragment_precision_high
GL_OES_compressed_ETC1_RGB8_texture
GL_OES_EGL_image
GL_OES_required_internalformat
GL_OES_depth_texture
GL_OES_get_program_binary
GL_OES_packed_depth_stencil
GL_OES_standard_derivatives
GL_OES_vertex_array_object
GL_OES_egl_sync
GL_EXT_multi_draw_arrays
GL_EXT_texture_format_BGRA8888
GL_EXT_discard_framebuffer
GL_EXT_shader_texture_lod
GL_IMG_shader_binary
GL_IMG_texture_compression_pvrtc
GL_IMG_texture_stream2
GL_IMG_texture_npot
GL_IMG_texture_format_BGRA8888
GL_IMG_read_format
GL_IMG_program_binary
GL_IMG_multisampled_render_to_texture

adb の usb ドライバは android_winusb.inf の書き換えだけで
つながりました。

%SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_0002
%CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_0002&MI_01


関連ページ
日本で発売された端末全リスト


新しい ASTC 形式で圧縮したテクスチャ画像を比べてみました。
「ETC2 の比較」 と同じ画像をエンコードして一部を切り出し 4倍に拡大しています。

↓ASTC 4x4 (8.0 bpp)
astc_4x4_ex_z0.png astc_4x4_ex_z1.png

↓ASTC 5x4 (6.5 bpp)
astc_5x4_ex_z0.png astc_5x4_ex_z1.png

↓ASTC 5x5 (5.3 bpp)
astc_5x5_ex_z0.png astc_5x5_ex_z1.png

↓ASTC 6x5 (4.4 bpp)
astc_6x5_ex_z0.png astc_6x5_ex_z1.png

↓ASTC 6x6 (3.6 bpp)
astc_6x6_ex_z0.png astc_6x6_ex_z1.png

↓ASTC 8x5 (3.3 bpp)
astc_8x5_ex_z0.png astc_8x5_ex_z1.png

↓ASTC 8x6 (2.7 bpp)
astc_8x6_ex_z0.png astc_8x6_ex_z1.png

↓ASTC 10x5 (2.6 bpp)
astc_10x5_ex_z0.png astc_10x5_ex_z1.png

↓ASTC 10x6 (2.2 bpp)
astc_10x6_ex_z0.png astc_10x6_ex_z1.png

↓ASTC 8x8 (2.0 bpp)
astc_8x8_ex_z0.png astc_8x8_ex_z1.png

↓ASTC 10x8 (1.6 bpp)
astc_10x8_ex_z0.png astc_10x8_ex_z1.png

↓ASTC 10x10 (1.3 bpp)
astc_10x10_ex_z0.png astc_10x10_ex_z1.png

↓ASTC 12x10 (1.1 bpp)
astc_12x10_ex_z0.png astc_12x10_ex_z1.png

↓ASTC 12x12 (0.9 bpp)
astc_12x12_ex_z0.png astc_12x12_ex_z1.png

ASTC 4x4 は画質がよく見えるかもしれませんが当然です。
8bpp なので DXT1/ETC1/ETC2 の半分の圧縮率です。
データサイズも 2倍になっています。

圧縮率を高めると徐々にブロックが目立ちますが、
それなりに階調は保っていることがわかります。
特に右の画像は 12x12 の 0.9bpp でも劣化が目立ちません。

下記の表を見て分かる通り、12x12 の場合わずか 7.6KB しか
ありません。

format       size     (byte)    bpp
--------------------------------------
ASTC 4x4     64.0KB   (65536)   8.0bpp
ASTC 5x4     52.0KB   (53248)   6.5bpp
ASTC 5x5     42.2KB   (43264)   5.3bpp
ASTC 6x5     34.9KB   (35776)   4.4bpp
ASTC 6x6     28.9KB   (29584)   3.6bpp
ASTC 8x5     26.0KB   (26624)   3.3bpp
ASTC 8x6     21.5KB   (22016)   2.7bpp
ASTC 10x5    21.1KB   (21632)   2.6bpp
ASTC 10x6    17.4KB   (17888)   2.2bpp
ASTC 8x8     16.0KB   (16384)   2.0bpp
ASTC 10x8    13.0KB   (13312)   1.6bpp
ASTC 10x10   10.5KB   (10816)   1.3bpp
ASTC 12x10    9.0KB   ( 9152)   1.1bpp
ASTC 12x12    7.6KB   ( 7744)   0.9bpp

ETC1/2 RGB   32.0KB   (32768)   4.0bpp
元画像      192.0KB  (196608)  24.0bpp  (256x256)

使用したコマンド

astcenc src dest 4x4 -exhaustive


関連エントリ
OpenGL 4.3/GLES 3.0 次の圧縮テクスチャ ASTC
OpenGL ES 3.0 / OpenGL 4.3 ETC2 テクスチャ圧縮の比較


DXTC(S3TC)/PVRTC/ETC1/ETC2 など、4x4 block を 64bit 単位で
変換する圧縮テクスチャフォーマットが第一世代なら、
128bit 単位で処理する BC6H/BC7 (BPTC) は第二世代の新しい
圧縮テクスチャフォーマットと言えます。

64bit の枠を超えた余剰 bit を、モード分岐やパーティション分割等
画質を向上させるための様々な情報として用います。

ASTC も同様で、BC6H/BC7(BPTC) と同じように 128bit 単位で圧縮を
行います。その仕組はさらに複雑でより踏み込んだ内容でした。

 ・128bit 単位
 ・複雑なモード分岐
 ・Dual Plane 機能 (Index を 2セット持つ)
 ・Partition 分割 (カラーセット Endpoint を複数持つ)

これらの特徴は BC6H/BC7(BPTC) と共通のものです。
ASTC にはさらに独自の仕様が多数含まれています。

 ・可変 Block サイズ (4x4 ~ 12x12)
 ・最大 4分割 の Partition (BPTC は 3分割まで)
 ・2,3,5 の 3種類の基数選択
 ・1~4 component の自由なフォーマット (R,RG,RGB,RGBA)

Khronos の仕様では LDR モードのみ定義されていますが、
ARM のドキュメントでは 3D texture や HDR まで言及されており
より幅広い用途が想定されていたことがわかります。

KHR_texture_compression_astc_ldr
ARM Mali developer Center: ASTC Evaluation Codec

bit field は非常に自由で、モードと Endpoint (代表カラー値) が
下位 bit から、Index (Texel Weight) が上位 bit から必要個数並ぶという
可変フォーマットです。
そのため組み合わせ数は膨大で単純なモード数では表現できません。

また 2進数からくる制約が少ないのも大きな特徴の一つです。
例えば block サイズも 5x5 , 6x6 , 10x8 など中途半端なサイズを
選ぶことができます。
Index によるカラーの補間も、DXT 等では 2bit なので 4段階ですが、
ASTC では 3値や 5値等の任意の段階を選ぶことができます。

DXT では 2色の代表カラーを選んでも、4階調だとちょうど中間の値を
生成することができません。画像によっては都合が悪く、敢えて
DXT1 の 3色モード (Alpha 1bit) を用いることがありました。

ASTC は 3 と 5 の基数を用いることができます。
5つの 3階調値を 8bit (3^5 = 243) に格納し、同様に 3つの 5階調値を
7bit (5^3 = 125) に収めます。
これに任意ビット数のスケール値を掛けることで、2 の n 乗に制限されず
下記の値の範囲を格納することができます。

 3 (0-2) =  3  + 0bit
 4 (0-3) =       2bit
 5 (0-4) =  5  + 0bit
 6 (0-5) =  3  + 1bit = 3 * 2
 8 (0-7) =       3bit
10 (0-9) =  5  + 1bit = 5 * 2
12 (0-11)=  3  + 2bit = 3 * 4
 :

例えば 12 (0~11) 段階をエンコードするなら 5個単位で格納します。
それぞれが 2bit のスケールを持つので、8bit + 5*2bit = 18bit (5個分)
となります。

このようにより自由なエンコードアルゴリズムを用いつつ、かつハードウエアで
実装しやすいようさまざまな工夫が施されています。


関連エントリ
OpenGL 4.3/ES 3.0 ETC2 Texture 圧縮の仕組み (PVRTC2,ASTC)
Direct3D11/OpenGL 圧縮テクスチャ BPTC, BC6H/BC7 の詳細構造 (2)
Direct3D11/OpenGL 圧縮テクスチャ BPTC, BC6H/BC7 の詳細構造 (1)
OpenGL の圧縮テクスチャ (3) BPTC, BC6H/BC7
OpenGL の圧縮テクスチャ (2) 法線圧縮
Android OpenGL ES 2.0 の圧縮テクスチャ


比べてみました。

↓元 (4倍に拡大したものです)
orig_enc0z.png orig_enc1z.png

↓DXT1 (S3TC)
dxt1b_enc0z.png dxt1b_enc1z.png

↓ETC1 (RGB8)
etc1_enc0z.png etc1_enc1z.png

↓ETC2 (RGB8)
etc2_enc0z.png etc2_enc1z.png

結果はエンコーダーの能力にも依存します。
おそらくもっと良い圧縮ツールもあると思います。
特に DXT (S3TC) はツールが豊富なので、上の例よりも良い結果に
なるかもしれません。


ETC1 しか使えない Mali-400 等の GPU では、今までテクスチャの
圧縮方法が限られていました。

・RGB8 のみで Alpha がない
・4x2 単位で 1色しか選択できない

ひとつは Alpha が使えないなど機能的な問題ですが、もうひとつは
画質の問題です。上の例のように 4x2 の大きなブロックが生じ、
DXT1 よりも著しく劣化するケースがありました。

結果を見ても、ETC2 ではこの問題が解消されていることがわかります。

・Alpha や 1-2 component などバリエーションが豊富
・DXT のように 4x4 単位で 2色使える mode が追加された
・GPU 間で共通のフォーマットとして使える (ようになるはず、将来は)

(注意: 手元に手頃なサンプル画像がなかっただけで、決して法線圧縮に
利用しているわけではありません。)


関連エントリ
OpenGL 4.3/ES 3.0 ETC2 Texture 圧縮の仕組み (PVRTC2,ASTC)


ARM Mali Developer Center で ETC2 に対応した Texture Compression Tool
が公開されています。

Mali GPU Texture Compression Tool v4.0

ところが自分の環境 (Windows 7 x64) では画像変換時にエラーとなり
今まで正しく動いていませんでした。

GUI を使わずにコマンドラインで変換すれば動作することがわかりました。
Program Files の install フォルダ↓にパスを通しておきます。

「 ARM\Mali Developer Tools\Mali Texture Compression Tool v4.0.0\bin 」

etcpack.exe を直接実行します。

etcpack  INPUTFILE.tga  outputdir  -ktx -c etc2 -s slow


これで outputdir に ktx 形式でファイルが作られます。
ktx から ppm への逆変換もできます。

ktx 形式は OpenGL 版の dds のようなものです。
OpenGL の GLenum をそのまま用いるため、どんなフォーマットも格納できます。
詳しくは下記エントリ参照。

Android OpenGL ES 2.0 の圧縮テクスチャ

環境を整えたら実際の変換結果なども比べてみたいと思います。


関連エントリ
OpenGL 4.3/ES 3.0 ETC2 Texture 圧縮の仕組み (PVRTC2,ASTC)
Android OpenGL ES 2.0 の圧縮テクスチャ


OpenGL ES 3.0 の API はおよそ 100 個増えています。
OpenGL ES 2.0 で 150 弱だった命令数が 250 個になりました。
シェーダーと世代の対応は下記の通り。

OpenGL         OpenGL ES        DirectX         ShaderModel
---------------------------------------------------------------
OpenGL 1.x     OpenGL ES 1.x    Direct3D 7      Fixed Pileline
OpenGL 2.x     OpenGL ES 2.0    Direct3D 9      Shader Model 3
OpenGL 3.x     OpenGL ES 3.0    Direct3D 10     Shader Model 4
OpenGL 4.x     --               Direct3D 11     Shader Model 5

OpenGL ES 3.0 は OpenGL 3.x 同様に DirectX10 世代、ShaderModel 4.0 に
相当します。

ハードウエアも API も順当に進化しています。
GPU 毎に機能差は生じますが、下記はそれぞれ最小値の比較です。

                            GLES 2.0   GLES 3.0  (DirectX)
-----------------------------------------------------------------
Vertex Uniform Vectors        128        256     (VSH Constant)
Fragment Uniform Vectors       16        224     (PSH Constant)
Vertex Attribs                  8         16     (VSH Input)
Vertex Output Vectors           8         16     (VSH Output)
Fragment Input Vectors          8         15     (PSH Input)
Draw Buffers                    1          4     (PSH Output,MRT)
Vertex Texture Image Units      0         16     (Vertex Texture)
Texture Image Units             8         16     (Pixel Texture)
Combined Texture Image Units    8         32

Uniform Block (D3D の ConstantBuffer) があるためこのあたりの制限は
さらにゆるくなるはずです。

このあたりを踏まえて wiki もいろいろ更新しました。

Mobile GPU 毎の機能比較表
OpenGL のバージョン表など
テクスチャフォーマットまとめ
Desktop 向け OpenGL ES 2.0 / OpenGL ES 3.0 実行環境

OpenGL ES 3.0 には GeometryShader がありませんが、これは OpenGL 3.0 も
同様でした。
GeometryShader が追加されたのは OpenGL 3.2 からなので、
同じように OpenGL ES にも今後 GeometryShader が追加拡張される
可能性が高いといえます。


関連ページ
OpenGL まとめトップ


OpenGL ES 3.0 は OpenGL ES 2.0 との上位互換性が保たれています。
まだ GL 4.3 の GL_ARB_ES3_compatibility と Mali/Adreno Emulator で
試しているだけですが、OpenGL ES 3.0 上で今までのソースコードも
シェーダーも 2.0 のまま変更なしに動いています。
OpenGL ES 3.0 は OpenGL ES 2.0 の実行環境の一つとして利用できそうです。

OpenGL ES 3.0 対応のため EGL の初期化は若干変更しています。
EGL_CONTEXT_CLIENT_VERSION に 3 を渡しています。
Mali のドキュメントでは EGL_OPENGL_ES3_BIT を使っていますが、
定義が見つからなかったため EGL_OPENGL_ES2_BIT のまま使用しました。

GLSL のシェーダーバージョン対応は下記のとおりです。

                 GLSL     shader 内の指定
-----------------------------------------------------------
OpenGL ES 2.0    1.0      #version 100
OpenGL 2.0       1.1      #version 110
OpenGL 2.1       1.2      #version 120

OpenGL 3.0       1.3      #version 130
OpenGL 3.1       1.4      #version 140
OpenGL 3.2       1.5      #version 150 [core/compatibility]
OpenGL ES 3.0    3.0      #version 300 es
OpenGL 3.3       3.3      #version 330 [core/compatibility]
OpenGL 4.0       4.0      #version 400 [core/compatibility]
OpenGL 4.1       4.1      #version 410 [core/compatibility]
OpenGL 4.2       4.2      #version 420 [core/compatibility]
OpenGL 4.3       4.3      #version 430 [core/compatibility/es]

番号が重なっていないためバージョンの数値だけでもすべて区別可能です。
shader の 1行目に #version が存在しない場合、OpenGL では 1.1 とみなします。
OpenGL ES では 1.0 とみなすことになっています。

バージョン番号の後に profile を指定できるようになったのは 1.5 からです。
OpenGL 4.3 では core, compatibility の他に es も加えられています。
実際に OpenGL 4.3 の context のまま "#version 300 es" を指定しても
コンパイルは通りました。

OpenGL 3.0 以後と以前でシェーダーの書き方が変わります。
OpenGL ES 3.0 も OpenGL 3.x 以降と同じ記述方法になりました。
共存させるために下記のようなヘッダを用いています。

// Vertex Shader
#ifdef GL_ES
# define LOWP       lowp
# define MEDIUMP    mediump
# define HIGHP      highp
precision HIGHP float;
#else
# define LOWP       
# define MEDIUMP    
# define HIGHP      
#endif

#if __VERSION__ < 130
# define IN         attribute
# define OUT        varying
#else
# define IN         in
# define OUT        out
#endif


// Vertex Shader
#ifdef GL_ES
# define LOWP       lowp
# define MEDIUMP    mediump
# define HIGHP      highp	
precision MEDIUMP float;
#else
# define LOWP
# define MEDIUMP
# define HIGHP
#endif

#if __VERSION__ < 130
# define IN     varying
# define        out_FragColor  gl_FragColor
#else
# define IN     in
out vec4        out_FragColor;
#endif

上記以外に texture のサンプリング命令も変わります。


DXT(S3TC/BC) 等、テクスチャ圧縮は基本的に 4x4 pixel 単位で行います。
DXT1~5 (BC1~3) では代表色 2色を RGB565 で格納し、その補間値
3~4 level に対して 2bit の index を持ちます。
これを 4x4 = 16 pixel 分格納します。

代表色 2色   16bit x 2色     = 32bit
Index         2bit x 16pixel = 32bit

16pixel 分の情報が 64bit で収まります。

DXT1(BC1)    64bit    4bpp
RGB565      256bit   16bpp
RGB888      384bit   24bpp

1pixel あたり 2bit の選択しか出来ないので、4x4 block 単位で最大
4種類のカラー値に変換していることになります。
これはその他のテクスチャ圧縮フォーマットでもほぼ同等の制約です。

色変化の差が激しい画像など、4種類のカラー値で表現しきれない場合は
ブロックノイズとして目立つことになります。
これらの欠点を無くするために、後発のフォーマットでは様々な工夫が
行われています。

高画質化のための方針の一つがモード分岐です。
対象とする画像に応じてブロック単位に圧縮アルゴリズムそのものを
変えてしまうわけです。

特に、以前解説した BC6H/BC7 (OpenGL では BPTC) 圧縮フォーマットに
至っては、8または 14 通りものモード分岐が存在しています。
block 分割 mode を含めれば種類はもっと多くなります。

Direct3D11/OpenGL 圧縮テクスチャ BPTC, BC6H/BC7 の詳細構造 (1)
Direct3D11/OpenGL 圧縮テクスチャ BPTC, BC6H/BC7 の詳細構造 (2)

Mobile 系 GPU 、Android 等で使われている ETC1 では、各ブロックをさらに
4x2 のサブブロックに分割します。
各ブロック単位で代表色 1色 + 4段階補間が可能なので、4x4 単位で 8種類の
カラー値を持つことができます。

その代わり色解像度は 4x2 ブロック単位となるため、元画像よりもおよそ
1/8 に低下します。分割方向は block 単位で縦横選べますが、YUV のように
色情報を 4x2 block で共有しているようなものです。

そのため色変化が激しい画像では 4x2block の大きなノイズが生じます。
特にはっきりとした 2色の境界線では ETC1 の劣化が目立ちます。
DXT1 の方がずっと綺麗に出ます。 (2012/08/23追記 実例を載せました)

OpenGL ES 3.0 ではこれらの欠点を克服するために ETC2 が採用されました。


● ETC2 の改善点

(1) ETC1 の block ノイズが出やすいケースを軽減、高画質化
(2) DXT5/3DC-X/3DC-XY (BC3/BC4/BC5) のようなフォーマットバリエーションの追加


(1) 高画質化

ETC1 に対するモード分岐の追加です。
もともとカラー値には 2通りの格納方法がありましたが合計 5 mode 分岐に
増えました。

ETC2 の特徴の一つが ETC1 の上位互換で、bit フォーマットは完全に
互換性があります。
ETC1 の差分 mode のオーバーフローを利用して、存在し得ない bit 並び
になたっときに ETC2 とみなします。

ETC1  444(x4 LV) + 444(x4 LV)      table 3+3 = 30+32= 62bit (4x2 block)
ETC1  555(x4 LV) + diff 333(x4 LV) table 3+3 = 30+32= 62bit (4x2 block)
ETC2  444(x3 LV) + 444             dist  3   = 27+32= 59bit (T-Mode)
ETC2  444(x2 LV) + 444(x2 LV)      dist  3   = 27+32= 59bit (H-Mode)
ETC2  676 + 676 + 676                        = 57bit        (Planar)

ETC1 の上 2つは 4x2 サブブロック分割があり、分割方向を選ぶことができます。
ETC2 の T-Mode/H-Mode はサブブロック分割がありません。
そのため 4x4 block 内で 4値の選択となります。

ETC2 の最後の Planar は 4x4 block で 3色を直に格納します。
index がなく単純なグラデーションのみとなります。
ポリゴンの頂点カラーをグーロー補間するような感じです。

まだ実際に画像で試していませんが、サブブロック分割が無くなったため
斜め線など 2色の境界は表現できるようになっているようです。


(2) フォーマットバリエーションの追加

ETC1 は RGB しか格納できず alpha カラー値が含まれる場合 GPU
固有の圧縮フォーマットを用いる必要がありました。
ETC2 は 単チャンネル圧縮フォーマット EAC との組み合わせで DXT5(BC3)
のような使い方ができます。

ETC2 RGB                 4bpp    DXT1/BC1
ETC2 RGB + Alpha 1bit    4bpp    DXT1/BC1
ETC2 RGB + Alpha EAC     8bpp    DXT5/BC3
EAC                      4bpp    3DC-X/BC4
EAC + EAC                8bpp    3DC-XY/BC5

DXT1 は Alpha 1bit のあり無しを 4x4 block 単位で選ぶことができました。
ETC2 では別フォーマット扱いとなります。
ETC1 互換モードの mode 選択 bit を流用するため ETC1 時に 1 mode 減ります。
EAC は BC4/5 同様 pixel あたり 3bit の情報を持ち、8段階選択できます。
ただしベース値を元に 11bit 相当の補間が可能となっているようです。



●その他の新テクスチャフォーマット

・PVRTC2 (PVRTCII)

ETC2 同様に PVRTC とほぼ互換性を保ちつつ、ほとんど使われることが
なかった bit を利用してモード分岐が追加されています。
4 mode あるようですが詳しい構造はわかりません。
すでにツールがあるので比較できますが、従来苦手だった画像でも良くなっており
かなり画質向上が見込めるようです。


・ASTC

ETC2 とそのバリエーションによって OpenGL ES 3.0 では S3TC(DXT) BC1~5
相当をカバーできるようになりました。
ASTC はさらにその上を狙ったもので、HDR対応などを考えるとおそらく
BC6H/BC7 (BPTC) の対抗フォーマットではないかと思います。

圧縮サイズの単位が 128bit なのも BC6H/BC7 (BPTC) と同じです。

block 圧縮のテクスチャフォーマットの方向性の一つがモード分岐の
増加ですが、ASTC はさらにブロックサイズが可変となりました。

PVRTC の 2bpp mode は、通常 4x4 サイズであるブロックを 8x4 に拡張する
ことで実現しています。8x4 = 32block では index が足りないため、
実質 32pixel で 2色の選択になります。

ASTC では可変 block サイズを汎用化しており、mode 分岐だけでなく
より効率の良い 8bpp 未満の圧縮率も同時に実現しているようです。

後ほどもう少し詳しく調べてみたいと思っています。

(2012/08/23追記 :OpenGL 4.3/GLES 3.0 次の圧縮テクスチャ ASTC)


関連エントリ
Direct3D11/OpenGL 圧縮テクスチャ BPTC, BC6H/BC7 の詳細構造 (2)
Direct3D11/OpenGL 圧縮テクスチャ BPTC, BC6H/BC7 の詳細構造 (1)
OpenGL の圧縮テクスチャ (3) BPTC, BC6H/BC7
OpenGL の圧縮テクスチャ (2) 法線圧縮
Android OpenGL ES 2.0 の圧縮テクスチャ


OpenGL 4.x の GL_ARB_ES2_compatibility を用いる場合 Windows では
WGL との組み合わせになります。

AMD の GPU は OpenGL ES 2.0 driver を提供しており、GL ES2 API を
native に呼び出すことが可能です。
Emulator 系 lib と同じように EGL を利用できるため、互換性を保ちやすくなります。

x64 でも動くので以前から試していますが、より便利な lib (SDK) も提供されていました。

AMD OpenGL ES SDK

2012/08/13現在

GL4            ES2  WGL   x86/x64
GL4.4          ES3  WGL   x86/x64
AMD            ES2  EGL   x86/x64   libEGL/libGLESv2
Angle Project  ES2  EGL   x86/x64   libEGL/libGLESv2
PVR Emu        ES2  EGL   x86/x64   libEGL/libGLESv2
Adreno Emu     ES2  EGL   x86       libEGL/libGLESv2
Adreno Emu     ES3  EGL   x86       libEGL/libGLESv3
Mali Emu       ES2  EGL   x86       libEGL/libGLESv2
Mali Emu       ES3  EGL   x86       libEGL/libGLESv2
Tegra Emu      ES2  EGL   x86       libGLESv20

GL4 ES2/3 と Tegra Emu 以外は ABI が同一なので libEGL/libGLESv2 を
取り替えて使うことができます。


Angle Project の新しいバージョンは GL_ANGLE_depth_texture が
追加されており shadow map も使えるようになりました。

angleproject

Angle を VisualStudio 2010 で x64 向けにビルドすると size_t のキャストで
エラーが出ます。
このエラーは Disable Specific Warnings に 4267 を追加してとりあえず
無視することができます。
Debug 版だと log を出力するため低速です。
利用する場合は必ず Release ビルドにしておきます。


関連エントリ
Desktop の OpenGL ES 2.0 実行環境
GeForce/RADEON で OpenGL ES 2.0 を動かす
OpenGL ES 2.0 Emulator


NVIDIA の beta driver 305.53 で OpenGL 4.3 を試してみました。
以下は GL_ARB_ES3_compatibility を走らせた結果です。
すでに ETC2/EAC が利用可能となっていることがわかります。

GL_VERSION: OpenGL ES 3.0 305.53
GL_RENDERER: GeForce GTX 560 Ti/PCIe/SSE2
GL_VENDOR: NVIDIA Corporation
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 3.00

TextureFormat 23
tc[00]=83f0  GL_COMPRESSED_RGB_S3TC_DXT1_EXT
tc[01]=83f2  GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
tc[02]=83f3  GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
tc[03]=8b90  GL_PALETTE4_RGB8
tc[04]=8b91  GL_PALETTE4_RGBA8
tc[05]=8b92  GL_PALETTE4_R5_G6_B5
tc[06]=8b93  GL_PALETTE4_RGBA4
tc[07]=8b94  GL_PALETTE4_RGB5_A1
tc[08]=8b95  GL_PALETTE8_RGB8
tc[09]=8b96  GL_PALETTE8_RGBA8
tc[10]=8b97  GL_PALETTE8_R5_G6_B5
tc[11]=8b98  GL_PALETTE8_RGBA4
tc[12]=8b99  GL_PALETTE8_RGB5_A1
tc[13]=9274  GL_COMPRESSED_RGB8_ETC2
tc[14]=9275  GL_COMPRESSED_SRGB8_ETC2
tc[15]=9276  GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
tc[16]=9277  GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
tc[17]=9278  GL_COMPRESSED_RGBA8_ETC2_EAC
tc[18]=9279  GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
tc[19]=9270  GL_COMPRESSED_R11_EAC
tc[20]=9271  GL_COMPRESSED_SIGNED_R11_EAC
tc[21]=9272  GL_COMPRESSED_RG11_EAC
tc[22]=9273  GL_COMPRESSED_SIGNED_RG11_EAC

ちなみに 305.53 の OpenGL 4.3 でも ETC2/EAC は有効です。

GL_VERSION: 4.3.0
GL_RENDERER: GeForce GTX 560 Ti/PCIe/SSE2
GL_VENDOR: NVIDIA Corporation
GL_SHADING_LANGUAGE_VERSION: 4.30 NVIDIA via Cg compiler

pconst=2048 vconst=4096 vin=16 vout=124 ptex=32 vtex=32 combotex=192 maxrender=16384 maxtexsize=16384 cubetexsize=16384 viewdims=16384
blocks ver=14 frag=14   blocksize=65536 combined=84
geometry  const=2048 tex=32 block=14  out=1024 outT=1024  comb=231424
tess ctrl const=2048 tex=32 block=14  out=128 outT=4216 in=128 comb=231424
tess eval const=2048 tex=32 block=14  out=128 patch=120 in=128 comb=231424

TextureFormat 23
tc[00]=83f0  GL_COMPRESSED_RGB_S3TC_DXT1_EXT
tc[01]=83f2  GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
tc[02]=83f3  GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
tc[03]=8b90  GL_PALETTE4_RGB8
tc[04]=8b91  GL_PALETTE4_RGBA8
tc[05]=8b92  GL_PALETTE4_R5_G6_B5
tc[06]=8b93  GL_PALETTE4_RGBA4
tc[07]=8b94  GL_PALETTE4_RGB5_A1
tc[08]=8b95  GL_PALETTE8_RGB8
tc[09]=8b96  GL_PALETTE8_RGBA8
tc[10]=8b97  GL_PALETTE8_R5_G6_B5
tc[11]=8b98  GL_PALETTE8_RGBA4
tc[12]=8b99  GL_PALETTE8_RGB5_A1
tc[13]=9274  GL_COMPRESSED_RGB8_ETC2
tc[14]=9275  GL_COMPRESSED_SRGB8_ETC2
tc[15]=9276  GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
tc[16]=9277  GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
tc[17]=9278  GL_COMPRESSED_RGBA8_ETC2_EAC
tc[18]=9279  GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
tc[19]=9270  GL_COMPRESSED_R11_EAC
tc[20]=9271  GL_COMPRESSED_SIGNED_R11_EAC
tc[21]=9272  GL_COMPRESSED_RG11_EAC
tc[22]=9273  GL_COMPRESSED_SIGNED_RG11_EAC

ETC2 は ETC1 と上位互換なので、Desktop GPU でも ETC1 による描画が
可能となります。

ETC1 は 4x2 pixel あたり 1色しか使えませんでしたが、
ETC2 では DXT 同様 4x4 で 2色使えるよう拡張されています。
単純なグラデーション限定ですが独立した 3色の指定も可能です。

EAC との組み合わせでほぼ DXT1/DXT5/3DC の代用が可能なので、
今後は共通の圧縮テクスチャフォーマットとして ETC2 が使われて
いくのかも知れません。

より詳細な extension はこちらに追記しました。

Mobile GPU の OpenGL Extension
Desktop GPU の OpenGL Extension

GLSL の version は、OpenGL と OpenGL ES で見事に重ならないように
なっています。

OpenGL ES 2.0    GLSL ES 1.0     #version 100      (GLSL 1.1+)
OpenGL 2.0       GLSL 1.1        #version 110
OpenGL 2.1       GLSL 1.2        #version 120
OpenGL 3.0       GLSL 1.3        #version 130
OpenGL 3.1       GLSL 1.4        #version 140
OpenGL 3.2       GLSL 1.5        #version 150
OpenGL ES 3.0    GLSL ES 3.0     #version 300 es   (GLSL 3.3-)
OpenGL 3.3       GLSL 3.3        #version 330
OpenGL 4.0       GLSL 4.0        #version 400
OpenGL 4.1       GLSL 4.1        #version 410
OpenGL 4.2       GLSL 4.2        #version 420
OpenGL 4.3       GLSL 4.3        #version 430

OpenGL ES 3.0 Emulator も出ています。

Mali Developer Center: OpenGL ES 3.0 Emulator
QDevNet : Mobile Gaming & Graphics Optimization (Adreno™)


GL_VERSION: OpenGL ES 3.0
GL_RENDERER: OpenGL ES Emulator Revision r2p0-00rel0
GL_VENDOR: ARM Ltd.
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 3.00

pconst=512 vconst=1024 vin=16 vout=31 ptex=32 vtex=32 combotex=192 maxrender=16384 maxtexsize=16384 cubetexsize=16384 viewdims=16384

TextureFormat 10
tc[00]=9270  GL_COMPRESSED_R11_EAC
tc[01]=9272  GL_COMPRESSED_RG11_EAC
tc[02]=9274  GL_COMPRESSED_RGB8_ETC2
tc[03]=9276  GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
tc[04]=9278  GL_COMPRESSED_RGBA8_ETC2_EAC
tc[05]=9271  GL_COMPRESSED_SIGNED_R11_EAC
tc[06]=9273  GL_COMPRESSED_SIGNED_RG11_EAC
tc[07]=9279  GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
tc[08]=9277  GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
tc[09]=9275  GL_COMPRESSED_SRGB8_ETC2

Adreno は ETC2 がありませんでした。

GL_VERSION: OpenGL ES 3.0 Confetti Special Effects Build 01
GL_RENDERER: Qualcomm OpenGL ES 3.0 Emulator
GL_VENDOR: Qualcomm
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL 3.00

pconst=224 vconst=256 vin=15 vout=8 ptex=8 vtex=1 combotex=9 maxrender=2048 maxtexsize=1024 cubetexsize=1024 viewdims=2048

TextureFormat 16
tc[00]=8c92  GL_ATC_RGB_AMD
tc[01]=8c93  GL_ATC_RGBA_EXPLICIT_ALPHA_AMD
tc[02]=87ee  GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD
tc[03]=87f9  GL_3DC_X_AMD
tc[04]=87fa  GL_3DC_XY_AMD
tc[05]=8d64  GL_ETC1_RGB8_OES
tc[06]=8b90  GL_PALETTE4_RGB8
tc[07]=8b91  GL_PALETTE4_RGBA8
tc[08]=8b92  GL_PALETTE4_R5_G6_B5
tc[09]=8b93  GL_PALETTE4_RGBA4
tc[10]=8b94  GL_PALETTE4_RGB5_A1
tc[11]=8b95  GL_PALETTE8_RGB8
tc[12]=8b96  GL_PALETTE8_RGBA8
tc[13]=8b97  GL_PALETTE8_R5_G6_B5
tc[14]=8b98  GL_PALETTE8_RGBA4
tc[15]=8b99  GL_PALETTE8_RGB5_A1