2016-07-29 3 views
4

J'implémente certaines fonctionnalités qui nécessitent l'implémentation d'une API pour attendre la fin du rendu de d3d10. Essentiellement, j'essaie d'implémenter l'accès de synchronisation à une texture partagée de sorte que je puisse mettre à jour un texture après d3d10 est capable de présenter au backbuffer avec succès. En appelant cette boîte noire api je pense que cela peut être réalisé et je pense que ce sera quelque chose de similaire à glfinish() .J'ai lu que nous pouvons utiliser les requêtes ID3D10Query pour implémenter l'accès de synchronisation.Implémenter l'API pour attendre la fin des commandes d3d10

D3D10_QUERY_DESC queryDesc; 

    ... // Fill out queryDesc structure 

    ID3D10Query * pQuery; 
    pDevice->CreateQuery(&queryDesc, &pQuery); 

    pQuery->Begin(); 

    ... // Issue graphis commands, do whatever 

    pQuery->End(); 

    UINT64 queryData; // This data type is different depending on the query type 

    while(S_OK != pQuery->GetData(&queryData, sizeof(UINT64), 0)) 
    { 
    } 

dois-je mettre une commande factice entre commencer et terminer cela? depuis que je veux exposer cette fonctionnalité comme API publique quelque chose nommé waitforgraphiscompletion

ce qui devrait être une commande factice ici?

Répondre

2

Si vous essayez de synchroniser l'exécution CPU et GPU dans OpenGL, vous utiliserez glFenceSync suivi d'un glClientWaitSync. Les équivalents dans Direct 10 sont ID3D10Asynchronous::End, et ID3D10Asynchronous::GetData (note, dans DX11, les interfaces sont légèrement différentes). Ceux-ci vous permettent de savoir quand le GPU a fini de traiter le tampon de commande à un point particulier. Cela vous permet de savoir quand les opérations précédentes de lecture/écriture sur une ressource sont terminées et que l'UC peut accéder en toute sécurité à la ressource sans synchronisation supplémentaire.

Vous n'êtes pas obligé de placer des commandes dans la boucle while. Le tampon de commande finira par traiter votre requête, et retournera S_OK (ou un message d'erreur, que vous pourriez vouloir traiter). Cependant, cela est un peu inutile, car le CPU va juste tourner en attente pour le GPU, donc si possible, vous devriez faire un travail supplémentaire utile dans la boucle. Remarquez que si vous avez utilisé D3D10_ASYNC_GETDATA_DONOTFLUSH comme paramètre final à GetData (au lieu de '0'), ce qui précède ne serait pas le cas - il n'y a aucune garantie que le tampon de commande serait 'automatiquement' lancé, et vous pourriez finir dans une boucle infinie (et, en tant que tel n'est pas l'utilisation recommandée).

+0

merci cela me fait parfaitement sens. J'ai une ou deux questions à ce sujet. En quoi glfinish est-il différent de glFenceSync suivi d'un glClientWaitSync? En ce qui concerne D3D10 cela signifie juste que j'ai juste besoin d'appeler end sur ID3D10Query (cela signifie pas de début) et il attendra que toute la commande soit exécutée sur le périphérique à partir duquel ID3D10Query a été créé? –

+0

glFinish attendra la fin de toutes les opérations OpenGL, y compris l'écriture dans le framebuffer. glClientWaitSync ne garantit pas cela, il garantit seulement que toutes les commandes GL émises avant la fin de glFenceSync. Ce n'est généralement pas nécessaire si vous cherchez à synchroniser l'accès à une texture particulière, comme vous devriez le savoir quand il est lu/écrit à partir de votre propre code de rendu. – MuertoExcobito

+0

Hmm l'ai eu grâce –