int main(int argc, char **argv) { struct window_info wi; Display *dpy = XOpenDisplay(NULL); int sawVertex3fv1, sawVertex3fv2, *pSawVertex3fv; int i; int ret = 1; GLXContext ctx = None; void *vendorHandle; if (!dpy) { printError("No display!\n"); goto fail; } memset(&wi, 0, sizeof(wi)); if (!testUtilsCreateWindow(dpy, &wi, 0)) { printError("Failed to create window!\n"); goto fail; } ctx = glXCreateContext(dpy, wi.visinfo, NULL, GL_TRUE); if (!ctx) { printError("Failed to create a context!\n"); goto fail; } if (!glXMakeContextCurrent(dpy, wi.win, wi.win, ctx)) { printError("Failed to make current\n"); goto fail; } vendorHandle = dlopen("libGLX_patchentry.so", RTLD_LAZY); if (!vendorHandle) { printError("No valid vendor library handle\n"); goto fail; } pSawVertex3fv = (int *)dlsym(vendorHandle, "__glXSawVertex3fv"); if (!pSawVertex3fv) { printError("Could not find __glXSawVertex3fv\n"); goto fail; } for (i = 0; i < NUM_VERTEX3FV_CALLS; i++) { glVertex3fv(NULL); } // Read the resulting value sawVertex3fv1 = *pSawVertex3fv; if (!glXMakeContextCurrent(dpy, None, None, NULL)) { printError("Could not lose current\n"); goto fail; } // Read again. The NOP stubs should be restored by libglvnd for (i = 0; i < NUM_VERTEX3FV_CALLS; i++) { glVertex3fv(NULL); } sawVertex3fv2 = *pSawVertex3fv; dlclose(vendorHandle); pSawVertex3fv = NULL; if (sawVertex3fv1 != NUM_VERTEX3FV_CALLS) { printError("sawVertex3fv1 mismatch: expected %d, got %d\n", NUM_VERTEX3FV_CALLS, sawVertex3fv1); goto fail; } if (sawVertex3fv2 != sawVertex3fv1) { printError("sawVertex3fv2 mismatch: expected %d, got %d\n", NUM_VERTEX3FV_CALLS, sawVertex3fv2); goto fail; } ret = 0; fail: if (ctx) { glXDestroyContext(dpy, ctx); } testUtilsDestroyWindow(dpy, &wi); return ret; }
int main(int argc, char **argv) { Display *dpy; int numScreens; int screen, initScreen = 0; struct window_info *wi = NULL; int ret = 0; GLXContext *ctxs; char **vendorNames; MakeCurrentScreenThreadArgs *tArgs = NULL; int major, event, error; TestOptions t; int i; init_options(argc, argv, &t); dpy = XOpenDisplay(NULL); FAILIF(!dpy, "No display!\n"); numScreens = ScreenCount(dpy); FAILIF(numScreens < 0, "Invalid screen count!\n"); FAILIF(!XQueryExtension(dpy, XGLV_EXTENSION_NAME, &major, &event, &error), "No " XGLV_EXTENSION_NAME " extension!\n"); wi = malloc(sizeof(struct window_info) * numScreens); ctxs = malloc(sizeof(GLXContext) * numScreens); vendorNames = malloc(sizeof(char *) * numScreens); FAILIF(!wi || !ctxs || !vendorNames, "Out of memory!\n"); tArgs = malloc(sizeof(*tArgs) * t.threads); for (i = 0; i < t.threads; i++) { tArgs[i].iterations = t.iterations; tArgs[i].firstScreen = i % numScreens; tArgs[i].numScreens = numScreens; tArgs[i].wi = wi; tArgs[i].ctxs = ctxs; tArgs[i].vendorNames = vendorNames; } for (; initScreen < numScreens; initScreen++) { FAILIF(!testUtilsCreateWindow(dpy, &wi[initScreen], initScreen), "Failed to create window for screen %d!\n", initScreen); ctxs[initScreen] = glXCreateContext(dpy, wi[initScreen].visinfo, NULL, GL_TRUE); FAILIF(!ctxs[initScreen], "Failed to create a context!\n"); vendorNames[initScreen] = XGLVQueryScreenVendorMapping(dpy, initScreen); } pMakeCurrentTestResults = (PFNGLMAKECURRENTTESTRESULTSPROC) glXGetProcAddress((GLubyte *)"glMakeCurrentTestResults"); FAILIF(!pMakeCurrentTestResults, "Could not get glMakeCurrentTestResults!\n"); if (t.threads == 1) { ret = (int)!!MakeCurrentScreenThread((void *)&tArgs[0]); } else { glvnd_thread_t *threads = malloc(t.threads * sizeof(glvnd_thread_t)); void *one_ret; XInitThreads(); if (!glvndSetupPthreads(RTLD_DEFAULT, &pImp)) { exit(1); } for (i = 0; i < t.threads; i++) { FAILIF(pImp.create(&threads[i], NULL, MakeCurrentScreenThread, (void *)&tArgs[i]) != 0, "Error in pthread_create(): %s\n", strerror(errno)); } for (i = 0; i < t.threads; i++) { FAILIF(pImp.join(threads[i], &one_ret) != 0, "Error in pthread_join(): %s\n", strerror(errno)); if (one_ret) { ret = 1; } } free(threads); } cleanup: free(tArgs); if (wi) { for (screen = 0; screen < initScreen; screen++) { testUtilsDestroyWindow(dpy, &wi[screen]); } } free(wi); if (dpy) { XCloseDisplay(dpy); } return ret; }