/* * Copyright (c) 2017, NVIDIA CORPORATION. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and/or associated documentation files (the * "Materials"), to deal in the Materials without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Materials, and to * permit persons to whom the Materials are furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * unaltered in all copies or substantial portions of the Materials. * Any additions, deletions, or changes to the original source files * must be clearly indicated in accompanying documentation. * * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ /** * \file * * This program tests the various GLX functions to create a context. */ #include #include #include #include #include #include "test_utils.h" #include "dummy/GLX_dummy.h" static int runTestGLX12(struct window_info *wi); static int runTestGLX13(struct window_info *wi); static int runTestGLXAttribsConfig(struct window_info *wi); static int runTestGLXAttribsScreen(struct window_info *wi); static int runTestGLXAttribsVendor(struct window_info *wi); static int runTestCommon(struct window_info *wi, GLXContext ctx, const char *testName); static PFNGLXCREATECONTEXTATTRIBSARBPROC ptr_glXCreateContextAttribsARB; static PFNGLXCREATECONTEXTVENDORDUMMYPROC ptr_glXCreateContextVendorDUMMY; int main(int argc, char **argv) { Display *dpy = NULL; struct window_info wi = {}; int result = 1; dpy = XOpenDisplay(NULL); if (dpy == NULL) { printError("No display! Please re-test with a running X server\n" "and the DISPLAY environment variable set appropriately.\n"); goto done; } // Call glXQueryServerString to make libGLX.so load the vendor library for // the screen before we try to load any extension functions. glXQueryServerString(dpy, DefaultScreen(dpy), GLX_EXTENSIONS); ptr_glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte *) "glXCreateContextAttribsARB"); if (ptr_glXCreateContextAttribsARB == NULL) { printError("Could not load glXCreateContextAttribsARB\n"); goto done; } ptr_glXCreateContextVendorDUMMY = (PFNGLXCREATECONTEXTVENDORDUMMYPROC) glXGetProcAddress((const GLubyte *) "glXCreateContextVendorDUMMY"); if (ptr_glXCreateContextVendorDUMMY == NULL) { printError("Could not load glXCreateContextVendorDUMMY\n"); goto done; } if (!testUtilsCreateWindowConfig(dpy, &wi, DefaultScreen(dpy))) { printError("Failed to create window\n"); goto done; } // Start by testing the core GLX functions, glXCreateContext and // glXCreateNewContext. result = runTestGLX12(&wi); if (result != 0) { goto done; } result = runTestGLX13(&wi); if (result != 0) { goto done; } // Next, test using glXCreateContextAttribsARB. This can dispatch one of // two ways. First, test dispatching using a GLXFBConfig handle. result = runTestGLXAttribsConfig(&wi); if (result != 0) { goto done; } // Next, test using the GLX_EXT_no_config_context extension. In this case, // we'll pass NULL for the GLXFBConfig parameter, but then specify a screen // number using an attribute. result = runTestGLXAttribsScreen(&wi); if (result != 0) { goto done; } // All of the above functions have dispatch stubs in libGLX.so itself, so // test to make sure that a vendor can provide an extension function and // dispatch stub to create a context. result = runTestGLXAttribsVendor(&wi); if (result != 0) { goto done; } done: if (dpy != NULL) { if (wi.dpy != NULL) { testUtilsDestroyWindow(dpy, &wi); } XCloseDisplay(dpy); } return result; } int runTestGLX12(struct window_info *wi) { GLXContext ctx = glXCreateContext(wi->dpy, wi->visinfo, NULL, True); return runTestCommon(wi, ctx, "glXCreateContext"); } int runTestGLX13(struct window_info *wi) { GLXContext ctx = glXCreateNewContext(wi->dpy, wi->config, GLX_RGBA_TYPE, NULL, True); return runTestCommon(wi, ctx, "glXCreateNewContext"); } int runTestGLXAttribsConfig(struct window_info *wi) { GLXContext ctx = ptr_glXCreateContextAttribsARB(wi->dpy, wi->config, NULL, True, NULL); return runTestCommon(wi, ctx, "glXCreateContextAttribsARB(config)"); } int runTestGLXAttribsScreen(struct window_info *wi) { // Create a context using the GLX_EXT_no_config_context extension. In this // case, we pass NULL for the GLXFBConfig parameter, but then specify a // screen number using an attribute. const int attribs[] = { GLX_SCREEN, wi->visinfo->screen, None }; GLXContext ctx = ptr_glXCreateContextAttribsARB(wi->dpy, NULL, NULL, True, attribs); return runTestCommon(wi, ctx, "glXCreateContextAttribsARB(screen)"); } int runTestGLXAttribsVendor(struct window_info *wi) { GLXContext ctx = ptr_glXCreateContextAttribsARB(wi->dpy, wi->config, NULL, True, NULL); return runTestCommon(wi, ctx, "glXCreateContextVendorDUMMY"); } int runTestCommon(struct window_info *wi, GLXContext ctx, const char *testName) { int value = -1; int ret = 1; if (ctx == NULL) { printError("%s: failed to create context\n", testName); goto done; } // Call glXQueryContext to make sure that we can dispatch to this context if (glXQueryContext(wi->dpy, ctx, GLX_CONTEX_ATTRIB_DUMMY, &value) != Success) { printError("%s: glXQueryContext failed\n", testName); goto done; } if (value != 1) { printError("%s: glXQueryContext returned wrong value %d\n", testName, value); goto done; } printf("Test succeeded: %s\n", testName); ret = 0; done: if (ctx != NULL) { glXDestroyContext(wi->dpy, ctx); } return ret; }