2016-11-25 1 views
1

J'utilise Desktop Duplication pour copier le contenu de l'écran vers un bitmap en mémoire. Je reçois la texture de bureau, puis crée une texture de transfert, utilise CopyResource pour copier la texture de bureau dans la texture de transfert, puis appelle le ID3D11DeviceContext::Map pour accéder aux bits de texture de transfert et les copier. A peu près la même manière que décrit ici: https://stackoverflow.com/a/27283837/825318ID3D11DeviceContext :: Map performance lente

Le problème est que Map appel prend beaucoup de temps - pour les grandes résolutions d'affichage tels que 4K il peut prendre jusqu'à 100 ms par appel, ce qui est inacceptable que j'ai besoin pour assurer une vitesse de 30 fps.

Est-il possible d'obtenir le contenu de la texture plus rapidement? Si ce n'est pas le cas, y a-t-il un moyen de fournir mon propre pointeur d'adresse de mappage afin que le système copie les données de texture à cet endroit? Merci

+1

La documentation [ID3D11DeviceContext :: Map] (https://msdn.microsoft.com/en-us/library/windows/desktop/ff476457 (v = vs.85) .aspx) parle de la pénalité de performance et suggère la stratégies appropriées et la fin de la page. L'un d'eux est d'utiliser le pointeur volatile. –

+0

Merci, cependant, cela ne s'applique qu'aux surfaces en écriture seule, alors que ma tâche consiste à lire les données de la surface. – Isso

Répondre

3

Très probablement, l'opération Map attend la fin de CopyResource. Vous pouvez utiliser GPUView pour vérifier cela. Si tel est le cas, la solution recommandée est d'accepter la latence en faveur du framerate. La façon de gérer cela est de garder au moins 3 textures de mise en scène et faites pivoter entre eux de la manière suivante:

frame # 1 - début ressources de copie à la mise en scène texture # 1

cadre # 2 - début ressources de copie mise en scène texture # 2

cadre # 3 - début ressources de copie à la mise en scène texture # 3 et la carte mise en scène texture # 1 pour accéder aux données

cadre # 4 - début ressources de copie à la mise en scène texture # 1 (ancien contenu devrait déjà être enregistré) et mapper la texture de mise en scène # 2 pour accéder aux données

De cette façon, vous pouvez conserver 30 FPS mais introduire une latence de ~ 130ms, ce qui est acceptable pour la plupart des applications.

+0

Merci! Malheureusement, j'ai besoin d'une latence minimale, donc votre solution ne résout pas vraiment mon problème, mais c'est une approche intelligente et GPUView semble être un utilitaire très utile. Ainsi, je vous accorde la prime. – Isso

+1

Si vous souhaitez une latence minimale, vous devez synchroniser le processeur avec le GPU pour garantir que la texture est lue dès qu'elle est copiée. Cela signifie que le GPU et le CPU ne fonctionneraient pas en parallèle et c'est exactement ce que vous voyiez dans votre question initiale. S'il me manque quelque chose alors s'il vous plaît faites le moi savoir il semble que vous essayez de satisfaire deux exigences opposées. – moradin