Direct3D 10 に関してよく寄せられる質問

XNA デベロッパー コネクション (XDC)

2008 年 6 月

ここでは、既存のアプリケーションを Direct3D 9 (D3D9) から Direct3D 10 (D3D10) に移植しようとする開発者から Direct3D 10 に関してよく寄せられる質問の一部を掲載します。

  • 定数バッファー
  • ステート
  • フォーマット
  • シェーダー リンケージ
  • 描画呼び出し
  • リソース
  • テクスチャーとしての深度
  • MSAA
  • クラッシュ
  • プレディケート レンダリング
  • ジオメトリ シェーダー
  • HLSL

定数バッファー

定数バッファーを更新するための最善の方法を教えてください。

サブリソースをつかって更新するか自前でマッピングしたりそれを破棄したする場合は、双方で同じ速度で行う必要があります。コピーするメモリー量が最小限になる方を選択してください。データが既にメモリー内で 1 つの連続ブロックに格納されている場合は、UpdateSubresource を使用します。他の場所からデータを集積する必要がある場合は、自前でマッピングしたりそれを破棄します。

定数バッファーの最もよくない構成とはどのようなものでしょうか。

特定のシェーダーのすべての定数を 1 つの定数バッファーに格納すると、パフォーマンスが最低となります。D3D9 から D3D10 に移植する方法としてはこれが最も簡単ですが、パフォーマンスを損なう可能性があります。たとえば、次の定数バッファーを使用するシナリオについて考えてみます。

cbuffer VSGlobalsCB
{
    matrix  ViewProj;
    matrix  Bones[100];
    matrix  World;
    float   SpecPower;
    float4  BDRFCoefficients;
    float   AppTime;
    uint2   RenderTargetSize;
};

このバッファーは 6560 バイトです。1000 個のオブジェクトをレンダリングするアプリケーションがあり、そのうちの 100 個はスキン メッシュ、900 個はスタティック メッシュであるとします。また、このアプリケーションで、光源を 1 つ持つシャドウ マップを使用しているとします。つまり、ライトからレンダリングされる深度マップのパスとフォワード レンダリング パスの 2 つのパスが存在します。その結果、2000 回の描画呼び出しが行われます。毎回の描画呼び出しで定数バッファーのすべての部分を更新する必要はありませんが、依然として定数バッファー全体が更新され、カードに送信されています。このため、フレームごとに 13 MB のデータが更新されることになります (2000 回の描画呼び出しに 6560 KB を乗算した大きさ)。

定数バッファーを構成するための最善の方法を教えてください。

更新の頻度別に定数バッファーを構成するのが最善の方法です。ほぼ同じ頻度で更新される定数を、同じバッファーに格納してください。たとえば、「定数バッファーの最もよくない構成とはどのようなものでしょうか」で示したシナリオで、定数のレイアウトが次のように改善されたとします。

cbuffer VSGlobalPerFrameCB
  { 
    float   AppTime; 
  };
cbuffer VSPerSkinnedCB
  { 
    matrix  Bones[100]; 
  };
cbuffer VSPerStaticCB
  {
    matrix  World;
  };
cbuffer VSPerPassCB
  {
    matrix  ViewProj;
    uint2   RenderTargetSize;
  };
cbuffer VSPerMaterialCB
  {
    float   SpecPower;
    float4  BDRFCoefficients;
  };
    

定数バッファーがその更新頻度で分けられていますが、解決策としてはまだ半分です。この分割を最大限に活用するには、アプリケーションで定数バッファーを正しく更新する必要があります。前述のシーンをもう一度想定します。つまり、900 個のスタティック メッシュ、100 個のスキン メッシュ、1 つのライト パス、そして 1 つのフォワード パスがあります。また、オブジェクトごとにいくつかの定数バッファーが格納されるとします。つまり、スキンとスタティックのどちらであるかに応じて、各オブジェクトに VSPerSkinnedCB または VSPerStaticCB が格納されます。この操作には、パイプラインを通じて送信される行列の量が倍増するのを防ぐ目的があります。

フレームを 3 つのフェーズに分割します。最初のフェーズはフレームの始まりで、レンダリングは行われず、定数の更新だけが行われます。

開始フレーム

  • アプリケーション時間用の VSGlobalPerFrameCB を更新 (4 バイト)。
  • 100 個のスキン オブジェクト用の 100 個の VSPerSkinnedCB を更新 (640000 バイト)
  • 900 個のスタティック オブジェクト用の VSPerStaticCB を更新 (57600 バイト)

次はシャドウ マップ パスです。実際に更新する定数バッファーは VSPerPassCB だけであることに注意してください。それ以外の定数バッファーはいずれも開始フレーム パスで更新されています。これらの定数バッファーをバインドする必要はありますが、バッファーは既に更新されているので、ビデオ カードに渡される情報量はごくわずかです。

シャドウ パス

  • VSPerPassCB を更新 (72 バイト)
  • 100 個のスキン メッシュを描画 (100 回のバインド、更新なし)
  • 900 個のスタティック メッシュを描画 (900 回のバインド、更新なし)

同様に、フォワード レンダリング パスでは、データがメッシュ単位で格納されていないため、マテリアル単位でデータを更新する必要があります。仮に、シーンで 500 個のマテリアルが使用されているとします。

フォワード パス

  • VSPerPassCB を更新 (72 バイト)
  • 500 個の VSPerMaterialCB を更新 (10000 バイト)

この結果、合計はわずか 707 KB となります。このシナリオはかなり不自然ではありますが、定数を更新頻度別にソートすることで定数更新のオーバーヘッドをいかに削減できるかを示しています。

メッシュやマテリアルなどに個別の定数バッファーを格納できるだけのスペースがない場合はどうすればよいですか。

階層化された定数バッファーを随時使用できます。目標とする必要な定数バッファー サイズに達するまで、可変サイズのバッファー (16 バイト、32 バイト、64 バイトなど) を作成します。定数バッファーをシェーダーにバインドする段階になったときに、シェーダーが必要とするデータを保持できる最小限の定数バッファーを選択します。この方法は効率が若干劣りますが、中間のステップとして効果的です。

複数のシェーダー間で定数バッファーを共有しています。定数を全部使用しているシェーダーもあれば、一部しか使用していないシェーダーもあります。このようなバッファーを更新するための最善の方法を教えてください。

1 つの方法として、定数バッファーをさらに分割することができます。ただし、バインドする定数バッファーが多くなりすぎることがあります。その場合は、複数のシェーダーが使用していない可能性がある定数を、定数バッファーの最後に移します。シェーダーから変数データを取得する際に、D3D10_SHADER_VARIABLE_DESC から D3D10_SVF_USED フラグを使用して、その変数が使用されているかどうかを確認します。使用されていない変数を定数バッファーの最後に配置することで、その変数を使用しないシェーダーに小さなバッファーをバインドできるので、更新の負荷が軽減されます。

キャラクターのボーンを、パス/描画ごとに 1 回ではなくフレームごとに 1 回だけアップロードすると、フレーム レートはどの程度上がりますか。

フレーム レートは、冗長なデータの量に応じて 8 ~ 50 パーセント高めることができます。最悪のケースでも、パフォーマンスが低下することはありません。

1 回にバインドする定数バッファーはいくつにする必要がありますか。

すべてのデータをシェーダーに送るために必要な最小数の定数バッファーをバインドしてください。現実的なシナリオで、使用する定数バッファーの数として推奨されているのは 5 つです。シェーダー間で定数バッファーを共有 (頂点シェーダーとピクセル シェーダーに同じ定数バッファーをバインド) することで、パフォーマンスが向上する可能性もあります。

使用していない定数バッファーをバインドすると負荷がかかりますか。

かかります。バッファーを実際に使用する予定がない場合は、VSSetConsantBuffer や PSSetConstantBuffer を呼び出さないでください。複数の描画呼び出しにわたって、この余分な API のオーバーヘッドが累積される可能性があります。

ステート

D3D10 でステートを管理するための最善の方法を教えてください。

事前にすべてのステートを把握し、ステート オブジェクトを作成しておくことです。つまり、レンダリング時にはステートのバインドだけが行われるようにします。D3D10 が重複するステートの除去も行います。

私のゲームでは、コンテンツが動的にロードされたりユーザーによって生成されたりします。すべてのステート オブジェクトを事前にロードすることができません。どうすればよいですか。

2 つの解決策があります。1 つは、ステート オブジェクトをその場で作成し、D3D10 に重複するオブジェクトの除去を任せる方法です。ただし、フレームあたりのステート オブジェクト変更回数が多いシナリオでは、この方法はお勧めできません。より適切な解決策は、ステート オブジェクトを自分でハッシュし、要件を満たすステート オブジェクトがハッシュ テーブルに見つからない場合にのみステート オブジェクトを作成することです。カスタム ハッシュ テーブルを使用する理由は、アプリケーションが独自の使用シナリオに基づいて高速ハッシュを選択できるからです。たとえば、アプリケーションが BlendState で rendertargetwritemask のみを変更し、それ以外の値を一切変更しない場合は、アプリケーションで構造全体ではなく rendertargetwritemask からハッシュを生成できます。

AlphaTest ステートが見あたりません。どこにあるのでしょうか。

AlphaTest はシェーダーで実行されるようになりました。FixedFuncEMU サンプルを参照してください。

ユーザー クリップ面はどうなったのですか。

ユーザー クリップ面はシェーダーに移されました。これを処理するには、2 つの方法があります。1 つは、頂点シェーダーまたはジオメトリ シェーダーから SV_ClipDistance を出力する方法です。もう 1 つは、頂点シェーダーまたはジオメトリ シェーダーから渡された値を基に、ピクセル シェーダーで discard を使用する方法です。両方を試してみて、自分のシナリオではどちらが処理が速いかを確認してください。SV_ClipDistance を使用すると、ハードウェアでジオメトリベースのクリッピング ルーチンが使用され、ジオメトリにバインドされた描画呼び出しの実行が遅くなる場合があります。同様に、discard を使用すると作業がピクセル シェーダーに移されて、ピクセルにバインドされた描画呼び出しの実行速度が遅くなる場合があります。

ラスタライザー ステートでのシザー矩形設定などのステート設定が、クリアで考慮されません。

クリアはパイプライン ステートと切り離されました。D3D9 形式の動作にするには、フルスクリーン クワッドを描画することでクリアをエミュレートします。

レンダリング エラーを試して診断する目的でステートを既定値に戻しました。画面にオブジェクトを描画しているのですが、画面は黒いだけで何も表示されません。

ステートを既定値 (NULL) に戻す際に、OMSetBlendState の呼び出しで SampleMask をゼロにしないでください。SampleMask がゼロに設定されていると、すべてのサンプルでゼロとの論理積が計算されます。このシナリオでは、どのサンプルもブレンド テストを通過しません。

D3DSAMP_SRGBTEXTURE ステートが見あたりません。

SRGB はサンプラー ステートから削除され、現在はテクスチャー フォーマットに統合されています。SRGB テクスチャーをバインドすると、Direct3D 9 で D3DSAMP_SRGBTEXTURE を指定した場合と同じサンプリングが得られます。

フォーマット

D3D9 フォーマットと D3D10 フォーマットの対応関係を教えてください。

DirectX SDK の「Direct3D 9 から Direct3D 10 への移行時の考慮事項」を参照してください。

A8R8G8B8 テクスチャー フォーマットはどうなったのですか。

D3D10 で非推奨となりました。テクスチャーを R8G8B8A8 として再取得するか、ロード時にスィズルするか、シェーダーでスィズルすることができます。

パレット化テクスチャーはどのように使用するのですか。

カラー パレットをテクスチャーまたは定数バッファーに配置し、パイプラインにバインドします。ピクセル シェーダーでは、パレット化テクスチャーのインデックスを使用して間接的なルックアップを実行します。

新しい SRGB フォーマットとはどのようなものですか。

SRGB はサンプラー ステートから削除され、現在はテクスチャー フォーマットに統合されています。SRGB テクスチャーをバインドすると、Direct3D 9 で D3DSAMP_SRGBTEXTURE を指定した場合と同じサンプリングが得られます。

トライアングル ファンが見あたりません。

トライアングル ファンは D3D10 で非推奨となりました。トライアングル ファンは、コンテンツ パイプラインで、またはロード時に変換する必要があります。

シェーダー リンケージ

Direct3D 9 シェーダーが問題なくシェーダー モデル 4.0 にコンパイルされましたが、これをパイプラインにバインドすると、デバッグ ランタイムによるデバッグ出力にリンケージ エラーが表示されます。

シェーダー リンケージは、D3D10 で大幅に厳密化されました。後続のステージの要素は、前のステージで出力された順に読み取る必要があります。次に例を示します。

頂点シェーダーからの出力 :

    float4 Pos  : SV_POSITION;
    float3 Norm : NORMAL;
    float2 Tex  : TEXCOORD0;

ピクセル シェーダーでの読み取り :

        float3 Norm : NORMAL;
        float2 Tex  : TEXCOORD0;
      

ピクセル シェーダーでは位置は不要ですが、頂点シェーダーから位置が出力され、ピクセル シェーダーで位置が読み取られていないために、この処理はリンケージ エラーとなります。この誤りが解消されているのが次のバージョンです。

頂点シェーダーからの出力 :

        float3 Norm : NORMAL;
        float2 Tex  : TEXCOORD0;
        float4 Pos  : SV_POSITION;
      

ピクセル シェーダーでの読み取り :

        float3 Norm : NORMAL;
        float2 Tex  : TEXCOORD0;
      

この場合、頂点シェーダーは同じ情報を出力していますが、ピクセル シェーダーはその情報を出力された順に読み取っています。ピクセル シェーダーが読み取っている情報より多くの情報を頂点シェーダーが出力していますが、ピクセル シェーダーが Tex より後の情報を読み取っていないため、心配する必要はありません。

入力レイアウトを作成するためにシェーダー シグネチャが必要ですが、シェーダーを作成する前にメッシュをロードしてレイアウトを作成しています。どうすればよいですか。

解決策の 1 つは、順序を入れ替えて、シェーダーをロードしてからメッシュをロードすることです。ただし、実際に行うのはそれほど簡単ではありません。入力レイアウトは、アプリケーションから要求があるたびにオンデマンドで作成できます。シェーダー シグネチャのバージョンは手元に用意しておく必要があります。シェーダーとバッファー レイアウトに基づいてハッシュを作成し、一致するものが存在しない場合にのみ入力レイアウトを作成するようにしてください。

描画呼び出し

D3D10 で 60 Hz を実現するための描画呼び出しの制限を教えてください。30 Hz ではどうですか。

Direct3D 9 では、1 回の描画呼び出しにかかる CPU コストのために、描画呼び出しの回数が制限されていました。Direct3D 10 では、1 回の描画呼び出しのコストが削減されています。ただし、描画呼び出しとフレーム レートとの間には明確な相関関係がなくなっています。描画呼び出しには、多くの場合多数の補助的な呼び出し (定数バッファーの更新、テクスチャー バインディング、ステート設定など) が必要となるため、API がフレーム レートに与える影響は、単純な描画呼び出しの回数ではなく全体的な API の使用状況に左右されるようになりました。

リソース

どの操作にどのタイプのリソース使用法を使用すればいいでしょうか。

次の対応表を使用してください。

  • CPU がフレームごとにリソースを複数回更新する場合 :D3D10_USAGE_DYNAMIC
  • CPU がフレームごとにリソースを 1 回未満更新する場合 :D3D10_USAGE_DEFAULT
  • CPU がリソースを更新しない場合 :D3D10_USAGE_IMMUTABLE
  • CPU がリソースを読み取る必要がある場合 :D3D10_USAGE_STAGING

定数バッファーは常に頻繁に更新されるように意図されているので、この対応表には当てはまりません。定数バッファーに使用するリソース タイプについては、「定数バッファー」を参照してください。

DrawPrimitiveUP と DrawIndexedPrimitiveUP はどうなったのですか。

D3D10 で廃止されました。動的なジオメトリには、大きな D3D10_USAGE_DYNAMIC バッファーを使用してください。フレームの先頭で、D3D10_MAP_WRITE_DISCARD を指定してバッファーをマップします。後続の各描画呼び出しでは、書き込みポインターを前に描画された頂点の位置の先に進め、D3D10_MAP_WRITE_NO_OVERWRITE を指定してバッファーをマップします。フレームが終わる前にバッファーの最後に近づいたら、書き込みポインターを先頭に向けて折り返し、D3D10_MAP_WRITE_DISCARD を指定してマップします。

16 ビットのインデックスと 32 ビットのインデックスを同じ動的ジオメトリ バッファーに書き込むことはできますか。

できますが、ハードウェアによってはパフォーマンスが低下することがあります。動的な 16 ビットのインデックス データ用と 32 ビットのインデックス データ用に別々のバッファーを作成した方が安全です。

GPU から CPU にデータを読み戻すにはどうすればよいですか。

ステージング リソースを使用する必要があります。CopyResource を使用して、GPU リソースからステージング リソースにデータをコピーします。ステージング リソースをマップしてデータを読み取ります。

StretchRect 機能に依存していたアプリケーションがあります。

この機能は、実質的には基本的な Direct3D 機能のラッパーであったため、API から削除されました。StretchRect 機能の一部は、D3DX10LoadTextureFromTexture に移されています。フォーマット変換とテクスチャーのコピーは、D3DX10LoadTextureFromTexture で行うことができます。ただし、あるサイズから別のサイズに変換する処理などでは、アプリケーションでテクスチャーにレンダリングする操作が必要となる可能性があります。

リソースのマップ呼び出しにオフセットやサイズがありません。Direct3D 9 のロック呼び出しにはオフセットやサイズがあったのですが、なぜ変更されたのでしょうか。

Direct3D 9 のロック呼び出しのオフセットとサイズは、基本的には API の不要物であり、多くの場合ドライバーで無視されていました。オフセットは、マップ呼び出しで返されたポインターからアプリケーションで計算するようにしてください。

テクスチャーとしての深度

深度をテクスチャーとして使用するのと、アルファに深度を書き込んでそれを読み取るのとでは、どちらの方が速いでしょうか。

それはアプリケーションとハードウェアによります。帯域幅を節約できる方を使用してください。既に複数のレンダー ターゲットを使用していて、かつ余分なチャンネルがある場合は、シェーダーから深度を書き込む方がよいでしょう。また、深度をアルファまたは別のレンダー ターゲットに書き込むと、線形の深度値を書き込めるようになり、深度バッファーにアクセスするために必要な計算を迅速化できます。

深度の書き込みを無効にすれば、テクスチャーを入力としてバインドし、深度ステンシル テクスチャーとしてバインドできますか。

D3D10 ではできません。

MSAA

MSAA 深度ステンシル テクスチャーを解決することはできますか。

D3D10 ではできません。ただし、MSAA テクスチャーから個々のサンプルをサンプリングすることはできます。詳細については、「HLSL」を参照してください。

MSAA を有効にするとすぐにアプリケーションがクラッシュするのはなぜでしょうか。

実際にはドライバーによって列挙される MSAA サンプル数とクオリティ ナンバーを有効にしていることを確認してください。

クラッシュ

D3D10 やドライバーでアプリケーションがクラッシュするのですが、原因がわかりません。

まず、デバッグ ランタイムを有効にします (CreateDevice に D3D10_CREATE_DEVICE_DEBUG フラグを渡す)。これにより、最も多く見られるエラーがデバッグ出力で明らかになります。

PIX でアプリケーションを使用しようとすると、PIX がクラッシュします。

まず、デバッグ ランタイムを有効にします (CreateDevice に D3D10_CREATE_DEVICE_DEBUG フラグを渡す)。デバッグ出力がクリーンでないと、PIX がクラッシュする可能性が高くなります。

32 ビット版 Vista で D3D10 を使用すると、ゲームで仮想アドレス空間が足りなくなります。同じゲームでも D3D9 では問題が生じません。

D3D10 と仮想アドレス空間にはいくつかの問題がありました。この問題は KB940105 (http://support.microsoft.com/kb/940105) で修正されています。それでも問題が解決しない場合は、D3D10 で作成しているマップ (ロック) 可能なリソースが、D3D9 のときに比べて増えていないかを確認してください。また、今後は 64 ビットの普及が進むので、64 ビットへの移植も検討してください。

プレディケート レンダリング

オクルージョン クエリの結果を基にプレディケート レンダリングを使用しました。それでもアプリケーションの処理速度が変わらないのはなぜでしょうか。

まず、スキップの対象とするレンダリングが本当にアプリケーションのボトルネックであるかを確認してください。ボトルネックでなければ、レンダリングをスキップしてもフレーム レートへの効果はありません。次に、クエリの発行からプレディケートするレンダリングまでの時間が十分であるかを確認してください。レンダリング呼び出しが GPU に到達するまでにクエリが完了していないと、レンダリングが実行されることになります。最後に、プレディケーションでは一部の呼び出ししかスキップされません。スキップされる呼び出しは、Draw、Clear、Copy、Update です。ステート設定、IA セットアップ、Map、Create の各呼び出しは、プレディケーションに関係しません。プレディケートされる描画呼び出しに多数のステート設定呼び出しが関連する場合は、それらのステートが設定されることになります。

ジオメトリ シェーダー

作成した (対象は何でもかまいません) をテッセレーションするためにジオメトリ シェーダーを使用する必要がありますか。

いいえ。ジオメトリ シェーダーはテッセレーションに使用しないでください。

ジオメトリ シェーダーを使用してジオメトリを作成できますか。

ごく限られたシナリオで可能です。現在の D3D10 (2008) のジオメトリ シェーダーには、多数の展開を処理する能力がありません。この状況は今後変わる可能性があります。既存のポイント スプライト ハードウェアのために、ビデオ カードのベンダーが 1 ~ 4 個の展開に対応する特別なパスを用意している場合があります。それ以外の展開はかなり制限する必要があります。ParticlesGS および PipesGS サンプルは、限られた展開のみを実行することで、高いフレーム レートを実現しています。各フレームで展開される点の数はごくわずかです。

ジオメトリ シェーダーは何に使用するのですか。

シルエット検出や重心座標など、プリミティブ全体に対する操作を必要とするすべての処理に使用します。プリミティブの送信先となるレンダー ターゲット配列のスライスを選択する場合にも使用します。

ジオメトリ シェーダーから不定量のジオメトリを出力することはできますか。

できますが、パフォーマンスに問題が生じるおそれがあります。たとえば、ある呼び出しで 1 つの点、別の呼び出しで 4 つの点を出力するとします。この場合、展開のガイドラインには適応しているものの、ジオメトリ シェーダーのスレッドが連続的に実行される可能性があります。

D3D10 は、メッシュに隣接インデックスを生成する方法をどのように認識するのですか。あるいは、ジオメトリ シェーダーに隣接性情報が必要であることを指定すると、D3D10 で正しくレンダリングが行われなくなるのはなぜですか。

隣接性情報は、D3D10 ではなくアプリケーションによって作成されます。隣接インデックスは、アプリケーションで生成され、プリミティブごとに 6 つのインデックスを含んでいる必要があります。この 6 つのうち、奇数番号のインデックスはエッジ隣接頂点です。このデータは、ID3DX10Mesh::GenerateAdjacencyAndPointsReps を使用して生成できます。

HLSL

整数命令とビット単位命令は処理速度が遅いですか。

その可能性はあります。さまざまな D3D10 カードが、使用可能な ALU ユニットのサブセットでしか整数演算を発行できない可能性があります。これは、ハードウェアに大きく依存します。特定のハードウェアでの整数演算を扱う方法については、個々のハードウェア ベンダーの指示を仰いでください。また、型間のキャストについては十分に注意してください。

VPOS はどうなったのですか。

ピクセル シェーダーに対する入力を SV_POSITION として宣言すると、VPOS として宣言した場合と同じ動作を得られます。

MSAA テクスチャーをサンプリングするにはどうすればよいですか。

シェーダーでテクスチャーを Texture2DMS として宣言します。これで、Texture2DMS オブジェクトの Sample メソッドを使用して個々のサンプルをフェッチできるようになります。

定数バッファー内のシェーダー変数が実際に使用されているかどうかはどうすればわかりますか。

その変数が反映された D3D10_SHADER_VARIABLE_DESC 構造体を確認します。uFlags に D3D10_SVF_USED フラグが設定されているはずです。

定数バッファー内のシェーダー変数が実際に FX10 を使用しているかどうかを確認するにはどうすればよいですか。

現時点ではこれは FX10 を使用できません。

FX10 によって作成された定数バッファーを制御できません。この定数バッファーはどのように作成され、更新されるのですか。

FX10 によって管理される定数バッファーは、いずれも D3D10_USAGE_DEFAULT リソースとして作成され、UpdateSubresource を使用して更新されます。FX10 は全定数データのバッキング ストアを保持しているので、UpdateSubresource が更新方法として最も適しています。

シェーダーを使用して固定機能パイプラインをエミュレートするにはどうすればよいですか。

FixedFuncEMU サンプルを参照してください。

[unroll]、[loop]、[branch] などの新しいコンパイラ ヒントを使用する必要はありますか。

一般には必要ありません。コンパイラは、多くの場合両方の方法を試して速い方を選択します。場合によっては、ループ内のテクスチャー フェッチがグラデーションにアクセスする必要がある場合などに、[unroll] の使用が必要となることがあります。

D3D10 では部分精度に何か違いがありますか。D3D9 HLSL では部分精度を指定できますが、D3D10 HLSL では指定できません。

D3D10 の演算は、いずれも 32 ビットの浮動小数点精度で実行するように指定されます。したがって、D3D10 では部分精度に何も違いはないはずです。

DOCERROR: The <proch /> tag can only contain text or <term />.

D3D9 では、深度バッファーをテクスチャーとしてバインドし、通常の tex2d HTSL 命令を使用することで、ハードウェア PCF シャドウ フィルタリングを実行できました。D3D10 でこれを行うにはどうすればよいですか。

比較サンプラー ステートを使用し、SampleCmp 命令を使用する必要があります。

レジスタ キーワードは D3D10 でどのように機能しますか。

D3D10 では、特定のリソースがバインドされているスロットにレジスタ キーワードが適用されるようになりました。この場合、リソースとはバッファー (定数バッファーまたはそれ以外)、テクスチャー、またはサンプラーです。

  • 定数バッファーの場合の構文 :register(bN) (N は入力スロット (0 ~ 15))
  • テクスチャーの場合の構文 :register(tN) (N は入力スロット (0 ~ 127))
  • サンプラーの場合の構文 :register(sN) (N は入力スロット (0 ~ 127))

レジスタを使用してバッファー全体のバインド先だけが指定されている場合に、定数バッファー内に変数を配置するにはどうすればよいですか。

packoffset キーワードを使用します。packoffset の引数の形式は c[0-4095].[x,y,z,w] です。次に例を示します。

        cbuffer cbLotsOfEmptySpace
        {
        float   IWaste2Floats   : packoffset(c0.z);
        float4  IWasteMore  : packoffset(c13);
        };
      

この定数バッファーでは、IWaste2Floats が定数バッファーの 3 番目の float (12 バイト目) に配置されます。IWasteMore は、定数バッファー内の 13 番目の float4 または 52 番目の float に配置されます。