Types de ressources (Direct3D 10)
Toutes les ressources utilisées par le pipeline Direct3D dérivent de deux types de ressources de base : les mémoires tampons et les textures. Une mémoire tampon est une collection de données brutes (éléments) ; une texture est une collection de texels (éléments de texture).
Il existe deux façons de spécifier entièrement la disposition (ou l’empreinte mémoire) d’une ressource :
Élément | Description |
---|---|
Tapé |
Spécifiez entièrement le type lors de la création de la ressource. |
Sans type |
Spécifiez entièrement le type lorsque la ressource est liée au pipeline. |
Une ressource de mémoire tampon est une collection de données entièrement typées ; en interne, une mémoire tampon contient des éléments. Un élément est composé de 1 à 4 composants. Voici quelques exemples de types de données d’élément : une valeur de données packée (comme R8G8B8A8), un entier 8 bits unique, quatre valeurs float de 32 bits. Ces types de données sont utilisés pour stocker des données, telles qu’un vecteur de position, un vecteur normal, une coordonnée de texture dans une mémoire tampon de vertex, un index dans une mémoire tampon d’index ou un état d’appareil.
Une mémoire tampon est créée en tant que ressource non structurée. Étant donné qu’elle n’est pas structurée, une mémoire tampon ne peut pas contenir de niveaux mipmap, n’est pas filtrée lors de la lecture et ne peut pas être multisamplée.
Une mémoire tampon est une collection d’éléments ; une mémoire tampon de vertex contient des données par vertex. L’exemple le plus simple est une mémoire tampon de vertex qui contient un type de données, comme les données de position. Elle peut être visualisées comme l’illustration suivante.
Plus souvent, une mémoire tampon de vertex contient toutes les données nécessaires pour spécifier entièrement les sommets 3D. Par exemple, il peut s’agir d’une mémoire tampon de vertex qui contient une position par vertex, des coordonnées normales et de texture. Ces données sont généralement organisées en tant qu’ensembles d’éléments par vertex, comme illustré dans l’illustration suivante.
Cette mémoire tampon de vertex contient des données par vertex pour huit sommets ; chaque vertex stocke trois éléments (position, normal et coordonnées de texture). La position et la normale sont généralement spécifiées à l’aide de trois floats 32 bits (DXGI_FORMAT_R32G32B32_FLOAT) et des coordonnées de texture utilisant deux floats 32 bits (DXGI_FORMAT_R32G32_FLOAT).
Pour accéder aux données à partir d’une mémoire tampon de vertex, vous devez savoir quel vertex accéder et ces autres paramètres de mémoire tampon :
- Offset : nombre d’octets entre le début de la mémoire tampon et les données du premier sommet. Le décalage est fourni à IASetVertexBuffers.
- BaseVertexLocation : nombre d’octets du décalage au premier sommet utilisé par l’appel de dessin approprié (voir Méthodes Draw).
Avant de créer une mémoire tampon de vertex, vous devez définir sa disposition en créant un objet de disposition d’entrée. Pour ce faire, appelez CreateInputLayout. Une fois l’objet input-layout créé, liez-le à l’étape d’assembleur d’entrée en appelant IASetInputLayout.
Pour créer une mémoire tampon de vertex, appelez CreateBuffer.
Une mémoire tampon d’index contient un ensemble séquentiel d’index 16 bits ou 32 bits ; chaque index est utilisé pour identifier un sommet dans une mémoire tampon de vertex. L’utilisation d’une mémoire tampon d’index avec une ou plusieurs mémoires tampons de vertex pour fournir des données à la phase IA est appelée indexation. Une mémoire tampon d’index peut être visualisées comme l’illustration suivante.
Les index séquentiels stockés dans une mémoire tampon d’index se trouvent avec les paramètres suivants :
- Offset : nombre d’octets entre le début de la mémoire tampon et le premier index. Le décalage est fourni à IASetIndexBuffer.
- StartIndexLocation : nombre d’octets du décalage au premier sommet utilisé par l’appel de dessin approprié (voir Méthodes Draw).
- IndexCount : nombre d’index à afficher.
Pour créer une mémoire tampon d’index, appelez CreateBuffer.
Une mémoire tampon d’index peut assembler plusieurs bandes de traits ou de triangles en les séparant par un index de coupe de bandes. Un index de coupe de bandes permet de dessiner plusieurs bandes de traits ou triangles avec un seul appel de dessin. Un index de coupe de bandes est simplement la valeur maximale possible pour l’index (0xffff pour un index 16 bits, 0xffffffff pour un index 32 bits). L’index de coupe à bandes réinitialise l’ordre d’enroulement dans les primitives indexées et peut être utilisé pour supprimer la nécessité de dégénérer des triangles qui peuvent autrement être nécessaires pour maintenir l’ordre d’enroulement approprié dans une bande de triangles. L’illustration suivante montre un exemple d’index de coupe de bandes.
Direct3D 10 a introduit une nouvelle mémoire tampon pour fournir des constantes de nuanceur appelées mémoire tampon de nuanceur ou simplement une mémoire tampon constante. Conceptuellement, il ressemble à une mémoire tampon de vertex à élément unique, comme illustré dans l’illustration suivante.
Chaque élément stocke une constante de composant de 1 à 4, déterminée par le format des données stockées.
Les mémoires tampons constantes réduisent la bande passante requise pour mettre à jour les constantes de nuanceur en permettant à celles-ci d’être regroupées et validées en même temps plutôt que d’effectuer des appels individuels pour valider chaque constante séparément.
Pour créer une mémoire tampon de nuanceur constante, appelez CreateBuffer et spécifiez l’indicateur de liaison de mémoire tampon constante D3D10_BIND_CONSTANT_BUFFER (voir D3D10_BIND_FLAG).
Pour lier une mémoire tampon de constante de nuanceur au pipeline, appelez l’une des méthodes suivantes : GSSetConstantBuffers, PSSetConstantBuffers ou VSSetConstantBuffers.
Notez que lors de l’utilisation de l’interface ID3D10Effect, le processus de création, de liaison et de comitting d’une mémoire tampon constante est géré par l’instance id3D10Effect Interface. Dans ce cas, il est uniquement nécessaire d’obtenir la variable à partir de l’effet avec l’une des méthodes GetVariable telles que GetVariableByName et de mettre à jour la variable avec l’une des méthodes SetVariable telles que SetMatrix. Pour obtenir un exemple d’utilisation de l’interface ID3D10Effect pour gérer une mémoire tampon constante, consultez le tutoriel 07.
Un nuanceur continue de lire des variables dans une mémoire tampon constante directement par nom de variable de la même manière que les variables qui ne font pas partie d’une mémoire tampon constante sont lues.
Chaque étape de nuanceur permet jusqu’à 15 mémoires tampons constantes de nuanceur ; chaque mémoire tampon peut contenir jusqu’à 4 096 constantes.
Utilisez une mémoire tampon constante pour stocker les résultats de l’étape de sortie de flux.
Consultez les constantes shader (DirectX HLSL) pour obtenir un exemple de déclaration d’une mémoire tampon constante dans un nuanceur.
Une ressource de texture est une collection structurée de données conçue pour stocker des texels. Contrairement aux mémoires tampons, les textures peuvent être filtrées par des échantillonneurs de texture, car elles sont lues par unités de nuanceur. Le type de texture a un impact sur la façon dont la texture est filtrée. Un texel représente la plus petite unité d’une texture qui peut être lue ou écrite par le pipeline. Chaque texel contient 1 à 4 composants, organisés dans l’un des formats DXGI (voir DXGI_FORMAT).
Les textures sont créées en tant que ressource structurée afin que leur taille soit connue. Toutefois, chaque texture peut être typée ou moins au moment de la création des ressources, tant que le type est entièrement spécifié à l’aide d’une vue lorsque la texture est liée au pipeline.
Il existe plusieurs types de textures : 1D, 2D, 3D, chacun pouvant être créé avec ou sans mipmaps. Direct3D 10 prend également en charge les tableaux de textures et les textures à plusieurs échantillonnages.
Une texture 1D dans sa forme la plus simple contient des données de texture qui peuvent être traitées avec une seule coordonnée de texture ; elle peut être visualisées sous la forme d’un tableau de texels, comme illustré dans l’illustration suivante.
Chaque texel contient un certain nombre de composants de couleur en fonction du format des données stockées. En ajoutant plus de complexité, vous pouvez créer une texture 1D avec des niveaux mipmap, comme illustré dans l’illustration suivante.
Un niveau mipmap est une texture qui est une puissance de deux plus petite que le niveau au-dessus de celui-ci. Le niveau le plus élevé contient le plus de détails, chaque niveau suivant est plus petit ; pour un mipmap 1D, le plus petit niveau contient un texel. Les niveaux différents sont identifiés par un index appelé LOD (niveau de détail) ; vous pouvez utiliser le LOD pour accéder à une texture plus petite lors du rendu de la géométrie qui n’est pas aussi proche de la caméra.
Direct3D 10 a également une nouvelle structure de données pour un tableau de textures. Un tableau de textures 1D ressemble conceptuellement à l’illustration suivante.
Ce tableau de textures contient trois textures. Chacune des trois textures a une largeur de texture de 5 (qui est le nombre d’éléments dans la première couche). Chaque texture contient également un mipmap de 3 couches.
Tous les tableaux de textures dans Direct3D sont un tableau homogène de textures ; cela signifie que chaque texture d’un tableau de textures doit avoir le même format et la même taille de données (y compris la largeur de texture et le nombre de niveaux mipmap). Vous pouvez créer des tableaux de textures de tailles différentes, tant que toutes les textures de chaque tableau correspondent à la taille.
Une ressource Texture2D contient une grille 2D de texels. Chaque texel est adressable par un vecteur u, v. Étant donné qu’il s’agit d’une ressource de texture, elle peut contenir des niveaux mipmap et des sous-ressources. Une ressource de texture 2D entièrement remplie ressemble à l’illustration suivante.
Cette ressource de texture contient une texture 3x5 unique avec trois niveaux mipmap.
Une ressource Texture2DArray est un tableau homogène de textures 2D ; autrement dit, chaque texture a le même format de données et les mêmes dimensions (y compris les niveaux mipmap). Elle a une disposition similaire au tableau de textures 1D, sauf que les textures contiennent désormais des données 2D et ressemblent donc à l’illustration suivante.
Ce tableau de textures contient trois textures ; chaque texture est 3x5 avec deux niveaux mipmap.
Un cube de texture est un tableau de textures 2D qui contient 6 textures, une pour chaque face du cube. Un cube de texture entièrement rempli ressemble à l’illustration suivante.
Un tableau de textures 2D qui contient 6 textures peut être lu à partir de nuanceurs avec les fonctions intrinsèques de la carte de cube, une fois qu’elles sont liées au pipeline avec une vue de texture de cube. Les cubes de texture sont traités à partir du nuanceur avec un vecteur 3D pointant vers le centre du cube de texture.
Une ressource Texture3D (également appelée texture de volume) contient un volume 3D de texels. Étant donné qu’il s’agit d’une ressource de texture, elle peut contenir des niveaux mipmap. Une texture 3D entièrement remplie ressemble à l’illustration suivante.
Lorsqu’une tranche mipmap de texture 3D est liée en tant que sortie cible de rendu (avec une vue de cible de rendu), la texture 3D se comporte de façon identique à un tableau de textures 2D avec n tranches. La tranche de rendu particulière est choisie à partir de l’étape du nuanceur géométrique, en déclarant un composant scalaire de données de sortie comme valeur système SV_RenderTargetArrayIndex.
Il n’existe aucun concept de tableau de textures 3D ; par conséquent, une sous-ressource de texture 3D est un niveau mipmap unique.
L’API Direct3D 10 référence des ressources entières ou sous-ensembles de ressources. Pour spécifier une partie des ressources, Direct3D a créé les sous-ressources de terme, ce qui signifie un sous-ensemble d’une ressource.
Une mémoire tampon est définie en tant que sous-ressource unique. Les textures sont un peu plus complexes, car il existe plusieurs types de texture différents (1D, 2D, etc.) qui prennent en charge les niveaux de mipmap et/ou les tableaux de texture. À partir du cas le plus simple, une texture 1D est définie en tant que sous-ressource unique, comme illustré dans l’illustration suivante.
Cela signifie que le tableau de texels qui composent une texture 1D est contenu dans une seule sous-ressource.
Si vous développez une texture 1D avec trois niveaux mipmap, elle peut être visualisées comme suit.
Considérez cela comme une texture unique composée de trois sous-texte. Chaque sous-texte est compté en tant que sous-ressource, de sorte que cette texture 1D contient 3 sous-ressources. Un sous-texte (ou sous-source) peut être indexé à l’aide du niveau de détail (LOD) pour une seule texture. Lorsque vous utilisez un tableau de textures, l’accès à un sous-texte particulier nécessite à la fois le LOD et la texture particulière. Sinon, l’API combine ces deux éléments d’informations en un seul index de sous-ressource de base zéro, comme illustré ici.
Certains API accèdent à une ressource entière (par exemple CopyResource), d’autres accèdent à une partie d’une ressource (par exemple UpdateSubresource ou CopySubresourceRegion). L’API qui accède à une partie d’une ressource utilise généralement une description d’affichage (par exemple, D3D10_TEX2D_ARRAY_DSV) pour spécifier les sous-ressources à accéder.
Ces illustrations illustrent les termes utilisés par une description d’affichage lors de l’accès à un tableau de textures.
Compte tenu d’un tableau de textures, chaque texture avec mipmaps, une tranche de tableau (représentée par le rectangle blanc) comprend une texture et toutes ses sous-textures, comme illustré dans l’illustration suivante.
Une tranche mip (représentée par le rectangle blanc) inclut un niveau mipmap pour chaque texture d’un tableau, comme illustré dans l’illustration suivante.
Vous pouvez utiliser ces deux types de tranches pour choisir une sous-ressource unique, comme illustré dans l’illustration suivante.
Vous pouvez également utiliser ces deux types de tranches avec le nombre de niveaux mipmap et/ou le nombre de textures, pour choisir plusieurs sous-ressources.
Quel que soit le type de texture que vous utilisez, avec ou sans mipmaps, avec ou sans tableau de textures, vous pouvez utiliser la fonction d’assistance D3D10CalcSubresource pour calculer l’index d’une sous-ressource particulière.
La création d’une ressource entièrement typée limite la ressource au format avec lequel elle a été créée. Cela permet au runtime d’optimiser l’accès, en particulier si la ressource est créée avec des indicateurs indiquant qu’elle ne peut pas être mappée par l’application. Les ressources créées avec un type spécifique ne peuvent pas être réinterprétées à l’aide du mécanisme d’affichage.
Dans une ressource moins de type, le type de données est inconnu lors de la création de la ressource. L’application doit choisir parmi le type disponible moins de formats (voir DXGI_FORMAT). Vous devez spécifier la taille de la mémoire à allouer et déterminer si le runtime doit générer les sous-texte dans un mipmap. Toutefois, le format de données exact (si la mémoire sera interprétée comme des entiers, des valeurs à virgule flottante, des entiers non signés, etc.) n’est pas déterminé tant que la ressource n’est pas liée au pipeline avec une vue. Étant donné que le format de texture reste flexible jusqu’à ce que la texture soit liée au pipeline, la ressource est appelée stockage faiblement typé. Le stockage faiblement typé présente l’avantage qu’il peut être réutilisé ou réinterprété (dans un autre format) tant que le bit du composant du nouveau format correspond au nombre de bits de l’ancien format.
Une ressource unique peut être liée à plusieurs étapes de pipeline tant que chacun a une vue unique, qui qualifie entièrement les formats à chaque emplacement. Par exemple, une ressource créée avec le format DXGI_FORMAT_R32G32B32A32_TYPELESS peut être utilisée en tant que DXGI_FORMAT_R32G32B32A32_FLOAT et un DXGI_FORMAT_R32G32B32A32_UINT à différents emplacements du pipeline simultanément.