- ベストアンサー
DirectX LPDIRECT3DDEVICE9のマルチスレッドでの使用について
- DirectX LPDIRECT3DDEVICE9のマルチスレッドでの使用についての要約文1
- DirectX LPDIRECT3DDEVICE9のマルチスレッドでの使用についての要約文2
- DirectX LPDIRECT3DDEVICE9のマルチスレッドでの使用についての要約文3
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
>このサンプルは、上記の処理をD3DCREATE_MULTITHREADEDフラグをいれず、 >そのまま行っているもので、テクスチャを別スレッドで、ひたすらロードと、解放を行っています。 >これを実行した結果、特に問題ない(強制終了などしない)ように見えました。 D3DXCreateTextureFromFileとBeginScene他がたまたまメモリをお互いに干渉しない ということでしょう。 もしg_pDevice->BeginScene();~g_pDevice->EndScene(); でテクスチャのロードが終わっていない段階で テクスチャ(hoge.bmp)の読み込みを行えば落ちるでしょう。 まったく関係無さそうなDirectXのAPI同士(例えばBeginSceneとD3DXCreateTextureFromFile) でもメモリを共有してる可能性があり ランタイム等が変われば落ちる可能性はあります。 別のスレッドから呼ぶことは避けたほうが良いです。 マルチスレッドで問題になるのは異なる2つのスレッドで メモリ対して読み込みと書き込み、或いは書き込みと書き込みが 同時に起こった時に整合性がとれなくなることです。 別にD3DCREATE_MULTITHREADEDを指定してなくても、 DirectXのAPIを呼び出す部分だけを専用のスレッドにすれば 他の部分はマルチスレッド化する事は可能です。 (プログラマとしてはD3DCREATE_MULTITHREADEDによって どのような影響が出るかはMSDNで公開されている情報以外に 知る術は基本的にありません。とりあえずわかることは D3DCREATE_MULTITHREADEDを指定すると CriticalSectionを多様するようになる為 パフォーマンスに影響の可能性があると説明されています。 これ以上の事を知りたいならMSDNのフォーラムに質問すると良いかもしれません。) ソースをみてスレッドの落とし方が気になりました。スレッドを安全に落とすためには boolフラグ等を使ってスレッドで監視し、スレッド自ら終了させます。 それをメインスレッドでWaitForSingleObject(WaitForMultibleObject)を使い スレッドのハンドルを監視しスレッドが終了したことを確認してから CloseHandleを行った方が良いです。 "たまたま動いている"類のものはOSやDirectXのバージョン が変わったときにアプリケーションごと落ちたりする事が よくあります。(DirectXやOSの設計者が意図していない使われ方 をしている為です)
補足
sha-girlさん、回答をして下さった上に、ソースの不備まで指摘していただいて、ありがとうございます。 >"たまたま動いている"類のものはOSやDirectXのバージョン >が変わったときにアプリケーションごと落ちたりする事が >よくあります。 やはりこの方法では、危険ですか。。。 ゲームクリエイターをなさっているとのことなので、少し突っ込んだことを質問させて下さい。 今回のようなNowLoadingを実装するには、実際にはどのようにするのが理想的なのでしょうか? 自分で、思いつくものは下の二つです。 (1)ロードと、描画は別のスレッドで行うが、ロード中だけ、LPDIRECT3DDEVICE9を使用するときは自前でCriticalSectionを通すようにする。 (2)D3DCREATE_SOFTWARE_VERTEXPROCESSINGを使用してLPDIRECT3DDEVICE9を本来の描画用とは別にもう一つ作成し、それをロード中に描画に利用する。 別スレッドで、本来の描画用に利用しているLPDIRECT3DDEVICE9でロード処理を行う。 (1)を利用すれば、DirectXが実際に何をやっているのかに関係なく、上手くは行くと思うのですが、あまり格好の良いものとは思えません。 (2)は一回試したのですが、これも偶然動いている可能性も捨てきれず悩んでいます。