2017-02-10 11 views
1

ペンタブの入力を待ち受け、頂点/インデックスバッファから描画を行うレンダリングループがあります(とりわけ)。頂点データは成長することができ、それが特定のレベルに達したとき、DispatchMsg(& MSG)は、この遭遇:DirectX11のビデオメモリを超えました

シーンに割り当て頂点およびインデックスバッファの合計サイズは、同じレベルの周りに各時間である
Unhandled exception at 0x5DDBDEF0 (msvcr110d.dll) in App.exe: 0xC0000005: Access violation writing location 0x00000000. 

Total Vertices count: 10391370 
Total Indices count: 41565480 
Total Vertices size: 249392880 (bytes) 
Total Indices size: 997571520 (bytes) 

、別のサンプリングで :

Total Vertices count: 9969300 
Total Indices count: 39877200 
Total Vert size: 239263200 
Total Indices size: 957052800 

頂点とインデックスバッファが両方D3D11_USAGE_DEFAULTです。シーンの合計サイズの割り当ては上記の値よりも高くなっていますが、小さいバッファは頻繁に解放されます。最後の頂点/インデックスバッファにはいくつかのパディングもあります。

(例外が到達する)たびに派遣されようとしているメッセージは、私がかもしれ信じていた、581です:

#define WM_POINTERUPDATE    0x0245 

私は本当にゆっくりとレンダリングシーンを気にしませんが、私はあればいくつかの最大メモリ割り当て(ビデオメモリ?)に達すると、メモリは速度を犠牲にしてマインドメモリに/からゆっくりとページングする方法がありますか?私は、ピクセル、頂点シェーダー、および描画呼び出しを呼び出すdraw()呼び出しを無効にしようとしましたが、例外はまだ発生します。私は、速度のトレードオフや回避策を例外的に好むだろう。

+0

あなたが描いている頂点の数はいくつですか?それは多くのデータのようです。 1000万バーツ? – tadman

+0

正解、それは高いようですので、私はある時点で問題を予期しています、理由を理解したい、またはそれについて何ができるかを知りたいのです。 – user176692

+0

それはたくさんのvertsです。私はあなたが火を引く何もせずに多くを割り当てることができたのに驚いています。あなたは何とかそれらを漏らすように、あまりにも多くを作成していますか? – tadman

答えて

1

あなたの質問内の番号から、あなたが(1.2ギガバイト程度)あなたの頂点とインデックスデータのために多くのメモリを割り当てているようです。あなたのアプリが32ビット(x86、x64ではなく)の場合は、2GBのメモリにしかアクセスできないため、プロセスのメモリが不足している可能性があります。

GPUは、(GPUメモリに比べて非常に遅い、ないメモリに全てよりも良好な)システムメモリの一部へのアクセスを有します。たとえば、NVidia GPUの場合、NVidiaコントロールパネルには「システム情報」>「共有システムメモリ」の下に表示されます。これは通常、システムのRAMの総量の半分です。私が知っている限り、このシステムメモリはプロセスのアドレス空間の一部を占めています。

"かなり古い" GPUに512MBのメモリがある場合は、メモリ要求を満たすために約768MBの追加システムメモリが必要です。このため、アプリケーションには1.2GBが残ります。あなたのアプリケーションは、あなたがGPUにアップロードしたいジオメトリデータを取るアレイに1.2GBのシステムメモリを割り当てようとしていると思います。これはちょうどいいでしょうが、あなたのアプリケーションコードもどこかにある必要があります。この仮説的なケースでは、すでにメモリ不足になっています。もちろん、ジオメトリデータをGPUにアップロードした後は、システムメモリ配列を取り除くことができますが、この時点では、要求されたサイズのGPUメモリバッファを作成するのに十分なメモリがシステムにありません。

64ビット(Visual Studioではx64)にプロジェクトを切り替えると、プロセスが大幅に多くのメモリ(ほとんどの場合、システムとページファイルで使用できるものまで)を使用して問題を解決できます。メモリの制約が実際に問題である場合。

別のこと:あなたの数字が正しいと仮定して、インデックスバッファのインデックスごとに24バイトを割り当てます。頂点バッファの各頂点に割り当てるのと同じくらいです。あれは正しいですか?インデックス(頂点バッファへの単なるオフセット)は4バイトを超えてはいけません。あなたが実際に必要とするGPUメモリの6倍を割り当てようとしていますか、それともあなたのアプリケーションで誤った計算ですか?

GPUでバッファをすばやく解放してから再作成すると、D3Dは「古い」バッファをしばらく(GPUパイプラインにバインドされている限り)保持している可能性があります。そのために記憶が不足している。したがって、あなたが解放しようとしているバッファを実際にアンバインドするのに役立つかもしれません(IASetVertexBuffers(NULL, 0, 0, 0, 0)IASetIndexBuffer(NULL, DXGI_FORMAT_R16_UINT, 0)を呼び出すことによって)。

+0

インデックスの割り当てはオフになっている可能性がありますが、各頂点はピラミッド型またはダイアモンド型のシェイプを構築するためにかなり再利用されていました。これは、リアルタイムレンダリングのためのコントロールポイントとテッセレーションシェーダ、またはオフラインレンダリングのための球体に置き換えられています。 32ビットのアドレス空間は大きな問題ですが、これを言及してくれてありがとう、私はそれを完全に見落としました。私が構築したいくつかの32ビットライブラリを使用しており、それらを移植する必要があります。また、W5100 Fireproを使用して、メモリ機能も拡張します。 – user176692

+0

あまりにも高いように見えるインデックスの数(再利用インデックスFTW)ではなく、インデックスが占めるメモリの量(バイト数)であることは明らかです。あなたの最初の例の41565480インデックスは、41565480 * 4 = 166261920バイト(166MB)を占めるが、あなたの質問によれば997571520バイト(997MB!)が割り当てられ、32ビットプロセスのメモリ制限。記載されているメモリの量はインデックスの数に24を掛けたもの(頂点のサイズ)なので、インデックスバッファサイズの計算や入力ミスでエラーになる可能性があります。 – Pepor

+0

そうだと思います!これがコメントアウトされていたのですが、どのデバッグメッセージを使用していたのかわかりませんでした。debugMsg( "Ind size:" + iToS(sizeof(Vertex)* editingModel-> builtIndicesCount));だから私はデバッグログに間違って表示するだけで、割り当ては少なくなっていました。すでにコントロールポイントを使用し、ジオメトリの作成方法を変更しますが、良いキャッチ! – user176692

1

答えを見つけて問題を解決しました。私の入力頂点数によっては、CreateBufferが失敗したか、malloc/HeapAllocが失敗していました。

GPUが特定のポイントの後でメインシステムメモリにページングメモリする必要がある場合、または各フレームの計算中にシーンデータがGPUメモリ上に残る必要があるため避けられない場合は、私は手動でバッファを解放/再割り当てすると(おそらく遅くなる)、B)allocされたバッファ(頂点、インデックスなど)のサイズが問題はなく、フレームごとの計算ではありません。

他のバッファ使用(USAGE_DYNAMIC)に切り替えようとしましたが、割り当ての失敗は同じレベルで発生しました。

私はバッファサイズ(パディングが必要なバッファ)をすばやく変更しました。今は少なくとも2,000万個の頂点までです。私のGPUはかなり古いので、それほど悪くはないが、レンダラーの中にはこれを越えてうまくいくかもしれないが、わかっている。

回避策に焦点を当て、可能な限り詳細を絞り込みます。私はテクスチャで15倍以上の詳細を得ることができると思うので、悪い形ではありません。

これ以上の洞察力を持っている人は、あなたの回答を正解に切り替えることができますが、ここで別の経路を取るかどうかはわかりません。

関連する問題