c++ - privativos - install nvidia drivers debian 9
Varios contextos de representación de OpenGLX fallan en Linux con los controladores de Nvidia propietarios (1)
Cuando intento ejecutar más de 128 contextos de representación de OpenGLX actuales en subprocesos individuales, la llamada a glXMakeCurrent
comienza a fallar.
Display *display = XOpenDisplay(":0")
Window root_win = RootWindow(display, screen);
Window win = XCreateWindow (display, root_win, ...)
GLXContext context = glXCreateContext(display, visinfo, 0, True);
glXMakeCurrent(display, win, context); <---- Fails here on 128th
Este problema solo ocurre con los controladores propietarios de Nvidia y las GPU de Nvidia. No pude reproducirme con las GPU de Intel.
Código de reproducción glx.cpp
:
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glx.h>
#include <GL/glxext.h>
#include <string.h>
#include <unistd.h>
#include <thread>
#include <vector>
#include <mutex>
#include <condition_variable>
#include <chrono>
#define MAX_CONTEXTS 200;
std::mutex mutex;
std::condition_variable cond;
bool will_stop = false;
int numSuccessfulContexts = 0;
#define EXIT_IF(condition, ...) if (condition) { printf(__VA_ARGS__); exit(EXIT_FAILURE);}
#define RETURN_IF(condition, ...) if (condition) { printf(__VA_ARGS__); stop(); return; }
void stop() {
std::lock_guard<std::mutex> lk(mutex);
will_stop = true;
cond.notify_all();
}
void createWindow() {
/* Init X and GLX */
Display *display = XOpenDisplay(":0.0");
RETURN_IF(!display, "Cannot open X display/n");
int screen = DefaultScreen(display);
Window root_win = RootWindow(display, screen);
RETURN_IF(!glXQueryExtension(display, 0, 0),"X Server doesn''t support GLX extension/n");
/* Pick an FBconfig and visual */
static const int attributeList[] = { None };
int fbcount;
GLXFBConfig *fbconfig = glXChooseFBConfig(display, screen, attributeList, &fbcount);
EXIT_IF(!fbconfig, "Failed to get GLXFBConfig/n");
XVisualInfo *visinfo = glXGetVisualFromFBConfig(display, *fbconfig);
EXIT_IF(!visinfo, "Failed to get XVisualInfo/n");
/* Create the X window */
XSetWindowAttributes winAttr ;
winAttr.colormap = XCreateColormap(display, root_win, visinfo->visual, AllocNone);
unsigned int mask = CWColormap;
Window win = XCreateWindow (display, root_win, 256, 64, 320, 320, 0,
visinfo->depth, InputOutput, visinfo->visual, mask, &winAttr) ;
/* Create an OpenGL context and attach it to our X window */
GLXContext context = glXCreateContext(display, visinfo, 0, True);
EXIT_IF(!context, "Could not create GL context/n");
RETURN_IF(! glXMakeCurrent(display, win, context), "glXMakeCurrent failed 1. /n");
RETURN_IF(!glXIsDirect (display, glXGetCurrentContext()), "Indirect GLX rendering context obtained/n");
RETURN_IF(!glXMakeCurrent(display, win, context), "glXMakeCurrent failed 2./n");
numSuccessfulContexts++;
std::unique_lock<std::mutex> lk(mutex);
cond.wait(lk, [] {return will_stop;});
}
int main(int argc, char *argv[]) {
std::vector<std::thread> ts;
printf("Starting, your computer might become unresponsive.../n");
int maxContexts = MAX_CONTEXTS;
while (maxContexts--) {
ts.push_back(std::thread(&createWindow));
}
{
std::unique_lock<std::mutex> lk(mutex);
cond.wait_for(lk, std::chrono::seconds(10), []{return will_stop;});
}
if (!will_stop) {
stop();
}
for (auto& v: ts) {
v.join();
}
printf("Done. Max concurrent contexts: %d/n", numSuccessfulContexts);
return EXIT_SUCCESS;
}
Construir y ejecutar:
g++ -std=c++11 glx.cpp -L/usr/lib/nvidia-375 -lGL -lX11 -lGLU -lGLX -lpthread -o glx && ./glx
Como se comentó en los comentarios, parece que está llegando a un límite de conductor porque está haciendo algo muy inusual e inesperado. Estoy respondiendo esto para eliminarlo de la lista de preguntas sin respuesta.