SwapBuffers вылетает из моей программы! - PullRequest
4 голосов
/ 21 марта 2009

У меня есть программа OpenGL, которая работает на всех моих компьютерах, кроме одного. Это рабочий стол с Vista 64 и Radeon HD4850. Кажется, проблема в моем вызове SwapBuffers (hdc).

Он прекрасно компилируется, а затем выдает мне исключение:

Необработанное исключение в 0x00000000 в Program.exe: 0xC0000005: нарушение доступа.

Использование VC ++ для прерывания до вызова SwapBuffers показывает значение hdc:

0xfe011734 {unused = ???} CXX0030: Ошибка: выражение не может быть оценено

Кто-нибудь знает, что может происходить? Есть ли что-то в SwapBuffers, которое будет меняться с одного компьютера на другой? Я заставил его работать на XP32, XP64 и (другой) Vista64.

while (!quit)
    {
        if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
                quit = true;

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        renderFrame();  //draws the scene

        SwapBuffers(hdc);

        if (GetAsyncKeyState(VK_ESCAPE))
            shutdown();

        think();        //calculates object positions, etc.
    } 

Драйверы на проблемной системе (HD4850) обновлены. Я запустил и написал программу на другой системе Vista64 с Radeon HD4870, также с современными драйверами. Насколько я знаю, драйверы для этих двух карт почти идентичны, так как оба в серии HD48xx. По этой причине кажется странным, что проблема связана с GPU.

В любом случае, я ошибаюсь или это проблема с памятью? (Нарушение доступа)

Кроме того, если я уберу вызов SwapBuffers (hdc), программа будет работать хорошо, хотя, конечно, ничего не рисуется, потому что кадровые буферы никогда не меняются местами. Но это по крайней мере стабильно.

Стек вызовов (-> ptr стека):

    ATKOGL32.dll!6aef27bc()     
    opengl32.dll!665edb2d()     
    opengl32.dll!665f80d1()     
    gdi32.dll!75e14104()    
->   MyProg.exe!WinMain(HINSTANCE__ * hinstance=0x009a0000, HINSTANCE__ * hprevinstance=0x00000000, char * lpcmdline=0x003b4a51, int nshowcmd=1)  Line 259 + 0xe bytes
    MyProg.exe!__tmainCRTStartup()  Line 578 + 0x35 bytes
    MyProg.exe!WinMainCRTStartup()  Line 400
    kernel32.dll!7641e3f3()     
    ntdll.dll!777dcfed()    
    ntdll.dll!777dd1ff()    

Вот сборка (-> следующая инструкция, которая будет выполнена):

            SwapBuffers(hdc);
    009B1B5C  mov         esi,esp 
    009B1B5E  mov         eax,dword ptr [hdc (9BF874h)] 
    009B1B63  push        eax  
    009B1B64  call        dword ptr [__imp__SwapBuffers@4 (0E1040Ch)] 
->  009B1B6A  cmp         esi,esp 
    009B1B6C  call        @ILT+780(__RTC_CheckEsp) (9B1311h) 

Ответы [ 3 ]

1 голос
/ 21 марта 2009

Похоже, что вы могли получить доступ к HDC после того, как окно было разрушено, исчезнет ли проблема, если вы выйдете из цикла, как только получите WM_QUIT?

0 голосов
/ 11 мая 2009

Это почти наверняка ошибка в драйверах. Причина, по которой вы не можете увидеть значение hdc, заключается в том, что верхний стек для фрейма находится на самом деле внутри ATKOGL32.dll, но поскольку для этого нет символов, отладчик показывает вам ваш код. Насколько я могу судить, ATKOGL32.dll на самом деле является оболочкой ASUS для драйвера ATI, и именно здесь происходит сбой. Возможно, вы захотите установить стоковые драйверы ATI с amd.com и посмотреть, сохраняется ли сбой.

Хотя драйвер никогда не должен аварийно завершать работу, независимо от того, какую серию вызовов OpenGL вы делаете, по моему опыту, обычно сбои являются результатом какого-то неправильного вызова, который делает ваша программа. Технически это следует просто игнорировать и устанавливать состояние ошибки, но это не всегда происходит. Вы можете легко проверить любые недействительные вызовы OpenGL с помощью программы, такой как gDebugger.

0 голосов
/ 24 марта 2009

Независимо от того, какое значение установлено для hdc, оно не выглядит как правильное значение. Окно создано до этого вызова? Есть ли многопоточность, связанная с этим приложением, которое может повредить HDC?

Попробуйте создать часы по адресу самого hdc и посмотрите, когда значение будет изменено на недопустимое местоположение, что может подсказать вам, где оно меняется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...