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 のパフォーマンスは、ターゲット リソースの競合があるかどうかによって異なります。 たとえば、頂点バッファー リソースの競合は、アプリケーションが Draw 呼び出しを実行し、後で同じ頂点バッファーで UpdateSubresource を 呼び出した後、 Draw 呼び出しが GPU によって実際に実行される前に発生します。
- リソースの競合が発生すると、 UpdateSubresource はソース データの 2 つのコピーを実行します。 最初に、データは CPU によってコマンド バッファーからアクセスできる一時記憶域にコピーされます。 このコピーは、 メソッドが戻る前に行われます。 その後、GPU によって 2 つ目のコピーが実行され、ソース データがマップ不可能なメモリにコピーされます。 この 2 番目のコピーは、コマンド バッファーがフラッシュされるときに GPU によって実行されるため、非同期的に行われます。
- リソースの競合がない場合、 UpdateSubresource の動作は、(CPU の観点から) どちらが高速であるかに依存します。データをコマンド バッファーにコピーしてから、コマンド バッファーがフラッシュされたときに 2 つ目のコピーを実行するか、CPU でデータを最終的なリソースの場所にコピーします。 これは、基になるシステムのアーキテクチャに依存します。
このビジュアルの各ブロックはデータの要素を表し、各要素のサイズはリソースの形式に依存します。 たとえば、リソース形式がDXGI_FORMAT_R32G32B32A32_FLOAT場合、各要素のサイズは 128 ビットまたは 16 バイトになります。 この 3D ボリューム テクスチャの幅は 2、高さは 3、奥行きは 4 です。
特定のリソースのソース行のピッチとソースの深さのピッチを計算するには、次の式を使用します。
- ソース行ピッチ = [バイト単位の 1 つの要素のサイズ] * [1 行の要素の数]
- ソース深度ピッチ = [ソース行ピッチ] * [行数 (高さ)]
- ソース行ピッチ = 16 * 2 = 32
- ソース深度ピッチ = 16 * 2 * 3 = 96
たとえば、次のコード スニペットは、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 |