Question

Voir Modifier les mises à jour ci-dessous. La question d'origine a été modifiée!

J'ai une fenêtre de travail qui utilise un appareil DX11. Mon problème arrive lorsque j'essaie de faire un écran plein à l'aide d'ALT + Entrée. Si la fenêtre n'est pas concentrée, je reçois une sortie de débogage qui dit:

'MyGame.exe': Loaded 'C:\Windows\SysWOW64\D3D10SDKLayers.DLL', Cannot find or open the PDB file

Et puis l'avertissement

DXGI Warning: IDXGISwapChain::Present: Fullscreen presentation inefficiencies incurred due to application not using IDXGISwapChain::ResizeBuffers appropriately, specifying a DXGI_MODE_DESC not available in IDXGIOutput::GetDisplayModeList, or not using DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH

Je suis assez certain qu'un jeu DX11 ne devrait pas charger d3d10sdklayers.dll, en particulier au milieu de l'exécution. À partir des documents MSDN, j'ai rassemblé que cette DLL est chargée sur la création de l'appareil: if a device is created with the appropriate layer flag, this DLL is loaded automatically. J'ai donc vérifié si mes méthodes de création d'appareils étaient appelées d'une manière ou d'une autre au milieu de l'exécution, et elles ne le sont pas. Je n'ai que 2 places dans mon jeu où la création d'appareils existe, et aucun des deux endroits n'est touché. Edit: Après avoir vérifié MSDN, il semble que cette DLL ne soit qu'une DLL de débogage et pourrait être chargée pour imprimer l'avertissement lui-même, sans autre objectif.

Cas de reproduction explicites:

1) ALT + Entrez 6 fois (3 cycles de transition à écran complet, dans les deux sens, démarrage de démarrage), le 7e, la DLL est chargée et l'avertissement apparaît. Cela se produit quelle que soit la focalisation des fenêtres.

Résumé de la hiérarchie des appels de la méthode (Aller à plein écran):

1) TogglefullScreen () - Ma méthode, seule méthode appelée par Alt + Entrée
2) resizetargetandbuffers () - ma méthode, sous-méthodes ci-dessous
3) dxgiswapchain-> resizetarget (frontbufferdesc) redimensive tampon avant à res
4) dxgiswapchain-> getfullScreenState () pour déterminer l'état plein écran
5) dxgiswapchain-> setfullScreenState (vrai, null) pour devenir plein écran
6) ResidizedxGiBuffers (largeur, hauteur, vrai) ma méthode, redimensionne le tampon, sous-méthode ci-dessous
7) dxgiswapchain-> redimensibuffers (comptage, largeur, hauteur, format, drapeaux) pour redimensionner le tampon
8) dxgiswapchain-> resizetarget (frontbufferdesc) empêche les problèmes de taux de rafraîchissement. Rafraîchir le membre zéro conformément aux meilleures pratiques MSDN.
9) dxgiswapchain-> getfullScreenState () pour déterminer l'état plein écran

Résumé de la hiérarchie des appels de la méthode (Vergitable):

1) TogglefullScreen () - Ma méthode, seule méthode appelée par Alt + Entrée
2) resizetargetandbuffers () - ma méthode, sous-méthodes ci-dessous
3) dxgiswapchain-> resizetarget (backbufferdesc) redimente le tampon avant pour spécifié res
4) dxgiswapchain-> getfullScreenState () pour déterminer l'état plein écran
5) dxgiswapchain-> setfullScreenState (false, null) pour aller en plein écran
6) dxgiswapchain-> resizetarget (backbufferdesc) pour redimensionner le tampon avant à la résolution de Windows (a aidé à résoudre certains problèmes de res)
7) ResidizedxGiBuffers (largeur, hauteur, faux) ma méthode, redimensionne le tampon, sous-méthodes ci-dessous
8) dxgiswapchain-> redimensibuffers (comptage, largeur, hauteur, format, drapeaux) pour redimensionner le tampon
9) dxgiswapchain-> getfullScreenState () pour déterminer l'état plein écran

Les répercussions de cela sont assez graves. Mon crochet de clavier de bas niveau qui attrape Alt + Entrée n'est plus appelé, donc Windows est capable de faire sa manipulation ALT + automatique, ce qui contourne entièrement ma méthode de bascule et définit la fenêtre sur la résolution du bureau. Cela fait que les tampons sont de la mauvaise taille (puisque je ne les ai pas définis, Windows l'a fait), provoquant l'avertissement d'inefficacité et joué avec les variables de mon programme qui n'ont plus une connaissance correcte des tailles de tampons et si la fenêtre est en plein écran ou non.

Des idées quant à ce qui pourrait en être causé?

PS Si vous avez besoin d'échantillons de code, soyez précis sur ce que vous voulez voir et j'essaierai de le mettre en place si possible. Je ne peux pas mettre en place l'intégralité de la liste de code.

Edit: le code de création de périphérique est ci-dessous.


         hr = D3D11CreateDevice(    pAdapter,
                                    driverType,
                                    NULL,
                                    rDeviceSettings.m_CreateFlags,
                                    &rDeviceSettings.m_eD3DDeviceFeatureLevel,
                                    1,
                                    D3D11_SDK_VERSION,
                                    &pGraphicsDevice,
                                    &eFeatureLevel,
                                    &pDeviceContextI
            );


            if ( FAILED( hr ) ) {
                pAdapter = NULL;
                // Remote desktop does not allow you to enumerate the adapter.  In this case, we let D3D11 do the enumeration.
                if ( driverType == D3D_DRIVER_TYPE_UNKNOWN ) { 
                    hr = D3D11CreateDevice( pAdapter,
                                            driverType,
                                            NULL,
                                            rDeviceSettings.m_CreateFlags,
                                            &rDeviceSettings.m_eD3DDeviceFeatureLevel,
                                            1,
                                            D3D11_SDK_VERSION,
                                            &pGraphicsDevice,
                                            &eFeatureLevel,
                                            &pDeviceContextI
                    );
                }

Le premier appel réussit 99% du temps, à savoir lorsque vous n'utilisez pas de bureau à distance, donc je me concentrerai uniquement sur celui-ci. Je lui donne l'adaptateur, DriverType comme d3d_driver_type_hardware, m_createflags comme d3d11_create_device_debug et m_efeaturelevel en tant que d3d_feature_level_11_0. Appel assez standard, et il réussit toujours.

Modifier la mise à jour 1: Après un débogage approfondi, j'ai constaté que lorsque la DLL est chargée et que l'avertissement d'inefficacité apparaît, des circonstances très intéressantes surviennent. Ils sont répertoriés ci-dessous:

1) Le débogueur VS2010 ne déclenche plus les points d'arrêt dans le crochet clé.
2) La sortie imprimée ne fonctionne plus dans le crochet clé.
3) La fenêtre peut devenir non re-sizable si elle était re-sizable avant
4) La fenêtre peut devenir innovable.
5) Un trio de fils de sortie.

Modifier la mise à jour 2: la première mise à jour d'édition peut avoir des hypothèses incorrectes; Si je le trouve, je le supprimerai. Il s'avère que mon crochet de clé de bas niveau n'est plus appelé (je pense, car aucun point d'arrêt ou énoncé d'impression ne fonctionne à l'intérieur), donc si quelque chose dans mon programme ne l'informe accidentellement, cela entraînerait tous les problèmes ci-dessus . Tester ça demain ...

Modifier la mise à jour 3: Je ne sais plus ce qui se passe. J'ai testé le même projet propre sur mon ordinateur personnel et mon ordinateur de travail, et j'ai obtenu des résultats différents. À la maison, je peux alt + entrer indéfiniment sans aucun problème, mais au travail alt + entre dans la 7e fois, le crochet clé ne soit plus appelé et les problèmes de tampon se produisent.

Modifier la mise à jour 4: plus de tests (au travail). Le crochet clé est définitivement retiré après la 3e transition en mode fenêtré. Il n'imprime plus du tout à l'intérieur de la méthode de crochet de clé, et les points d'arrêt ne sont pas déclenchés, quelle que soit la touche appuyée. Je pense que je vais ouvrir une question distincte à ce sujet, car tous les autres problèmes que je décris ci-dessus ne sont que les conséquences de ce crochet clé n'appelant pas TogglefullScreen (). Pour référence, j'ai fourni le code de crochet clé ci-dessous.


LRESULT _stdcall MyClass::WindowsKeyHook( s32 nCode, WPARAM wParam, LPARAM lParam ) {
    printf("Key hook called, nCode: %d. ", nCode);
    if( nCode < 0 || nCode != HC_ACTION )  { // do not process message 
        return CallNextHookEx( MyClassVar.GetWindowsKeyHook(), nCode, wParam, lParam );
    }
    printf(" Key hook status ok.\n");

    BOOL bEatKeystroke = FALSE;
    KBDLLHOOKSTRUCT* p = ( KBDLLHOOKSTRUCT* )lParam;
    switch( wParam ) {
        //NOTE: Alt seems to be a system key when it is PRESSED, but a regular key when it is released...
        case WM_SYSKEYDOWN:
            if(p->vkCode == VK_MENU || p->vkCode == VK_LMENU || p->vkCode == VK_RMENU) {
                MyClassVar.SetAltPressed(TRUE);
            }
            if(MyClassVar.IsAltPressed() && p->vkCode == VK_RETURN) {
                bEatKeystroke = TRUE;
                MyClassVar.SetAltEnterUsed(TRUE);
                printf("Alt+Enter used.\n");
            }
            break;
        case WM_SYSKEYUP:
            //NOTE: releasing alt+enter causes a SYSKEYUP message with code 0x13: PAUSE key...
            break;
        case WM_KEYDOWN:
            break;
        case WM_KEYUP: {
            if(p->vkCode == VK_MENU || p->vkCode == VK_LMENU || p->vkCode == VK_RMENU) {
                MyClassVar.SetAltPressed(FALSE);
            }
            bEatKeystroke = ( !MyClassVar.IsShortcutKeysAllowed() &&
                                ( p->vkCode == VK_LWIN || p->vkCode == VK_RWIN ) );
            break;
        }
    }

    if( bEatKeystroke ) {
        return 1;
    }
    else {
        return CallNextHookEx( MyClassVar.GetWindowsKeyHook(), nCode, wParam, lParam );
    }
}

Les instructions PRINTF montrent que le crochet clé est appelé jusqu'à la 6ème alt + entre. Il s'agit de la 3e transition en mode fenêtré. Il n'est pas nécessaire pour moi d'aller en plein écran une 4ème fois, comme je le pensais auparavant, pour causer le problème. Toutes les méthodes appelées par MyClassvar sont en ligne pour faire aller le crochet clé aussi rapidement que possible, car je sais qu'il y a un délai d'attente sur les crochets de clés Windows. Le traitement réel d'Alt + Entrée est géré par un fil dans MyClass.

De plus, quelqu'un peut-il en faire un wiki communautaire? Je pense que cette question est beaucoup trop spécifique pour être utile comme wiki. La seule raison pour laquelle il est devenu une est que je l'ai mise à jour régulièrement avec les modifications.

Pas de solution correcte

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top