Metodo ID3D11DeviceContext::UpdateSubresource (d3d11.h)

Vedere l'esempio di ologramma di base.

La CPU copia i dati dalla memoria a una sottoresource creata in memoria non mappabile.

Sintassi

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

Parametri

[in] pDstResource

Tipo: ID3D11Resource*

Puntatore alla risorsa di destinazione (vedere ID3D11Resource).

[in] DstSubresource

Tipo: UINT

Indice in base zero, che identifica la sottoresource di destinazione. Per altre informazioni, vedere D3D11CalcSubresource .

[in, optional] pDstBox

Tipo: const D3D11_BOX*

Puntatore a una casella che definisce la parte della sottoresource di destinazione in cui copiare i dati della risorsa. Le coordinate sono in byte per i buffer e in texel per le trame. Se NULL, i dati vengono scritti nella sottoresource di destinazione senza offset. Le dimensioni dell'origine devono adattarsi alla destinazione (vedere D3D11_BOX).

Una casella vuota genera un no-op. Una casella è vuota se il valore superiore è maggiore o uguale al valore inferiore oppure il valore sinistro è maggiore o uguale al valore destro oppure il valore anteriore è maggiore o uguale al valore posteriore. Quando la casella è vuota, UpdateSubresource non esegue un'operazione di aggiornamento.

[in] pSrcData

Tipo: const void*

Puntatore ai dati di origine in memoria.

[in] SrcRowPitch

Tipo: UINT

Dimensione di una riga dei dati di origine.

[in] SrcDepthPitch

Tipo: UINT

Dimensioni di una sezione approfondita dei dati di origine.

Valore restituito

nessuno

Osservazioni

Per un buffer costante shader; impostare pDstBox su NULL. Non è possibile usare questo metodo per aggiornare parzialmente un buffer costante shader.

Non è possibile usare una risorsa come destinazione se:

  • la risorsa viene creata con utilizzo non modificabile o dinamico .
  • la risorsa viene creata come risorsa profondità-stencil.
  • la risorsa viene creata con funzionalità di multicampionamento (vedere DXGI_SAMPLE_DESC).
Quando UpdateSubresource restituisce, l'applicazione è libera di modificare o liberare i dati puntati da pSrcData perché il metodo ha già copiato/eliminato il contenuto originale.

Le prestazioni di UpdateSubresource dipendono dalla presenza o meno di contesa per la risorsa di destinazione. Ad esempio, la contesa per una risorsa del buffer dei vertici si verifica quando l'applicazione esegue una chiamata Draw e successivamente chiama UpdateSubresource nello stesso buffer dei vertici prima che la chiamata Draw venga effettivamente eseguita dalla GPU.

  • Quando è presente una contesa per la risorsa, UpdateSubresource eseguirà 2 copie dei dati di origine. Prima di tutto, i dati vengono copiati dalla CPU in uno spazio di archiviazione temporaneo accessibile dal buffer dei comandi. Questa copia viene eseguita prima che il metodo venga restituito. Una seconda copia viene quindi eseguita dalla GPU per copiare i dati di origine in memoria non mappabile. Questa seconda copia avviene in modo asincrono perché viene eseguita dalla GPU quando il buffer dei comandi viene scaricato.
  • Quando non è presente alcuna contesa delle risorse, il comportamento di UpdateSubresource dipende da quale è più veloce (dal punto di vista della CPU): copiare i dati nel buffer dei comandi e quindi avere una seconda copia eseguita quando il buffer di comando viene scaricato o avere la copia dei dati nel percorso della risorsa finale. Ciò dipende dall'architettura del sistema sottostante.
NotaSi applica solo al livello di funzionalità 9_x hardware Se si usa UpdateSubresource o ID3D11DeviceContext::CopySubresourceRegion per copiare da una risorsa di staging a una risorsa predefinita, è possibile danneggiare il contenuto della destinazione. Ciò si verifica se si passa una casella di origine NULL e se la risorsa di origine ha dimensioni diverse rispetto a quelle della risorsa di destinazione o se si usano offset di destinazione, (x, y e z). In questa situazione, passare sempre una casella di origine che rappresenta la dimensione completa della risorsa di origine.
 
Per comprendere meglio i parametri di passo della riga di origine e profondità di origine, la figura seguente mostra una trama del volume 3D. Illustrazione di una trama del volume 3D

Ogni blocco in questo oggetto visivo rappresenta un elemento di dati e le dimensioni di ogni elemento dipendono dal formato della risorsa. Ad esempio, se il formato della risorsa è DXGI_FORMAT_R32G32B32A32_FLOAT, le dimensioni di ogni elemento saranno 128 bit o 16 byte. Questa trama del volume 3D ha una larghezza di due, un'altezza di tre e una profondità di quattro.

Per calcolare il passo della riga di origine e il passo di profondità di origine per una determinata risorsa, usare le formule seguenti:

  • Pitch di riga di origine = [dimensioni di un elemento in byte] * [numero di elementi in una riga]
  • Pitch di profondità di origine = [Passo riga di origine] * [numero di righe (altezza)]
Nel caso di questa trama del volume 3D di esempio in cui le dimensioni di ogni elemento sono 16 byte, le formule sono le seguenti:
  • Campo di riga di origine = 16 * 2 = 32
  • Profondità di origine = 16 * 2 * 3 = 96
La figura seguente mostra la risorsa come è disposta in memoria. Illustrazione di una trama del volume 3D disposta in memoria

Ad esempio, il frammento di codice seguente illustra come specificare un'area di destinazione in una trama 2D. Si supponga che la trama di destinazione sia 512x512 e l'operazione copia i dati puntati da pData a [(120.100).. (200.220)] nella trama di destinazione. Si supponga inoltre che rowPitch sia stato inizializzato con il valore appropriato (come illustrato sopra). front-andback sono impostati rispettivamente su 0 e 1, perché con anteriore uguale a indietro, la casella è tecnicamente vuota.


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 );

Il caso 1D è simile. Il frammento di codice seguente illustra come specificare un'area di destinazione in una trama 1D. Usare gli stessi presupposti indicati in precedenza, ad eccezione del fatto che la trama è 512 in lunghezza.


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 );

Per informazioni sui vari tipi di risorse e sul funzionamento di UpdateSubresource con ogni tipo di risorsa, vedere Introduzione a una risorsa in Direct3D 11.

Chiamata di UpdateSubresource in un contesto posticipato

Se l'applicazione chiama UpdateSubresource in un contesto posticipato con una casella di destinazione, a cui pDstBox punta, che ha un offset non(0,0,0) e se il driver non supporta gli elenchi di comandi, UpdateSubresource applica in modo inappropriato tale offset della casella di destinazione al parametro pSrcData . Per risolvere questo comportamento, usare il codice seguente:

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;
}

Requisiti

   
Piattaforma di destinazione Windows
Intestazione d3d11.h
Libreria D3D11.lib

Vedi anche

ID3D11DeviceContext

ID3D11Resource

Esempio di ologramma di base