Freigeben über


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).
Wenn UpdateSubresource zurückgibt, kann die Anwendung die Daten, auf die pSrcData verweist, ändern oder sogar freigeben, da die Methode den ursprünglichen Inhalt bereits kopiert/angedockt hat.

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.
HinweisGilt nur für Hardware auf Featureebene 9_x Wenn Sie UpdateSubresource oder ID3D11DeviceContext::CopySubresourceRegion verwenden, um von einer Stagingressource in eine Standardressource zu kopieren, können Sie den Zielinhalt beschädigen. Dies tritt auf, wenn Sie ein NULL-Quellfeld übergeben und die Quellressource andere Dimensionen als die der Zielressource aufweist oder wenn Sie Zieloffsets (x, y und z) verwenden. Übergeben Sie in diesem Fall immer ein Quellfeld, das der vollständigen Größe der Quellressource entspricht.
 
Die folgende Abbildung zeigt eine 3D-Volumentextur, um die Parameter für die Tonhöhe der Quellzeile und die Quelltiefe zu verstehen. Abbildung einer 3D-Volumentextur

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)]
Im Fall dieses Beispiels für eine 3D-Volumetextur, bei der die Größe jedes Elements 16 Bytes beträgt, lauten die Formeln wie folgt:
  • Quellzeilenabstand = 16 * 2 = 32
  • Source Depth Pitch = 16 * 2 * 3 = 96
Die folgende Abbildung zeigt die Ressource, wie sie im Arbeitsspeicher angeordnet ist. Abbildung einer 3D-Volumentextur, die im Arbeitsspeicher angeordnet ist

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

Weitere Informationen

ID3D11DeviceContext

ID3D11Resource

Einfaches Hologrammbeispiel