ID3D11DeviceContext::UpdateSubresource メソッド (d3d11.h)

基本的なホログラムのサンプルを参照してください。

CPU は、マップできないメモリに作成されたサブリソースにメモリからデータをコピーします。

構文

void UpdateSubresource(
  [in]           ID3D11Resource  *pDstResource,
  [in]           UINT            DstSubresource,
  [in, optional] const D3D11_BOX *pDstBox,
  [in]           const void      *pSrcData,
  [in]           UINT            SrcRowPitch,
  [in]           UINT            SrcDepthPitch
);

パラメーター

[in] pDstResource

種類: ID3D11Resource*

宛先リソースへのポインター ( ID3D11Resource を参照)。

[in] DstSubresource

型: UINT

宛先サブリソースを識別する 0 から始まるインデックス。 詳細については、「 D3D11CalcSubresource 」を参照してください。

[in, optional] pDstBox

型: const D3D11_BOX*

リソース データのコピー先となるサブリソースの部分を定義するボックスへのポインター。 座標はバッファーの場合はバイト単位、テクスチャの場合はテクセル単位です。 NULL の場合、データはオフセットなしで宛先サブリソースに書き込まれます。 ソースのディメンションは、変換先に合っている必要があります ( 「D3D11_BOX」を参照)。

空のボックスを使用すると、操作が不要になります。 上の値が下の値以上であるか、左の値が右の値以上であるか、前面の値が戻り値以上の場合、ボックスは空です。 ボックスが空の場合、 UpdateSubresource は更新操作を実行しません。

[in] pSrcData

型: const void*

メモリ内のソース データへのポインター。

[in] SrcRowPitch

型: UINT

ソース データの 1 行のサイズ。

[in] SrcDepthPitch

型: UINT

ソース データの 1 つの深度スライスのサイズ。

戻り値

なし

解説

シェーダー定数バッファーの場合。 pDstBox を NULL に設定 します。 このメソッドを使用してシェーダー定数バッファーを部分的に更新することはできません。

次の場合、リソースを宛先として使用することはできません。

  • リソースは、 不変 または 動的な 使用で作成されます。
  • リソースは深度ステンシル リソースとして作成されます。
  • リソースはマルチサンプリング機能を使用して作成されます ( DXGI_SAMPLE_DESCを参照)。
UpdateSubresource が戻ると、pSrcData が指すデータをアプリケーションで自由に変更したり解放したりすることもできます。これは、 メソッドが元のコンテンツを既にコピーまたはスナップしているためです。

UpdateSubresource のパフォーマンスは、ターゲット リソースの競合があるかどうかによって異なります。 たとえば、頂点バッファー リソースの競合は、アプリケーションが Draw 呼び出しを実行し、後で同じ頂点バッファーで UpdateSubresource を 呼び出した後、 Draw 呼び出しが GPU によって実際に実行される前に発生します。

  • リソースの競合が発生すると、 UpdateSubresource はソース データの 2 つのコピーを実行します。 最初に、データは CPU によってコマンド バッファーからアクセスできる一時記憶域にコピーされます。 このコピーは、 メソッドが戻る前に行われます。 その後、GPU によって 2 つ目のコピーが実行され、ソース データがマップ不可能なメモリにコピーされます。 この 2 番目のコピーは、コマンド バッファーがフラッシュされるときに GPU によって実行されるため、非同期的に行われます。
  • リソースの競合がない場合、 UpdateSubresource の動作は、(CPU の観点から) どちらが高速であるかに依存します。データをコマンド バッファーにコピーしてから、コマンド バッファーがフラッシュされたときに 2 つ目のコピーを実行するか、CPU でデータを最終的なリソースの場所にコピーします。 これは、基になるシステムのアーキテクチャに依存します。
ハードウェア9_x機能レベルにのみ適用されますUpdateSubresource または ID3D11DeviceContext::CopySubresourceRegion を使用してステージング リソースから既定のリソースにコピーすると、コピー先のコンテンツが破損する可能性があります。 これは、 NULL ソース ボックスを渡し、ソース リソースのディメンションがターゲット リソースのディメンションと異なる場合、または変換先のオフセット (x、y、z) を使用する場合に発生します。 このような場合は、ソース リソースのフル サイズであるソース ボックスを常に渡します。
 
ソース行のピッチパラメーターとソース深度ピッチ パラメーターを理解するために、次の図は 3D ボリューム テクスチャを示しています。 3D ボリューム テクスチャの図

このビジュアルの各ブロックはデータの要素を表し、各要素のサイズはリソースの形式に依存します。 たとえば、リソース形式がDXGI_FORMAT_R32G32B32A32_FLOAT場合、各要素のサイズは 128 ビットまたは 16 バイトになります。 この 3D ボリューム テクスチャの幅は 2、高さは 3、奥行きは 4 です。

特定のリソースのソース行のピッチとソースの深さのピッチを計算するには、次の式を使用します。

  • ソース行ピッチ = [バイト単位の 1 つの要素のサイズ] * [1 行の要素の数]
  • ソース深度ピッチ = [ソース行ピッチ] * [行数 (高さ)]
この例の 3D ボリューム テクスチャの場合、各要素のサイズが 16 バイトの場合、数式は次のようになります。
  • ソース行ピッチ = 16 * 2 = 32
  • ソース深度ピッチ = 16 * 2 * 3 = 96
次の図は、メモリにレイアウトされているリソースを示しています。 メモリにレイアウトされた 3D ボリューム テクスチャの図

たとえば、次のコード スニペットは、2D テクスチャでターゲット領域を指定する方法を示しています。 コピー先のテクスチャが 512 x 512 で、 pData が指すデータが [(120,100) にコピーされるとします。(200,220)] をターゲット テクスチャに設定します。 また、 rowPitch が適切な値で初期化されていると仮定します (上で説明したように)。 前面背面 はそれぞれ 0 と 1 に設定されます。 これは、前面背面と等しい場合、ボックスは技術的に空であるためです。


D3D11_BOX destRegion;
destRegion.left = 120;
destRegion.right = 200;
destRegion.top = 100;
destRegion.bottom = 220;
destRegion.front = 0;
destRegion.back = 1;

pd3dDeviceContext->UpdateSubresource( pDestTexture, 0, &destRegion, pData, rowPitch, 0 );

1D ケースも同様です。 次のスニペットは、1D テクスチャでターゲット領域を指定する方法を示しています。 テクスチャの長さが 512 であることを除き、上記と同じ前提条件を使用します。


D3D11_BOX destRegion;
destRegion.left = 120;
destRegion.right = 200;
destRegion.top = 0;
destRegion.bottom = 1;
destRegion.front = 0;
destRegion.back = 1;

pd3dDeviceContext->UpdateSubresource( pDestTexture, 0, &destRegion, pData, rowPitch, 0 );

さまざまなリソースの種類と 、UpdateSubresource が各リソースの種類でどのように機能するかについては、「 Direct3D 11 のリソースの概要」を参照してください。

遅延コンテキストでの UpdateSubresource の呼び出し

アプリケーションが遅延コンテキストで UpdateSubresource を呼び出し、宛先ボックス ( pDstBox が指す) が非 (0,0,0) オフセットを持つ場合、ドライバーがコマンド リストをサポートしていない場合、 UpdateSubresource はその宛先ボックス オフセットを pSrcData パラメーターに不適切に適用します。 この動作を回避するには、次のコードを使用します。

HRESULT UpdateSubresource_Workaround(
  ID3D11Device *pDevice,
  ID3D11DeviceContext *pDeviceContext,
  ID3D11Resource *pDstResource,
  UINT dstSubresource,
  const D3D11_BOX *pDstBox,
  const void *pSrcData,
  UINT srcBytesPerElement,
  UINT srcRowPitch,
  UINT srcDepthPitch,
  bool* pDidWorkAround )
{
     HRESULT hr = S_OK;
     bool needWorkaround = false;
     D3D11_DEVICE_CONTEXT_TYPE contextType = pDeviceContext->GetType();

     if( pDstBox && (D3D11_DEVICE_CONTEXT_DEFERRED == contextType) )
     {
          D3D11_FEATURE_DATA_THREADING threadingCaps = { FALSE, FALSE };

          hr = pDevice->CheckFeatureSupport( D3D11_FEATURE_THREADING, &threadingCaps, sizeof(threadingCaps) );
          if( SUCCEEDED(hr) )
          {
               if( !threadingCaps.DriverCommandLists )
               {
                    needWorkaround = true;
               }
          }
     }

     const void* pAdjustedSrcData = pSrcData;

     if( needWorkaround )
     {
          D3D11_BOX alignedBox = *pDstBox;
		
          // convert from pixels to blocks
          if( m_bBC )
          {
               alignedBox.left     /= 4;
               alignedBox.right    /= 4;
               alignedBox.top      /= 4;
               alignedBox.bottom   /= 4;
          }

          pAdjustedSrcData = ((const BYTE*)pSrcData) - (alignedBox.front * srcDepthPitch) - (alignedBox.top * srcRowPitch) - (alignedBox.left * srcBytesPerElement);
     }

     pDeviceContext->UpdateSubresource( pDstResource, dstSubresource, pDstBox, pAdjustedSrcData, srcRowPitch, srcDepthPitch );

     if( pDidWorkAround )
     {
          *pDidWorkAround = needWorkaround;
     }

     return hr;
}

必要条件

   
対象プラットフォーム Windows
ヘッダー d3d11.h
Library D3D11.lib

関連項目

ID3D11DeviceContext

ID3D11Resource

基本的なホログラム サンプル