ID3D11DeviceContext::UpdateSubresource-Methode (d3d11.h)
Sehen Sie sich das Grundlegende Hologrammbeispiel an.
Die CPU kopiert Daten aus dem Arbeitsspeicher in eine Unterressource, die im nicht zugeordneten Arbeitsspeicher erstellt wurde.
Syntax
void UpdateSubresource(
[in] ID3D11Resource *pDstResource,
[in] UINT DstSubresource,
[in, optional] const D3D11_BOX *pDstBox,
[in] const void *pSrcData,
[in] UINT SrcRowPitch,
[in] UINT SrcDepthPitch
);
Parameter
[in] pDstResource
Typ: ID3D11Resource*
Ein Zeiger auf die Zielressource (siehe ID3D11Resource).
[in] DstSubresource
Typ: UINT
Ein nullbasierter Index, der die Zielunterressource identifiziert. Weitere Informationen finden Sie unter D3D11CalcSubresource .
[in, optional] pDstBox
Typ: const D3D11_BOX*
Ein Zeiger auf ein Feld, das den Teil der Zielunterressource definiert, in den die Ressourcendaten kopiert werden sollen. Koordinaten sind in Bytes für Puffer und in Texels für Texturen. Wenn NULL, werden die Daten ohne Offset in die Zielunterressource geschrieben. Die Dimensionen der Quelle müssen dem Ziel entsprechen (siehe D3D11_BOX).
Ein leeres Feld führt zu einem No-Op. Ein Feld ist leer, wenn der obere Wert größer oder gleich dem unteren Wert oder der linke Wert größer oder gleich dem rechten Wert ist oder der vordere Wert größer oder gleich dem back-Wert ist. Wenn das Feld leer ist, führt UpdateSubresource keinen Updatevorgang aus.
[in] pSrcData
Typ: const void*
Ein Zeiger auf die Quelldaten im Arbeitsspeicher.
[in] SrcRowPitch
Typ: UINT
Die Größe einer Zeile der Quelldaten.
[in] SrcDepthPitch
Typ: UINT
Die Größe eines Tiefenslices der Quelldaten.
Rückgabewert
Keine
Bemerkungen
Für einen Shaderkonstantenpuffer; Legen Sie pDstBox auf NULL fest. Es ist nicht möglich, diese Methode zum teilweisen Aktualisieren eines Shaderkonstantenpuffers zu verwenden.
Eine Ressource kann nicht als Ziel verwendet werden, wenn:
- Die Ressource wird mit unveränderlicher oder dynamischer Verwendung erstellt.
- Die Ressource wird als Tiefenschablonenressource erstellt.
- Die Ressource wird mit der Multisamplingfunktion erstellt (siehe DXGI_SAMPLE_DESC).
Die Leistung von UpdateSubresource hängt davon ab, ob ein Konflikt für die Zielressource vorliegt oder nicht. Beispielsweise tritt ein Konflikt um eine Vertexpufferressource auf, wenn die Anwendung einen Draw-Aufruf und später UpdateSubresource für denselben Vertexpuffer aufruft, bevor der Draw-Aufruf tatsächlich von der GPU ausgeführt wird.
- Wenn ein Konflikt für die Ressource vorliegt, führt UpdateSubresource zwei Kopien der Quelldaten aus. Zunächst werden die Daten von der CPU in einen temporären Speicherplatz kopiert, auf den der Befehlspuffer zugreifen kann. Diese Kopie erfolgt, bevor die Methode zurückgibt. Anschließend wird eine zweite Kopie von der GPU ausgeführt, um die Quelldaten in den nicht zugeordneten Arbeitsspeicher zu kopieren. Diese zweite Kopie erfolgt asynchron, da sie von der GPU ausgeführt wird, wenn der Befehlspuffer geleert wird.
- Wenn kein Ressourcenkonflikt vorliegt, hängt das Verhalten von UpdateSubresource davon ab, was schneller (aus CPU-Sicht) ist: Kopieren der Daten in den Befehlspuffer und anschließendes Ausführen einer zweiten Kopie, wenn der Befehlspuffer geleert wird, oder die CPU die Daten an den endgültigen Ressourcenspeicherort kopieren lassen. Dies hängt von der Architektur des zugrunde liegenden Systems ab.
Jeder Block in diesem Visual stellt ein Datenelement dar, und die Größe jedes Elements hängt vom Format der Ressource ab. Wenn das Ressourcenformat beispielsweise DXGI_FORMAT_R32G32B32A32_FLOAT ist, beträgt die Größe jedes Elements 128 Bit oder 16 Bytes. Diese 3D-Volumentextur hat eine Breite von zwei, eine Höhe von drei und eine Tiefe von vier.
Verwenden Sie die folgenden Formeln, um die Neigung der Quellzeile und die Quelltiefe für eine bestimmte Ressource zu berechnen:
- Quellzeilenabstand = [Größe eines Elements in Bytes] * [Anzahl der Elemente in einer Zeile]
- Quelltiefe Pitch = [Quellzeilenabstand] * [Anzahl der Zeilen (Höhe)]
- Quellzeilenabstand = 16 * 2 = 32
- Source Depth Pitch = 16 * 2 * 3 = 96
Der folgende Codeausschnitt zeigt beispielsweise, wie ein Zielbereich in einer 2D-Textur angegeben wird. Angenommen, die Zieltextur ist 512 x 512, und der Vorgang kopiert die Daten, auf die pData verweist, nach [(120,100).. (200,220)] in der Zieltextur. Gehen Sie auch davon aus, dass rowPitch mit dem richtigen Wert initialisiert wurde (wie oben erläutert). vorne und hinten sind auf 0 bzw. 1 festgelegt, da die Box technisch leer ist, da die Front gleich hinten ist.
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 );
Der 1D-Fall ist ähnlich. Der folgende Codeausschnitt zeigt, wie Sie einen Zielbereich in einer 1D-Textur angeben. Verwenden Sie die gleichen Annahmen wie oben, mit der Ausnahme, dass die Textur 512 lang ist.
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 );
Informationen zu verschiedenen Ressourcentypen und dazu, wie UpdateSubresource mit jedem Ressourcentyp funktionieren kann, finden Sie unter Einführung in eine Ressource in Direct3D 11.
Aufrufen von UpdateSubresource für einen verzögerten Kontext
Wenn Ihre Anwendung UpdateSubresource in einem verzögerten Kontext mit einem Zielfeld aufruft, auf das pDstBox verweist, das einen Nicht-(0,0,0)-Offset aufweist, und wenn der Treiber keine Befehlslisten unterstützt, wendet UpdateSubresource diesen Zielfeldoffset unangemessen auf den pSrcData-Parameter an. Verwenden Sie den folgenden Code, um dieses Verhalten zu umgehen:
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;
}
Anforderungen
Zielplattform | Windows |
Kopfzeile | d3d11.h |
Bibliothek | D3D11.lib |