「 DirectX 」一覧

DirectX12 でポリゴンを3D描画する その2


前回はポリゴンを3Dで表示できましたが、実は1つ問題点がありました。気付いている方もいるかと思いますが、デプスバッファがないため、複数のポリゴンから構成されるデータを描画した場合にはうまく描画できません。下図の右側のような結果を期待しても、左側のような感じになります。今回はこのデプスバッファを作って右側のような結果となるように改良したいと思います。

dx12_cube

注意事項

繰り返しの内容となりますが、以下の点をご了承ください。

現時点において DirectX12 の部分はプレビュー版となっています。正式版では大きく変更される可能性があります。よってここの情報は 2015/04 現在の限定された環境でのみ動作するという点をご理解ください。

また以下の内容は間違っている点もあるかと思います。その点にはご注意ください。

本内容は既に最新環境では正常にコンパイルできません。ご注意ください 2015/5

デプスバッファを使用した描画

キューブのデータ等はリポジトリのほうを参照してください。ここではデプスバッファを作るあたりと設定する部分を抜粋して説明していきます。

デプスバッファの作成

以下のような感じでデプスバッファ用のディスクリプタヒープやリソースを準備します。 続きを読む


DirectX12 でポリゴンを3D描画する


前回でポリゴンは描画することが出来ました。今回はこのポリゴンを3D空間上で回してみたいと思います。幸いにも DirectXMath が普通に使えるようで、今回は行列をシェーダーに渡す、「定数バッファ(コンスタントバッファ)」を DirectX12 でどのように生成&使用するのかといった点がポイントとなります。
本内容は既に最新環境では正常にコンパイルできません。ご注意ください 2015/5

注意事項

繰り返しの内容となりますが、以下の点をご了承ください。
現時点において DirectX12 の部分はプレビュー版となっています。正式版では大きく変更される可能性があります。よってここの情報は 2015/04 現在の限定された環境でのみ動作するという点をご理解ください。また以下の内容は間違っている点もあるかと思います。その点にはご注意ください。

dx12_moving_triangle

ポリゴンを回す

知っての通りポリゴンを回すために、ワールド行列、ビュー行列、プロジェクション行列を用います。これらの演算には DirectXMath を使用してしまいます。この行列を格納した定数バッファを準備する必要があるので、ここから確認していきます。
また今回は定数バッファ1つを使う前提で処理します。そのためややこしいディスクリプタヒープ等は使わないで設定する方向でいきます(自分自身あまりまだ理解できていなかったりするので) 続きを読む


DirectX12 で最初のポリゴン描画


前回は DirectX12 (D3D12) を初期化して画面のクリアを行うまでの手順でした。ようやく1つの三角形ポリゴンを描画するところまで手順がわかったので説明したいと思います。

注意事項

繰り返しの内容となりますが、以下の点をご了承ください。

現時点において DirectX12 の部分は実装途中となっています。正式版では大きく変更される可能性があります。よってここの情報は 2015/04 現在の限定された環境でのみ動作するという点をご理解ください。

なおMSDNドキュメントですら不十分な状況で手探りで動作させたため、以下の内容は間違っていることが多く含まれる可能性があります。その点にはご注意ください。

本内容は既に最新環境では正常にコンパイルできません。ご注意ください 2015/5
dx12_triangle

最初の三角形描画

前回で画面のクリアまでの手順については把握できたので、今回は初めての描画に必要なデータを用意するところから説明します。なお以前のコードからリファクタリングしたコードをベースとして今回は作成しています。 GitHub にコードをあげてありますので気になる人は(&全貌を確認したい人)はそちらを参照お願いします。 続きを読む


DirectX12 で画面クリアまでの最小サンプル実装


DirectX12 を使っての画面クリアまでの処理について、先日の内容をより洗練させることができました。前回のものは手探り状態だったのもあって無駄な部分が紛れ込んでいました。具体的には、実は RootSignature はもっと簡単でよかったこと、 ID3D12DescriptorHeap は1つでも実装上問題なかったことです。
多くの部分で繰り返しとなりますが、改めて画面クリアまでの実装をチュートリアル的に確認していきたいと思います。
本内容は既に最新環境では正常にコンパイルできません。ご注意ください 2015/5

注意事項

現時点において DirectX12 の部分は実装途中となっています。正式版では大きく変更される可能性があります。よってここの情報は 2015/04 現在の限定された環境でのみ動作するという点をご理解ください。

なおMSDNドキュメントですら不十分な状況で手探りで動作させたため、以下の内容は間違っていることが多く含まれる可能性があります。その点にはご注意ください。


2015/04/11 従来実装と違いアロケーター1つで処理できるようにできたため該当部分だけコード例を修正しました。正しい内容は、GitHubのコードリポジトリをご参照ください。

必要なもの

  • VisualStudio 2015 CTP6
  • VisualStudio Tools for Windows10 Technical Preview
  • Windows10 Technical Preview 10041

d3d12_clear

とりあえず上記のように画面のクリア処理がうまく動くようになりました。結構手間取ったので喜びもなおさらです! 続きを読む


DirectX12 で画面クリアまで (祝)


DirectX12 (D3D12) を使ってようやく画面のクリアだけエラーも起こらず動作させることができるようになりました。そもそも SDK が正式版ではないので、今後変更されることもあると思います。それでも気になる人のために、コードをさらしてみたいと思います。Windows8.x以降、 Win32 アプリケーションは肩身が狭くなってきた感がありますが、ここでのサンプルは相変わらず Win32アプリケーションで作成してみました。
以下の内容は既に古くなっています。以下のコードでも動きますが、よりコード量の少なくなったこちらの記事を参考にどうぞ
本内容は既に最新環境では正常にコンパイルできません。ご注意ください 2015/5

必要なもの

VisualStudio 2013 でも作業できそうに思いますが、すべて最新の状況で作業しました。作業している最中に Windows10 は 10049 に上がっちゃいましたが。以下のものをインストールしました。

  • VisualStudio 2015 CTP6
  • VisualStudio Tools for Windows10 Technical Preview
  • Windows10 Technical Preview 10041

d3d12_clear

とりあえず上記のように画面のクリア処理がうまく動くようになりました。結構手間取ったので喜びもなおさらです! 続きを読む


DirectX12を触ってみた(不完全)


DirectX12 (D3D12) を使って画面のクリアまでは簡単にやれるかなと思っていたのですが、そこまでたどり着けませんでした。先日のドキュメント参照しながらやっているだけでは不十分で、ちょっと試行錯誤&ヘッダの探索なども必要でした。

自分の現状ではこんなところですが、これからトライされる方々にちょっとでも参考になればと思って、いくらかメモを残しておこうと思います。以下の項目は自分がとても時間がかかってしまったポイントばかりです。

なお、正式な情報が見当たらないため、ここにある情報も正しいどころか間違っている可能性もとても高いのでその辺はご了承くださいませ。なお以下の話はすべて Win32Application で C++ のみでやってます。

GetDefaultCommandQueue は無い

ドキュメントでは ID3D12Device から GetDefaultCommandQueue なる API があるように書かれていますが、実際のところは存在しません。
これについては、 D3D12_COMMAND_QUEUE_DESC に値をセットして自分で明示的に ID3D12CommandQueue を作成して対処しました。

SwapChainの作成

ドキュメントの方では ID3D12Device から QueryInterface で IDXGIDevice2 インターフェイスを取得するようになっています。しかしながら手元の環境ではこのインターフェースを取得することが出来ませんでした。 WARP デバイスが悪いのかと思い、 GCN 世代のボードと換装してトライしましたが同様の結果でした。
結局のところは CreateDXGIFactory2 関数から IDXGIFactory2 をもらうことでスワップチェインの作成を行っています。

ID3D12CommandListについて

ID3D12CommandList ではなく、 ID3D12GraphicsCommandList を生成する必要があるようです。そうしないと、グラフィックス用のいろいろなメソッドが使用できませんでした。たとえば、 SetDescriptorHeaps, ClearRenderTargetView など。
また、直接はコマンドキューに積めないので、 CommandListCast というキャスト用関数を介してキューに積むようにしています。これもヘッダの中を探索していて発見した関数です。もしかしたらMSDN ドキュメントに記載があったかもしれませんが・・・。

以降は、さらに不確定さ怪しさが高いので、概要だけにしておきます。 続きを読む


ついにDirectX12 を触れるようになったようです!


Windows 10 Technical Preview と VisualStudio 2015 Preview CTP6 により、とうとう一般の開発者でも DirectX12 (D3D12) のプログラムを作れる&試せるようになってきました。また MSDN のドキュメントとしても次の場所に公開されたので、 dll だけあるけど使い方がわからないというような状況から抜け出せたようです。

このような状況になったので、手元の物理 PC に早速 Windows10 Technical Preview (Win10TP) をインストールし、VS2015CTP6 も導入を開始しました。 CTP6 をフルインストールしたら結構時間がかかってしまったので、簡単に確認できたところだけ紹介したいと思います。 続きを読む


Direct3D9Exでフルスクリーン


DirectX9 でのフルスクリーンのサンプルはそこそこ見かけるのですが、DirectX9Ex でのフルスクリーンのサンプルってほとんど見かけないので作ってみました。通常の DirectX9 とほとんど同じで、違う箇所は初期化のところだけだったのでその部分だけを本記事では紹介したいと思います。

DirectX9Exの初期化

Direct3DCreate9 の代わりに Direct3DCreate9Ex を使用します。引数がちょっと変わっています。
そして定番の D3DPRESENT_PARAMETERS を設定します。本来はもうちょっとモニタの設定とか確認したりエラーチェック入れたりする必要があるのですが、サンプルなので省略してます。

ここでのポイントは特にないと思います。続いて CreateDeviceEx を呼び出してデバイスを作成するのですが、こちらの方には気をつけるポイントが存在します。まずはコードを示します。

ポイントとは、Windowモードの時には D3DDISPLAYMODEEX を設定してはならない点、フルスクリーンのときには設定が必須となる点が1つです。もう1つは D3DPRESENT_PARAMETERS のリフレッシュレート設定と DISPLAYMODEEX のリフレッシュ設定を同じにしなくてはならない点です。適当にゼロを入れておくのでは関数が失敗となります。

この関数が成功したらあとは通常の DirectX9 と変わらないです。

今回は不遇の扱いをされているDirectX9Ex のしかもほとんど情報がなさそうなフルスクリーンをやってみました。通常の DirectX9 と違い DirectX9Ex ではデバイスロストの問題も発生しないですし、割と使いやすいものだと思います。 Vista 以降を必須とする点はちょっとマイナスかもしれませんが、毛嫌いするほど出来が悪いとも思えないんですよね~


BC7の圧縮ノイズについて調べてみた


優秀だという BC7 圧縮の品質がどんなものか調べてみました。
そのためにはそこそこの品質以上の画像データが必要だったので友人に協力してもらい画像を使わせてもらっています。
この場を借りてお礼申し上げます。

BC7への圧縮については Codeplex からダウンロードできる Microsoft の TexConv を使用しています。この最高品質となる CPU で処理した結果ではなく、 GPU を用いた速度とのバランスがとれているであろうモードを選択しています。

比較

いきなりですが圧縮前後の画像を比較してみます。
左が圧縮前、右が圧縮後のデータです。圧縮ノイズなどは確認できるでしょうか?自分では等倍でぱっと見た感じわかりませんでした。心持ち髪の毛曲線部とアルファの部分でノイズが気になるかも程度です。
compare_std_bc7_sample01
compare_std_bc7_sample02

続きを読む


DirectX9 on Windows 7 でメモリの消費調査


今回は DirectX 9.0 を用いた場合ではどんな感じになるのかを調べてみました。環境は Windows 7 (x64) です。また DirectX 9.0 と表記していますが、実際のところは DirectX 9.0 EX のことを指すものとします。

Windows XP までの頃は VRAM の仮想化というものがなく、デバイスロスト発生のためのケアが必要になっていました。その代わり VRAM にデータを送ってしまい、メインメモリは消費しないということができたように思います。(もしかするとできていなかったのかもしれませんが、今更検証価値も低そうなので手元でテストしていないです・・・。)
一方で Windows 7 になってVRAM仮想化が導入され、VRAMの空き容量など取得が難しくなってきました。 DirectX 9.0 は動くものの、その挙動は XP のころとはまた違ったものになっていると予想されます。それなのに検証をしていないままだったので、 VRAMの情報取得という武器ができた今、調べてみようと思ったわけです。

NVIDIA (Geforce9800) の場合

安定状態になってから頂点バッファ 32MB を D3DPOOL_DEFAULT にて作成しました.

状態 メモリ(MB) Dedicate(MB) 共有メモリ(MB)
定常状態 1054.6 47 13
VertexBuffer作成 1回目 1086.7 80 13
VertexBuffer作成 2回目 1119.3 112 13

どの場合においてもメインメモリ 32MB 程度消費し、Dedicate のメモリ 32MB ほど消費している結果となりました。

AMD (RADEON) の場合

状態 メモリ(MB) Dedicate(MB) 共有メモリ(MB)
定常状態 1028.9 45 22
VertexBuffer作成 1回目 1061.1 77 22
VertexBuffer作成 2回目 1093.8 109 22

こちらの場合においてもメインメモリ 32MB 程度消費し、Dedicate のメモリ 32MB ほど消費している結果となりました。

実験その2

描画フレームを回しながら、 100 フレームごとに頂点バッファを確保し描画するという定番のプログラムで実験してみました。
上記の消費メモリが永続的なものではなくテンポラリ扱いならば、相当の数のバッファが作れるはずです。

しかし予想外の結果になりました。

メインメモリの消費が、自分のプロセスに対して発生していました。どうやら D3DPOOL_DEFAULT では自プロセスのどこかにバックアップのバッファが存在するようです。

GTX 750Ti 2GB の状態で普通の 32bit アプリケーションで実行の場合には、x64環境といえども、 1プロセスで使えるサイズは 2GB まで。そのため VRAM 使用量が 1GB 程度のところで DirectX がバッファの作成に失敗しました、とエラーを出しました。このときのプロセスの状況を調べてみましたが、消費されている仮想アドレスが 2GB 近かったです。
 一方で、 32bit アプリで LAA オプションをつけて再実行してみると、今度は VRAM 使用量は 1.7GB 程度にまでなり、プロセスの仮想アドレス使用量は 4GB 近くにまでなっていました。

※ このプロセス内での状況を知るのに VMMap というツールは便利です。

まとめ

DirectX 9.0 の場合においては NVIDIA も AMD も同じような挙動となることを確認できました。またどちらの場合においても使用するリソース分、メインメモリも消費していることが確認できました。これはこれで挙動把握さえできてしまえば、扱いやすそうです。
ただ注意が必要であると感じたのが、自分のプロセスの仮想アドレス空間にバックアップ先を確保するため、メモリ不足よりも自身の仮想アドレス空間を枯渇させてしまうのが早そうに思います。 64bit 環境を必須とするなら 32bit アプリケーションの場合、 LAA 必須といってもいいレベルだと思いました。
 この場合、よいビデオボードを使っていて 「 4GB の VRAM 全部使いきる DirectX 9.0 アプリケーションを開発してやるぞ。 ただし 32bit アプリケーションだけどなっ」 という夢はかなわないことが判明しました。そんな人は少数派だとは思いますが・・・。