D3D Shader/OpenGL」カテゴリーアーカイブ

Direct3D 12 と ASTC 圧縮 Texture

オプション扱いですが Direct3D12/Direct3D11.3 では新たに
ASTC 圧縮テクスチャがサポートされています。
ASTC は OpenGL ES 3.0 で導入された新しい圧縮形式です。
DirectX では BC 系以外では初であり、モバイルからの逆輸入になります。

MSDN DXGI_FORMAT

これで dds ファイルに ASTC 画像を格納できるようになりました。
下記ページの一覧表に DXGI_FORMAT_ASTC_* を追加しています。

圧縮 Texture

ASTC について以前の解説

OpenGL 4.3/GLES 3.0 次の圧縮テクスチャ ASTC

● 64bit 単位の圧縮

圧縮テクスチャの多くは 4×4 block 単位で 64bit に圧縮します。
例えば下記のフォーマットは 64bit です。

DXT1(BC1), ETC1, ETC2(RGB), ATITC(RGB), PVRTC 4bpp, PVRTC2 4bpp

64 bit/16 pixel なので 1pixel あたり 4bit (4bpp)。

DXT3/5 (BC2/3) や ETC2-EAC などアルファ付きフォーマットは 128bit 8bpp ですが、
内部的には 64bit/block の構造が 2個並んでいるだけです。
処理の単位はあくまで 64bit になります。

DXT1 (BC1)
+-----------+
|COLOR 64bit|
+-----------+

DXT3 (BC2)   DXT1 + A4
+-----------+ +-----------+
|COLOR 64bit| |ALPHA 64bit|
+-----------+ +-----------+

DXT5 (BC3)   DXT1 + BC4
+-----------+ +-----------+
|COLOR 64bit| |ALPHA 64bit|
+-----------+ +-----------+


ETC2
+-----------+
|COLOR 64bit|
+-----------+

EAC (EAC-R11)
+-----------+
|RED   64bit|
+-----------+

ETC2-EAC     ETC2 + EAC
+-----------+ +-----------+
|COLOR 64bit| |ALPHA 64bit|
+-----------+ +-----------+

EAC_RG11     EAC + EAC
+-----------+ +-----------+
|RED   64bit| |GREEN 64bit|
+-----------+ +-----------+

● 128bit 単位の圧縮フォーマット

64bit/block を第一世代とすれば、BC6H/BC7 は 128bit/block の第二世代の
圧縮テクスチャに相当します。

64bit では 16個の index 値がエンコードスペース大半を占めるので
あまり複雑なアルゴリズムを選ぶことができませんでした。
追加の圧縮情報が増えるとベースカラー (Endpoint) の bit を減らすしかないので
カラー精度と圧縮アルゴリズムのどちらを取るかトレードオフになります。

128bit/block ならスペースに余裕があるためフォーマットの自由度が増します。
BC6H/BC7 はこの追加容量を、HDR 対応化や高画質化に割り当てています。
8~14 種類のアルゴリズム選択、Partition 分割による複数の Endpoint セットなど
より複雑なエンコードが行われています。

画質が向上する反面 BC6H/BC7 は容量が増えます。
単純な RGB カラーでは DXT1 の 2倍なので、圧縮率を優先する場合は BC7 は
あまり出番が無いかもしれません。

● 圧縮率とブロックサイズ

block あたりの容量を減らさなくても、block サイズを増やせば圧縮率が上がります。
その代表例が PVRTC/PVRTC2 の 2bpp フォーマットです。

PVRTC は 64bit/block ですが、block サイズを 8×4 に広げることで 2bpp まで
圧縮することができます。
ただしこの場合 index 数が増えるためピクセルの階調が減ります。
index は 8×4 = 32個必要なので 1pixel あたり 1bit になるためです。

● ASTC

ASTC は 128bit/block の第二世代に属し、128bit エリアをフルに使った
複雑なエンコードを行います。
しかしながら block サイズを可変にすることで、同時に高い圧縮率も実現しています。

4×4 block の場合は BC6H/BC7 同様 8bpp ですが、
6×6 block ではおよそ 3.6bpp、
8×8 block では 2bpp と
目的に合わせて圧縮率を選ぶことができます。
もちろん圧縮率を上げると画質はそれなりに下がります。

OpenGL ES 3.0 / OpenGL 4.3 ASTC 圧縮テクスチャの比較

ASTC の注意点は、これまで絶対安全だった 256×256 や 512×512 といった
2^n サイズのテクスチャが必ずしも割り切れないことです。
例えば ASTC 6×6 の場合、 256×256 サイズのテクスチャも内部的には
258×258 でデータを持つことになります。

テクスチャローダーでは注意が必要です。
bpp が割り切れる整数値にならないことと、テクスチャサイズで端数が生じることから
ASTC 対応のためにいくつかの手直しが必要になるかもしれません。

関連ページ
HYPERでんち: 圧縮 Texture 一覧
HYPERでんち: 解説記事一覧

関連エントリ
iPad Air 2 (Apple A8X) の GPU
OpenGL ES 3.0 / OpenGL 4.3 ASTC 圧縮テクスチャの比較
OpenGL 4.3/GLES 3.0 次の圧縮テクスチャ ASTC
Direct3D11/OpenGL 圧縮テクスチャ BPTC, BC6H/BC7 の詳細構造 (2)

GeForce の OpenGL 4.5 ES3_1_Compatibility は AEP 対応

OpenGL 4.5 から GL_ARB_ES3_1_compatibility が含まれるようになりました。
Mobile 向け API OpenGL ES 3.1 と互換性があります。

OpenGL 4.1    GL_ARB_ES2_compatibility
OpenGL 4.3    GL_ARB_ES3_compatibility
OpenGL 4.5    GL_ARB_ES3_1_compatibility

実際に GeForce GTX 650 (GK107 Kepler) で OpenGL ES 3.1 context を作成したのが
下記の結果です。

GL_VERSION: OpenGL ES 3.1 NVIDIA 347.09
GL_RENDERER: GeForce GTX 650/PCIe/SSE2
GL_VENDOR: NVIDIA Corporation
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 3.10

Extension:
GL_NV_internalformat_sample_query
GL_EXT_base_instance
~
GL_OES_vertex_half_float
GL_ANDROID_extension_pack_es31a

Extension として GL_ANDROID_extension_pack_es31a が含まれており、
OpenGL ES 3.1 AEP に対応していることがわかります。
つまり Android 向け Tegra K1 同様に OpenGL ES API でも D3D11 相当の機能を
利用することができるわけです。

省略部分を含めてより詳しい結果は下記のページに追加しました。

Desktop GPU Extensions

下記には Tegra K1 (Kepler) のデータを載せていますので、比べてみると
Tegra K1 と GeForce GTX 650 の結果ほとんど同じであることがわかります。

CPU/GPU OpenGL ES Extension (Mobile GPU)

同じ GPU Core かつドライバもおそらく同一なのでしょう。
Android で動くなら Linux も同様で、共通化されているものと思われます。
実際に OpenGL ES 3.1 context を作成することができました。

// Windows WGL
static const int  opengl_es31[]= {
  WGL_CONTEXT_MAJOR_VERSION_ARB,   3,
  WGL_CONTEXT_MINOR_VERSION_ARB,   1,
  WGL_CONTEXT_FLAGS_ARB,           0,
  WGL_CONTEXT_PROFILE_MASK_ARB,    WGL_CONTEXT_ES2_PROFILE_BIT_EXT,
  0,
};
HGLRC hglrc= wglCreateContextAttribsARB( hDC, 0, opengl_es31 );
// X11 GLX
static const int  opengl_es31[]= {
  GLX_CONTEXT_MAJOR_VERSION_ARB,   3,
  GLX_CONTEXT_MINOR_VERSION_ARB,   1,
  GLX_CONTEXT_FLAGS_ARB,           0,
  GLX_CONTEXT_PROFILE_MASK_ARB,    GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
  None,
};
GLXContext context= glXCreateContextAttribsARB( display, config, 0, True, opengl_es31 );

上では Version 3.1 を指定していますが、Android と同じく ES 2.0 の Context に
対しても 3.1 を返すようです。
この手順は下記のページにも追加しました。

Desktop 向け OpenGL ES 2.0 / OpenGL ES 3.0 / OpenGL ES 3.1 (AEP) 実行環境

Desktop でも Kepler 世代 GeForce を載せているならそもそも同じ GPU なので、
以前の Emulator のようなツールに頼る必要がないわけです。
逆に Mobile GPU で OpenGL ES を使う意味も無くなりつつあります。
↓ NVIDIA SHILED Tablet では OpenGL 4.5 に対応したことが発表されています。

Impress NVIDIA、SHIELDタブレット用Android 5.0.1アップデートを配信開始

ハイエンド向け API はそろそろ統合してもよいのかもしれません。

関連エントリ
Android Nexus 6 Adreno 420 も OpenGL ES 3.1 AEP 対応 (Direct3D 11相当)
Android 5.0 Nexus 10 Mali-T604 は OpenGL ES 3.1 対応
Nexus 9 Tegra K1 と ARM 64bit Denver
NVIDIA SHIELD Tablet Tegra K1 は OpenGL ES 3.1 で Extension Pack 対応
OpenGL ES 3.1 は OpenGL 4.x 相当で ComputeShader に対応
OpenGL 4.3 と GL_ARB_ES3_compatibility

Android Wear 5.0 Watch Face API 対応と互換性

Android Wear 5.0 の新しい Witch Face API に載せ替えました。

3D imclock for Android Wear
Google play

Activity ではなく Service を使用しています。LiveWallpaper と同じです。
OpenGL 初期化や描画タイミング ( onTimeTick() ) の管理もほぼお任せで、
System UI, Card のレイアウトなどの設定も可能。
新しい API を使用したことで全体的にバッテリー消費量も減りました。

対応する描画モードは 4種類あります。

Interactive mode  通常の描画、秒針などアニメーション付き
Ambient mode      スリープ状態、1分に一度の描画更新
Protect mode      Ambient mode 時に描画面積を最小に
LowBit mode       Ambient mode 時に白黒 2階調

Protect/LowBit が有効かどうかはデバイス依存で onPropertiesChanged() によって判定します。

// G2WatchService.java
@Override
public void onPropertiesChanged( Bundle properties )
{
    super.onPropertiesChanged( properties );
    boolean protect= properties.getBoolean( PROPERTY_BURN_IN_PROTECTION, false );
    boolean lowbit=  properties.getBoolean( PROPERTY_LOW_BIT_AMBIENT, false );
    ~
}

OpenGL で直接描画しているため、画面形状への対応も自前で行う必要があります。
丸型かどうかの区別は onApplyWindowInsets() で行います。

// G2WatchService.java
@Override
public void onApplyWindowInsets( WindowInsets insets )
{
    super.onApplyWindowInsets( insets );
    boolean round_style= insets.isRound();
    ~
}

Watch Face 以外のアプリでは自分で Listener を登録できます。

// GAScreen.java
public class GAScreenView extends GLSurfaceView
          implements View.OnApplyWindowInsetsListener {
    public GAScreenView( Context context ) {
        super( context );
	setOnApplyWindowInsetsListener( this );
    }
    ~
}

Gles2WatchFaceService を使うと簡単に描画できる反面、EGL 初期化は
内部で行われており、任意の GLES Context を選べないなどいくつか制限も出てきます。

im-clock でもいくつか問題が生じていたので、LiveWallpaper のように
GLSurfaceView を使った方法も試しました。
最終的にはデバイス互換性を維持するのが難しくて断念。
結局 Gles2WatchFaceService を使い MSAA は自前で処理しています。

ChiRaKS for Android Wear では Moto 360 で画面が 90度回転してしまうとの報告を
かなり多数いただきました。
原因は Android 版で指定していた screenOrientation=”portrait” が残っていたこと。
Moto 360 だけ画面が landscape 扱いとなっているようです。
ちなみに画面だけでなく使用している SoC も Moto 360 だけ異なります。

Device         SoC             GPU             CPU
--------------------------------------------------------------------
Moto 360       TI OMAP3630     PowerVR SGX530  Cortex-A8
LG G Watch 他  Snapdragon 400  Adreno 305      Cortex-A7 (1~4 core)

より詳しいスペック比較表は下記よりどうぞ

Smart Watch のスペック比較

Device             Display              Viewport
-----------------------------------------------------------
Moto 360           320x290 Landscape    (0,-30,320,320)
LG G Watch W100    280x280 Portrait     (0,0,280,280)
Galaxy Gear Live   320x320 Portrait     (0,0,320,320)
LG G Watch R W110  320x320 Portrait     (0,0,320,320)
SmartWatch SWR50   320x320 Portrait     (0,0,320,320)
ZenWatch WI500Q    320x320 Portrait     (0,0,320,320)

上記のように Moto 360 だけ 320×290 と画面が横長です。
ただしアプリケーションからは他のデバイス同様 320×320 の正方形画面に見えます。

OpenGL ES の場合どうやらデフォルトで設定されている Viewport でハードの違いを
吸収しているようです。
OpenGL は左下原点なので y に -30 のオフセットが入っています。
これを知らずに自分で Viewport を設定し (0,0,width,height) で上書きしていたため、
Moto 360 で動かした場合だけ描画が上に 30pix ずれていたことが後から判明しました。
互換性の対処のためにも日本で発売して欲しいデバイスです。

関連エントリ
Android Wear Sony SmartWatch 3 SWR50 は速い
Android Wear 3D のアナログ時計 (Watch Face)
Android Wear にゲームを移植

Android Nexus 6 Adreno 420 も OpenGL ES 3.1 AEP 対応 (Direct3D 11相当)

Nexus 6 の GPU Adreno 420 は OpenGL ES 3.1 AEP (Android Extension Pack)
に対応していることがわかりました。

OpenGL ES 3.1 は ComputeShader に対応しています。
OpenGL ES 3.1 AEP ではさらに Tessellator (HullShader/DomainShader,TCS/TES) や
GeometryShader など Direct3D 11 相当の機能が加わります。

これまでに判明した OpenGL ES 3.0 以上対応の GPU

                SoC               GPU           OpenGL
------------------------------------------------------------------
Kindle Fire HD6 MediaTek MT8135   PowerVR G6430 OpenGL ES 3.0
iPhone/iPad     Apple A7/A8       PowerVR G6430 OpenGL ES 3.0
MeMO Pad ME176  BayTrail-T Z3745  HD Graphics   OpenGL ES 3.0
LG G Watch W100 Snapdragon 400    Adreno 305    OpenGL ES 3.0
Nexus 7(2013)   Snapdragon S4 Pro Adreno 320    OpenGL ES 3.0
Nexus 5         Snapdragon 800    Adreno 330    OpenGL ES 3.0

Nexus 10        Exynos 5 Dual     Mali-T604     OpenGL ES 3.1

Nexus 6         Snapdragon 805    Adreno 420    OpenGL ES 3.1 AEP
Nexus 9         NVIDIA Tegra K1   Kepler(192)   OpenGL ES 3.1 AEP

Nexus 9 の Tegra K1 に続き、新型 Nexus はどちらも AEP に対応していることになります。

以下 Nexus 6 Snapdargon 805 APQ8084 の GL Extension

Extension:
GL_EXT_debug_marker
GL_OES_EGL_image
GL_OES_EGL_image_external
GL_OES_EGL_sync
GL_OES_vertex_half_float
GL_OES_framebuffer_object
GL_OES_rgb8_rgba8
GL_OES_compressed_ETC1_RGB8_texture
GL_AMD_compressed_ATC_texture
GL_KHR_texture_compression_astc_ldr
GL_OES_texture_npot
GL_EXT_texture_filter_anisotropic
GL_EXT_texture_format_BGRA8888
GL_OES_texture_3D
GL_EXT_color_buffer_float
GL_EXT_color_buffer_half_float
GL_QCOM_alpha_test
GL_OES_depth24
GL_OES_packed_depth_stencil
GL_OES_depth_texture
GL_OES_depth_texture_cube_map
GL_EXT_sRGB
GL_OES_texture_float
GL_OES_texture_float_linear
GL_OES_texture_half_float
GL_OES_texture_half_float_linear
GL_EXT_texture_type_2_10_10_10_REV
GL_EXT_texture_sRGB_decode
GL_OES_element_index_uint
GL_EXT_copy_image
GL_EXT_geometry_shader
GL_EXT_tessellation_shader
GL_OES_texture_stencil8
GL_EXT_shader_io_blocks
GL_OES_shader_image_atomic
GL_OES_sample_variables
GL_EXT_texture_border_clamp
GL_EXT_multisampled_render_to_texture
GL_OES_shader_multisample_interpolation
GL_EXT_draw_buffers_indexed
GL_EXT_gpu_shader5
GL_EXT_robustness
GL_EXT_texture_buffer
GL_OES_texture_storage_multisample_2d_array
GL_OES_sample_shading
GL_OES_get_program_binary
GL_EXT_debug_label
GL_KHR_blend_equation_advanced
GL_KHR_blend_equation_advanced_coherent
GL_QCOM_tiled_rendering
GL_ANDROID_extension_pack_es31a
GL_EXT_primitive_bounding_box
GL_OES_standard_derivatives
GL_OES_vertex_array_object
GL_KHR_debug

関連エントリ
Android 5.0 Nexus 10 Mali-T604 は OpenGL ES 3.1 対応
(Kindle) Fire HD 6 は OpenGL ES 3.0 対応で非対称 4 core CPU
iPad Air 2 (Apple A8X) の GPU
NVIDIA SHIELD Tablet Tegra K1 は OpenGL ES 3.1 で Extension Pack 対応
Extension で記事検索