「 2015年03月 」一覧

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 をフルインストールしたら結構時間がかかってしまったので、簡単に確認できたところだけ紹介したいと思います。 続きを読む


ASTCの圧縮ノイズを調べてみた


今回は期待のASTC圧縮のノイズを調べてみました。

ASTCについて

詳しいことは各所のサイトで触れられていますのでここでは簡単に。 Adaptive Scalable Texture Compression の略で、ARM が開発しました。DXTCがS3の特許関係で色々とあったためか、 ASTC はロイヤリティフリーなことも取り上げられています。
基本的には他の現世代のテクスチャ圧縮と同じくブロックごとのモードを多数持っていることが特徴です。ASTC 固有の特徴は、なんといってもブロックサイズの変更ができるということではないかと思います。

実験

ASTCではブロックサイズを変更することができ、許容できる範囲で BPP を落として削減することができます。試行錯誤の余地があるといえます。
ここでは BC7 や PVRTC への対抗と考えて、それと同じレベルの BPP でチェックをしてみたいと思います。

圧縮のためのツールとしては Mali Texture Compression Tool を用いています。圧縮品質としては最大の品質レベルを選択してデータを作成しました。

ASTC 8BPP(4×4)での結果

8BPPとなるように 4×4 ブロックで圧縮を行いました。この場合は以下のような結果となりました。次の規格レベルだけあって予想通り綺麗に圧縮できていると思われます。左右に並べたくらいではちょっとわかりません。

compare_std_astc_sample01

compare_std_astc_sample02

ツールのほうでは圧縮前後でノイズ具合も表示できるのでこちらの画像も掲載しておきます。
ノイズは割と控えめな感じかと思われます。 [続きを読む]


ETC2の圧縮ノイズを調べてみた


今回は OpenGL ES 3.0 以降で使えるようになった ETC2 について試してみました。アルファチャンネル入りでの圧縮形式として標準的に使えるようになった形式です。基本的な実装方針は ETC1 の拡張したイメージになっています。

データの作成は Mali Texture Compression Tool を用いて行っています。品質は最高品質を選んでいますが、待てないほどではないにしろ割と時間がかかるかなという印象です。その分画質はどうなっているか確認してみたいと思います。

左がオリジナル、右が ETC2 圧縮したものですがどうでしょうか。違いはぱっと見た感じでわかるでしょうか?

compare-etc2-sample01
compare-etc2-sample02

個人的には ETC1 のころと違ってよく綺麗に圧縮できているのではないかと思っています。そこで今度はこれらの一部分を拡大して確認してみたいと思います。 続きを読む


Jetson TK1 で USB WiFi ドングルを使う


以前 RaspberryPI で USB WiFi ドングルの話を書きましたが、同じものを Jetson TK1 で使えるのでは?と思って試してみました。

予想外にも、装着して起動してみても wlan0 のインターフェースは出現しませんでした。よくよく見るとドライバっぽいものはロードされており中途半端な感じです。
起動ログを確認すると rtlwifi/rtl8192cufw_TMSC.bin がロードできない意が出力されており、確かにファイルがフォルダごと存在していませんでした。

http://elinux.org/Jetson/Network_Adapters の部分を確認すると USB WiFi アダプタとしては使用可能な部類になっています。しかし丁寧にこの表の下部を読んでみるとそこにダウンロード先が書いてあります。 rtl8192cufw.bin.zip というものです。

このファイルをダウンロードして展開すると、見事に rtl8192cufw_TMSC.bin があるので、これをドライバが期待するパスに配置してあげます

これで再起動すると無事に wlan0 が使用可能状態となり、ネットワークが使用可能となりました。

またパワーマネジメント関連も同じようにあるのか?と確認したところ、
/sys/module/rtl8192cu/parameters の中にはそのような項目が存在しませんでした。
ただしばらく放置してみて、外部からTK1に向けて ping を打ってみると反応しませんでした。同じような気配です。対処する方法についてはまだ見つかっていません。

今回の件とは違う話になりますが、JetsonTK1はシステム全体がもっさりとしている気がします。Raspberry PI ではその重さとかは感じませんでしたが、同じディストリビューションではないですし、簡単に比較はできません。(Ubuntu vs Debian ですし)
RPI2が非力なことを自覚しておりそれに合わせたディストリビューション選択、および、コンポーネントの導入をしているため自分の思っていた以上に軽快に動いていた感なのかと思っています。


Direct3D9Exでフルスクリーン


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

DirectX9Exの初期化

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

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

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

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

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


PVRTC2の圧縮ノイズを調べてみた


今回は PVRTC2 の圧縮について、どのくらいの劣化が起こるのかを調べてみました。 PVRTC2 って有名なようでイマイチな感じで、これを検索キーワードにしても PVRTC1 の 2BPP モードがヒットする感じです。 PVRTC-I, PVRTC-II という表記の方がいいのかもしれませんが、 imgtec のブログでは PVRTC, PVRTC2 という記述をされているようです。

PVRTC2について

PVRTC2 は PVRTC をさらに拡張した形式となっています。基本的なブロックフォーマットはそのままに、ブロックごとの2色を記している最上位ビットに別の意味を持たせた感じにしています。それぞれに Opaque なビットは不要、他方から判定すればよし!というのは納得がいきます。
この別の意味を付与されたビットを HardBit と呼んでいます。これにより最近流行のブロックのモードを追加するということを実現しており、追加されたモードは Non-interpolated(非補間), Local palette(ローカルパレット) モードの2種類となっています。これらの仕組みから PVRTC2 は画質の向上のために用意されているようです。

参考: PVRTC,PVRTC2についての Imagination Technologies のブログ

実験

以前の BC7 のノイズ検証でも使ったデータを利用して確認してみます。PVRTC2 データの作成ついては、今のところ PVRTexTool で行えます。
このツールは前後でのノイズ(エラー)も表示させることが可能なため、以前のように別アプリで処理しなくても簡単に確認できます。ここではそのスクリーンショットを載せることで見ていきたいと思います。
注意事項としては、 BC7 と PVRTC2 を単純に比較してはいけないということです。お気づきかと思いますが、 BC7 は 8bit per pixel(BPP) であり、 PVRTC2 は 4BPP であるということです。つまり PVRTC2 が BC7 よりも2倍圧縮率が高いということで、すなわち BC7 より見た目が悪くても当然ということです。

pvrtc2-noise-sample01

pvrtc2-noise-sample02

よく言われていることではありますが、PVRTC系はアルファチャンネルも持たせられるがその場合カラーの品質が落ちる、というのが今回も健在のようです。最初の例ではアルファ抜きの部分にもノイズがありますし、アルファが変化するブロックにあるカラーブロックがひどいノイズとなっています。
アルファ不要のケースにおいてはノイズは階調が変わる輪郭部分に大きく発生していますが、等倍の目視ではあまり感じられないかと思います。 続きを読む


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


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

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

比較

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

続きを読む


OpenGLでBC7テクスチャ圧縮を使う


今回は今までにやっていそうでやっていなかった OpenGL で圧縮テクスチャを使用する方法です。
基本的には、定番のDXT1,DXT3,DXT5 などの形式をロードする方法と全く同じなのですが、意外と誰もBC6H, BC7 で書いていなかったため、情報として残しておこうと思った次第です。

BC7テクスチャ圧縮について

詳しいことは他のサイトにお任せしますが、BC7はアルファチャンネル付きでも見た目の情報劣化が少ないテクスチャ圧縮形式です。従来はこの領域では DXT5 が使用されましたが、DXT5 は意外と汚いという認識があるようです。BC7はこの点を改善していますが、今のところ圧縮時間がそれなりにかかるのが懸念点となっています。
とはいっても、GPUの支援を使い一定レベルの変換は割と早くできますし、今となっては問題も少ないんじゃないでしょうか

BC7テクスチャをどう作るか

テクスチャを使用するプログラムは難しくないのですが、データを作成するところが現時点では問題になるかと思います。
いくつか方法はあるのですが、ここではマイクロソフトの公開している方法を紹介したいと思います。

DirectXTex プロジェクト一式をダウンロードすると、その中に TexConv というプロジェクトが含まれています。これをVisualStudio で開いて、ビルドするとコマンドラインツールとしての TexConv ができあがります。

詳しいオプションはツールのヘルプを見てほしいのですが、大体以下のような感じで使えます。入力フォーマットもそこそこ対応しているようです。

通常だとGPUが支援として使える状況であればそちらを使うようで、 -nogpu というオプションをつけるとフルにCPUで演算するモードとなります。
どのくらい重い処理なのか一度試してみるのもおもしろいと思います。2048×2048 なデータで試してみると15~20分くらい返ってこなかった気がします・・・。

BC7 形式で dds 出力すると従来の DDS と違い、DX10 用のヘッダも格納されている点に注意して、ロードプログラムを作成します。

プログラム

ロードする際の肝は、従来と変わらずの glCompressedTexImage2D 関数を使用します。気をつけるポイントは前に述べたデータ開始位置が異なることでしょうか。
DDSを識別するマジックナンバー、DDSヘッダ、DX10ヘッダ の分を先頭からずらした位置が BC7データの開始位置となります。

コード例としてはこんな感じになりました。
BC7 をロードする際には、 GL_COMPRESSED_RGBA_BPTC_UNORM_ARB をフォーマットとして設定して glCompressedImage を呼び出します。また本来ならば、DDSのヘッダから画像解像度を取り出して使うべきですが、手抜きして直接 256×256 を指定してしまっています。

OpenGL-BC7

補足

BC6Hの場合には、GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB を指定します。
また、BC7のSRGBが要求されるときには、GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB を使用します。
それ以外はロードの方法に変更はありません。


Raspberry PI 2 を WiFi で運用する


特に Raspberry PI 2 に限った話ではないのでしょうが、せっかく小型な機械なので WiFi のみで使えるようにしたいなと思ってしまったのが運の尽きでした。これが意外と面倒な感じでした。

問題点その1 アダプタが高発熱

手持ちの USB-WiFi アダプタを接続したところ正常に認識してうまくつながったので OK だと思ってました。しかしながら、 USB ドングルがとてつもなく熱くなり、これはやばい!と思えるレベルになってました。USB端子部なんかUSBのカイロレベル以上でした。
そんなアダプタは Logitec の LAN-W300N/U2S というシロモノでした。

この手の熱い!という話は他にもあるようで意外と定番のもののようでした。
他の定番に熱いものとしては、WLI-UC-GNM だそうです。

解決

比較的発熱が少ないものとして定番のようだったのが プラネックスのアダプタで、 GW-USNANO2A という型番のものです。割と安価だったのもポイントで、自分は Amazon で購入しました。
同時間使ってみても発熱具合はかなりマシになりました。使ってみてUSBを抜いて端子部分を触っての確認をしてみましたが暖かさは感じますがずいぶんとマシになりました

問題点その2 PCから接続できない

Raspberry PI でネットワークを使用していたり、 PCから ssh で接続したままの状態のときには問題に気づきませんでした。しかし未接続のまま放置して、再度接続を試みると接続できない状態になっていました。 ping を打ってみても反応せず、しかし Raspberry PIでの状態を見ると IP はちゃんと降られているままですし、謎でした。

これには2つの問題点が絡んでいたと思います。
1つは有線と無線のローミング設定、もう1つがパワーセーブモードの存在です。

ローミング設定を切る

有線設定を優先するようになっていたようで、普段は WiFi を使用する前提で、設定ファイルを方を書き換えることにしました。自分の環境では以下のように /etc/network/interfaces ファイルを書き換えています。

WiFiのパワーマネージメントをオフにする

今使用している GW-USNANO2A がどのドライバを使っているか確認してみると、 8192cu というものでした。これを元に現在の状態を以下のパラメータを参照してどうなっているか確認してみます。

上記のように1が表示されました。この値の意味は、次のようになっているとのことです。
0: 省電力管理無効
1: 最小限の電力管理
2: 最大限の電力管理

というわけで電力管理が有効なようで、これを 0 となるようにしたいと思います。
/etc/modprobe.d/8192cu.conf を作成し、この中に以下の記述を入れておきます。

再起動して、再度 rtw_power_mgnt の値を表示させてみて 0 となっていれば設定完了です。

まとめ

以上の手順でとりあえず今のところは無事に WiFi で使用できるようになりました。
Raspberry PI は情報が豊富なので、丁寧に調べれば解決にたどり着けるのがよいですね

参考

Raspberry Pi: Wi-Fi USB アダプタ(Wi-Fi ドングル)の選択
Raspbian で Wi-Fi がスリープするのを防ぐ

おまけ

スループットは以下のような感じでした。おおむね満足ですね。

RPI ← PC : 38 Mbps
RPI → PC : 88 Mbps