Coral Edge TPU Dev Board の OpenGLES 環境を整える


1. 概要

 Coral EdgeTPU Devboard を入手したので、さっそく、前回記事:PosenetをOpenGLESで可視化 を試そうと思っているのですが、前準備として、Coral Edge TPU Devboard で OpenGLES を使うための環境構築手順 をまとめておきます。

 (注)本記事は、Coral EdgeTPU Devboard に関する話ですが、EdgeTPUエンジンを使った推論や、Posenetを動かす話には触れません。純粋に OpenGLES の話です。Devboard上でTeapotを描画するまでが目標です。

 Edge TPU を使い倒すための Devboard なので、わざわざ OpenGLES でGPUを叩くような方は少数派かもしれませんが、
  ・EdgeTPU の認識結果を様々な表現方法で 快速に可視化 できる
  ・TensorFlow Lite の GPU Delegate を使えば、EdgeTPU vs GPU のガチンコ性能比較 できるかも
という将来性があると信じて作業しました。

2. 前提

 アプリのビルドは、Coral Edge TPU Devboard 上で、ネイティブビルドします。
 NXP の i.MX8M Quad のドキュメントを漁ってみたものの、ホストPC上でクロスビルド環境を立ち上げるための確固たる情報源が見つけられなかったからです。

#本記事は 2019/8/31 に書いていますが、いずれ Devboard 用ファームウェアや、ソフト開発用ドキュメントが整備されると、もっとスマートなやり方が出てくるかもしれません。

3. OpenGLES を使ったアプリをビルドために必要なこと

 Edge TPU Devboard では、ウィンドウマネージャとして、X11 ではなく、Wayland/Weston が動いているようです。Wayland環境でウィンドウ表示するには、アプリビルド時に wayland-egl で OpenGLES を初期化する必要があります。

 OpenGLES や wayland 関連ランタイムライブラリは、EdgeTPU Devboard のファームウェアに書き込まれているようです。が、ビルドに必要なヘッダファイルはファームウェア内に含まれていないようなので、何とかして調達しないといけません。

[Coral Edge TPU Devboard]
mendel@green-rabbit:~$ cd /
mendel@green-rabbit:/$ sudo find . -name *GLES*
./usr/lib/aarch64-linux-gnu/libGLESv2.so.2.0.0
./usr/lib/aarch64-linux-gnu/libGLESv2.so.2
./usr/lib/vivante/libGLESv1_CL.so.1
./usr/lib/vivante/libGLESv1_CM.so.1
./usr/lib/vivante/libGLESv2.so
./usr/lib/vivante/libGLESv1_CL.so
./usr/lib/vivante/libGLESv1_CM.so
./usr/lib/vivante/libGLESv2.so.2

3.1 OpenGLES 関連ヘッダファイルの調達

 本来なら、OpenGLES のヘッダファイルは、SoCベンダやGPUベンダからランタイムライブラリとセットで取得するのが正しい形だと思います。(GPUベンダごとの独自拡張な情報を含んでいるので)

 が、今回、(1) ボードベンダ Coral、(2) SoCベンダ NXP, (3) GPUベンダ Vivante の3者の Web サイトをみても情報がみつけることができませんでした。

 仕方がないので、エイヤで下記コマンドでヘッダファイルの入手を行うことにしました。
 ひょっとすると、Vivante GPU が持っている OpenGLES 拡張機能が一部使えなくなる可能性があるかもしれませんが、OpenGLES 標準機能を使う分にはこれで十分だと考えたからです。

[Coral Edge TPU Devboard]
mendel@green-rabbit:~$ sudo apt install libgles2-mesa-dev 

4. 結果

 若干の不安はありましたが、上記の環境で、Edge TPU Devboard 上で OpenGLES アプリをビルドして動かすことができました。

[Edge TPU Devboard]
mendel@green-rabbit:~$ cd tflite_gles_app/gl2teapot
mendel@green-rabbit:~/tflite_gles_app/gl2teapot$ make TARGET_ENV=edgetpu_devboard
mendel@green-rabbit:~/tflite_gles_app/gl2teapot$ ./gl2teapot

ちゃんと 60fps 出ていますが、ときどきコマ落ちしているようです。
他に忙しい仕事もないはずなので、コマ落ちせず 60fps でしっかり動いてほしいですが、CPUやGPUが省エネモードに落ちたりしてるのかなぁ。(謎)

5. OpenGLES 参考情報

 OpenGLES のコンフィグ情報を query すると下記の通りでした。
 GL_RENDERERVivante GC7000L になっているので、ちゃんとGPUを使って描画できている (CPUによるソフトレンダラじゃない) ことが確認できました。
 また、GL_VERSIONOpenGL ES 3.1 V6.2.4.p2.163672 となっているので、TensorFlow Lite GPU Delegate に必要な要件は満たしていそうです。いずれ試そうと思います。

============================================
    EGL INFO
============================================
EGL_CLIENT_APIS : OpenGL_ES OpenVG
EGL_VENDOR      : Vivante Corporation
EGL_VERSION     : 1.5
EGL_EXTENSIONS  :
                  EGL_KHR_fence_sync
                  EGL_KHR_reusable_sync
                  EGL_KHR_wait_sync
                  EGL_KHR_image
                  EGL_KHR_image_base
                  EGL_KHR_image_pixmap
                  EGL_KHR_gl_texture_2D_image
                  EGL_KHR_gl_texture_cubemap_image
                  EGL_KHR_gl_renderbuffer_image
                  EGL_EXT_image_dma_buf_import
                  EGL_EXT_image_dma_buf_import_modifiers
                  EGL_KHR_lock_surface
                  EGL_KHR_create_context
                  EGL_KHR_surfaceless_context
                  EGL_EXT_create_context_robustness
                  EGL_EXT_protected_surface
                  EGL_EXT_protected_content
                  EGL_EXT_buffer_age
                  EGL_WL_bind_wayland_display
                  EGL_WL_create_wayland_buffer_from_image
                  EGL_KHR_partial_update
                  EGL_EXT_swap_buffers_with_damage
                  EGL_KHR_swap_buffers_with_damage
============================================
    GL INFO
============================================
GL_VERSION      : OpenGL ES 3.1 V6.2.4.p2.163672
GL_SL_VERSION   : OpenGL ES GLSL ES 3.10
GL_VENDOR       : Vivante Corporation
GL_RENDERER     : Vivante GC7000L
GL_EXTENSIONS   :
                  GL_OES_vertex_type_10_10_10_2
                  GL_OES_vertex_half_float
                  GL_OES_element_index_uint
                  GL_OES_mapbuffer
                  GL_OES_vertex_array_object
                  GL_OES_compressed_ETC1_RGB8_texture
                  GL_OES_compressed_paletted_texture
                  GL_OES_texture_npot
                  GL_OES_rgb8_rgba8
                  GL_OES_depth_texture
                  GL_OES_depth_texture_cube_map
                  GL_OES_depth24
                  GL_OES_depth32
                  GL_OES_packed_depth_stencil
                  GL_OES_fbo_render_mipmap
                  GL_OES_get_program_binary
                  GL_OES_fragment_precision_high
                  GL_OES_standard_derivatives
                  GL_OES_EGL_image
                  GL_OES_EGL_sync
                  GL_OES_texture_stencil8
                  GL_OES_shader_image_atomic
                  GL_OES_texture_storage_multisample_2d_array
                  GL_OES_required_internalformat
                  GL_OES_surfaceless_context
                  GL_OES_copy_image
                  GL_OES_draw_buffers_indexed
                  GL_OES_texture_border_clamp
                  GL_OES_texture_buffer
                  GL_OES_texture_cube_map_array
                  GL_OES_draw_elements_base_vertex
                  GL_OES_texture_half_float
                  GL_OES_texture_float
                  GL_KHR_blend_equation_advanced
                  GL_KHR_debug
                  GL_KHR_robustness
                  GL_KHR_robust_buffer_access_behavior
                  GL_EXT_texture_type_2_10_10_10_REV
                  GL_EXT_texture_filter_anisotropic
                  GL_EXT_texture_compression_dxt1
                  GL_EXT_texture_format_BGRA8888
                  GL_EXT_texture_compression_s3tc
                  GL_EXT_read_format_bgra
                  GL_EXT_multi_draw_arrays
                  GL_EXT_frag_depth
                  GL_EXT_discard_framebuffer
                  GL_EXT_blend_minmax
                  GL_EXT_multisampled_render_to_texture
                  GL_EXT_color_buffer_half_float
                  GL_EXT_color_buffer_float
                  GL_EXT_robustness
                  GL_EXT_texture_sRGB_decode
                  GL_EXT_draw_buffers_indexed
                  GL_EXT_texture_border_clamp
                  GL_EXT_texture_buffer
                  GL_EXT_copy_image
                  GL_EXT_texture_cube_map_array
                  GL_EXT_multi_draw_indirect
                  GL_EXT_draw_elements_base_vertex
                  GL_EXT_texture_rg
                  GL_EXT_protected_textures
                  GL_EXT_sRGB
                  GL_VIV_direct_texture

6. 最後に

 OpenGLES を使った描画環境ができたので、いよいよ EdgeTPU エンジンを使った推論にとりかかろうと思います。
 Teapot 描画のソースコードは GitHub で公開しています。