SwapBuffers приводит к сбою моей программы!

У меня есть программа 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. По этой причине кажется странным, что проблема связана с графическим процессором.

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

Кроме того, если я удалю вызов 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) 

person Tony R    schedule 20.03.2009    source источник


Ответы (3)


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

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

person Lucas    schedule 11.05.2009
comment
Спустя более двух лет после того, как я задал этот вопрос, а также несколько сообщений на других сайтах технических форумов, я все еще не смог решить проблему с этой картой. Мне приходится переустанавливать драйверы каждый раз, когда я перезагружаю компьютер. Я уверен, что карта неисправна ... Я приму ваш ответ, потому что вы, наверное, самый близкий. - person Tony R; 30.04.2011
comment
У меня такое случилось, когда я забыл загрузить свои вершинные и индексные буферы, поэтому они были пустыми, когда я вызвал glDrawElements. На самом деле драйвер должен просто игнорировать вызов, так как нет данных для рисования ... но нет, нарушение прав доступа в драйверах Nvidia. Меня тоже свело с ума, так как я думал, что новая библиотека, которую я втянул, портит память. - person jpfx1342; 29.04.2020

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

person Michael    schedule 20.03.2009
comment
Неа. Вылет происходит сразу при запуске программы. Я попробовал сделать перерыв; в после выхода = истина; и такая же проблема ... - person Tony R; 21.03.2009
comment
Вы можете добавить, что такое аварийный стек вызовов? - person Michael; 21.03.2009

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

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

person Andrei Krotkov    schedule 23.03.2009
comment
Я не занимаюсь многопоточностью. hdc до сбоя вроде никогда не менялся. На других моих компьютерах значение hdc такое же (не используется; выражение не может быть вычислено). Я установил более старый драйвер дисплея, и все работает, пока я не перезагружу компьютер. Затем мне нужно переустановить драйвер, чтобы он заработал. - person Tony R; 24.03.2009
comment
Хорошо, вау. Моими дальнейшими действиями после обнаружения этого было бы начать возиться с Аппаратным обеспечением. Замените видеокарту, посмотрите, поможет ли это? - person Andrei Krotkov; 25.03.2009
comment
Я заменил HD4850 ​​на HD4870 на другом рабочем компьютере. Нет проблем. Кажется, это ошибка HD4850? - person Tony R; 26.03.2009
comment
Попробуйте заменить 4850 на другой работающий компьютер с Vista - посмотреть, драйверы это или сама карта? - person Andrei Krotkov; 26.03.2009