IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

DirectX Discussion :

DrawIndexedInstanced et alignement mémoire matrices


Sujet :

DirectX

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Mars 2006
    Messages : 143
    Points : 112
    Points
    112
    Par défaut DrawIndexedInstanced et alignement mémoire matrices
    bonjour,

    j'écris un système de particules dans lequel
    j'utilise DrawIndexedInstanced() pour le rendu d'instances de quad
    j'ai donc un VB avec les vertices du quad, et un autre pour les matrices d'instances

    j'ai plusieurs questions :

    quand on copie dans le vertex buffer les matrices d'instances des quad
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    	D3DXMATRIX* pDestMatrices = NULL;
    	D3DXMATRIX* pScrMatrices = m_pMatrixInstanceList;		// tableau d'instances interne calculé dans UpdateInstancedMatrix()
     
    	m_pParticleInstanceData->Map( D3D10_MAP_WRITE_DISCARD, NULL, ( void** )&pDestMatrices );
    	memcpy( pDestMatrices, pScrMatrices, uiNumInstances * sizeof( D3DXMATRIX ) );
    	m_pParticleInstanceData->Unmap();
    le tableau de matrices d'instances associé à pSrcMatrices doit être défini avec des directives #pragma d'alignement en mémoire
    comme dans l'exmple Instancing10
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #pragma pack(push, 1)
    struct INSTANCEDATA
    {
        D3DXMATRIX mMatWorld;
        float fOcc;
    };
    #pragma pack(pop)
    donc je déclare le tableau de matrices d'instances avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    // #pragma empêche compression en mémoire, donc changement d'alignement des matrices en RAM, sinon problème de shader
    #define MAX_PARTICLES 8192					// nombre maximal de particules
     
    #pragma pack(push, 1)	
    	D3DXMATRIX	g_pMatrixArrayList[ MAX_PARTICLES ];		
    #pragma pack(pop)
    sinon on obtient des erreurs au niveau du shader

    est ce bien vrai ?

    puis je encapsuler la déclaration du tableau dans ma classe avec les directives d'alignement en RAM ?

    j'utilise un CGrowableArray pour stocker mes particules, puis, je copie les matrices associées dans un tableau à taille fixe,
    déclaré aligné en RAM, puis je passe un pointeur vers ce tableau lors de la copie des matrices d'instances vers le vb dynamique
    pour faire mon rendu avec DrawIndexedInstanced()

    je dois pouvoir m'y prendre différemment, la taille fixe des tableaux est elle nécessaire ?

    lorsque je change le nombre d'instances à rendre dans DrawIndexedInstanced() d'une frame à l'autre, j'obtiens un warning

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    D3D10: WARNING: ID3D10Device::DrawIndexedInstanced: Vertex Buffer at the input vertex slot 1 is not big enough for what the Draw*() call expects to traverse.
    ais je intérêt à créer des ressources et à utiliser CopySubresourceRegion() , plutôt que Map() pour les copies de données ?

    pourquoi l'utilisation de DXMATRIXA16 en place de D3DXMATRIX ne solutionne pas le problème ?


    quelqu'un peut il m'éclairer un peu sur tout ça ?

  2. #2
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 382
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 382
    Points : 4 936
    Points
    4 936
    Par défaut
    effectivement pour les vb, il faut que les données soient contigus en mémoire.

    pour ma part, j'utilise souvent un vector pour stocker mes éléments du vb, le vector garantissant la continuité en mémoire des éléments stockés, mais j'ai jamais vraiment porté plus d'attention à ça.

    concernant CopySubresourceRegion() et Map(), je dirai c'est selon XD

    et pour DXMATRIXA16 ça créé une matrice aligné certes, mais est ce que les conteneurs de DXMATRIXA16 seront alignés, ça je doute.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Mars 2006
    Messages : 143
    Points : 112
    Points
    112
    Par défaut
    aprés des tests sur l'exemple "Instancing10",

    le fait de désactiver la directive #pragma ne semble pas provoquer de problèmes particulier !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #pragma pack(push, 1)
    struct INSTANCEDATA
    {
        D3DXMATRIX mMatWorld;
        float fOcc;
    };
    #pragma pack(pop)
    à quoi servent donc alors ces directives ?


    si je comprends bien D3DXMATRIXA16 n'aligne en mémoire que le contenu de la matrice et non pas la variable matrice elle même ?


    dans l'exemple "Instanging10" du SDK, lorsque je modifie le nombre d'instance des arbres à rendre via ler slider d'interface, j'obtiens un warning
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    D3D10: WARNING: ID3D10Device::DrawIndexedInstanced: Vertex Buffer at the input vertex slot 1 is not big enough for what the Draw*() call expects to traverse. 
    This is OK, as reading off the end of the Buffer is defined to return 0. However the developer probably did not intend to make use of this behavior. 
     [ EXECUTION WARNING #356: DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL ]
    ça viens de moi ?

    et j'ai le même problème lorsque je veux augmenter le nombre d'instances à rendre lors du "DrawIndexedInstanced(..)" dans mon programme

    Est ce qu'on peut modifier le nombre d'instances à rendre sans problème ?

    L'exemple du SDK fonctionne outre les warning ?

    faut t-il impérativement utiliser un tableau à taille fixe, lors du passage des instances à rendre au shader avec DrawIndexedInstanced(..)" ?

  4. #4
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 382
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 382
    Points : 4 936
    Points
    4 936
    Par défaut
    Citation Envoyé par korsakoff69 Voir le message
    aprés des tests sur l'exemple "Instancing10",

    le fait de désactiver la directive #pragma ne semble pas provoquer de problèmes particulier !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #pragma pack(push, 1)
    struct INSTANCEDATA
    {
        D3DXMATRIX mMatWorld;
        float fOcc;
    };
    #pragma pack(pop)
    à quoi servent donc alors ces directives ?
    à s'assurer que sizeof(INSTANCEDATA) = sizeof(D3DXMATRIX) + sizeof(float).
    c'est vrai que sans ces directives ça marche aussi, mais rien ne nous garanti que l'assertion juste au dessus sera valable quelque soit le compilateur ou le type de processeur cible (x86, x64, ia64).
    l'ajout des pragma nous assurent qu'il y aura pas de padding ajouté à la structure.


    Citation Envoyé par korsakoff69 Voir le message
    si je comprends bien D3DXMATRIXA16 n'aligne en mémoire que le contenu de la matrice et non pas la variable matrice elle même ?
    ola attention, j'ai dit que D3DXMATRIXA16 était aligné, mais que je ne savais pas si, dans le cas ou on faisait un vector<D3DXMATRIXA16>, si le vector en lui même était aligné.


    Citation Envoyé par korsakoff69 Voir le message
    dans l'exemple "Instanging10" du SDK, lorsque je modifie le nombre d'instance des arbres à rendre via ler slider d'interface, j'obtiens un warning
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    D3D10: WARNING: ID3D10Device::DrawIndexedInstanced: Vertex Buffer at the input vertex slot 1 is not big enough for what the Draw*() call expects to traverse. 
    This is OK, as reading off the end of the Buffer is defined to return 0. However the developer probably did not intend to make use of this behavior. 
     [ EXECUTION WARNING #356: DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL ]
    ça viens de moi ?
    moi aussi j'ai ce warning, et ce qui est le plus bizarre c'est que si je rajoute 15 octets au buffer d'entrée, le warning disparait
    donc je suis en train de chercher pourquoi.

    Citation Envoyé par korsakoff69 Voir le message
    et j'ai le même problème lorsque je veux augmenter le nombre d'instances à rendre lors du "DrawIndexedInstanced(..)" dans mon programme

    Est ce qu'on peut modifier le nombre d'instances à rendre sans problème ?

    L'exemple du SDK fonctionne outre les warning ?
    l'exemple semble fonctionner, mais c'est un warning, il vaut mieux s'assurer quand même que c'est voulu et non pas imposé à cause d'une erreur.

    Citation Envoyé par korsakoff69 Voir le message
    faut t-il impérativement utiliser un tableau à taille fixe, lors du passage des instances à rendre au shader avec DrawIndexedInstanced(..)" ?
    comme je l'ai dit, j'utilise souvent un vector sans visiblement de soucis particulier.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Mars 2006
    Messages : 143
    Points : 112
    Points
    112
    Par défaut
    merci pour toute ces réponses, ça me fait avancer

    je vais tester l'utilisation de vector3<..>

    15 octets ? à quel buffer tu les rajoutes ?

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 382
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 382
    Points : 4 936
    Points
    4 936
    Par défaut
    dans la fonction HRESULT LoadInstanceData( ID3D10Device* pd3dDevice, ID3D10Buffer** ppInstanceData, DWORD* pdwNumLeaves, LPCTSTR szFileName )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    D3D10_BUFFER_DESC bufferDesc =
    {
        ( *pdwNumLeaves+0 ) * sizeof( INSTANCEDATA )+0, // +0 +15 O_o
        D3D10_USAGE_DYNAMIC,
        D3D10_BIND_VERTEX_BUFFER,
        D3D10_CPU_ACCESS_WRITE,
        0
    };
    là ou j'ai rajouté deux +0, le deuxième j'ai testé de 0 à beaucoup, et à partir de 15 je n'avais plus de warning, c'est débile, mais je comprends pas pourquoi ><

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Mars 2006
    Messages : 143
    Points : 112
    Points
    112
    Par défaut
    dans le create device

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        // Load our leaf instance data
        V_RETURN( LoadInstanceData( pd3dDevice, &g_pLeafInstanceData, &g_dwNumLeaves, g_szTreeLeafInstanceNames[0] ) );
    dwNumLeaves = 2497
    soit 2497*DWORD, cà n'est pas aligné en nombre d'instances ?

  8. #8
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 382
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 382
    Points : 4 936
    Points
    4 936
    Par défaut
    heu ... je ne comprends pas ce que tu veux dire.

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Mars 2006
    Messages : 143
    Points : 112
    Points
    112
    Par défaut
    ajouter des octets à la taille , ou au nombre des instances ne change rien pour moi, il y a toujours erreur

    sizeof(INSTANCEDATA) = 68 octets = 16 float de matrice + 1 float = 17*4

    2497 instances * 68 = 169796, la taille du buffer d'instances,

    qui n'a pas besoin d'être aligné, excuse moi

    peut être que le problème vient du shader qui s'attend à avoir un nombre fixe d'instances
    le message d'erreur met en cause la taille buffer fournie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Vertex Buffer at the input vertex slot 1 is not big enough for what the Draw*() call expects to travers
    et le rendu des feuilles utilise comme buffer d'entrée dans le shader
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    struct VSQuadIn
    {
        float3 pos : POSITION;
        float2 tex : TEXTURE0;
        row_major float4x4 mTransform : mTransform;
        float fOcc : fOcc;
        uint InstanceId : SV_InstanceID;
    };
    dans la technique pour rendre les feuilles
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    //--------------------------------------------------------------------------------------
    // Quad (leaf) vertex shader.  Instances the quad over multiple leaf positions and 
    // multiple trees.  This demonstrates how to do double instancing.
    //--------------------------------------------------------------------------------------
    PSQuadIn VSQuadmain(VSQuadIn input)
    ce qui ne correspond pas au buffer d'instances dans le programme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #pragma pack(push, 1)
    struct INSTANCEDATA
    {
       D3DXMATRIX mMatWorld;
       float fOcc;
    };
    #pragma pack(pop)
    que se passe t-il quand on varie le nombre d'instances dans le code ?

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Mars 2006
    Messages : 143
    Points : 112
    Points
    112
    Par défaut
    j'ai donc continué sur le sujet
    et pour le système de particules,
    j'utilise un CGrowableArray pour mes particules

    et deux tableaux à taille fixe, ( que je recréé en cas de changment de nombre max )
    un pour mes matrices d'instances,
    un pour les indices associés que je passe à par de warning type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    D3D10: WARNING: ID3D10Device::DrawIndexedInstanced: Vertex Buffer at the input vertex slot 1 is not big enough for what the Draw*() call expects to traverse
    tant que je n'essaye pas d'allouer plus de particules que la taille des tableaux, mais je rencontre parfois, ce type de warning quand j'alloue plus de 2K à mes tableaux !

    je ne vois toujours pourquoi dans l'exemple Instancing10 du SDK, il y a ce warning avec plus d'un arbre instancié

    un rapport avec le GPU ? des idées ?

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Indre et Loire (Centre)

    Informations forums :
    Inscription : Mars 2006
    Messages : 143
    Points : 112
    Points
    112
    Par défaut
    vu que le warning se trouve dans l'exemple Instancing10 du SDK,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    [ EXECUTION WARNING #356: DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL ]
    dès qu'il y a plus d'une instance de l'arbre
    je vais le considérer comme sans motif, à défaut d'autre solution

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Microtec 68000 et alignement mémoire
    Par transgohan dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 18/09/2013, 17h13
  2. Réponses: 17
    Dernier message: 27/09/2011, 22h31
  3. Alignement de matrice
    Par rabbi_jaccob dans le forum Mathématiques - Sciences
    Réponses: 2
    Dernier message: 04/12/2009, 08h25
  4. [Débutant] Aligner des matrices
    Par cladsam dans le forum Mathématiques - Sciences
    Réponses: 10
    Dernier message: 10/11/2006, 12h10
  5. Alignement mémoire pour les structures.
    Par SpaceToto dans le forum Visual C++
    Réponses: 4
    Dernier message: 14/09/2006, 11h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo