通常描画は成立する
本編画面は継続して表示され、セーブ画面も操作できる。描画全体の停止ではない。
GetBuffer(index > 0) を、Present後も保持されているback bufferへ対応させる
要旨: 64bitのD3D11アプリケーションをDXVKで動かすと、通常描画とセーブ処理は完了する一方、セーブスロットに表示されるサムネイルだけが黒くなった。保存ファイルではなく、swapchainから画像を読み戻す境界に原因があった。
本編画面は継続して表示され、セーブ画面も操作できる。描画全体の停止ではない。
保存処理そのものは成功する。壊れているのは記録用画像の取得だけだった。
特定の画像や動画に依存せず、セーブするたびに同じ症状を再現した。
セーブ操作と同時に、DXVKのGetImageが要求を拒否していた。
セーブ操作の直前からDXGIとDXVKのログを照合すると、毎回同じ一行が現れた。
err: D3D11: GetImage: BufferId > 0 not supported
ゲーム側は、セーブ画面のUIが重なる前に表示していたシーンを使うため、IDXGISwapChain::GetBuffer(index > 0)を呼んでいた。観測したDXVK実装はback bufferを1枚だけ扱い、非ゼロのindexを未対応として拒否していた。
「黒いサムネイル」という症状名だけで既存修正を横展開せず、実際に通るAPIを基準に切り分けた。
セーブデータとサムネイル用ファイルは作成される。失敗点は、書き込み前の画素取得に限定できた。
動画を表示できる構成へ変更した後も、非ゼロのbuffer要求は同じ場所で拒否された。動画の合成経路を直しても解消しない。
CMVSの事例はGetBackBuffer + LockRectを使うD3D9経路だった。本件はD3D11/DXVKのGetBuffer経路なので、修正対象が異なる。
D3D11SwapChain::GetImageで要求が終端していた。画面を新しく保存する仕組みではなく、保持中のback bufferを返す互換処理が必要だった。
修正は履歴バッファを追加するものではない。Present後も次の描画まで内容が残るback buffer 0を、非ゼロの要求にも返す。
Gcenx/DXVK-macOS 1.10.x系のソースを再ビルドし、D3D11SwapChain::GetImageの非ゼロ要求だけを変更した。
従来はBufferId > 0なら即座に未対応を返していた。修正後は、DXVKが保持しているm_backBufferを画像取得元として返す。
パッチはx64/x32のD3D11 DLLとして再ビルドできる形で管理し、同梱ランタイムへ反映した。
BufferId > 0 - return UNSUPPORTED + image = m_backBuffer Present後の内容 + 次の描画まで利用
GetBuffer(index > 0)を使う経路に限定する。