HTC Touch Diamond で Direct3DMobile その(3) 実際の頂点性能

HTC Touch Diamond の 3D アクセラレータの速度テストです。
Qualcomm MSM7201A 内蔵 ATI core

時間がないので軽く調査、厳密なテストではないです。
頂点性能だけ見たかったので TriangleStrip で見えるか見えないかぎりぎりの
極小ポリゴン描画を並べたもの。ほとんど 1pixel 以下です。
単一バッファで一度だけ DrawPrimitive() しています。

●低負荷と思われるフォーマットでどれだけ頂点処理できるか

テクスチャ無し、ライティング無し、頂点カラーのみ

FVF = D3DMFVF_XYZ_FLOAT|D3DMFVF_DIFFUSE
struct { // 16byte
	float	x, y, z;
	DWORD	color;
};

頂点数  解像度  頂点形式     速度
 16384   VGA    xyz col     17.0fps   58msec
 32768   VGA    xyz col      9.6fps  103msec
 49152   VGA    xyz col      7.8fps  128msec
 65536   VGA    xyz col      5.7fps  176msec

おおざっぱに 16K 頂点が 40msec とすると、どんなにがんばっても最高 40万頂点/sec
程度しか出ない計算に。
ボトルネックが、頂点補充が追いつかないのか演算なのかは不明。

●ピーク速度に近づきたいために頂点カラーも無くしてみる

FVF = D3DMFVF_XYZ_FLOAT
struct { // 12byte
	float	x, y, z;
};

頂点数  解像度  頂点形式     速度
 16384   VGA    xyz         17.4fps   57msec
 32768   VGA    xyz          9.9fps  100msec
 49152   VGA    xyz          8.0fps  125msec
 65536   VGA    xyz          5.8fps  172msec

頂点カラーの影響は 16K 頂点あたり 1msec くらい。
65536頂点時に 38万頂点/sec

●解像度変更

頂点数  解像度  頂点形式     速度
 16384   VGA    xyz         17.4fps   57msec
 16384   HVGA   xyz         15.7fps   63msec
 16384   QVGA   xyz         22.5fps   44msec
 65536   VGA    xyz          5.8fps  172msec
 65536   HVGA   xyz          9.2fps  108msec
 65536   QVGA   xyz         11.2fps   88msec

フィルの影響も調べるために解像度も変えてテスト。
ポリゴン描画以外はクリアと Flip (COPY) だけなのに解像度の影響がかなりあります。
頂点数の増加によって解像度の影響をより強く受けているので、極小ポリゴンとは
いえそれなりにフィルを消費していることがわかります。

VGA = 639×480 (なぜ 639 なのかはこちら)
HVGA = 480×320 (iPhone/iPod touch や Android G1 がこれ)
QVGA = 320×240

●Memory Pool の違い

頂点数  解像度  頂点形式  Pool          速度
 65536   VGA    xyz       videomem      5.8fps 172msec
 65536   VGA    xyz       systemmem     5.8fps 172msec

caps ではどちらにも配置可能。特に差は無し。
速度が同じなのか、最初から同じメモリなのか、内部で Pool を無視して同一処理して
いるのかは不明。

●Index かどうか

もともと TriangleStrip だし頂点キャッシュが(もしあったとしても)有効なケース
ではないので、アクセスすべきメモリが増えた分だけ遅くなるはず。

頂点数  解像度  頂点形式  Index                   速度
 65536   VGA    xyz       DrawPrimitive           5.8fps 172msec
 65536   VGA    xyz       DrawIndexedPrimitive    5.8fps 173msec

結果、誤差の範囲でほとんど差は出ていません。

●浮動小数と固定少数の違い

頂点形式を FIXED にしても全く差がなかったです。
もともと caps が NATIVEFLOAT を返してくるし HW T&L 入ってるので Float だと
思いますが、どちらにせよ頂点バッファを作った時点で効率よい形式に
変換されていると考えられます。

● Texture つき

一番実用に近いと思われる頂点形式でテストです。
これが使い物になれば何とでもなる。

FVF=	D3DMFVF_XYZ_FLOAT|D3DMFVF_TEX1
	|D3DMFVF_TEXCOORDSIZE2(0)|D3DMFVF_TEXCOORDFLOAT(0)
struct _VTYPE {
	float	x, y, z;
	float	tu, tv;
};

頂点数  解像度  頂点形式       速度
 16384   VGA    xyz tex       16.8fps   59msec
 32768   VGA    xyz tex        9.6fps  104msec
 49152   VGA    xyz tex        7.6fps  131msec
 65536   VGA    xyz tex        5.3fps  190msec
  1000   QVGA   xyz tex       28.5fps   35msec
  1000   VGA    xyz tex       28.0fps   35msec
  5000   VGA    xyz tex       27.4fps   36msec
 10000   VGA    xyz tex       25.8fps   38msec
 20000   VGA    xyz tex       15.9fps   62msec

頂点の負担を見ることが目的なので、結果に大きな影響が出ないように Texture は
1pixel しか読み込んでいません。

ずっと気になっていたのが、必ず 29fps くらいで頭打ちになること。
設定はどれも D3DMPRESENT_INTERVAL_IMMEDIATE です。
これを D3DMPRESENT_INTERVAL_ONE にしてもなぜか同じ。

● Texture + Color つき

かなり使われることが多いフォーマットです。
これが使えればテクスチャを減らせます。

FVF=	D3DMFVF_XYZ_FLOAT|D3DMFVF_DIFFUSE|D3DMFVF_TEX1
	|D3DMFVF_TEXCOORDSIZE2(0)|D3DMFVF_TEXCOORDFLOAT(0)
struct _VTYPE {
	float	x, y, z;
	DWORD	color;
	float	tu, tv;
};

頂点数  解像度  頂点形式       速度
 16384   VGA    xyz col tex   16.6fps   60msec
 32768   VGA    xyz col tex    9.2fps  108msec
 49152   VGA    xyz col tex    6.9fps  145msec
 65536   VGA    xyz col tex    5.2fps  193msec
 10000   VGA    xyz col tex   25.8fps   38msec
 20000   VGA    xyz col tex   15.9fps   63msec

実用的な頂点処理能力としては、フレームあたり 1万ポリゴンくらいが限界といったところです。
ただし単一バッファで一回の描画でこの数値です。
実際は多数の DrawPrimitive() を呼び出すことになるので速度は落ちるはずです。

また前回やった通りライティングはかなり遅いのでテストしてません。
●光源処理あり 2008/01/07 3:02 追記

せっかくなので本当にどれだけ遅いのか光源もテストしてみました。
ハードウエア光源を使うだけで頂点が 2.5倍以上重くなっています。
これは純粋に演算量の増加によるものでしょう。

FVF = D3DMFVF_XYZ_FLOAT|D3DMFVF_NORMAL
struct { // 16byte
	float	x, y, z;
	float	nx, ny, nz;
};

◎平行光源 x1、スペキュラ無し
頂点数  解像度  頂点形式    光源                      速度
 16384   VGA    xyz normal  Dir x1  Diffuse           7.0fps  143msec
 32768   VGA    xyz normal  Dir x1  Diffuse           3.7fps  264msec
 49152   VGA    xyz normal  Dir x1  Diffuse           2.7fps  371msec
 65536   VGA    xyz normal  Dir x1  Diffuse           2.0fps  497msec

◎平行光源 x2、スペキュラ無し
頂点数  解像度  頂点形式    光源                      速度
 16384   VGA    xyz normal  Dir x2  Diffuse           6.9fps  144msec
 32768   VGA    xyz normal  Dir x2  Diffuse           3.7fps  275msec
 49152   VGA    xyz normal  Dir x2  Diffuse           2.6fps  380msec
 65536   VGA    xyz normal  Dir x2  Diffuse           1.9fps  512msec

◎平行光源 x1、スペキュラあり Power=10
頂点数  解像度  頂点形式    光源                      速度
 16384   VGA    xyz normal  Dir x1  Diffuse+Specular  6.1fps  165msec
 32768   VGA    xyz normal  Dir x1  Diffuse+Specular  3.2fps  310msec
 49152   VGA    xyz normal  Dir x1  Diffuse+Specular  2.3fps  440msec

◎平行光源 x2、スペキュラあり Power=10
頂点数  解像度  頂点形式    光源                      速度
 16384   VGA    xyz normal  Dir x2  Diffuse+Specular  6.0fps  165msec
 32768   VGA    xyz normal  Dir x2  Diffuse+Specular  3.2fps  311msec

●TriangleList の負荷 2008/01/07 9:30 追記

TriangleStrip で描画していた全く同じ頂点配列+ポリゴンを、Index で
TriangleList に展開したものです。
Index の数が (vertices-2)*3 に増えた分だけメモリアクセスが増えますが、
キャッシュがある一般的な GPU だと速度が落ちません。

頂点数  解像度  頂点形式 描画API      PrimitiveType   速度
 32768   VGA    xyz    DrawPrimitive  TriangleStrip  10.1fps   99msec
 32768   VGA    xyz    DrawIndexedPri TriangleStrip  10.0fps  100msec
 32768   VGA    xyz    DrawIndexedPri TriangleList    4.0fps  248msec

プログラムが間違っていなければ頂点キャッシュ無し確定。
おそらく演算が 3倍になってると思われます。

問題はむしろフィルの方なので、あとはピクセルがどれくらい出るかどうか。

IT Media QUALCOMM、MSM7201A上で動作するAndroidのデモを公開
上のページには PSP に近いくらいと書かれていますが、現状とてもそこまで
出せそうにないです。

関連エントリ
HTC Touch Diamond で Direct3DMobile を使う。その (2)
HTC Touch Diamond で Direct3DMobile を使う。ハードウエアアクセラレータ