Множество контекстов рендеринга OpenGLX не работают в Linux с проприетарными драйверами Nvidia

Когда я пытаюсь запустить более 128 текущих контекстов рендеринга OpenGLX в отдельных потоках, glXMakeCurrent начинает терпеть неудачу.

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

Эта проблема возникает только с проприетарными драйверами Nvidia и графическими процессорами Nvidia. Я не смог воспроизвести с графическими процессорами Intel.

Код воспроизведения 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;
}

строить & Бежать:

g++ -std=c++11 glx.cpp -L/usr/lib/nvidia-375 -lGL -lX11 -lGLU -lGLX -lpthread -o glx && ./glx

25

Решение

Как уже говорилось в комментариях, кажется, что вы попали под ограничение водителя, потому что вы делаете что-то очень необычное и неожиданное. Я отвечаю на это, чтобы удалить его из списка оставшихся без ответа вопросов.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]