Partager via


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).
Lorsque UpdateSubresource retourne une valeur, l’application est libre de modifier ou même de libérer les données pointées par pSrcData , car la méthode a déjà copié/supprimé le contenu d’origine.

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.
RemarqueS’applique uniquement au niveau des fonctionnalités 9_x matériel Si vous utilisez UpdateSubresource ou ID3D11DeviceContext::CopySubresourceRegion pour copier d’une ressource intermédiaire vers une ressource par défaut, vous pouvez endommager le contenu de destination. Cela se produit si vous transmettez une zone source NULL et si la ressource source a des dimensions différentes de celles de la ressource de destination ou si vous utilisez des décalages de destination, (x, y et z). Dans ce cas, transmettez toujours une zone source qui correspond à la taille complète de la ressource source.
 
Pour mieux comprendre les paramètres de tangage de ligne source et de profondeur de la source, l’illustration suivante montre une texture de volume 3D. Illustration d’une texture de volume 3D

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)]
Dans le cas de cet exemple de texture de volume 3D où la taille de chaque élément est de 16 octets, les formules sont les suivantes :
  • Pitch de ligne source = 16 * 2 = 32
  • Profondeur de la source pitch = 16 * 2 * 3 = 96
L’illustration suivante montre la ressource telle qu’elle est disposée en mémoire. Illustration d’une texture de volume 3D disposée en mémoire

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

Voir aussi

ID3D11DeviceContext

ID3D11Resource

Exemple d’hologramme de base