月別アーカイブ: 2007年7月

D3D10 Geometry Instancing の問題と

「Direct3D10 の Geometry Instancing の問題と機能の解説」
Direct3D9 の ShaderModel3.0 から Geometry Instancing に対応し、
Direct3D10 では必須機能となりました。Geometry Instancing がなぜ重要
なのか、また D3D9 での機能については前回こちらで触れました。
Direct3D Geometry Instancing
今回は D3D10 での Geometry Instancing についてわかったことなどを
書いてみます。

D3D9 までの DrawPrimitive 命令は無くなり、D3D10 ではただの Draw 命令
となりました。これでいちいちプリミティブ数を計算して求める必要が無くなり
ました。頂点数やインデックス数だけで描画命令を発行できます。

●頂点指定の描画命令
 Draw()
 DrawInstanced()

●インデックス指定の描画命令
 DrawIndexed()
 DrawIndexedInstanced()

~Instanced() 命令は、それぞれの描画命令に繰り返し機能が付いたバージョンです。
繰り返す回数を指定することで、InputLayout の D3D10_INPUT_PER_VERTEX_DATA
指定した頂点バッファが、繰り返し数分だけ何度も読み込まれます。

例えば 24頂点の Cube の描画は

 iDevice->Draw( 24, 0 );

ですが、これを繰り返し回数 (InstanceCount) 8 回 で描画すると

 iDevice->DrawInstanced( 24, 8, 0, 0 );

となります。このとき同じ場所に同じモデルを 8回上書きするだけなので、
描画負荷が上がる以外に特に意味はありません。

この 8回の描画位置を何らかの方法で指定してあげる必要があります。
さまざまな方法が考えられますが、例えば Shader 内でも System Value
Semantic の SV_InstanceID を使って何個目の描画なのか取得することが
できます。Constant Buffer で Geometry を渡して Index に使えば
任意の位置に描画することが可能です。

Constant Buffer は容量的な上限があります。またアドレッシングしなくても
効率よくデータを読み込めるように、専用 Stream を使うことができます。
この Stream には区別のために D3D10_INPUT_PER_INSTANCE_DATA を指定します。

D3D10_INPUT_PER_INSTANCE_DATA 指定された Stream は、読み進めるための
ポインタを Instance 毎にしか更新しません。同一 Instance の頂点には
すべて同じ値が渡されるわけです。

これがまさに Direct3D9 の Geometry Instancing と同じもので、本来は
この使い方を想定して API の設計が行われているようです。
対して最初の Stream を使わない Direct3D10 独自の手法を
Stream Less Instancing と名付けておきます。

Per Instance Stream も単なる Buffer であって基本的には頂点と変わりません。
Draw() に DrawIndexed() があるように、Per Instance Stream でももっと
凝ったことをやろうとすると Index が欲しくなるでしょう。

Index とまでは行きませんが、D3D10 では通常の stream だけでも多少凝った
指定ができるようになっています。D3D10_INPUT_PER_INSTANCE_DATA にも同じ
ストリームを多重読み込みできるように、個別に読み込み回数を指定可能です。
ローカルなループを構成できるわけです。

このローカルな回数は InputLayout を作るときに設定します。
InstanceDataStepRate です。

この機能を使えば、繰り返し回数 (InstanceCount) = 8回のデータでも、
2個の Per Instance Data をそれぞれ 4回ずつ描画する
(InstanceDataStepRate = 4)、といった柔軟な設定が可能になります。

このとき D3D10_INPUT_PER_INSTANCE_DATA の Stream は 2個のジオメトリ
分の大きさですが、DrawInstanced()/DrawIndexedInstanced() には
InstanceCount = 8 を設定します。

ここで今の DirectX Runtime (June2007) には若干問題があって、
Debug Build だと Instance 用の VertexBuffer が描画回数に比べて
少なすぎるという WARNING が毎フレーム発生してしまいます。

[EXECUTION WARNING #356: DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL]

どうやら判定時に InstanceDataStepRate を見ていないようです。
当初自分のアプリケーションの問題かと思っていたのですが、
Sample の Instancing10 でも発生していました。

とりあえず、Direct3D10 の Geometry Instancing は、無理やり拡張したような
D3D9 と比べてかなりシェーダーで自由に扱うことができます。
情報が少ないのがネックですがかなり思い通りに使うことができるようです。

InstanceDataStepRate はいわゆる通常の Geometry Instancing に
さらに Stream Less Instancing を混在利用しているわけですし、
Texture/Buffer 読み込みを使えば Instance Data の Index 化もおそらく
可能でしょう。

emobile EM・ONE ファームアップとワンセグ

先日のファームアップデートは安定度の向上が中心で、特にこれが変わった!
という目だったものも無いし問題も無いので、なかなか新しくなったという
実感がわきません。
EM・ONE 新ファームウエア v1.01
アップデータを起動したあとに「しまった」と思ったのは、
ついうっかり RealVGA(WVGA) 化したまま実行してしまったこと。
だけどアップデート作業も順調で、更新も何のトラブルもなく終わりました。
至って順調なので、ReavlVGA 化は気にしなくても良かったみたいです。

アップデート後、確かにワンセグの安定度が増したように感じます。

以前(v1.00時)はワンセグの電波状況も良くて放送が入るのに、
音声だけ時たま途切れがちになることがありました。
何らかの負荷が高くなって一瞬処理落ちしているような感じです。

同一の条件でも、携帯 V905SH の方ではスムーズで途切れることもなく
ワンセグの視聴ができました。

ファームウエアを v1.01a に更新した後は EM・ONE でも音声が安定して
途切れることがなく、大画面で放送を楽しむことができるようになりました。
EM・ONE は画面が大きく液晶も明るいので、机の上に置いても見やすいですね。

画質については、デジタル放送といいつつ結構機種によって違いがあるようです。

SHARP V905SH ワンセグ
 比較的シャープで、文字なども輪郭がくっきりしてきれいです。
 色は EM・ONE とくらべて浅目の落ち着いた感じです。

SHARP EM・ONE ワンセグ
 液晶のドット比率のせいもあるかもしれませんが、強いアンチエリアスが
 かかったような感じ。文字は V905SH に比べると細部がぼやけて見えます。
 色は強く、コントラストが高い濃い画面です。

ちなみに一番きれいなのは、外部アンテナを繋いで条件が良いときの
V905SH のアナログ放送です。ノイズは多少乗るけど滑らかです。
ただ外部アンテナが無く条件が悪いときはノイズだらけで全く見えません。

悪条件の下、単体でもきちんと絵が出て十分な視聴レベルであるワンセグは
やっぱりすごいのですね。

D3D10 GetResourceBindingDesc

相変わらず Effect 管理と Reflection まわりを触っています。
ID3D10Effect から ID3D10ShaderReflection を取り出すには、
D3D10/DX10 Effect Interface内情報
に書いた手順の通りです。
取り出した Reflection を使って、描画のために Shader の Setup を
行うためには BindingDesc を調べる必要があります。

ID3D10ShaderReflection* iReflection; // input
D3D10_SHADER_DESC shdesc;
iReflection->GetDesc( &shdesc );
for( DWORD i= 0 ; i< shdesc.BoundResources ; i++ ){
 D3D10_SHADER_INPUT_BIND_DESC binddesc;
 iReflection->GetResourceBindingDesc( i, &binddesc );
  // :
}

これで binddesc.Name に対応する HLSL の変数名が、
bdesc.Type に Resource の種類が、
bdesc.BindPoint に Resource を割り付けるスロット番号が入ります。

bdesc.Type は D3D10_SHADER_INPUT_TYPE で定義されています。

——————————————————–
enum D3D10_SHADER_INPUT_TYPE
{
D3D10_SIT_CBUFFER,
D3D10_SIT_TBUFFER,
D3D10_SIT_TEXTURE,
D3D10_SIT_SAMPLER,
};
——————————————————–

上記の通り 4種類に分類されていることがわかります。

CBUFFER, SAMPLER は特に問題ありません。それぞれ
GSSetConstantBuffers(), GSSetSamplers() (VS~, PS~) 等の
API でシェーダーに割り当てるので、独自に BindPoint (Slot番号) が
割り当てられます。

TBUFFER と TEXTURE はどちらも Texture なので、シェーダーに
割り当てるための API は GSSetShaderResources() (VS~, PS~)
しかありません。
というのは、どちらも ID3D10ShaderResourceView で扱いは一緒なのです。
そのため Type は別でも BindPoint は両方合わせてカウントされます。

では TBUFFER と TEXTURE の違いは何かというと、
D3D10_SHADER_INPUT_BIND_DESC の ReturnType や Dimension が違います。
結局は Buffer と Texture の違いであって、Sampler を使えるかどうかの
違いといえるかもしれません。

なお ID3D10Effect 等は全部やってくれていますが、BindPoint は
GS, PS, VS それぞれ参照状況に応じて異なっている可能性があり、
さらに Effect 内に複数の Pass や Technique が存在する場合はその数だけ
区別しておく必要があります。
セットアップも必要に応じて GS, PS, VS 全部に対して実行しなければならず、
自前でやろうとすると思ったよりも手間がかかります。
やっぱり完全に ID3D10Effect 任せにした方が簡単ではあります。

emobile EM・ONE スーパー大容量バッテリ2

フル充電したまま月曜から使ってまだ持っています。
使いっぷりによるとは思いますが、自分の普段の稼働率だと
平日で一週間いけそうです。
EMOBILE EM・ONE スーパー大容量バッテリー

EM・ONE はもともとかなり薄さにこだわって作られたそうです。
むちゃなお願い”から生まれた「EM・ONE」――その開発経緯とは?
標準バッテリーをはずしてみると、裏側のケース分の厚みを削ってあって
薄く仕上げるための苦労のあとが見えます。
スライド式のキーボードを持った2枚構造で薄く仕上げるには、
かなりの試行錯誤があったのでしょう。

でも普段もって歩く分には、意外にも「薄い」という感じはしません。
非スライド式の PDA ではもっと薄いものがいっぱいあるからかもしれません。

だけどスライドしてキーボードを出したときは別で、
インプットスタイルで触れるキーボード側の板は、本当に薄いなと感じます。

そんな EM・ONE に超大容量バッテリーをつけると、
一番触って薄いと実感できたキーボード面が2倍ほどの厚みになります。
キーを打っているときの安定感、重量感は別物。体感的には2倍以上です。

超大容量バッテリーのカバーは、底面を広く覆って安定します。
机においてもぐらつくこともありません。
ボタン類には干渉せず、電源スイッチもワンセグアンテナの引っ張り
出しも違和感なく行えます。
スタイラスの取り出しでは多少カバーの角が気になってしまうかも。

カバーに付いたスタンドは最初は硬くて引っ張り出せませんでした。
しばらく使ってると馴染んできます。安定性も申し分ないです。
立てたときは電源とUSBケーブルが干渉してしまうので、
単体で使うときに限られます。

実用時のバッテリー持続時間のテストはよほど暇なときで無いとむり
かもしれないです。過去のバッテリーテストこちら
emobile EM・ONE のバッテリーと操作
emobile EM・ONE 無線LANのバッテリー時間

バッテリカバーをはずすときは、三角マークのところを抑えて押し付ける
ようにしてスライドします。標準バッテリーのカバーと構造はいっしょです。

W-SIM Interface 8月号の つないでイーサ

CG出版のインターフェースは組み込みよりの技術者向けの雑誌です。
「PHS通信モジュールW-SIMを利用したLinuxベース携帯電話の開発」など
WILLCOM 関連のネタも結構載っています。

今月号(2007年8月号)には W-SIM を直接 LAN に接続できる
つないでイーサの紹介や解説が載っていました。
「PHS経由でネットに接続できるEthernetアダプタのファームウェアをハック 前編」

この「つないでイーサ」は簡単にファームウエアを入れ替えることが可能で、
ユーザーが好きなプログラムを走らせることができるとのことです。
例として、サポートページで配布している SilentC が紹介されています。

プロンプトの無い行番号式スクリーンエディット画面には OK と表示されていて
run でプログラムの実行ができて
「? 計算式」だけで演算結果を表示しています。
C言語ながら、8bit パソコン時代の BASIC のような、対話式の良い使い勝手を
しっかり再現しているようです。

というのもそのはず、よく見るとこの記事を書いているのはあの Oyajin さんこと
中本伸一さん。OyajinAppointment など WindowsCE ではすっかりおなじみです。
そして Hu-BASIC の生みの親でもあるのですから。