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).
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.
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)]
- Campo di riga di origine = 16 * 2 = 32
- Profondità di origine = 16 * 2 * 3 = 96
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 |