Précédent   Forum du club des développeurs et IT Pro > Applications > Développement 2D, 3D et Jeux > API graphiques
API graphiques Forum d'entraide sur les API et bibliothèques graphiques 2D et 3D
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 23/08/2011, 11h13   #1
victor_gasgas
Membre du Club
 
Inscription : avril 2009
Messages : 186
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 186
Points : 64
Points : 64
Par défaut [OpenGL 3.3 - 4.2] Problème de contexte Nvidia

Bonjour,

Je suis sur Linux, et j'aimerais codé avec les nouvelles versions OpenGL. Avec AMD je n'ai aucun problème.

Par contre avec les pilotes Nvidia, si le contexte OpenGL est Core Profile alors tout les appels OpenGL après la première frame déclenche une erreur, récupérée avec glGetError(). Mais pas dans la première frame.
Et si le contexte en en Compatibility Profile alors la aucun problème.

Ci-dessous un code minimal. Il suffit d'avoir les derniers drivers Nvidia (avec le hardware compatible) et d'avoir installé les fichiers dev X11 : paquet libx11-dev sur Ubuntu.

Il suffit de commenter/décommenter la ligne 126 pour changer le comportement de l'appli au travers du contexte.

On compile avec g++ main.cpp -o m -lX11 -lGL.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GL/gl.h>
#include <GL/glx.h>
 
#include <iostream>
 
 
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
 
 
int main (int argc, char ** argv)
{
    Display *display = XOpenDisplay(0);
 
    if (!display)
    {
        printf( "Failed to open X display\n" );
        exit(1);
    }
 
    static int visual_attribs[] =
    {
        GLX_X_RENDERABLE    , True,
        GLX_DRAWABLE_TYPE   , GLX_WINDOW_BIT,
        GLX_RENDER_TYPE     , GLX_RGBA_BIT,
        GLX_X_VISUAL_TYPE   , GLX_TRUE_COLOR,
        GLX_RED_SIZE        , 8,
        GLX_GREEN_SIZE      , 8,
        GLX_BLUE_SIZE       , 8,
        GLX_ALPHA_SIZE      , 8,
        GLX_DEPTH_SIZE      , 24,
        GLX_STENCIL_SIZE    , 8,
        GLX_DOUBLEBUFFER    , True,
        None
    };
 
    int glx_major, glx_minor;
 
    // FBConfigs were added in GLX version 1.3.
    if ( !glXQueryVersion( display, &glx_major, &glx_minor ) || ( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) )
    {
        printf( "Invalid GLX version" );
        exit(1);
    }
 
    printf( "Getting matching framebuffer configs\n" );
 
    int fbcount;
    GLXFBConfig *fbc = glXChooseFBConfig( display, DefaultScreen( display ), 
    visual_attribs, &fbcount );
 
    if ( !fbc || fbcount < 1)
    {
        printf( "Failed to retrieve a framebuffer config\n" );
        exit(1);
    }
 
 
 
    GLXFBConfig bestFbc = fbc[0];
 
 
 
    // Get a visual
    XVisualInfo *vi = glXGetVisualFromFBConfig( display, bestFbc );
 
    XSetWindowAttributes swa;
    Colormap cmap;
    swa.colormap = cmap = XCreateColormap( display,RootWindow( display, vi->screen ), vi->visual, AllocNone );
    swa.background_pixmap = None ;
    swa.border_pixel      = 0;
    swa.event_mask        = StructureNotifyMask;
 
 
    printf( "Creating window\n" );
    Window win = XCreateWindow(display, 
                               RootWindow( display, vi->screen ), 
                               0, 0, 100, 100, 0, vi->depth, 
                               InputOutput, 
                               vi->visual, 
                               CWBorderPixel|CWColormap|CWEventMask, 
                               &swa );
 
    if (!win)
    {
        printf( "Failed to create window.\n" );
        exit(1);
    }
 
    // Done with the visual info data
    XFree( vi );
 
    XStoreName( display, win, "OpenGL Window" );
    XMapWindow( display, win );
 
 
 
 
 
 
    glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
    glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
    glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
 
    GLXContext ctx = 0;
 
    if (!glXCreateContextAttribsARB)
    {
        printf( "glXCreateContextAttribsARB() not found\n" );
        exit(1);
    }
 
 
    else
    {
        int context_attribs[] =
        {
            GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
            GLX_CONTEXT_MINOR_VERSION_ARB, 3,
 
            //GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
            None
        };
 
        printf( "Creating context\n" );
        ctx = glXCreateContextAttribsARB( display, bestFbc, 0, True, context_attribs );
 
 
        XSync( display, False );
        if (!ctx)
        {
            printf( "Failed to create GL 3.3 context\n" );
            exit(1);
        }
    }
 
 
    if ( !glXIsDirect ( display, ctx ) )
        printf( "Indirect GLX rendering context obtained\n" );
 
    else
        printf( "Direct GLX rendering context obtained\n" );
 
 
 
    printf( "Making context current\n" );
    glXMakeCurrent( display, win, ctx );
 
 
    const GLubyte* oglVersion = glGetString(GL_VERSION);
    std::cout << "OpenGL version : " << oglVersion << std::endl;
 
 
 
    GLenum lastError = glGetError();
 
 
 
 
    // Frame 1 :
 
    glClearColor ( 0, 0.5, 1, 1 );
    glClear ( GL_COLOR_BUFFER_BIT );
 
    if( glGetError() != GL_NO_ERROR)
        std::cout << "Error OpenGL frame 1" << std::endl;
 
    glXSwapBuffers ( display, win );
 
    sleep( 1 );
 
 
 
 
    // Frame 2 :
 
    glClearColor ( 1, 0.5, 0, 1 );
 
    if( glGetError() != GL_NO_ERROR)
        std::cout << "Error OpenGL frame 2" << std::endl;
 
    glClear ( GL_COLOR_BUFFER_BIT );
    glXSwapBuffers ( display, win );
 
    sleep( 1 );
 
 
 
 
 
    glXMakeCurrent( display, 0, 0 );
    glXDestroyContext( display, ctx );
 
    XDestroyWindow( display, win );
    XFreeColormap( display, cmap );
    XCloseDisplay( display );
}
Si je pouvais avoir des retours!

Merci beaucoup d'avance!!
victor_gasgas est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/08/2011, 11h26   #2
screetch
Invité(e)
 
Messages : n/a
Détails du profil
Informations forums :
Messages : n/a
Points : 0
et si tu ajoutes un traitement des événements au milieu:

Code :
1
2
3
4
5
6
    XEvent event;
    /* wait for events*/
    while (XPending(display) > 0)
    {
        XNextEvent(display, &event);
    }
ca aide?
  Envoyer un message privé Réponse avec citation 00
Vieux 23/08/2011, 11h30   #3
victor_gasgas
Membre du Club
 
Inscription : avril 2009
Messages : 186
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 186
Points : 64
Points : 64
Merci pour la réponse.

En réalité j'ai une appli bien plus grosse avec gestion des événements. Et même constat.

La c'est juste un exemple minimal qui fonctionne pour bien cibler le problème! Donc non sa ne résoud pas le problème mais merci quand même.
victor_gasgas est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/08/2011, 11h36   #4
screetch
Invité(e)
 
Messages : n/a
Détails du profil
Informations forums :
Messages : n/a
Points : 0
je cherche je cherche
l'exemple du dessus reproduit le bug, pas vrai?
c'est quoi l'erreur renvoyée?
  Envoyer un message privé Réponse avec citation 00
Vieux 23/08/2011, 19h23   #5
victor_gasgas
Membre du Club
 
Inscription : avril 2009
Messages : 186
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 186
Points : 64
Points : 64
Pardon pardon j'étais au travail.

En fait l'exemple suivant créer un contexte OpenGL 3.3.
Ensuite il exécute deux frames, chacune terminée par un glXSwapBuffers()

Or en Core Profile, une fois le premier glXSwapBuffers() appelé, tout appel à une fonction OpenGL (typiquement gl*) se solde par une erreur, rattraper par glGetError().

L'exemple montre qu'en mode Compatibility Profile les deux appels à glGetError ne relèvent rien du tout. Alors qu'avec le Core Profile, en output sur la console on a droit à un bel "Error OpenGL frame 2". Preuve que c'est bien la deuxième frame (un appel a glXSwapBuffers).

Et il est possible de changer l'appel qu'il envoi l'erreur, ici glClearColor(), mais on obtiens le même résultat avec glBind*() et d'autres...


Donc en fait je suis venus pour savoir s'il fallait connaître quelque chose en particulier sur les pilotes Nvidia linux, où alors une erreur sur la création de contexte.
Mais surtout si d'autres constate le même résultat avec ce code.
Bien sur je test ca avec un pilote à jour et un harware compatible GT 540M.

Voila Voila, Merci encore!

P.S. Sur d'autre ordinateur, avec une AMD j'arrive bien à utiliser OpenGL 4.1 avec la tesselation et tout se qui s'en suit. C'est juste que je me suis essayer à la portabilité hardware
victor_gasgas est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/08/2011, 21h22   #6
screetch
Invité(e)
 
Messages : n/a
Détails du profil
Informations forums :
Messages : n/a
Points : 0
"malheureusement", chez moi ton code marche bien.
OpenGL version : 3.3.0 NVIDIA 280.13
  Envoyer un message privé Réponse avec citation 00
Vieux 23/08/2011, 22h49   #7
victor_gasgas
Membre du Club
 
Inscription : avril 2009
Messages : 186
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 186
Points : 64
Points : 64
Tu as bien commenter-decommenter la ligne 126 (je crois c'est celle la. Elle permet d'avoir un contexte en core ou compatibility profile). C'est ce test la dont j'ai surtout besoin =)

Ensuite ayant un proc intel I5 sandy bridge, il faut savour que je dois utiliser bumblebee avec virtualgl. En effet pour ceux qui savent pas le serveur X utiliser par linux etant trop viellisant il est impossible aux drivers nvidia de switcher en direct entre la carte contenue dans le cpu (intel) et le gpu dedie (nvidia)... Alors que sous windows c'est easy..

J'ai déjà reussi a faire integrer le support d'opengl > 3 dans virtualgl (voir le projet sourceforge directement) avec l'extension GLX_ARB_create_context, ne reste qqu'a mettre fin a ce bug bien genant
victor_gasgas est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/08/2011, 11h36   #8
victor_gasgas
Membre du Club
 
Inscription : avril 2009
Messages : 186
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 186
Points : 64
Points : 64
J'ai parlé directement au developpeur de VirtualGL et apparemment la dernière version (head) sur le CVS corrige ce bug.

Donc je met en résolut. En tout cas merci de ton aide!
victor_gasgas est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 13h43.


 
 
 
 
Partenaires

Hébergement Web