2009-12-22 2 views
2

Parfois, dans mon application OpenGL je reçois une violation d'accès dans l'appel API suivante:violation d'accès à wglMakeCurrent

wglMakeCurrent(NULL, NULL); 

L'application ne dispose que d'un seul fil, et je l'ai vérifié que avant cet appel, les deux DC et HGLRC qui sont actuellement utilisés sont corrects et valides.

Il existe trois fenêtres différentes avec le contenu OpenGL, et elles sont toutes redessinées sur les messages WM_PAINT et si une actualisation est requise en raison de l'interaction de l'utilisateur (par exemple, la sélection d'un objet).

Cette violation d'accès se produit également sur différentes machines avec différentes cartes graphiques, donc je ne pense pas que ce soit un problème de pilote.

Que pourrait faire planter cet appel d'API? Que dois-je rechercher dans le code de l'application pour savoir où/pourquoi cela se produit? Je suis vraiment perdu ici depuis que j'ai vérifié tout ce à quoi je pouvais penser. J'espère que quelqu'un peut me donner des conseils/idées sur ce qu'il y a d'autre à vérifier.

+0

Peut-être vérifier la valeur de retour de l'appel wglMakeCurrent ou GetLastError. – Stringer

+2

wglMakeCurrent crash, il n'y a donc pas de valeur de retour. – Stefan

Répondre

1

Il s'avère qu'un pilote graphique mis à jour fixe la question. Donc, c'était un problème dans le pilote.

0

Essayez d'ajouter un appel glFlush juste avant de procéder. Peut-être que le pipeline de rendu n'a pas encore été entièrement vidé vers le GPU.

2

Le but de cet appel est-il de libérer le contexte de périphérique du thread en cours? C'est la seule fois que passer NULL pour les deux paramètres est valide. De la documentation:

« Si hglrc est NULL, la fonction rend le contexte de rendu actuel thread appelant aucun courant plus, et libère le contexte de l'appareil qui est utilisé par le contexte de rendu Dans ce cas, hdc est ignoré.. "

Suite à la suggestion de Tarydon d'ajouter un glFlush, il semble que ce serait redondant:

« Avant de passer au nouveau contexte de rendu, OpenGL débusque un contexte de rendu précédent qui était en cours au thread appelant "

Compte tenu de l'API se bloque en fait, et ne résulte pas simplement un échec, la seule suggestion que je peux penser est que le fil sur lequel vous appelez wglMakeCurrent pour libérer le HGLRC n'est pas le même contexte de fil utilisé pour associer le HGLRC au contexte de ce périphérique. Il se peut donc que le pilote recherche le mauvais stockage local de l'appel, provoquant ainsi le plantage. Que se passe-t-il si vous ajoutez de la journalisation à votre code et imprimez l'ID de thread actuel juste avant chaque appel à wglMakeCurrent?

Voir:

+0

Comme je l'ai mentionné, l'application entière n'utilise qu'un seul thread, donc des problèmes avec des threads différents ne sont pas possibles. Et l'ajout de code de journalisation n'aide pas non plus: l'application me déteste vraiment et ne plante tout simplement pas lorsque j'ajoute du code de journalisation. Je suppose que je dois creuser ici très très profond dans le code de dix ans :( – Stefan

+0

@Stefan Ensuite, je suggère d'ajouter le code de connexion à tous vos appels 'wglMakeCurrent' et affichant les valeurs de' DC' et 'HGLRC', et son retour Vous pouvez également essayer différentes formes de consignation (par exemple, écrire dans un fichier ou utiliser OutputDebugString, etc.) Dans le passé, j'ai trouvé que si votre application change de comportement lors de l'ajout (ou En supprimant) le code de journalisation, cela peut être un symptôme de corruption de la mémoire.Vous pouvez essayer un outil tel que BoundsChecker, qui peut détecter les erreurs à l'exécution (corruption de la mémoire ainsi que les échecs de l'API, etc.). – gavinb