DynamicTextureの制限

あまり使われることは無いDynamicTextureですが、制限や特別な仕様についてあまり資料が無かったのでメモしておこうと思います。


DynamicTextureは高速にCPUからTextureにメモリ転送させることを目的としたものとかそういうのは省いて、「D3DUSAGE_DYNAMIC,D3DPOOL_DEFAULT」を指定してテクスチャを生成します。
で、Lockでは「D3DLOCK_DISCARD」を使用するというのがセオリーです。


■Lock領域の制限
DirectXリファレンスを見る感じでは領域制限についての表記は無かったのですが、少なくてもうちの環境下ではLock時の領域に制限があります。

・成功
Texture.LockRect(0, lockRect, Nil, D3DLOCK_DISCARD);
・失敗
Texture.LockRect(0, lockRect, @rect, D3DLOCK_DISCARD);

常に全域をLockすることしか許されず、領域を指定すると問答無用でエラーを返します。
例え全領域を指定したrect構造体であっても、エラーを返します。
一部だけの更新で済む場合であっても、全領域分の更新が必要になる点に注意が必要です。


■更新は常に全ピクセルを書き換えること
Lockして内容を更新する際、必ず全ピクセルを書き換える必要があります。
Lockは書き込みのみ(WriteOnly)は勿論のこと、前回の内容は一切残っておらず、真っ黒のさら地が用意されます。
なので、最適化のため必要な箇所だけ書き換えると(上半分とか)、下半分が真っ黒になります。
動画再生では全画面更新が当たり前なので問題ないのですが、全画面更新をいつも必要が無い場合や、常に一部だけの更新で済むものの場合は、逆にDynamicTextureを使わないほうが効率的になる場合もあるでしょう。


とこの2点が重要な制限かと思います。
ManagedTextureでも転送は結構速いので、場合によってはそちらを使うことも悪くないでしょう。


なんで制限がわかったかというと、「必要更新領域を最小になるように最適化」して「奇数ライン・偶数ライン交互に転送して負荷軽減」なんてしていたら、両方とも制限にかかっちゃったってわけですよ。
ぐてぇ