Desktop GPU と OpenGL ES 3.1 API

OpenGL ES は Mobile 等で用いられる API ですが、Desktop 向け OpenGL にも
積極的に取り込まれており互換性が保たれるようになってきました。
OpenGL 4.5 では GL_ARB_ES3_1_compatibility をサポートし、
OpenGL ES 3.1 API としても使うことができます。

2015/06/25 現在 Windows での対応状況 (beta driver 含む)

Windows           Desktop API   Mobile API
-------------------------------------------------------------
GeForce           OpenGL 4.5    OpenGL ES 3.1 AEP
RADEON            OpenGL 4.5    OpenGL ES 3.1
Intel 4000 (Gen7) OpenGL 4.0    OpenGL ES 3.1    IvyBridge世代
Intel 4600 (7.5)  OpenGL 4.3    OpenGL ES 3.1    Haswell世代

Intel と GeForce は OpenGL ES 3.1 Context を作り直す必要があります。
RADEON の場合は OpenGL 4.5 Context のまま使用します。
Desktop GPU 上で OpenGL ES を使う方法については下記にまとめています。

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

Intel HD Graphics (D3D11世代) は OpenGL 4.5 に対応していませんが、
新しいドライバでは OpenGL ES 3.1 に対応しています。
具体的には Ivy Bridge 世代の Intel HD Graphics 4000/2500 以降で、
BayTrail の HD Graphics も含まれます。

Intel HD Graphics 4000 (Ivy Bridge) Windows 8.1 x64

GL_VERSION: OpenGL ES 3.1 - Build 10.18.10.4226
GL_RENDERER: Intel(R) HD Graphics 4000
GL_VENDOR: Intel
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 3.1 - Build 10.18.10.4226

Intel HD Graphics (BayTrail-T Atom Z3740) Windows 10 x86

GL_VERSION: OpenGL ES 3.1 - Build 10.18.10.3993
GL_RENDERER: Intel(R) HD Graphics
GL_VENDOR: Intel
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 3.1 - Build 10.18.10.3993

Intel HD Graphics 4600 (Haswell) Windows 10 x64

GL_VERSION: OpenGL ES 3.1 - Build 10.18.15.4235
GL_RENDERER: Intel(R) HD Graphics 4600
GL_VENDOR: Intel
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 3.10 - Build 10.18.15.4235

GeForce のように GL_ANDROID_extension_pack_es31a (AEP) はありませんが、
Tessellator/GeometryShader など一部の機能は独自に対応が行われているようです。
OpenGL ES 3.1 context には下記の extension が含まれていることがわかります。

GL_INTEL_tessellation
GL_INTEL_geometry_shader

Intel Developer Zone : Tessellation for OpenGL ES 3.1 on Android

GeForce は OpenGL ES 3.1 context で AEP をサポートしています。
ただし GPU によっては、AEP で必要な一部機能 (ASTC Texture) がソフトウエアで
エミュレーションされているようです。
NVIDIA は Mobile 向けに GLES Emulator Library をリリースしていないので
それを兼ねているのかもしれません。

RADEON は OpenGL 4.x そのままなので特に機能制限ありません。
よっていずれも GLES API ながら OpenGL 4.x 相当の機能が使えることになります。

GPU ごとの詳細は下記に載せています。
それぞれ可能な範囲で OpenGL ES 3.1 context の結果も含めました。

Desktop GPU Extensions

関連エントリ
Android 5.x OpenGL ES 3.1 と対応 GPU
Galaxy S6 Mali-T760 は AEP 非搭載ながら ASTC HDR 対応
GeForce の OpenGL 4.5 ES3_1_Compatibility は AEP 対応
Android Nexus 6 Adreno 420 も OpenGL ES 3.1 AEP 対応 (Direct3D 11相当)
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 対応
OpenGL ES 3.1 は OpenGL 4.x 相当で ComputeShader に対応

Desktop GPU と OpenGL ES 3.1 API」への5件のフィードバック

  1. かみやん

    かみやんです。BLOG更新されるたびに読ませていただいています。相変わらずエントリと関係ないことなのですが、
    最近、Android端末でトラブルがありました。FBOにbindしたtextureに対して、glTexImage2D()を行うと一部の機種で真っ白になったり全面透明になるという問題です。
    発生した機種は、Galaxy S6、Galaxy Tab 3 7.0、Galaxy Note 4、Nexus 6(OS5.1)、Galaxy Ch@t、8 Apollo、Asus MeMo Pad 7などのIntel HD系、、Covia FLEAZ F5 CP-F50aK、Galaxy Trend Plus、LGV32など。
    iOS系は問題が起きていないし、Androidも多くの機種は問題ないです。
    FBOになっているとGPU側からの書き込みとglTexImage2D()のCPU側からの書き込みで衝突する可能性があるので対応していないのかなとも思いますが、OpenGLの仕様としてNGとなっているのでしょうか。
    回避方法なのですが、FBOをunbindしてFBOを破棄しても一度でもFBOにbindしたtextureは症状が改善されなかったため仕方なくテンポラリのtextureを作成しそちらにglTexImage2D()でCPUメモリから転送し、そのテクスチャのFBOにbindした目的のtextureに描画することでとりあえず回避しました。
    なにかもうちょっとマシな方法はないのかな。と。
    ちなみにOpenGL ES2.0ベースで作っています。

  2. oga 投稿作成者

    動的なバッファに初期値を転送するということでしょうか。
    あまりやらない使い方なので、ほとんどテストされていないのかもしれません。
    動的なバッファ (GPU Buffer) への転送はレンダリングが一番確実だと思います。
    また API によっては Dynamic なバッファへの初期値の転送が禁じられているものもあります。
    それとも初期値ではなく、バッファに対して頻繁に画像の更新を行うような使い方でしょうか。
    glTexImage2D ではなく glTexSubImage2D ではどうでしょうか。
    D3D でも GPU Buffer へは CPU から直接転送できないので、頻繁な update でもやはり一旦別のバッファを経由した方が安全でしょう。

    まとめると使い方に問題があるように感じました。
    FBO への転送は
    ・初期値の転送 (最初一度だけ)
    ・描画中にバッファを更新する
    のどちらでしょうか。

  3. かみやん

    ありがとうございます。
    問題になったのは、初期値ではなくバッファに対して頻繁に画像の更新を行うような使い方です。
    glTexImage2D()もglTexSubImage2D()もどちらもダメでした。
    なお初期値の転送は、glTexImage2D()で転送した後に、FBOにbindするので問題ありませんでした。
    ibisPaintというお絵かきアプリを作っているので、GPUで描けることはそれで行うのですが一部の機能はCPUでラスター計算をしていまして、GPUメモリ<–>CPUメモリ間を往復しています。
    確かにゲーム等であればあまりやらないかもしれないですね。

  4. oga 投稿作成者

    バッファの動的な更新ですね。
    GPU Memory である RenderTarget を GPU 以外が更新するのはやはり問題があるように思います。
    D3D だとリソース管理が厳密でおそらくエラーになります。
    回避方法にあったように、別のテクスチャに転送した後 GPU がレンダリングを行うのが正しいやり方でしょう。
    また TexImage2D はメモリアロケート命令なので、更新なら glTexSubImage2D の方が良いです。

  5. かみやん

    ありがとうございます。
    回避方法の方法が正しいのですね。
    あ、glTexImage2D()はアロケート、更新はglTexSubImage2D()。すっかり忘れていました。以前にもハマったことがある気が。
    ありがとうございました。

コメントは停止中です。