Modifier

Share via


Direct3D 10 : Forum Aux Questions

Cet article contient certaines des questions fréquemment posées sur Direct3D 10 du point de vue d’un développeur qui porte une application existante de Direct3D 9 (D3D9) vers Direct3D 10 (D3D10).

Mémoires tampons constantes

Quelle est la meilleure façon de mettre à jour les mémoires tampons constantes ?

UpdateSubresource et Map with Discard doivent avoir à peu près la même vitesse. Choisissez entre eux en fonction de celui qui copie le moins de mémoire. Si vos données sont déjà stockées en mémoire dans un bloc contigu, utilisez UpdateSubresource. Si vous avez besoin d’accumuler des données à partir d’autres emplacements, utilisez Mapper avec Ignorer.

Quelle est la pire façon d’organiser les mémoires tampons constantes ?

Les pires performances sont réalisées en plaçant toutes les constantes d’un nuanceur particulier dans une mémoire tampon constante. Bien qu’il s’agit souvent du moyen le plus simple de porter de D3D9 vers D3D10, cela peut nuire aux performances. Par exemple, considérez un scénario qui utilise la mémoire tampon constante suivante :

cbuffer VSGlobalsCB
{
    matrix  ViewProj;
    matrix  Bones[100];
    matrix  World;
    float   SpecPower;
    float4  BDRFCoefficients;
    float   AppTime;
    uint2   RenderTargetSize;
};

La mémoire tampon est de 6 560 octets. Supposons qu’il existe une application avec 1 000 objets à afficher, dont 100 sont des maillages à apparence et 900 de dont des maillages statiques. En outre, supposons que cette application utilise le mappage d’ombres avec une seule source de lumière. Cela signifie qu’il y a deux passes, l’une pour la carte de profondeur rendue à partir de la lumière, et l’autre pour la passe de rendu avant. Il en résulte 2000 appels de dessin. Bien que chaque appel de dessin n’ait pas BESOIN de mettre à jour chaque partie de la mémoire tampon constante, la mémoire tampon constante entière est toujours mise à jour et envoyée à l’carte. Cela entraîne la mise à jour de 13 Mo de données par trame (2 000 appels de dessin fois 6560 Ko).

Quelle est la meilleure façon d’organiser mes mémoires tampons constantes ?

La meilleure façon est d’organiser les mémoires tampons constantes par fréquence de mise à jour. Les constantes mises à jour à des fréquences similaires doivent se trouver dans la même mémoire tampon. Par exemple, considérez le scénario présenté sous « Quelle est la pire façon d’organiser les mémoires tampons constantes ? », mais avec une meilleure disposition de constante :

cbuffer VSGlobalPerFrameCB
  { 
    float   AppTime; 
  };
cbuffer VSPerSkinnedCB
  { 
    matrix  Bones[100]; 
  };
cbuffer VSPerStaticCB
  {
    matrix  World;
  };
cbuffer VSPerPassCB
  {
    matrix  ViewProj;
    uint2   RenderTargetSize;
  };
cbuffer VSPerMaterialCB
  {
    float   SpecPower;
    float4  BDRFCoefficients;
  };    

Les mémoires tampons constantes sont divisées par leur fréquence de mise à jour, mais il ne s’agit que de la moitié de la solution. L’application doit mettre à jour correctement les mémoires tampons constantes afin de tirer pleinement parti du fractionnement. Nous allons supposer la même scène que ci-dessus : 900 maillages statiques, 100 maillages skinned, une passe légère et une passe avant. Nous partons également du principe que certaines mémoires tampons constantes par objet seront stockées. Cela signifie que chaque objet contient un VSPerSkinnedCB ou un VSPerStaticCB, selon qu’il est à apparence ou statique. Nous procédons ainsi afin d’éviter de doubler la quantité de matrices envoyées via le pipeline.

Nous divrons le cadre en trois phases. La première phase est le début de l’image et implique aucun rendu, juste des mises à jour constantes.

Begin Frame

  • Mettre à jour VSGlobalPerFrameCB pour l’heure de l’application (4 octets)
  • Mise à jour 100 VSPerSkinnedCB pour les 100 objets skinned (64 000 octets)
  • Mettre à jour VSPerStaticCB pour 900 objets statiques (57600 octets)

Ensuite se trouve la passe de carte fantôme. Notez que la seule mémoire tampon constante réellement mise à jour est VSPerPassCB. Toutes les autres mémoires tampons constantes ont été mises à jour pendant la passe de frame de début. Bien que nous ayons toujours besoin de lier ces mémoires tampons constantes, la quantité d’informations transmises à la vidéo carte est minime, car les mémoires tampons ont déjà été mises à jour.

Passe d’ombre

  • Mettre à jour VSPerPassCB (72 octets)
  • Dessiner 100 maillages skinned (100 liaisons, aucune mise à jour)
  • Dessiner 900 maillages statiques (100 liaisons, aucune mise à jour)

De même, la passe de rendu avant doit uniquement mettre à jour les données par matériau, car elles n’étaient pas stockées par maillage. Si nous partons du principe qu’il y a 500 matériaux utilisés dans la scène :

Passe vers l’avant

  • Mettre à jour VSPerPassCB (72 octets)
  • Mise à jour 500 VSPerMaterialB (10 000 octets)

Cela donne un total de seulement 707 Ko. Bien qu’il s’agisse d’un scénario très artificiel, il illustre à quel point la surcharge de mise à jour constante peut être réduite en triant les constantes par fréquence de mise à jour.

Que se passe-t-il si je n’ai pas assez d’espace pour stocker des mémoires tampons constantes individuelles pour mes maillages, mes matériaux, et ainsi de suite ?

Vous pouvez toujours utiliser un système hiérarchisé de mémoires tampons constantes. Créez des mémoires tampons constantes de taille variable (16 octets, 32 octets, 64 octets, etc.) jusqu’à la plus grande taille de mémoire tampon constante nécessaire. Lorsqu’il est temps de lier une mémoire tampon constante à un nuanceur, sélectionnez la plus petite mémoire tampon constante pouvant contenir les données nécessaires au nuanceur. Bien que cette approche soit légèrement moins efficace, il s’agit d’une bonne étape intermédiaire.

Je partage des mémoires tampons constantes entre différents nuanceurs. Un nuanceur peut utiliser toutes les constantes, mais un autre peut utiliser certaines constantes. Quelle est la meilleure façon de les mettre à jour ?

L’une des approches consiste à fractionner davantage la mémoire tampon constante. Toutefois, un trop grand nombre de mémoires tampons constantes sont liées. Dans ce cas, déplacez les constantes susceptibles d’être inutilisées par plusieurs nuanceurs vers la fin de la mémoire tampon constante. Lors de l’obtention des données de variable à partir du nuanceur, utilisez l’indicateur D3D10_SVF_USED du D3D10_SHADER_VARIABLE_DESC pour déterminer si la variable est utilisée. En plaçant les variables inutilisées à la fin de la mémoire tampon constante, vous pouvez lier une mémoire tampon plus petite au nuanceur qui n’utilise pas ces variables, ce qui permet d’économiser le coût de mise à jour.

Dans quelle mesure puis-je améliorer ma fréquence d’images si je ne charge les os de mon personnage qu’une fois par image au lieu d’une fois par passe/tirage ?

Vous pouvez améliorer la fréquence d’images comprise entre 8 et 50 pour cent en fonction de la quantité de données redondantes. Dans le pire des cas, les performances ne seront pas réduites.

Combien de mémoires tampons constantes dois-je avoir liées à la fois ?

Liez le nombre minimal de mémoires tampons constantes nécessaire pour obtenir toutes vos données dans le nuanceur. Dans un scénario réaliste, cinq est le nombre recommandé de mémoires tampons constantes à utiliser. Le partage de mémoires tampons constantes entre les nuanceurs (liaison du même cb aux vs et ps) peut également améliorer les performances.

Existe-t-il un coût pour la liaison de mémoires tampons constantes sans les utiliser ?

Oui, si vous ne comptez pas utiliser la mémoire tampon, n’appelez pas VSSetConsantBuffer ou PSSetConstantBuffer. Cette surcharge d’API supplémentaire peut s’ajouter au cours de plusieurs appels de dessin.

State

Quelle est la meilleure façon de gérer l’état dans D3D10 ?

La meilleure solution consiste à connaître tout votre état à l’avance et à créer les objets d’état à l’avance. Cela signifie qu’au moment du rendu, la liaison d’état est la seule opération qui doit se produire. D3D10 filtre également les doublons.

Mon jeu a chargé dynamiquement ou a du contenu généré par l’utilisateur. Je ne peux pas charger tous mes objets d’état à l’avance. Que dois-je faire ?

Il existe deux solutions ici. La première consiste simplement à créer des objets d’état à la volée et à laisser D3D10 filtrer les doublons. Toutefois, cela n’est pas recommandé pour les scénarios avec de nombreuses modifications d’objet d’état par image. Une meilleure solution consiste à hacher vous-même les objets d’état et à créer un objet d’état uniquement si celui qui répond aux exigences est introuvable dans la table de hachage. Le raisonnement derrière l’utilisation d’une table de hachage personnalisée est qu’une application peut sélectionner un hachage rapide en fonction du scénario d’utilisation propre à cette application. Par exemple, si une application modifie uniquement le masque rendertargetwrite dans BlendState et conserve toutes les autres valeurs identiques, l’application peut générer un hachage à partir du masque rendertargetwrite au lieu de la structure entière.

L’état AlphaTest est parti. Où est-il passé ?

AlphaTest doit maintenant être des performances dans le nuanceur. Consultez l’exemple FixedFuncEMU.

Qu’est-il arrivé aux plans de découpage des utilisateurs ?

Les plans de découpage utilisateur ont été déplacés dans le nuanceur. Il existe deux façons de gérer ce problème. La première consiste à générer SV_ClipDistance à partir du nuanceur de vertex ou du nuanceur de géométrie. L’autre option consiste à utiliser la suppression dans le nuanceur de pixels en fonction d’une valeur transmise par le nuanceur de vertex ou le nuanceur de géométrie. Testez les deux pour voir ce qui est le plus rapide pour votre scénario particulier. L’utilisation de SV_ClipDistance peut entraîner l’utilisation par le matériel d’une routine de découpage basée sur la géométrie qui peut ralentir l’exécution des appels de dessin liés à la géométrie. De même, l’utilisation de ignorer déplace le travail vers le nuanceur de pixels, ce qui peut ralentir l’exécution des appels de dessin liés aux pixels.

Les clears ne respectent aucun paramètre d’état, tels que mes paramètres de rect ciseau dans mon état rastériseur.

Les effacements ont été séparés de l’état du pipeline. Pour obtenir un comportement de type D3D9, émulez clears en dessinant un quad plein écran.

Je rétablis mes états par défaut pour essayer de diagnostiquer une erreur de rendu. Maintenant, mon écran affiche simplement le noir, bien que je sache que je dessine des objets sur l’écran.

Lorsque vous rétablissez les valeurs par défaut (NULL) de l’état, assurez-vous que sampleMask dans l’appel à OMSetBlendState n’est jamais égal à zéro. Si SampleMask est défini sur zéro, tous les échantillons seront logiquement ET avec zéro. Dans ce scénario, aucun échantillon ne réussira le test de fusion.

Où est passé l’état D3DSAMP\SRGBTEXTURE ?

SRGB a été supprimé dans le cadre de l’état de l’échantillonneur et est maintenant lié au format de texture. La liaison d’une texture SRGB entraîne le même échantillonnage que celui que vous obtiendriez si vous avez spécifié D3DSAMP_SRGBTEXTURE dans Direct3D 9.

Formats

Quel format D3D9 correspond à quel format D3D10 ?

Pour plus d’informations, consultez Considérations relatives à Direct3D 9 à Direct3D 10.

Qu’est-il arrivé aux formats de texture A8R8G8B8 ?

Ils ont été dépréciés dans D3D10. Vous pouvez re-sourcer vos textures en tant que R8G8B8A8, ou vous pouvez swizzle à la charge, ou vous pouvez swizzle dans le nuanceur.

Comment faire utiliser des textures palettisées ?

Placez votre palette de couleurs dans une texture ou une mémoire tampon constante et liez-la au pipeline. Dans le nuanceur de pixels, effectuez une recherche indirecte à l’aide de l’index dans votre texture palettisée.

Quels sont ces nouveaux formats SRGB ?

SRGB a été supprimé dans le cadre de l’état de l’échantillonneur et est maintenant lié au format de texture. La liaison d’une texture SRGB entraîne le même échantillonnage que celui que vous obtiendriez si vous avez spécifié D3DSAMP_SRGBTEXTURE dans Direct3D 9.

Où sont allés les fans de triangle ?

Les ventilateurs triangle ont été dépréciés dans D3D10. Les ventilateurs triangle devront être convertis dans le pipeline de contenu ou à la charge.

Liaison du nuanceur

Mes nuanceurs Direct3D 9 compilent correctement le modèle de nuanceur 4.0, mais quand je les lie au pipeline, des erreurs de liaison s’affichent dans la sortie de débogage avec le runtime de débogage.

La liaison du nuanceur est beaucoup plus stricte dans D3D10. Les éléments d’une étape suivante doivent être lus dans l’ordre dans lequel ils sont générés à partir de l’étape précédente. Par exemple :

Sorties d’un nuanceur de vertex :

    float4 Pos  : SV_POSITION;
    float3 Norm : NORMAL;
    float2 Tex  : TEXCOORD0;

Un nuanceur de pixels lit dans :

        float3 Norm : NORMAL;
        float2 Tex  : TEXCOORD0;

Bien que la position ne soit pas nécessaire dans le nuanceur de pixels, cela entraîne une erreur de liaison, car la position est en cours de sortie à partir du nuanceur de vertex, mais pas de lecture par le nuanceur de pixels. La version la plus correcte ressemble à ceci :

Sorties d’un nuanceur de vertex :

        float3 Norm : NORMAL;
        float2 Tex  : TEXCOORD0;
        float4 Pos  : SV_POSITION;

Un nuanceur de pixels lit dans :

        float3 Norm : NORMAL;
        float2 Tex  : TEXCOORD0;

Dans ce cas, le nuanceur de vertex affiche les mêmes informations, mais le nuanceur de pixels lit maintenant les éléments dans l’ordre de sortie. Étant donné que le nuanceur de pixels ne lit rien après Tex, nous n’avons pas à nous soucier du fait que le vs affiche plus d’informations que le PS ne le lit.

J’ai besoin d’une signature de nuanceur pour créer une disposition d’entrée, mais je charge mes maillages et crée des dispositions avant de créer des nuanceurs. Que faire ?

Une solution consiste à changer d’ordre et à charger des nuanceurs avant de charger des maillages. Cependant, c’est beaucoup plus facile à dire qu’à faire. Vous pouvez toujours créer les dispositions d’entrée à la demande lorsque l’application en a besoin. Vous devrez conserver une version de la signature du nuanceur. Vous devez créer un hachage basé sur le nuanceur et la disposition de la mémoire tampon, et créer uniquement la disposition d’entrée si celle qui correspond n’existe pas déjà.

Dessiner des appels

Quelle est ma limite d’appels de dessin pour que D3D10 atteigne 60 Hz ? 30 Hz ?

Direct3D 9 avait une limitation sur le nombre d’appels de tirage en raison du coût du processeur par appel de tirage. Sur Direct3D 10, le coût de chaque appel de tirage a été réduit. Toutefois, il n’existe plus de corrélation définie entre les appels de dessin et les fréquences d’images. Étant donné que les appels de dessin nécessitent souvent de nombreux appels de support (mises à jour de mémoire tampon constantes, liaisons de texture, paramètre d’état, etc.), l’impact de la fréquence d’images de l’API dépend désormais davantage de l’utilisation globale de l’API que de simplement dessiner le nombre d’appels.

Ressources

Quel type d’utilisation de ressource dois-je utiliser pour quelles opérations ?

Utilisez la aide-mémoire suivante :

  • Le processeur met à jour la ressource plusieurs fois par image : D3D10_USAGE_DYNAMIC
  • Le processeur met à jour la ressource moins d’une fois par image : D3D10_USAGE_DEFAULT
  • Le processeur ne met pas à jour la ressource : D3D10_USAGE_IMMUTABLE
  • Le processeur doit lire la ressource : D3D10_USAGE_STAGING

Étant donné que les mémoires tampons constantes sont toujours destinées à être mises à jour fréquemment, elles ne sont pas conformes au « cheat-sheet ». Pour connaître les types de ressources à utiliser pour les mémoires tampons constantes, consultez la section Mémoires tampons constantes .

Qu’est-il arrivé à DrawPrimitiveUP et DrawIndexedPrimitiveUP ?

Ils sont partis dans D3D10. Pour la géométrie dynamique, utilisez une mémoire tampon de grande D3D10_USAGE_DYNAMIC. Au début du cadre, mappez-le avec D3D10_MAP_WRITE_DISCARD. Pour chaque appel de dessin suivant, avancez le pointeur d’écriture au-delà de la position des sommets précédemment dessinés et mappez la mémoire tampon avec D3D10_MAP_WRITE_NO_OVERWRITE. Si vous approchez de la fin de la mémoire tampon avant la fin du cadre, encapsulez le pointeur d’écriture vers le début et mappez avec D3D10_MAP_WRITE_DISCARD.

Puis-je écrire des index 16 bits et des index 32 bits dans la même mémoire tampon de géométrie dynamique ?

Oui, vous pouvez le faire, mais cela peut entraîner une pénalité de performances sur certains matériels. Il est plus sûr de créer des mémoires tampons distinctes pour les données d’index 16 bits dynamiques et les données d’index 32 bits.

Comment faire lire les données du GPU vers le processeur ?

Vous devez utiliser une ressource intermédiaire. Copiez les données de la ressource GPU vers la ressource de préproduction à l’aide de CopyResource. Mappez la ressource de préproduction pour lire les données.

Mon application dépendait de la fonctionnalité StretchRect.

Étant donné qu’il s’agissait essentiellement d’un wrapper pour les fonctionnalités Direct3D de base, il a été supprimé de l’API. Une partie des fonctionnalités StretchRect a été déplacée dans D3DX10LoadTextureFromTexture. Pour les conversions de format et la copie de textures, D3DX10LoadTextureFromTexture peut effectuer le travail. Toutefois, les opérations telles que la conversion d’une taille en une autre nécessiteront probablement une opération de rendu en texture dans l’application.

Il n’y a aucun décalage ou taille sur les appels map pour les ressources. Ceux-ci étaient présents sur les appels de verrouillage sur Direct3D 9 ; pourquoi ont-ils changé ?

Les décalages et les tailles des appels de verrouillage sur Direct3D 9 étaient essentiellement encombrés par l’API et souvent ignorés par le pilote. Les décalages doivent être calculés à la place par l’application à partir du pointeur retourné dans l’appel de carte.

Profondeur en tant que texture

Qu’est-ce qui est plus rapide ? Utiliser la profondeur comme texture ou écrire la profondeur en alpha et lire cela ?

Il s’agit d’une application et d’un matériel spécifiques. Utilisez celui qui enregistre le plus de bande passante. Si vous utilisez déjà plusieurs cibles de rendu et disposez d’un canal supplémentaire, l’écriture de profondeur à partir du nuanceur peut être une meilleure solution. En outre, l’écriture de profondeur dans alpha ou une autre cible de rendu vous permet d’écrire des valeurs de profondeur linéaires qui peuvent accélérer les calculs qui doivent accéder à la mémoire tampon de profondeur.

Puis-je avoir une texture liée en tant qu’entrée ET en tant que texture de gabarit de profondeur tant que je désactive les écritures de profondeur ?

Pas dans D3D10.

MSAA

Puis-je résoudre une texture de gabarit de profondeur MSAA ?

Pas dans D3D10. Toutefois, vous pouvez échantillonner des exemples individuels à partir de la texture MSAA. Pour plus d’informations, consultez la section HLSL .

Pourquoi mon application se bloque-t-elle dès que j’active MSAA ?

Veillez à activer un nombre d’échantillons MSAA et un numéro de qualité qui sont effectivement énumérés par le pilote.

Crashes

Mon application se bloque dans D3D10 ou dans le pilote et je ne sais pas pourquoi.

La première étape consiste à activer le runtime de débogage (D3D10_CREATE_DEVICE_DEBUG indicateur passé dans D3D10CreateDevice). Cela expose les erreurs les plus courantes en tant que sortie de débogage.

PIX se bloque lorsque j’essaie d’utiliser mon application avec elle.

La première étape consiste à activer le runtime de débogage (D3D10_CREATE_DEVICE_DEBUG indicateur passé dans D3D10CreateDevice). PIX a une probabilité beaucoup plus élevée de se bloquer si la sortie de débogage n’est pas propre.

Mon jeu manque d’espace d’adressage virtuel sur Vista 32 bits sous D3D10. Il n’a pas de problèmes sur D3D9.

Il y a eu des problèmes avec D3D10 et l’espace d’adressage virtuel. Cela a été résolu dans KB940105. Si cela ne résout pas votre problème, assurez-vous que vous ne créez pas plus de ressources qui peuvent être mappées (verrouillées) dans D3D10 que vous avez créées dans D3D9. Pensez également au portage vers 64 bits, car cela deviendra plus courant à l’avenir.

Rendu prédicé

J’ai utilisé le rendu prédicé (basé sur les résultats de la requête d’occlusion). Pourquoi mon application est-elle toujours la même vitesse ?

Tout d’abord, assurez-vous que le rendu que vous souhaitez ignorer est bien le goulot d’étranglement de l’application. S’il ne s’agit pas du goulot d’étranglement, ignorer le rendu n’aidera pas la fréquence d’images.

Deuxièmement, assurez-vous que suffisamment de temps s’est écoulé entre le problème de la requête et le rendu que vous souhaitez prédicat. Si la requête n’est pas terminée au moment où l’appel de rendu atteint le GPU, le rendu se produit de toute façon.

Troisièmement, la prédication ignore uniquement certains appels. Les appels ignorés sont Draw, Clear, Copy, Update, ResolveSubresource et GenerateMips. Le paramètre d’état, la configuration IA, mapper et créer des appels ne respectent pas la prédication. S’il existe un grand nombre d’appels de paramètre d’état autour de l’appel de dessin à prédicer, ces états seront toujours définis.

Nuanceur de géométrie

Dois-je utiliser le nuanceur de géométrie pour mettre mon (insérer quelque chose ici) ?

Non. Le nuanceur de géométrie ne doit PAS être utilisé pour le pavage.

Puis-je utiliser le nuanceur geometry pour créer une géométrie ?

Oui, dans des scénarios très limités. Le nuanceur de géométrie dans les pièces D3D10 (2008) actuelles n’est pas équipé pour gérer une grande expansion. Cela pourrait changer à l'avenir. Les fournisseurs de carte vidéo peuvent avoir un chemin d’accès spécial pour une à quatre extensions en raison du matériel point sprite existant. Toute autre expansion devrait être très limitée. Les échantillons ParticlesGS et PipesGS atteignent des fréquences d’images élevées en effectuant uniquement une expansion limitée. Seuls quelques points sont développés par image.

Pour quoi dois-je utiliser le nuanceur geometry ?

Tout ce qui nécessite des opérations sur une primitive entière, comme la détection de silhouette, les coordonnées barycentriques, etc. Utilisez-la également pour sélectionner la tranche d’un tableau cible de rendu à laquelle envoyer des primitives.

Puis-je générer des quantités variables de géométrie à partir du nuanceur geometry ?

Oui, mais cela peut entraîner des problèmes de performances. Prenons l’exemple de la sortie de 1 point pour un appel et de 4 points pour un autre. Tout en respectant les instructions d’expansion, cela peut entraîner l’exécution en série des threads de nuanceur geometry.

Comment D3D10 sait-il comment générer des indices d’adjacence pour mon maillage ? Ou, pourquoi D3D10 ne s’affiche-t-il pas correctement quand je spécifie que le nuanceur de géométrie a besoin d’informations d’adjacence.

Les informations d’adjacence ne sont pas créées par D3D10, mais par l’application. Les index d’adjacence sont générés par l’application et doivent contenir six index par primitive ; parmi les six, les index numérotés impairs sont les sommets adjacents de bord. ID3DX10Mesh::GenerateAdjacencyAndPointsReps peut être utilisé pour générer ces données.

HLSL

Les instructions au niveau des nombres entiers et du bit sont-elles lentes ?

C’est possible. Différentes cartes D3D10 peuvent uniquement émettre des opérations entières sur un sous-ensemble des unités ALU disponibles. Cela dépend fortement du matériel. Consultez votre fournisseur de matériel individuel pour obtenir des recommandations sur la façon de traiter les opérations entières sur ce matériel particulier. Faites également très attention aux casts d’un type à l’autre.

Qu’est-il arrivé à VPOS ?

Si vous déclarez une entrée dans votre nuanceur de pixels comme SV_POSITION, vous obtiendrez le même comportement que la déclaration en tant que VPOS.

Comment faire échantillonner une texture MSAA ?

Dans votre nuanceur, déclarez votre texture en tant que Texture2DMS. Vous pouvez ensuite extraire des exemples individuels à l’aide des méthodes Sample de l’objet Texture2DMS.

Comment faire savoir si une variable de nuanceur dans une mémoire tampon constante est réellement utilisée ?

Examinez le struct de D3D10_SHADER_VARIABLE_DESC réfléchi pour cette variable. uFlags doit avoir l’indicateur D3D10_SVF_USED défini.

Comment faire savoir si une variable de nuanceur dans une mémoire tampon constante utilise effectivement FX10 ?

Pour l’instant, cela n’est pas possible à l’aide de FX10.

Je n’ai aucun contrôle sur les mémoires tampons constantes créées par FX10. Comment sont-ils créés et mis à jour ?

Toutes les mémoires tampons constantes gérées par FX10 sont créées en tant que ressources D3D10_USAGE_DEFAULT et mises à jour à l’aide de UpdateSubresource. Étant donné que FX10 conserve un magasin de sauvegarde de toutes les données constantes, UpdateSubresource est la meilleure approche pour les mettre à jour.

Comment faire émuler le pipeline de fonction fixe à l’aide de nuanceurs ?

Consultez l’exemple FixedFuncEMU.

Dois-je utiliser les nouveaux indicateurs de compilateur \[unroll\], \[loop\], \[branch\], et ainsi de suite ?

En général, non. Le compilateur essaie souvent les deux méthodes et choisit la plus rapide. Dans certains cas, il peut être nécessaire d’utiliser [unroll], par exemple, lorsqu’une extraction de texture à l’intérieur d’une boucle a besoin d’accéder à un dégradé.

La précision partielle fait-elle une différence sur D3D10 ? Je peux spécifier une précision partielle dans mon HLSL D3D9, mais pas dans mon D3D10 HLSL.

Toutes les opérations D3D10 sont spécifiées pour s’exécuter à une précision à virgule flottante 32 bits. Par conséquent, la précision partielle ne doit pas faire de différence dans D3D10.

Dans D3D9, je pouvais effectuer un filtrage d’ombre PCF HW en liant une mémoire tampon de profondeur en tant que texture et en utilisant des instructions hlsl tex2d standard. Comment faire faire cette opération sur D3D10 ?

Vous devez utiliser un état d’échantillonneur de comparaison et utiliser les instructions SampleCmp.

Comment fonctionne cet enregistrement mot clé dans D3D10 ?

Le registre mot clé dans D3D10 s’applique désormais à l’emplacement auquel une ressource particulière est liée. Dans ce cas, la ressource peut être une mémoire tampon (constante ou autre), une texture ou un échantillonneur.

  • Pour les mémoires tampons constantes, utilisez la syntaxe : register(bN), où N est l’emplacement d’entrée (0-15)
  • Pour les textures, utilisez la syntaxe : register(tN), où N est l’emplacement d’entrée (0-127)
  • Pour les échantillonneurs, utilisez la syntaxe : register(sN), où N est l’emplacement d’entrée (0-127)

Comment faire placer une variable à l’intérieur d’une mémoire tampon constante si le registre est simplement utilisé pour spécifier où lier la mémoire tampon entière ?

Utilisez le mot clé packoffset. L’argument de packoffset se présente sous la forme c[0-4095]. [x,y,z,w]. Par exemple :

        cbuffer cbLotsOfEmptySpace
        {
        float   IWaste2Floats   : packoffset(c0.z);
        float4  IWasteMore  : packoffset(c13);
        };

Dans cette mémoire tampon constante, IWaste2Floats est placé au troisième float (12e octet) dans la mémoire tampon constante. IWasteMore est placé au 13e float4 ou au 52e float dans la mémoire tampon constante.