ID3D11DeviceContext::UpdateSubresource, méthode (d3d11.h)
Consultez l’exemple d’hologramme de base.
Le processeur copie les données de la mémoire vers une sous-ressource créée dans la mémoire non mappable.
Syntaxe
void UpdateSubresource(
[in] ID3D11Resource *pDstResource,
[in] UINT DstSubresource,
[in, optional] const D3D11_BOX *pDstBox,
[in] const void *pSrcData,
[in] UINT SrcRowPitch,
[in] UINT SrcDepthPitch
);
Paramètres
[in] pDstResource
Type : ID3D11Resource*
Pointeur vers la ressource de destination (voir ID3D11Resource).
[in] DstSubresource
Type : UINT
Index de base zéro qui identifie la sous-ressource de destination. Pour plus d’informations, consultez D3D11CalcSubresource .
[in, optional] pDstBox
Type : const D3D11_BOX*
Pointeur vers une zone qui définit la partie de la sous-ressource de destination dans laquelle copier les données de ressource. Les coordonnées sont exprimées en octets pour les mémoires tampons et en texels pour les textures. Si la valeur est NULL, les données sont écrites dans la sous-ressource de destination sans décalage. Les dimensions de la source doivent correspondre à la destination (voir D3D11_BOX).
Une zone vide entraîne une absence d’opération. Une zone est vide si la valeur supérieure est supérieure ou égale à la valeur inférieure, ou si la valeur de gauche est supérieure ou égale à la valeur de droite, ou si la valeur de début est supérieure ou égale à la valeur d’arrière-plan. Lorsque la zone est vide, UpdateSubresource n’effectue pas d’opération de mise à jour.
[in] pSrcData
Type : const void*
Pointeur vers les données sources en mémoire.
[in] SrcRowPitch
Type : UINT
Taille d’une ligne des données sources.
[in] SrcDepthPitch
Type : UINT
Taille d’une tranche de profondeur des données sources.
Valeur de retour
Aucune
Remarques
Pour une mémoire tampon de constante de nuanceur ; définissez pDstBox sur NULL. Il n’est pas possible d’utiliser cette méthode pour mettre à jour partiellement une mémoire tampon de constante de nuanceur.
Une ressource ne peut pas être utilisée comme destination si :
- la ressource est créée avec une utilisation immuable ou dynamique .
- la ressource est créée en tant que ressource de gabarit de profondeur.
- la ressource est créée avec la fonctionnalité d’échantillonnage multiple (voir DXGI_SAMPLE_DESC).
Les performances de UpdateSubresource varient selon qu’il existe ou non une contention pour la ressource de destination. Par exemple, une contention pour une ressource de mémoire tampon de vertex se produit lorsque l’application exécute un appel Draw et appelle ultérieurement UpdateSubresource sur la même mémoire tampon de vertex avant que l’appel Draw ne soit réellement exécuté par le GPU.
- En cas de conflit pour la ressource, UpdateSubresource effectue 2 copies des données sources. Tout d’abord, les données sont copiées par le processeur dans un espace de stockage temporaire accessible par la mémoire tampon de commandes. Cette copie se produit avant le retour de la méthode. Une deuxième copie est ensuite effectuée par le GPU pour copier les données sources dans la mémoire non mappable. Cette deuxième copie se produit de manière asynchrone, car elle est exécutée par GPU lorsque la mémoire tampon de commande est vidée.
- En l’absence de conflit de ressources, le comportement de UpdateSubresource dépend de ce qui est le plus rapide (du point de vue de l’UC) : copie des données dans la mémoire tampon de commande, puis exécution d’une deuxième copie lorsque la mémoire tampon de commande est vidée, ou faire en sorte que le processeur copie les données vers l’emplacement de ressource final. Cela dépend de l’architecture du système sous-jacent.
Chaque bloc de ce visuel représente un élément de données, et la taille de chaque élément dépend du format de la ressource. Par exemple, si le format de ressource est DXGI_FORMAT_R32G32B32A32_FLOAT, la taille de chaque élément est de 128 bits ou 16 octets. Cette texture de volume 3D a une largeur de deux, une hauteur de trois et une profondeur de quatre.
Pour calculer le tangage de ligne source et le pas de profondeur de la source pour une ressource donnée, utilisez les formules suivantes :
- Pitch de ligne source = [taille d’un élément en octets] * [nombre d’éléments dans une ligne]
- Profondeur de la source Pitch = [Emplacement de la ligne source] * [nombre de lignes (hauteur)]
- Pitch de ligne source = 16 * 2 = 32
- Profondeur de la source pitch = 16 * 2 * 3 = 96
Par exemple, l’extrait de code suivant montre comment spécifier une région de destination dans une texture 2D. Supposons que la texture de destination est 512 x 512 et que l’opération copie les données pointées par pData vers [(120,100).. (200 220)] dans la texture de destination. Supposons également que rowPitch a été initialisé avec la valeur appropriée (comme expliqué ci-dessus). avant et arrière sont définis sur 0 et 1 respectivement, car en ayant l’avant égal à l’arrière, la boîte est techniquement vide.
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 );
Le cas 1D est similaire. L’extrait de code suivant montre comment spécifier une région de destination dans une texture 1D. Utilisez les mêmes hypothèses que ci-dessus, sauf que la texture est de 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 );
Pour plus d’informations sur les différents types de ressources et sur le fonctionnement de UpdateSubresource avec chaque type de ressource, consultez Présentation d’une ressource dans Direct3D 11.
Appel de UpdateSubresource sur un contexte différé
Si votre application appelle UpdateSubresource sur un contexte différé avec une zone de destination (vers laquelle pDstBox pointe) qui a un décalage non(0,0,0) et si le pilote ne prend pas en charge les listes de commandes, UpdateSubresource applique de manière inappropriée ce décalage de zone de destination au paramètre pSrcData . Pour contourner ce comportement, utilisez le code suivant :
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;
}
Configuration requise
Plateforme cible | Windows |
En-tête | d3d11.h |
Bibliothèque | D3D11.lib |