+ Répondre à la discussion
Affichage des résultats 1 à 8 sur 8
  1. #1
    Membre régulier
    Inscrit en
    avril 2009
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : avril 2009
    Messages : 207
    Points : 78
    Points
    78

    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!!

  2. #2
    screetch
    Invité(e)

    Par défaut

    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?

  3. #3
    Membre régulier
    Inscrit en
    avril 2009
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : avril 2009
    Messages : 207
    Points : 78
    Points
    78

    Par défaut

    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.

  4. #4
    screetch
    Invité(e)

    Par défaut

    je cherche je cherche
    l'exemple du dessus reproduit le bug, pas vrai?
    c'est quoi l'erreur renvoyée?

  5. #5
    Membre régulier
    Inscrit en
    avril 2009
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : avril 2009
    Messages : 207
    Points : 78
    Points
    78

    Par défaut

    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

  6. #6
    screetch
    Invité(e)

    Par défaut

    "malheureusement", chez moi ton code marche bien.
    OpenGL version : 3.3.0 NVIDIA 280.13

  7. #7
    Membre régulier
    Inscrit en
    avril 2009
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : avril 2009
    Messages : 207
    Points : 78
    Points
    78

    Par défaut

    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

  8. #8
    Membre régulier
    Inscrit en
    avril 2009
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : avril 2009
    Messages : 207
    Points : 78
    Points
    78

    Par défaut

    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!

+ Répondre à la discussion
Cette discussion est résolue.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •