月別アーカイブ: 2009年11月

NetWalker PC-Z1 i.MX515 OpenGL ES 2.0 (4) AMD Z430 タイルサイズ

AMD Z430 は PowerVR と同じようにタイルベースのレンダリング (TBR) を行うことで
知られています。TBR も Unified Shader の仕様も AMD は Xbox360 の GPU がベース
だと説明していますが、その両者の性能差は桁違いです。
一方は強力な GPU が要求するバス帯域に応えるため、もう一方はモバイル向けでタイトな
メモリ速度でもそれなりの性能を維持するため。同じ技術でも応用先の GPU が真逆なのは
面白いところです。

AMD Next-Gen Tile-Based GPUs (pdf)
AMD Next-Generation OpenGLR ES 2.0 Graphics Technology Achieves Industry Conformance

NetWalker に用いられている i.MX515 は GPU core として AMD (ATI) imageon Z430
を搭載しています。
ここ最近 NetWalker で OpenGL ES 2.0 を触っていますが、まだ Z430 の特性がうまく
つかめておらずあまり速度が出ていません。調べている最中です。
偶然 TBR のタイル領域の大きさを知ることが出来ました。

●タイルサイズ

NetWalker_OpenGLES03.jpg

フレームバッファをクリアしないで描画した場合の画面がこれです。GPU のタイルバッファも
クリアせずに上書きされているようです。
1024×600 の画面なので、上の写真のケースだと 1タイルは 256×128 ドット。
以下バックバッファの組み合わせ毎にタイルサイズをまとめてみました。

Color   Depth/Stencil   Tile
-----------------------------------
16bit   none            512x128
16bit   16bit           256x128
32bit   16bit           128x128
16bit   24bit/8bit      128x128
32bit   24bit/8bit      128x128

◎タイルバッファの容量

 少なくても 128KByte 存在しています。予想より大容量です。

◎Depth/Stencil との組み合わせ

 使用可能な depth の幅はカラーの影響を受けることが多いのですが、こちら
 書いたとおり Z430 では任意の組み合わせを選べます。PowerVR もそうだったので
 やはり TBR 専用のバッファを持っているおかげだと思われます。

◎32bit Color or 24bit Depth 利用時の速度低下

 Color か Depth どちらかを 16bit より増やすと速度に影響が出ます。
 その原因はバス帯域だと思っていましたが、この結果を見るとタイル分割数の増加が
 負担になっているのかもしれません。

● Extension

まだ試していませんが TBR を制御する API があります。

GL_VERSION: OpenGL ES 2.0
GL_RENDERER: AMD Z430
GL_VENDOR: Advanced Micro Devices, Inc.
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 1.00
GL_EXTENSIONS:
    GL_AMD_compressed_3DC_texture
    GL_AMD_compressed_ATC_texture
    GL_AMD_performance_monitor
    GL_AMD_program_binary_Z400
    GL_AMD_tiled_rendering
    GL_EXT_texture_filter_anisotropic
    GL_EXT_texture_type_2_10_10_10_REV
    GL_EXT_bgra
    GL_OES_compressed_ETC1_RGB8_texture
    GL_OES_compressed_paletted_texture
    GL_OES_depth_texture
    GL_OES_depth24
    GL_OES_EGL_image
    GL_OES_EGL_image_external
    GL_OES_element_index_uint
    GL_OES_fbo_render_mipmap
    GL_OES_fragment_precision_high
    GL_OES_get_program_binary
    GL_OES_packed_depth_stencil
    GL_OES_rgb8_rgba8
    GL_OES_standard_derivatives
    GL_OES_texture_3D
    GL_OES_texture_float
    GL_OES_texture_half_float
    GL_OES_texture_half_float_linear
    GL_OES_texture_npot
    GL_OES_vertex_half_float
    GL_OES_vertex_type_10_10_10_2
    GL_NV_fence

● NetWalker の速度比較

描画面積を出来るだけ小さくして頂点速度を測定しようとしたもの。

AMD Z430          48000x1 =  48000 Tris/s 30fps = 約 1.44M Tris/s  (1024x600)
PowerVR SGX 535   48000x4 = 192000 Tris/s 45fps = 約 8.64M Tris/s  ( 480x320)

フレームバッファのサイズが極端に違うし、どちらも Unified Shader なので頂点に
ピクセルの影響が全くないとは言い切れません。Clear → Swap だけでもあまり速度が
出ないので、広い画面が仇になっている可能性があります。
タイル+転送だけである程度の負荷がかかり、頂点も圧迫しているのでしょうか。
1024×600 は 480×320 のちょうど 4倍の面積です。

1024x600 = 614400 pixels  8 倍  NetWalker
 640x480 = 307200 pixels  4 倍  VGA
 480x320 = 153600 pixels  2 倍  iPhone
 320x240 =  76800 pixels  1 倍  QVGA

● VRAM 容量

PC のチップセット内蔵 GPU と同じように、VRAM はメインメモリから確保していると
考えられます。NetWalker の RAM は 512MB ですが 480MB しか見えないので、残りの
32MB が VRAM の取り分かもしれません。

1024×600 x16bit は 1.2MB (fb は 2.5MB) なので、32MB もあると少々無駄に感じる
かもしれません。ところが OpenGL ES 2.0 を使っていたらあっという間に VRAM が
溢れました。(GL_OUT_OF_MEMORY を返す)

その原因は自分のローダーでした。Z430 が DXT に対応していないため、圧縮された
テクスチャを 8888 に展開していたからです。あらかじめ ATC/3Dc/ETC へ変換して
おけば解決するはずです。計算したらテクスチャを 23MB も読み込んでいました。

もう一つ考えられる理由は TBR による遅延レンダリングです。
システムメモリからの逐次転送できず、シーンに必要なリソースを全部 VRAM に乗せて
おかないと描画できないのかもしれません。何らかの確証があるわけではなくあくまで
想像です。

どちらにせよ、設定を変えられるなら VRAM 容量はもうちょっと増やしたいところです。

●立ったまま OpenGL ES 2.0 プログラミング

帰りの電車の中では立ったまま、EGLConfig のパラメータを変えて make したりタイルの
データ取りをしてました。この大きさで開発+実行できるのは良いですね。

関連エントリ
NetWalker PC-Z1 i.MX515 OpenGL ES 2.0 (3)
NetWalker PC-Z1 i.MX515 OpenGL ES 2.0 (2)
NetWalker PC-Z1 i.MX515 OpenGL ES 2.0
OpenGL ES 2.0 Emulator

24年ぶりに「おくやくん」が移植されました。ポケコン PC-1245

●移植された!

「おくやくん」 は SHARP のポケットコンピュータ、PC-1245/50/51/55 で動くゲームです。
工学社の雑誌、PiO 1985年の 11月号に掲載されたので、もう 24年も前になります。
その古いゲームを、なんと 24年の時を経て他の機種に移植してくれた方が現れました。
下記ページで公開されています。

「ポケットコンピューター」について

こちらには新たに移植された PC-1450 版、PC-1260/61/62 版(*1)がありますし、
16ステージ分オンメモリに改良された PC-1251/55 向けも掲載されています。
BASIC による PC-G801/E200 版もあります。

ページに掲載されているプログラムは音声形式 WAVE ファイルで、これをカセット
インターフェースから読み込ませるとポケコン本体に転送できるという仕組みです。

このカセットインターフェース用のセーブ音を聞くだけでもう懐かしくて涙が出そうです。

●電卓みたいなコンピュータ

SHARP のポケコン PC-1245/50/51/55 や PC-1260/61/62 は非常に小さくて薄くて
ただの電卓にしか見えません。

今更こんな写真を見せられても、コンピュータとして使い物になるのかと疑問に思う方が
きっと多いことでしょう。
いや当時もそう思いました。

でもそこが魅力の一つでもあります。
見かけは薄っぺらな関数電卓なのに、BASIC だけでなくマシン語プログラムが走り、
高速なゲームが動いてサウンドの演奏もできます。当時としてはどれも驚くべきもの。
見た目のギャップと実力の差、中に詰まった感じが良かったのです。

●ゲーム内容

横画面のアスレチックぽい仕様となっていますが、実際は迷路ゲームです。
画面が 1行しかないことを逆手に取り、先が読めず決断を迫られることと、若干の
暗記力が必要でした。

一番の特徴はドット単位の上下スクロールです。
VRAM 構造上の制約もあったため、掲載時はまだ珍しかったように思います。
2D 風のフィールドを移動できてマシン語で比較的高速に動作するし、
内容もかなり緩いゲーム性だったこと、コンストラクションモードがあって自由に
面データを作れたのが良かったのかもしれません。

●おくやくん作成の話と機械語プログラミング

このゲームを作った目的はやっぱりスムーズな上下スクロールでした。
ただ最初はそこまで深く考えていなかったため、あまりきれいな作りではありません。
結局はライン単位でパターンを展開しているし、スクロールにキャラが付いてこない
ところも不完全です。
もっときちんと作っておけば良かったと、ここだけがずっと心残りでした。
完全に 2D 空間を滑らかにスクロール出来たのは、その後の別のゲーム
トロピカルアイランドだったように思います。

おくやくん はほぼ全部マシン語で書かれています。
アセンブラもパソコンも無かったので、紙に手でプログラムを書いていました。
ニモニックは使わずに 16進数で命令を並べ、自分で相対ジャンプを数えて、ある程度
出来たらマシン語モニタで直接 RAM に命令を書き込んでいきます。

これだとあとから大きな修正ができないので、プログラミングは完全にボトムアップです。
キー入力ルーチンやサウンド部分から始めて、パターン転送ルーチンなど小さい部品を
作り、テストしながらメモリ上に配置していきます。
ゲームとして全体が繋がるのは最後でした。
RAM が 2~10KByte しかなかったおかげか、こんな方法でも十分だったのです。

記憶メディアはカセットテープしかなかったものの、ポケコンは今で言うスリープ相当。
RAM の内容はバッテリーで保持されています。
ファイルやディスクといった概念もなく、メモリを書き換えたらそれがすべてです。
プログラムもエディットしたステージデータもずっと RAM 上に保存されています。

そのためプログラム実行時は最初に必ず初期化ルーチンが必要で、ワークエリアを
クリアしたり、パラメータの初期値を転送しなければなりません。
いつも最後に作るのがこの部分でした。

その頃には RAM エリアはすでに後ろまでいっぱい使い切っており、たいてい入る場所
が無くなっています。そこで逆にアドレスの前方に伸ばしていきます。ぎりぎりまで
BASIC エリアを浸食するようになるわけです。
プログラムの一番先頭にワーク初期化用のデータテーブルがあったり、プログラムの
スタートアドレスが途中の中途半端な番地になっているのもそのため。

ちなみに 「おくやくん」 というのは当時の友人、奥山君のこと。

●ポケコンユーザー

移植してくれた柳田さんありがとうございました。
今後他の機種へも移植を行っていくとのことです。

今年の 2月にもLC-3 コンパイラが欲しいとの問い合わせもあって、意外にもまだまだ
ポケコンを使ってる方が結構いらっしゃるようです。
このように問い合わせのメールをいただく度にいつも驚いています。
そして謝ります。すみません、コンパイラはまだ用意できてませんでした。

*1: PC-1260 には過去にも移植版があったようです。森岡氏 PC-1260

関連エントリ
BASICコンパイラと手書き原稿の時代
28年前のモバイル PC-1211 他
20年前のモバイル PC-1417G

NetWalker PC-Z1 i.MX515 OpenGL ES 2.0 (3)

わかる方、自力で何とか出来る方のみ参考にしてください。
すべて自己責任でお願いします。

(1) カーネルをコンパイルできる環境を作る。( 参考1, 参考2 )
(2) module を読み込めるようにカーネルを作る。
 (CONFIG_MODVERSIONS を無効化するなど> 例 Module versioning support を外す)
(3) 作成したカーネルを使って起動出来る環境を作る。
  ・SD カード上に作成
  ・本体フラッシュ (/dev/mtd3) を書き換え
  など

SD 上の debian で起動して insmod だけ確認した後、面倒なので /dev/mtd3 を
置き換えました。壊れても気にしない人のみ。それ以外はお勧めしません。
3Gモデム対応ツールを適用しており、かつ互換性あるカーネルを作っている前提です。
L2.6.28_4.5.1_SDK_Aug2009_source.tar.gz (こちら)を展開して install を実行。
以後メッセージに従う。
入力した展開先フォルダの中の ltib/pkgs の中からアーカイブを参照。

$ tar -zxvf amd-gpu-bin-mx51-4.5.1.tar.gz
$ cd amd-gpu-bin-mx51-4.5.1
$ sudo cp -r lib/module/2.6.28-419-g12a78a3/extra  /lib/modules/2.6.28-15-araneo/kernel/drivers/
$ sudo depmod

ファイルを手でコピー。ここでも気にしないでシステムを置き換えています。
分けるなら /usr/local 以下に配置。

$ sudo cp -r  usr/include/*  /usr/include/
$ sudo cp  usr/lib/*  /usr/lib/
$ sudo mkdir  /usr/local/bin
$ sudo cp  usr/bin/*  /usr/local/bin/
$ sudo /usr/local/bin/gpu-install install

最後の gpu-install でドライバを読み込んでいます。
「sudo /usr/local/bin/gpu-install install 」は再起動の度に必要。
添付のサンプルで動作確認。

$ sudo /usr/local/bin/tiger
$ sudo /usr/local/bin/es11ex

(実行結果の画面) フルスクリーンで起動するので VRAM を破壊します。実害はありません。
最初は ssh などネットワーク経由での実行をお勧めします。

サンプルが動けば動作はうまくいったように見えますが、ドキュメントやサンプル
ソースがあるわけでもないので、実際の使い方はまだまだ手探り状態です。

Display インターフェースは egl なので、初期化は以前 OpenGL ES 2.0 Emulator
を取り扱ったときのコードがほぼそのまま使えます。
AMD 版 GL ES 2.0 Emulator のターゲットがこの Z430 なので当たり前といえば
当たり前です。

OpenGL ES 2.0 Emulator

eglGetDisplay() は EGL_DEFAULT_DISPLAY を使用。

eglChooseConfig() では 4444, 565, 5551, 8888 が使えるようです。
depth は 0, 16, 24 (24+ stencil8) のどれかと組み合わせ。
カラーバッファが 16bit でも 24bit depth を使えます。
バックバッファのフォーマットなので、8888 を指定してもフロントバッファが
32bit になるわけではありません。

eglCreateWindowSurface() で描画と API をバインドしますが、この場合
EGLNativeWindowType に何を指定すればよいのか悩みました。
いろいろ試した結果、/dev/fb0 を渡したら動きました。

EGLNativeWindowType eglwin= open( "/dev/fb0", O_RDWR, 0 );
egl_Surface= eglCreateWindowSurface( egl_Display, egl_Config, eglwin, NULL );

描画のフラッシュと転送は普通に eglSwapBuffers() で動きます。

デバイスファイルにアクセスするため root で実行する必要があります。

フレームバッファは 16bit 1024×600 ですが、倍の容量存在しているのは 32bit
への切り替えを考慮してのことでしょうか。
この辺いろいろとステートを読み出したりしつつ調べている最中です。
例えば EGL_HORIZONTAL_RESOLUTION が 2048 になっている点など、まだ良く
わかっていない部分が多数あります。

描画の印象としてあまり速くありません。eglSwapInterval() に 1 しか設定
できないため、常にモニタのリフレッシュレートと同期している可能性があります。
ただ動作時間が半分ほどで終わってしまい、計算と一致していないのも謎です。
性能はまだ未知数。

取りあえず GLSL のシェーダーを読み込んで、テクスチャの描画まで成功。
シェーダーのコンパイルエラー発生時に、ドライバが詳細なエラーメッセージ(log)
を返してこないのも はまったところです。デバッグは Emulator で行った方が
良いかもしれません。

ヘッダ (GL ES 2.0 の場合)

#include  
#include  
#include  

ライブラリの指定など (Makefile)

CC      = gcc
LIBS    = -lm -lstdc++  -legl13 -lgles20
INCS	=
CFLAGS  = -O4 -Wall \
	-march=armv7-a  \
	-mtune=cortex-a8        \
	-mfloat-abi=softfp      \
	-mfpu=neon      \

TARGET  = main
OBJS    = main.o

$(TARGET): $(OBJS)
	$(CC) -o $(TARGET) $(OBJS) $(LIBS)

%.o:%.cpp
	$(CC) -c -o $@ $< $(CFLAGS) $(INCS)

ARM Cortex-A8 + OpenGL ES 2.0 は iPhone 3GS などハイエンドスマートフォントにも
搭載されています。
比べると NetWalker の良いところはクロス開発しなくてもいいところでしょう。
修正したり設定を変えてテストを繰り返していると、自分でコンパイルできるのは非常に
便利だと実感します。
micro SD 上で作業しているので、開発環境もこの小さい本体だけです。

関連エントリ
NetWalker PC-Z1 i.MX515 OpenGL ES 2.0 (2)
NetWalker PC-Z1 i.MX515 OpenGL ES 2.0
OpenGL ES 2.0 Emulator

NetWalker PC-Z1 i.MX515 OpenGL ES 2.0 (2)

NetWalker_OpenGLES01.jpg

NetWalker_OpenGLES02.jpg
いろいろ手間取ったけど、何とか動かすことに成功

追記:

Version: 1 3
EGL_CLIENT_APIS: OpenGL_ES OpenVG
EGL_EXTENSIONS: eglCreatePbufferFromClientBuffer EGL_KHR_image EGL_AMD_create_image
EGL_VENDOR: Advanced Micro Devices, Inc
EGL_VERSION: 1.3 Internal version 1.4.1

GL_VERSION: OpenGL ES 2.0
GL_RENDERER: AMD Z430
GL_VENDOR: Advanced Micro Devices, Inc.
GL_SHADING_LANGUAGE_VERSION: OpenGL ES GLSL ES 1.00

関連エントリ
NetWalker PC-Z1 i.MX515 OpenGL ES 2.0