primus-0~20150328/0000755000175000017500000000000012555052373013462 5ustar vincentvincentprimus-0~20150328/technotes.md0000644000175000017500000002051612555052336016003 0ustar vincentvincentNotes on primus implementation ============================== primus: quick'n'dirty OpenGL offloading The purpose is to redirect OpenGL rendering to another X display, and copy the rendered frames to the original (as if rendering was not redirected), similar to VirtualGL, but with different assumptions and design goals. primus makes the following assumptions: * both X servers are local, and direct rendering is available on both * the application is "well-behaved" (uses double buffering, does not use color index rendering, does not draw on top of the OpenGL drawable, etc.) In contrast, VirtualGL: * assumes that the application's X display is remote * supports obscure OpenGL functionality, making it more versatile The design goals are: * simplicity/minimalism: - only GLX functions are overridden - only two Xlib functions are used * efficiency: - minimal amount of framebuffer data copying achievable from application-level offloading (unfortunately OpenGL does not allow to reduce beyond 2 copies, readback+display) - pipelining of rendering, readback and display Put another way, VirtualGL is optimized for running arbitrary OpenGL applications over a network, with correctness and bandwidth being primary concerns, while primus is optimized for running modern games on hybrid graphics hardware setups, with simplicity and performance in mind. It is only needed until DMA-BUF/PRIME offloading is implemented and mature. This document collects various interesting issues encountered while implementing primus. Assuming that a secondary X server driving the rendering slave card is present, OpenGL offloading can be achieved by intercepting GLX calls to reroute application's rendering to a pbuffer on the secondary X server, and then reading back the framebuffer and displaying it on the original drawable. Intercepting GLX calls ---------------------- The usual way to perform symbol interposition in Linux is to use LD_PRELOAD, and that is what VirtualGL does. However, that is not enough when an application uses dlopen+dlsym to access library functions. To support that, VirtualGL overrides dlopen and dlsym via LD_PRELOAD as well, and it even intercepts `dlopen("libdl")`. Perhaps a cleaner approach is to make the wrapper provide the complete API (GLX+OpenGL in this case) and add the wrapper into LD_LIBRARY_PATH instead, which is what primus implements. One problem with this approach is that although primus overrides only GLX functions, it has to implement trivial forwarding for OpenGL functions. If the underlying OpenGL library is compiled without -Bsymbolic and calls GLX functions itself, those calls will invoke functions from the wrapper, which will cause failures unless the wrapper is prepared for that by keeping a per-thread boolean value indicating whether a wrapper function was entered but not returned yet (primus does not do that yet). Implementing GLX redirection ---------------------------- For each rendering context created by the application, primus creates an additional slave-side context for readback and master-side context for display (the latter would not be necessary if displaying the framebuffer was performed by some other means than OpenGL, but it's useful for vblank synchronization). For each application thread that calls glXMakeCurrent, primus additionally spawns a readback thread and a display thread. Rendering, readback and display are pipelined: application thread regains control as soon as readback thread issued an asynchronous glReadPixels into a PBO, and readback thread uses two PBOs to perform readback of a new frame into one while another is used by the display thread. Threads signal data availability/release via posix semaphores. Additionally, a GL sync object is required so that readback thread does not read an incomplete frame. The application sees slave-side FBConfig and GLXContext IDs, but master-side X Visuals. One GLX function that is not easily redirected is glXUseXFont, as it internally calls OpenGL functions on bitmap data from the X server. We need bitmap data from one server, but OpenGL functions need to be called in the other server's context. Direct Rendering on Both Servers -------------------------------- The worker threads each get a direct rendering context. One small issue that was encountered is that symbols from libglapi.so need to be loaded by primus in a global namespace (`dlopen("libglapi.so.0", RTLD_GLOBAL)`), otherwise DRI modules would fail to load (they need symbols from libglapi, but don't link against it). Starting with Mesa 9.0, DRI modules do link against libglapi, so this is not a problem. However, this means that without shared libglapi, it is not possible to obtain direct rendering context when loading Mesa with `dlopen("libGL.so.1", RTLD_LOCAL)`. Xlib and threads ---------------- primus spawns additional threads for each application thread that calls glXMakeCurrent: a readback thread and a display thread. The latter makes calls to glXSwapBuffers after drawing a full-screen quad asynchronously with the application. Initially, primus called XInitThreads to enable that, as suggested by the Xlib error message. However, if an applications loads both Xlib and libGL dynamically via dlopen, primus may not be able to call XInitThreads early enough. It turned out that opening separate X connections for primus' needs is a simpler and more robust solution. Forwarding OpenGL calls ----------------------- To provide OpenGL API functions, primus contains trivial forwarding functions (VirtualGL overrides some of OpenGL functions, e.g. glFinish to support single-buffered applications; primus does not support those). However, it would be better to rely on a dynamic linker mechanism to avoid the need to provide forwarder implementations, and instead make the dynamic linker resolve OpenGL functions to definitions found in a slave libGL. On Solaris, that would be possible with per-symbol DT_FILTER tagging; unfortunately, this is not supported in binutils and glibc. Another question is what functions need to be forwarded. Per OpenGL ABI document, libraries need to export only up to OpenGL 1.2 and ARB_multitexture, and anything above that the applications must obtain via glXGetProcAddress. In reality, Mesa's libGL and nVidia's libGL export a significant (but different) amount of functions implementing extensions, and there are applications either linking against those (fortunately not many, Braid and Trine 2 have been found guilty so far) or even trying to obtain pointers via dlsym (Enemy Territory). Compositing ----------- There had been reports that using primus under a compositing WM causes flickering or slow/uneven update rate. When worker threads are synchronized in a way that the application's thread calling glXSwapBuffers does not regain control until the display worker completed blitting and called glXSwapBuffers itself, those issues are not observed. It's unclear what mechanism is causing the problem. Waiting for the display worker to finish completely serializes render-readback-display, so may cause a big degradation in performance. The recommended mode is to make the display worker display the previously rendered frame: this should achieve better performance at the expense of latency of presentation (and black first frame unless special care is given). Window Resizing --------------- It is not obvious how to receive notifications of window resizing in primus. At the moment, it simply calls XGetGeometry every frame (without that, the only Xlib function called in primus would be XOpenDisplay). VirtualGL intercepts several resizing-related functions from Xlib, and additionally tries to deduce drawable size from glViewport calls. Window Destruction ------------------ Since display worker runs asynchronously by default, there is a problem that the window it is drawing to may be destroyed after application regained control after calling glXSwapBuffers, but before the display worker completed drawing and called glXSwapBuffers itself. The worker then encounters an X error and causes the application to terminate. This problem does not arise when worker threads are synchronized as described above. How to avoid this problem while still running the display worker asynchronously? Multilib -------- Linux dynamic linker expands $LIB in paths according to current architecture (since 2002). This nice feature is used both in dlopen() calls in primus and the wrapper script. primus-0~20150328/primusrun.10000644000175000017500000000370712555052336015616 0ustar vincentvincent.TH PRIMUSRUN "1" "February 2013" "primusrun" .SH NAME primusrun \- run an application on a discrete NVIDIA video card .SH SYNOPSIS \fBprimusrun\fR \fIcommand \fR .SH DESCRIPTION Primus implements low-overhead local-only client-side OpenGL offloading via GLX forking. .sp It is currently intended to be used alongside Bumblebee and provides a drop-in replacement for optirun (i.e. "primusrun"). .SH VARIABLES The following is a list of environment variables affecting primus library that may be relevant for end users: .IP "\s-1PRIMUS_SYNC\s0" 4 Readback-display synchronization method (default: 0) .br 0: no sync, 1: synced, display previous frame, 2: synced, display latest frame .IP "\s-1PRIMUS_VERBOSE\s0" 4 Verbosity level (default: 1) .br 0: only errors, 1: warnings, 2: profiling .IP "\s-1PRIMUS_DISPLAY\s0" 4 The secondary Xorg server display number (default: :8) .SH EXAMPLES .TP \fBprimusrun glxgears \-info\fR Runs the graphics demo supplied by mesa-utils to confirm whether the discrete card is being used for GL rendering. .TP \fBPRIMUS_VERBOSE=2 primusrun glxgears\fR Runs the graphics demo supplied by mesa-utils with verbose output from primus. .TP \fBvblank_mode=0 primusrun glxgears\fR Disable vblank synchronisation, typically used for benchmarking purposes. .SH ISSUES Since compositing hurts performance, invoking primus when a compositing WM is active is not recommended. If you need to use primus with compositing and see flickering or bad performance, synchronizing primus' display thread with the application's rendering thread may help. .sp \fBPRIMUS_SYNC=1 primusrun ...\fR .sp This makes primus display the previously rendered frame. Alternatively, with PRIMUS_SYNC=2 primus will display the latest rendered frame, trading frame rate for reduced visual latency. .SH AUTHOR Primus was created by Alexander Monakov . .PP This manual page was written by Vincent Cheng , for the Debian project (and may be used by others). primus-0~20150328/primusrun0000755000175000017500000000260012555052336015451 0ustar vincentvincent#!/bin/bash # Readback-display synchronization method # 0: no sync, 1: D lags behind one frame, 2: fully synced # export PRIMUS_SYNC=${PRIMUS_SYNC:-0} # Verbosity level # 0: only errors, 1: warnings (default), 2: profiling # export PRIMUS_VERBOSE=${PRIMUS_VERBOSE:-1} # Upload/display method # 0: autodetect, 1: textures, 2: PBO/glDrawPixels (needs Mesa-10.1+) # export PRIMUS_UPLOAD=${PRIMUS_UPLOAD:-0} # Approximate sleep ratio in the readback thread, percent # export PRIMUS_SLEEP=${PRIMUS_SLEEP:-90} # Secondary display # export PRIMUS_DISPLAY=${PRIMUS_DISPLAY:-:8} # "Accelerating" libGL # $LIB will be interpreted by the dynamic linker # export PRIMUS_libGLa=${PRIMUS_libGLa:-'/usr/$LIB/nvidia/libGL.so.1'} # "Displaying" libGL # export PRIMUS_libGLd=${PRIMUS_libGLd:-'/usr/$LIB/libGL.so.1'} # Directory containing primus libGL PRIMUS_libGL=${PRIMUS_libGL:-$(dirname `readlink -ne $0`)/'$LIB'} # On some distributions, e.g. on Ubuntu, libnvidia-tls.so is not available # in default search paths. Add its path manually after the primus library # PRIMUS_libGL=${PRIMUS_libGL}:/usr/lib/nvidia-current:/usr/lib32/nvidia-current # Mesa drivers need a few symbols to be visible # export PRIMUS_LOAD_GLOBAL=${PRIMUS_LOAD_GLOBAL:-'libglapi.so.0'} # Need functions from primus libGL to take precedence export LD_LIBRARY_PATH=${PRIMUS_libGL}${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} # And go! exec "$@" primus-0~20150328/primus.bash-completion0000644000175000017500000000006112555052336020003 0ustar vincentvincenthave primusrun && complete -F _command primusrun primus-0~20150328/libglfork.cpp0000644000175000017500000010270612555052336016146 0ustar vincentvincent#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #pragma GCC visibility push(default) #define GLX_GLXEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES #include #pragma GCC visibility pop #define primus_print(c, ...) do { if (c) fprintf(stderr, "primus: " __VA_ARGS__); } while (0) #define die_if(cond, ...) do {if (cond) {primus_print(true, "fatal: " __VA_ARGS__); exit(1);} } while (0) #define primus_warn(...) primus_print(primus.loglevel >= 1, "warning: " __VA_ARGS__) #define primus_perf(...) primus_print(primus.loglevel >= 2, "profiling: " __VA_ARGS__) // Try to load any of the colon-separated libraries static void *mdlopen(const char *paths, int flag) { char *p = strdupa(paths); char errors[1024], *errors_ptr = errors, *errors_end = errors + 1024; for (char *c = p; c; p = c + 1) { if ((c = strchr(p, ':'))) *c = 0; die_if(p[0] != '/', "need absolute library path: %s\n", p); void *handle = dlopen(p, flag); if (handle) return handle; errors_ptr += snprintf(errors_ptr, errors_end - errors_ptr, "%s\n", dlerror()); } die_if(true, "failed to load any of the libraries: %s\n%s", paths, errors); } static void *real_dlsym(void *handle, const char *symbol) { typedef void* (*dlsym_fn)(void *, const char*); static dlsym_fn pdlsym = (dlsym_fn) dlsym(dlopen("libdl.so.2", RTLD_LAZY), "dlsym"); return pdlsym(handle, symbol); } // Pointers to implemented/forwarded GLX and OpenGL functions struct CapturedFns { void *handle; // Declare functions as fields of the struct #define DEF_GLX_PROTO(ret, name, args, ...) ret (*name) args; #include "glx-reimpl.def" #include "glx-dpyredir.def" #include "glxext-reimpl.def" #include "gl-passthru.def" #include "gl-needed.def" #undef DEF_GLX_PROTO CapturedFns(const char *lib) { handle = mdlopen(lib, RTLD_LAZY); #define DEF_GLX_PROTO(ret, name, args, ...) name = (ret (*) args)real_dlsym(handle, #name); #include "glx-reimpl.def" #include "glx-dpyredir.def" #undef DEF_GLX_PROTO #define DEF_GLX_PROTO(ret, name, args, ...) name = (ret (*) args)this->glXGetProcAddress((GLubyte*)#name); #include "glxext-reimpl.def" #include "gl-passthru.def" #include "gl-needed.def" #undef DEF_GLX_PROTO } ~CapturedFns() { dlclose(handle); } }; // Drawable tracking info struct DrawableInfo { // Only XWindow is not explicitely created via GLX enum {XWindow, Window, Pixmap, Pbuffer} kind; GLXFBConfig fbconfig; GLXPbuffer pbuffer; Drawable window; int width, height; enum ReinitTodo {NONE, RESIZE, SHUTDOWN} reinit; GLvoid *pixeldata; GLsync sync; GLXContext actx; struct { pthread_t worker; sem_t acqsem, relsem; ReinitTodo reinit; void spawn_worker(GLXDrawable draw, void* (*work)(void*)) { reinit = RESIZE; sem_init(&acqsem, 0, 0); sem_init(&relsem, 0, 0); pthread_create(&worker, NULL, work, (void*)draw); } void reap_worker() { //pthread_cancel(worker); pthread_join(worker, NULL); sem_destroy(&relsem); sem_destroy(&acqsem); worker = 0; } } r, d; void reap_workers() { if (r.worker) { r.reinit = SHUTDOWN; sem_post(&r.acqsem); sem_wait(&r.relsem); r.reap_worker(); d.reap_worker(); } } void update_geometry(int width, int height) { if (this->width == width && this->height == height) return; this->width = width; this->height = height; __sync_synchronize(); reinit = RESIZE; } ~DrawableInfo(); }; struct DrawablesInfo: public std::map { bool known(GLXDrawable draw) { return this->find(draw) != this->end(); } }; struct ContextInfo { GLXFBConfig fbconfig; int sharegroup; }; struct ContextsInfo: public std::map { void record(GLXContext ctx, GLXFBConfig config, GLXContext share) { static int nsharegroups; int sharegroup = share ? (*this)[share].sharegroup : nsharegroups++; (*this)[ctx] = (ContextInfo){config, sharegroup}; } }; // Shorthand for obtaining compile-time configurable value that can be // overridden by environment #define getconf(V) (getenv(#V) ? getenv(#V) : V) // Runs before all other initialization takes place struct EarlyInitializer { EarlyInitializer(const char **adpy_strp, const char **libgla_strp) { #ifdef BUMBLEBEE_SOCKET // Signal the Bumblebee daemon to bring up secondary X int sock = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); struct sockaddr_un addr; addr.sun_family = AF_UNIX; strncpy(addr.sun_path, getconf(BUMBLEBEE_SOCKET), sizeof(addr.sun_path)); die_if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0, "failed to connect to Bumblebee daemon: %s\n", strerror(errno)); static char c[256]; if (!getenv("PRIMUS_DISPLAY")) { send(sock, "Q VirtualDisplay", strlen("Q VirtualDisplay") + 1, 0); recv(sock, &c, 255, 0); die_if(memcmp(c, "Value: ", strlen("Value: ")), "unexpected query response\n"); *strchrnul(c, '\n') = 0; *adpy_strp = strdup(c + 7); } if (!getenv("PRIMUS_libGLa")) { send(sock, "Q LibraryPath", strlen("Q LibraryPath") + 1, 0); recv(sock, &c, 255, 0); die_if(memcmp(c, "Value: ", strlen("Value: ")), "unexpected query response\n"); *strchrnul(c, '\n') = 0; int npaths = 0; for (char *p = c + 7; *p; npaths++, p = strchrnul(p + 1, ':')); if (npaths) { char *bblibs = new char[strlen(c + 7) + npaths * strlen("/libGL.so.1") + 1], *b = bblibs, *n, *p; for (p = c + 7; *p; p = n) { n = strchrnul(p + 1, ':'); b += sprintf(b, "%.*s/libGL.so.1", (int)(n - p), p); } *libgla_strp = bblibs; } } send(sock, "C", 1, 0); recv(sock, &c, 255, 0); die_if(c[0] == 'N', "Bumblebee daemon reported: %s\n", c + 5); die_if(c[0] != 'Y', "failure contacting Bumblebee daemon\n"); // the socket will be closed when the application quits, then bumblebee will shut down the secondary X #else #warning Building without Bumblebee daemon support #endif } }; // Process-wide data static struct PrimusInfo { const char *adpy_str, *libgla_str; EarlyInitializer ei; // Readback-display synchronization method // 0: no sync, 1: D lags behind one frame, 2: fully synced int sync; // 0: only errors, 1: warnings, 2: profiling int loglevel; // 0: autodetect, 1: texture, 2: PBO glDrawPixels int dispmethod; // sleep ratio in readback thread, percent int autosleep; // The "accelerating" X display Display *adpy; // The "displaying" X display. The same as the application is using, but // primus opens its own connection. Display *ddpy; // An artifact: primus needs to make symbols from libglapi.so globally // visible before loading Mesa const void *needed_global; CapturedFns afns; CapturedFns dfns; // FIXME: there are race conditions in accesses to these DrawablesInfo drawables; ContextsInfo contexts; PrimusInfo(): adpy_str(getconf(PRIMUS_DISPLAY)), libgla_str(getconf(PRIMUS_libGLa)), ei(&adpy_str, &libgla_str), sync(atoi(getconf(PRIMUS_SYNC))), loglevel(atoi(getconf(PRIMUS_VERBOSE))), dispmethod(atoi(getconf(PRIMUS_UPLOAD))), autosleep(atoi(getconf(PRIMUS_SLEEP))), adpy(XOpenDisplay(adpy_str)), ddpy(XOpenDisplay(NULL)), needed_global(dlopen(getconf(PRIMUS_LOAD_GLOBAL), RTLD_LAZY | RTLD_GLOBAL)), afns(libgla_str), dfns(getconf(PRIMUS_libGLd)) { die_if(!adpy, "failed to open secondary X display\n"); die_if(!ddpy, "failed to open main X display\n"); die_if(!needed_global, "failed to load PRIMUS_LOAD_GLOBAL\n"); } } primus; // Thread-specific data static __thread struct { Display *dpy; GLXDrawable drawable, read_drawable; void make_current(Display *dpy, GLXDrawable draw, GLXDrawable read) { this->dpy = dpy; this->drawable = draw; this->read_drawable = read; } } tsdata; // Profiler struct Profiler { const char *name; const char * const *state_names; double state_time[6], prev_timestamp, print_timestamp; int state, nframes, width, height; static double get_timestamp() { struct timespec tp; clock_gettime(CLOCK_MONOTONIC, &tp); return tp.tv_sec + 1e-9 * tp.tv_nsec; } Profiler(const char *name, const char * const *state_names): name(name), state_names(state_names), state(0), nframes(0), width(0), height(0) { memset(state_time, 0, sizeof(state_time)); prev_timestamp = print_timestamp = get_timestamp(); } void tick(bool state_reset = false) { if (primus.loglevel < 2) return; double timestamp = get_timestamp(); assert(state_reset || state_names[state]); if (state_reset) state = 0; assert(state * sizeof(state_time[0]) < sizeof(state_time)); state_time[state++] += timestamp - prev_timestamp; prev_timestamp = timestamp; if (state_names[state]) return; nframes++; // check if it's time to print again double period = timestamp - print_timestamp; // time since we printed if (period < 5) return; // construct output char buf[128], *cbuf = buf, *end = buf+128; for (int i = 0; i < state; i++) cbuf += snprintf(cbuf, end - cbuf, ", %.1f%% %s", 100 * state_time[i] / period, state_names[i]); primus_perf("%s: %dx%d, %.1f fps%s\n", name, width, height, nframes / period, buf); // start counting again print_timestamp = timestamp; nframes = 0; memset(state_time, 0, sizeof(state_time)); } }; // Find out the dimensions of the window static void note_geometry(Display *dpy, Drawable draw, int *width, int *height) { Window root; int x, y; unsigned bw, d; XGetGeometry(dpy, draw, &root, &x, &y, (unsigned *)width, (unsigned *)height, &bw, &d); } static GLXFBConfig* get_dconfigs(Display *dpy) { static const int attrs[] = {GLX_DOUBLEBUFFER, GL_TRUE, None}; int ncfg; GLXFBConfig *dconfigs = primus.dfns.glXChooseFBConfig(dpy, 0, attrs, &ncfg); die_if(!dconfigs, "broken GLX on main X display\n"); return dconfigs; } static bool test_drawpixels_fast(Display *dpy, GLXContext ctx, GLXFBConfig dconfig) { int width = 1920, height = 1080; int pbattrs[] = {GLX_PBUFFER_WIDTH, width, GLX_PBUFFER_HEIGHT, height, GLX_PRESERVED_CONTENTS, True, None}; GLXPbuffer pbuffer = primus.dfns.glXCreatePbuffer(dpy, dconfig, pbattrs); primus.dfns.glXMakeCurrent(dpy, pbuffer, ctx); GLuint pbo; primus.dfns.glGenBuffers(1, &pbo); primus.dfns.glBindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, pbo); primus.dfns.glBufferData(GL_PIXEL_UNPACK_BUFFER_EXT, width*height*4, NULL, GL_STREAM_DRAW); void *pixeldata = malloc(width*height*4); double end = 0.2 + Profiler::get_timestamp(); int iters = 0; do { primus.dfns.glBufferSubData(GL_PIXEL_UNPACK_BUFFER_EXT, 0, width*height*4, pixeldata); primus.dfns.glDrawPixels(width, height, GL_BGRA, GL_UNSIGNED_BYTE, NULL); primus.dfns.glXSwapBuffers(dpy, pbuffer); iters++; } while (end > Profiler::get_timestamp()); free(pixeldata); primus.dfns.glDeleteBuffers(1, &pbo); primus.dfns.glXDestroyPbuffer(dpy, pbuffer); bool is_fast = iters >= 12; primus_perf("upload autodetection: will use %s path (%d iters)\n", is_fast ? "PBO" : "texture", iters); return is_fast; } static void* display_work(void *vd) { GLXDrawable drawable = (GLXDrawable)vd; DrawableInfo &di = primus.drawables[drawable]; int width, height; static const float quad_vertex_coords[] = {-1, -1, -1, 1, 1, 1, 1, -1}; static const float quad_texture_coords[] = { 0, 0, 0, 1, 1, 1, 1, 0}; GLuint textures[2] = {0}, pbos[2] = {0}; int ctex = 0; static const char *state_names[] = {"wait", "upload", "draw+swap", NULL}; Profiler profiler("display", state_names); Display *ddpy = XOpenDisplay(NULL); if (!ddpy) // Chromium sandbox prevents opening new connections { ddpy = primus.ddpy; primus_warn("reusing initial X connection for display thread\n"); } assert(di.kind == di.XWindow || di.kind == di.Window); XSelectInput(ddpy, di.window, StructureNotifyMask); note_geometry(ddpy, di.window, &width, &height); di.update_geometry(width, height); GLXFBConfig *dconfigs = get_dconfigs(ddpy); GLXContext context = primus.dfns.glXCreateNewContext(ddpy, *dconfigs, GLX_RGBA_TYPE, NULL, True); die_if(!primus.dfns.glXIsDirect(ddpy, context), "failed to acquire direct rendering context for display thread\n"); if (!primus.dispmethod) primus.dispmethod = test_drawpixels_fast(ddpy, context, *dconfigs) ? 2 : 1; XFree(dconfigs); primus.dfns.glXMakeCurrent(ddpy, di.window, context); bool use_textures = (primus.dispmethod == 1); if (use_textures) { primus.dfns.glVertexPointer (2, GL_FLOAT, 0, quad_vertex_coords); primus.dfns.glTexCoordPointer(2, GL_FLOAT, 0, quad_texture_coords); primus.dfns.glEnableClientState(GL_VERTEX_ARRAY); primus.dfns.glEnableClientState(GL_TEXTURE_COORD_ARRAY); primus.dfns.glGenTextures(2, textures); primus.dfns.glEnable(GL_TEXTURE_2D); } else primus.dfns.glGenBuffers(2, pbos); for (;;) { sem_wait(&di.d.acqsem); profiler.tick(true); if (di.d.reinit) { if (di.d.reinit == di.SHUTDOWN) { if (use_textures) primus.dfns.glDeleteTextures(2, textures); else primus.dfns.glDeleteBuffers(2, pbos); primus.dfns.glXMakeCurrent(ddpy, 0, NULL); primus.dfns.glXDestroyContext(ddpy, context); if (ddpy != primus.ddpy) XCloseDisplay(ddpy); sem_post(&di.d.relsem); return NULL; } di.d.reinit = di.NONE; profiler.width = width = di.width; profiler.height = height = di.height; primus.dfns.glViewport(0, 0, width, height); if (use_textures) { primus.dfns.glBindTexture(GL_TEXTURE_2D, textures[ctex ^ 1]); primus.dfns.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); primus.dfns.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); primus.dfns.glBindTexture(GL_TEXTURE_2D, textures[ctex]); primus.dfns.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); primus.dfns.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); } else { primus.dfns.glBindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, pbos[ctex ^ 1]); primus.dfns.glBufferData(GL_PIXEL_UNPACK_BUFFER_EXT, width*height*4, NULL, GL_STREAM_DRAW); primus.dfns.glBindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, pbos[ctex]); primus.dfns.glBufferData(GL_PIXEL_UNPACK_BUFFER_EXT, width*height*4, NULL, GL_STREAM_DRAW); } sem_post(&di.d.relsem); continue; } if (use_textures) primus.dfns.glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, di.pixeldata); else primus.dfns.glBufferSubData(GL_PIXEL_UNPACK_BUFFER_EXT, 0, width*height*4, di.pixeldata); if (!primus.sync) sem_post(&di.d.relsem); // Unlock as soon as possible profiler.tick(); if (use_textures) { primus.dfns.glDrawArrays(GL_QUADS, 0, 4); primus.dfns.glBindTexture(GL_TEXTURE_2D, textures[ctex ^= 1]); } else { primus.dfns.glDrawPixels(width, height, GL_BGRA, GL_UNSIGNED_BYTE, NULL); primus.dfns.glBindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, pbos[ctex ^= 1]); } primus.dfns.glXSwapBuffers(ddpy, di.window); for (int pending = XPending(ddpy); pending > 0; pending--) { XEvent event; XNextEvent(ddpy, &event); if (event.type == ConfigureNotify) di.update_geometry(event.xconfigure.width, event.xconfigure.height); } if (primus.sync) sem_post(&di.d.relsem); // Unlock only after drawing profiler.tick(); } return NULL; } static void* readback_work(void *vd) { GLXDrawable drawable = (GLXDrawable)vd; DrawableInfo &di = primus.drawables[drawable]; int width, height; GLuint pbos[2] = {0}; int cbuf = 0; unsigned sleep_usec = 0; static const char *state_names[] = {"app", "sleep", "map", "wait", NULL}; Profiler profiler("readback", state_names); struct timespec tp; if (!primus.sync) sem_post(&di.d.relsem); // No PBO is mapped initially GLXContext context = primus.afns.glXCreateNewContext(primus.adpy, di.fbconfig, GLX_RGBA_TYPE, di.actx, True); die_if(!primus.afns.glXIsDirect(primus.adpy, context), "failed to acquire direct rendering context for readback thread\n"); primus.afns.glXMakeCurrent(primus.adpy, di.pbuffer, context); primus.afns.glGenBuffers(2, &pbos[0]); primus.afns.glReadBuffer(GL_FRONT); for (;;) { sem_wait(&di.r.acqsem); profiler.tick(true); if (di.r.reinit) { clock_gettime(CLOCK_REALTIME, &tp); tp.tv_sec += 1; // Wait for D worker, if active if (!primus.sync && sem_timedwait(&di.d.relsem, &tp)) { pthread_cancel(di.d.worker); sem_post(&di.d.relsem); // Pretend that D worker completed reinit primus_warn("timeout waiting for display worker\n"); die_if(di.r.reinit != di.SHUTDOWN, "killed worker on resize\n"); } di.d.reinit = di.r.reinit; sem_post(&di.d.acqsem); // Signal D worker to reinit sem_wait(&di.d.relsem); // Wait until reinit was completed if (!primus.sync) sem_post(&di.d.relsem); // Unlock as no PBO is currently mapped if (di.r.reinit == di.SHUTDOWN) { primus.afns.glBindBuffer(GL_PIXEL_PACK_BUFFER_EXT, pbos[cbuf ^ 1]); primus.afns.glUnmapBuffer(GL_PIXEL_PACK_BUFFER_EXT); primus.afns.glDeleteBuffers(2, &pbos[0]); primus.afns.glXMakeCurrent(primus.adpy, 0, NULL); primus.afns.glXDestroyContext(primus.adpy, context); sem_post(&di.r.relsem); return NULL; } di.r.reinit = di.NONE; profiler.width = width = di.width; profiler.height = height = di.height; primus.afns.glXMakeCurrent(primus.adpy, di.pbuffer, context); primus.afns.glBindBuffer(GL_PIXEL_PACK_BUFFER_EXT, pbos[cbuf ^ 1]); primus.afns.glBufferData(GL_PIXEL_PACK_BUFFER_EXT, width*height*4, NULL, GL_STREAM_READ); primus.afns.glBindBuffer(GL_PIXEL_PACK_BUFFER_EXT, pbos[cbuf]); primus.afns.glBufferData(GL_PIXEL_PACK_BUFFER_EXT, width*height*4, NULL, GL_STREAM_READ); } primus.afns.glWaitSync(di.sync, 0, GL_TIMEOUT_IGNORED); primus.afns.glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, NULL); if (!primus.sync) sem_post(&di.r.relsem); // Unblock main thread as soon as possible usleep(sleep_usec); profiler.tick(); if (primus.sync == 1) // Get the previous framebuffer primus.afns.glBindBuffer(GL_PIXEL_PACK_BUFFER_EXT, pbos[cbuf ^ 1]); double map_time = Profiler::get_timestamp(); GLvoid *pixeldata = primus.afns.glMapBuffer(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_ONLY); map_time = Profiler::get_timestamp() - map_time; sleep_usec = (map_time * 1e6 + sleep_usec) * primus.autosleep / 100; profiler.tick(); clock_gettime(CLOCK_REALTIME, &tp); tp.tv_sec += 1; if (!primus.sync && sem_timedwait(&di.d.relsem, &tp)) primus_warn("dropping a frame to avoid deadlock\n"); else { di.pixeldata = pixeldata; sem_post(&di.d.acqsem); if (primus.sync) { sem_wait(&di.d.relsem); sem_post(&di.r.relsem); // Unblock main thread only after D::work has completed } cbuf ^= 1; primus.afns.glBindBuffer(GL_PIXEL_PACK_BUFFER_EXT, pbos[cbuf]); } primus.afns.glUnmapBuffer(GL_PIXEL_PACK_BUFFER_EXT); profiler.tick(); } return NULL; } // Find appropriate FBConfigs on adpy for a given Visual on ddpy static GLXFBConfig* match_fbconfig(Display *dpy, XVisualInfo *vis) { int ncfg, attrs[] = { GLX_DOUBLEBUFFER, 0, GLX_STEREO, 0, GLX_AUX_BUFFERS, 0, GLX_RED_SIZE, 0, GLX_GREEN_SIZE, 0, GLX_BLUE_SIZE, 0, GLX_ALPHA_SIZE, 0, GLX_DEPTH_SIZE, 0, GLX_STENCIL_SIZE, 0, GLX_ACCUM_RED_SIZE, 0, GLX_ACCUM_GREEN_SIZE, 0, GLX_ACCUM_BLUE_SIZE, 0, GLX_ACCUM_ALPHA_SIZE, 0, GLX_SAMPLE_BUFFERS, 0, GLX_SAMPLES, 0, None }; for (int i = 0; attrs[i] != None; i += 2) primus.dfns.glXGetConfig(dpy, vis, attrs[i], &attrs[i+1]); return primus.afns.glXChooseFBConfig(primus.adpy, 0, attrs, &ncfg); } GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct) { GLXFBConfig *acfgs = match_fbconfig(dpy, vis); GLXContext actx = primus.afns.glXCreateNewContext(primus.adpy, *acfgs, GLX_RGBA_TYPE, shareList, direct); primus.contexts.record(actx, *acfgs, shareList); return actx; } GLXContext glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct) { GLXContext actx = primus.afns.glXCreateNewContext(primus.adpy, config, renderType, shareList, direct); primus.contexts.record(actx, config, shareList); return actx; } GLXContext glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config, GLXContext shareList, Bool direct, const int *attrib_list) { GLXContext actx = primus.afns.glXCreateContextAttribsARB(primus.adpy, config, shareList, direct, attrib_list); primus.contexts.record(actx, config, shareList); return actx; } void glXDestroyContext(Display *dpy, GLXContext ctx) { primus.contexts.erase(ctx); // kludge: reap background tasks when deleting the last context // otherwise something will deadlock during unloading the library if (primus.contexts.empty()) for (DrawablesInfo::iterator i = primus.drawables.begin(); i != primus.drawables.end(); i++) i->second.reap_workers(); primus.afns.glXDestroyContext(primus.adpy, ctx); } static GLXPbuffer create_pbuffer(DrawableInfo &di) { int pbattrs[] = {GLX_PBUFFER_WIDTH, di.width, GLX_PBUFFER_HEIGHT, di.height, GLX_PRESERVED_CONTENTS, True, None}; return primus.afns.glXCreatePbuffer(primus.adpy, di.fbconfig, pbattrs); } // Create or recall backing Pbuffer for the drawable static GLXPbuffer lookup_pbuffer(Display *dpy, GLXDrawable draw, GLXContext ctx) { if (!draw) return 0; bool known = primus.drawables.known(draw); DrawableInfo &di = primus.drawables[draw]; if (!known) { // Drawable is a plain X Window. Get the FBConfig from the context if (ctx) di.fbconfig = primus.contexts[ctx].fbconfig; else { XWindowAttributes attrs; die_if(!XGetWindowAttributes(dpy, draw, &attrs), "failed to query attributes"); int nvis; XVisualInfo tmpl = {0}, *vis; tmpl.visualid = XVisualIDFromVisual(attrs.visual); die_if(!(vis = XGetVisualInfo(dpy, VisualIDMask, &tmpl, &nvis)), "no visuals"); di.fbconfig = *match_fbconfig(dpy, vis); XFree(vis); } di.kind = di.XWindow; di.window = draw; note_geometry(dpy, draw, &di.width, &di.height); } else if (ctx && di.fbconfig != primus.contexts[ctx].fbconfig) { if (di.pbuffer) { primus_warn("recreating incompatible pbuffer\n"); di.reap_workers(); primus.afns.glXDestroyPbuffer(primus.adpy, di.pbuffer); di.pbuffer = 0; } di.fbconfig = primus.contexts[ctx].fbconfig; } if (!di.pbuffer) di.pbuffer = create_pbuffer(di); return di.pbuffer; } Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx) { GLXPbuffer pbuffer = lookup_pbuffer(dpy, drawable, ctx); tsdata.make_current(dpy, drawable, drawable); return primus.afns.glXMakeCurrent(primus.adpy, pbuffer, ctx); } Bool glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) { if (draw == read) return glXMakeCurrent(dpy, draw, ctx); GLXPbuffer pbuffer = lookup_pbuffer(dpy, draw, ctx); GLXPbuffer pb_read = lookup_pbuffer(dpy, read, ctx); tsdata.make_current(dpy, draw, read); return primus.afns.glXMakeContextCurrent(primus.adpy, pbuffer, pb_read, ctx); } void glXSwapBuffers(Display *dpy, GLXDrawable drawable) { XFlush(dpy); assert(primus.drawables.known(drawable)); DrawableInfo &di = primus.drawables[drawable]; primus.afns.glXSwapBuffers(primus.adpy, di.pbuffer); if (di.kind == di.Pbuffer || di.kind == di.Pixmap) return; GLXContext ctx = glXGetCurrentContext(); if (!ctx) primus_warn("glXSwapBuffers: no current context\n"); else if (drawable != tsdata.drawable) primus_warn("glXSwapBuffers: drawable not current\n"); if (di.r.worker && ctx && (!di.actx || primus.contexts[di.actx].sharegroup != primus.contexts[ctx].sharegroup)) { primus_warn("glXSwapBuffers: respawning threads after context change\n"); di.reap_workers(); } if (!di.r.worker) { // Need to create a sharing context to use GL sync objects di.actx = ctx; di.d.spawn_worker(drawable, display_work); di.r.spawn_worker(drawable, readback_work); } // Readback thread needs a sync object to avoid reading an incomplete frame di.sync = primus.afns.glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); sem_post(&di.r.acqsem); // Signal the readback worker thread sem_wait(&di.r.relsem); // Wait until it has issued glReadBuffer primus.afns.glDeleteSync(di.sync); if (di.reinit == di.RESIZE) { __sync_synchronize(); primus.afns.glXDestroyPbuffer(primus.adpy, di.pbuffer); di.pbuffer = create_pbuffer(di); if (ctx) // FIXME: drawable can be current in other threads glXMakeContextCurrent(dpy, tsdata.drawable, tsdata.read_drawable, ctx); di.r.reinit = di.reinit; di.reinit = di.NONE; } } GLXWindow glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList) { GLXFBConfig *dconfigs = get_dconfigs(dpy); GLXWindow glxwin = primus.dfns.glXCreateWindow(dpy, *dconfigs, win, attribList); XFree(dconfigs); DrawableInfo &di = primus.drawables[glxwin]; di.kind = di.Window; di.fbconfig = config; di.window = win; note_geometry(dpy, win, &di.width, &di.height); return glxwin; } DrawableInfo::~DrawableInfo() { reap_workers(); if (pbuffer) primus.afns.glXDestroyPbuffer(primus.adpy, pbuffer); } void glXDestroyWindow(Display *dpy, GLXWindow window) { assert(primus.drawables.known(window)); primus.drawables.erase(window); primus.dfns.glXDestroyWindow(dpy, window); } GLXPbuffer glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList) { GLXFBConfig *dconfigs = get_dconfigs(dpy); GLXPbuffer pbuffer = primus.dfns.glXCreatePbuffer(dpy, *dconfigs, attribList); XFree(dconfigs); DrawableInfo &di = primus.drawables[pbuffer]; di.kind = di.Pbuffer; di.fbconfig = config; for (int i = 0; attribList[i] != None; i++) if (attribList[i] == GLX_PBUFFER_WIDTH) di.width = attribList[i+1]; else if (attribList[i] == GLX_PBUFFER_HEIGHT) di.height = attribList[i+1]; return pbuffer; } void glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf) { assert(primus.drawables.known(pbuf)); primus.drawables.erase(pbuf); primus.dfns.glXDestroyPbuffer(dpy, pbuf); } GLXPixmap glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList) { GLXFBConfig *dconfigs = get_dconfigs(dpy); GLXPixmap glxpix = primus.dfns.glXCreatePixmap(dpy, *dconfigs, pixmap, attribList); XFree(dconfigs); DrawableInfo &di = primus.drawables[glxpix]; di.kind = di.Pixmap; di.fbconfig = config; note_geometry(dpy, pixmap, &di.width, &di.height); return glxpix; } void glXDestroyPixmap(Display *dpy, GLXPixmap pixmap) { assert(primus.drawables.known(pixmap)); primus.drawables.erase(pixmap); primus.dfns.glXDestroyPixmap(dpy, pixmap); } GLXPixmap glXCreateGLXPixmap(Display *dpy, XVisualInfo *visual, Pixmap pixmap) { GLXPixmap glxpix = primus.dfns.glXCreateGLXPixmap(dpy, visual, pixmap); DrawableInfo &di = primus.drawables[glxpix]; di.kind = di.Pixmap; note_geometry(dpy, pixmap, &di.width, &di.height); GLXFBConfig *acfgs = match_fbconfig(dpy, visual); di.fbconfig = *acfgs; return glxpix; } void glXDestroyGLXPixmap(Display *dpy, GLXPixmap pixmap) { glXDestroyPixmap(dpy, pixmap); } static XVisualInfo *match_visual(Display *dpy, int attrs[]) { XVisualInfo *vis = glXChooseVisual(dpy, 0, attrs); for (int i = 2; attrs[i] != None && vis; i += 2) { int tmp = attrs[i+1]; primus.dfns.glXGetConfig(dpy, vis, attrs[i], &attrs[i+1]); if (tmp != attrs[i+1]) vis = NULL; } return vis; } XVisualInfo *glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config) { if (!primus.afns.glXGetVisualFromFBConfig(primus.adpy, config)) return NULL; int i, attrs[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 0, GLX_GREEN_SIZE, 0, GLX_BLUE_SIZE, 0, GLX_ALPHA_SIZE, 0, GLX_DEPTH_SIZE, 0, GLX_STENCIL_SIZE, 0, GLX_SAMPLE_BUFFERS, 0, GLX_SAMPLES, 0, None }; for (i = 2; attrs[i] != None; i += 2) primus.afns.glXGetFBConfigAttrib(primus.adpy, config, attrs[i], &attrs[i+1]); XVisualInfo *vis = NULL; for (i -= 2; i >= 0 && !vis; i -= 2) { vis = match_visual(dpy, attrs); attrs[i] = None; } return vis; } int glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value) { int r = primus.afns.glXGetFBConfigAttrib(primus.adpy, config, attribute, value); if (attribute == GLX_VISUAL_ID && *value) return primus.dfns.glXGetConfig(dpy, glXGetVisualFromFBConfig(dpy, config), attribute, value); return r; } void glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) { primus.afns.glXQueryDrawable(primus.adpy, lookup_pbuffer(dpy, draw, NULL), attribute, value); } void glXUseXFont(Font font, int first, int count, int list) { unsigned long prop; Display *dpy = glXGetCurrentDisplay(); XFontStruct *fs = XQueryFont(dpy, font); XGetFontProperty(fs, XA_FONT, &prop); char *xlfd = XGetAtomName(dpy, prop); Font afont = XLoadFont(primus.adpy, xlfd); primus.afns.glXUseXFont(afont, first, count, list); XUnloadFont(primus.adpy, afont); XFree(xlfd); XFreeFontInfo(NULL, fs, 1); } GLXContext glXGetCurrentContext(void) { return primus.afns.glXGetCurrentContext(); } GLXDrawable glXGetCurrentDrawable(void) { return tsdata.drawable; } void glXWaitGL(void) { } void glXWaitX(void) { } Display *glXGetCurrentDisplay(void) { return tsdata.dpy; } GLXDrawable glXGetCurrentReadDrawable(void) { return tsdata.read_drawable; } // Application sees ddpy-side Visuals, but adpy-side FBConfigs and Contexts XVisualInfo* glXChooseVisual(Display *dpy, int screen, int *attribList) { return primus.dfns.glXChooseVisual(dpy, screen, attribList); } int glXGetConfig(Display *dpy, XVisualInfo *visual, int attrib, int *value) { return primus.dfns.glXGetConfig(dpy, visual, attrib, value); } // GLX forwarders that reroute to adpy #define DEF_GLX_PROTO(ret, name, par, ...) \ ret name par \ { return primus.afns.name(primus.adpy, __VA_ARGS__); } #include "glx-dpyredir.def" #undef DEF_GLX_PROTO // OpenGL forwarders #define DEF_GLX_PROTO(ret, name, par, ...) \ void ifunc_##name(void) asm(#name) __attribute__((visibility("default"),ifunc("i" #name))); \ extern "C" { \ static ret l##name par \ { return primus.afns.name(__VA_ARGS__); } \ static void *i##name(void) \ { return primus.afns.handle ? real_dlsym(primus.afns.handle, #name) : (void*)l##name; } } #include "gl-passthru.def" #undef DEF_GLX_PROTO // GLX extensions int glXSwapIntervalSGI(int interval) { return 1; // Indicate failure to set swapinterval } __GLXextFuncPtr glXGetProcAddress(const GLubyte *procName) { static const char * const redefined_names[] = { #define DEF_GLX_PROTO(ret, name, args, ...) #name, #include "glx-reimpl.def" #include "glxext-reimpl.def" #include "glx-dpyredir.def" #undef DEF_GLX_PROTO }; static const __GLXextFuncPtr redefined_fns[] = { #define DEF_GLX_PROTO(ret, name, args, ...) (__GLXextFuncPtr)name, #include "glx-reimpl.def" #include "glxext-reimpl.def" #include "glx-dpyredir.def" #undef DEF_GLX_PROTO }; enum {n_redefined = sizeof(redefined_fns) / sizeof(redefined_fns[0])}; // Non-GLX functions are forwarded to the accelerating libGL if (memcmp(procName, "glX", 3)) return primus.afns.glXGetProcAddress(procName); // All GLX functions are either implemented in primus or not available for (int i = 0; i < n_redefined; i++) if (!strcmp((const char *)procName, redefined_names[i])) return redefined_fns[i]; return NULL; } __GLXextFuncPtr glXGetProcAddressARB(const GLubyte *procName) { return glXGetProcAddress(procName); } static const char glxext_clientside[] = "GLX_ARB_get_proc_address "; static const char glxext_adpy[] = "GLX_ARB_create_context GLX_ARB_create_context_profile "; static const char glxext_ddpy[] = ""; const char *glXGetClientString(Display *dpy, int name) { static std::string exts(std::string(glxext_clientside) + glxext_adpy + glxext_ddpy); switch (name) { case GLX_VENDOR: return "primus"; case GLX_VERSION: return "1.4"; case GLX_EXTENSIONS: return exts.c_str(); default: return NULL; } } static std::string intersect_exts(const char *set1, const char *set2) { std::string r; for (const char *p; *set1; set1 = p + 1) { p = strchr(set1, ' '); if (memmem(set2, strlen(set2), set1, p - set1)) r.append(set1, p - set1 + 1); } return r; } const char *glXQueryExtensionsString(Display *dpy, int screen) { static std::string exts (std::string(glxext_clientside) + intersect_exts(glxext_adpy, primus.afns.glXQueryExtensionsString(primus.adpy, 0)) + intersect_exts(glxext_ddpy, primus.dfns.glXQueryExtensionsString(dpy, 0))); return exts.c_str(); } // OpenGL ABI specifies that anything above OpenGL 1.2 + ARB_multitexture must // be obtained via glXGetProcAddress, but some applications link against // extension functions, and Mesa and vendor libraries let them #ifndef PRIMUS_STRICT #warning Enabled workarounds for applications demanding more than promised by the OpenGL ABI // OpenGL extension forwarders #define P(name) \ void ifunc_##name(void) asm(#name) __attribute__((visibility("default"),ifunc("i" #name))); \ extern "C" { static void *i##name(void) \ { return primus.afns.handle ? real_dlsym(primus.afns.handle, #name) : NULL; } } #include "glext-passthru.def" #undef P #endif primus-0~20150328/glxext-reimpl.def0000644000175000017500000000041512555052336016742 0ustar vincentvincent// GLX extension functions implemented in primus DEF_GLX_PROTO(int, glXSwapIntervalSGI, (int interval)) DEF_GLX_PROTO(GLXContext, glXCreateContextAttribsARB,(Display *dpy, GLXFBConfig config, GLXContext shareList, Bool direct, const int *attrib_list)) primus-0~20150328/glx-reimpl.def0000644000175000017500000000572712555052336016234 0ustar vincentvincent// GLX Functions implemented by primus DEF_GLX_PROTO(GLXContext, glXCreateContext, (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct)) DEF_GLX_PROTO(GLXContext, glXCreateNewContext, (Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct)) DEF_GLX_PROTO(void, glXDestroyContext, (Display *dpy, GLXContext ctx)) DEF_GLX_PROTO(Bool, glXMakeCurrent, (Display *dpy, GLXDrawable drawable, GLXContext ctx)) DEF_GLX_PROTO(Bool, glXMakeContextCurrent,(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)) DEF_GLX_PROTO(void, glXSwapBuffers, (Display *dpy, GLXDrawable drawable)) DEF_GLX_PROTO(__GLXextFuncPtr, glXGetProcAddressARB, (const GLubyte *)) DEF_GLX_PROTO(__GLXextFuncPtr, glXGetProcAddress, (const GLubyte *)) DEF_GLX_PROTO(const char*, glXGetClientString, (Display *dpy, int name),name) DEF_GLX_PROTO(const char*, glXQueryExtensionsString, (Display *dpy, int screen),screen) DEF_GLX_PROTO(GLXWindow, glXCreateWindow, (Display *dpy, GLXFBConfig config, Window win, const int *attribList),config,win,attribList) DEF_GLX_PROTO(void, glXDestroyWindow, (Display *dpy, GLXWindow window),window) DEF_GLX_PROTO(GLXPbuffer, glXCreatePbuffer, (Display *dpy, GLXFBConfig config, const int *attribList),config,attribList) DEF_GLX_PROTO(void, glXDestroyPbuffer, (Display *dpy, GLXPbuffer pbuf),pbuf) DEF_GLX_PROTO(GLXPixmap, glXCreatePixmap, (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList),config,pixmap,attribList) DEF_GLX_PROTO(void, glXDestroyPixmap, (Display *dpy, GLXPixmap pixmap),pixmap) DEF_GLX_PROTO(GLXPixmap, glXCreateGLXPixmap, (Display *dpy, XVisualInfo *visual, Pixmap pixmap),visual,pixmap) DEF_GLX_PROTO(void, glXDestroyGLXPixmap, (Display *dpy, GLXPixmap pixmap),pixmap) DEF_GLX_PROTO(XVisualInfo*, glXGetVisualFromFBConfig, (Display *dpy, GLXFBConfig config),config) DEF_GLX_PROTO(int, glXGetFBConfigAttrib, (Display *dpy, GLXFBConfig config, int attribute, int *value),config,attribute,value) DEF_GLX_PROTO(void, glXQueryDrawable, (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value),draw,attribute,value) DEF_GLX_PROTO(XVisualInfo*, glXChooseVisual, (Display *dpy, int screen, int *attribList),screen,attribList) DEF_GLX_PROTO(int, glXGetConfig, (Display *dpy, XVisualInfo *visual, int attrib, int *value),visual,attrib,value) DEF_GLX_PROTO(void, glXUseXFont, (Font font, int first, int count, int list)) DEF_GLX_PROTO(GLXContext, glXGetCurrentContext, (void)) DEF_GLX_PROTO(GLXDrawable, glXGetCurrentDrawable, (void)) DEF_GLX_PROTO(void, glXWaitGL, (void)) DEF_GLX_PROTO(void, glXWaitX, (void)) DEF_GLX_PROTO(Display*, glXGetCurrentDisplay, (void)) DEF_GLX_PROTO(GLXDrawable, glXGetCurrentReadDrawable,(void)) primus-0~20150328/glx-dpyredir.def0000644000175000017500000000231612555052336016555 0ustar vincentvincent// GLX functions which need to be simply forwarded DEF_GLX_PROTO(void, glXCopyContext, (Display *dpy, GLXContext src, GLXContext dst, unsigned long mask),src,dst,mask) DEF_GLX_PROTO(Bool, glXQueryExtension, (Display *dpy, int *errorb, int *event),errorb,event) DEF_GLX_PROTO(Bool, glXQueryVersion, (Display *dpy, int *maj, int *min),maj,min) DEF_GLX_PROTO(Bool, glXIsDirect, (Display *dpy, GLXContext ctx),ctx) DEF_GLX_PROTO(const char*, glXQueryServerString, (Display *dpy, int screen, int name),screen,name) DEF_GLX_PROTO(GLXFBConfig*, glXChooseFBConfig, (Display *dpy, int screen, const int *attribList, int *nitems),screen,attribList,nitems) DEF_GLX_PROTO(GLXFBConfig*, glXGetFBConfigs, (Display *dpy, int screen, int *nelements),screen,nelements) DEF_GLX_PROTO(int, glXQueryContext, (Display *dpy, GLXContext ctx, int attribute, int *value),ctx,attribute,value) DEF_GLX_PROTO(void, glXSelectEvent, (Display *dpy, GLXDrawable drawable, unsigned long mask),drawable,mask) DEF_GLX_PROTO(void, glXGetSelectedEvent, (Display *dpy, GLXDrawable drawable, unsigned long *mask),drawable,mask) primus-0~20150328/glext-passthru.def0000644000175000017500000004441412555052336017142 0ustar vincentvincentP(glActiveProgramEXT) P(glAlphaFragmentOp1ATI) P(glAlphaFragmentOp2ATI) P(glAlphaFragmentOp3ATI) P(glAreProgramsResidentNV) P(glAreTexturesResidentEXT) P(glArrayElementEXT) P(glAttachObjectARB) P(glAttachShader) P(glBeginConditionalRender) P(glBeginConditionalRenderNV) P(glBeginFragmentShaderATI) P(glBeginQuery) P(glBeginQueryARB) P(glBeginQueryIndexed) P(glBeginTransformFeedback) P(glBeginTransformFeedbackEXT) P(glBindAttribLocation) P(glBindAttribLocationARB) P(glBindBuffer) P(glBindBufferARB) P(glBindBufferBase) P(glBindBufferBaseEXT) P(glBindBufferOffsetEXT) P(glBindBufferRange) P(glBindBufferRangeEXT) P(glBindFragDataLocation) P(glBindFragDataLocationEXT) P(glBindFragDataLocationIndexed) P(glBindFragmentShaderATI) P(glBindFramebuffer) P(glBindFramebufferEXT) P(glBindProgramARB) P(glBindProgramNV) P(glBindRenderbuffer) P(glBindRenderbufferEXT) P(glBindSampler) P(glBindTextureEXT) P(glBindTransformFeedback) P(glBindVertexArray) P(glBindVertexArrayOES) P(glBlendColorEXT) P(glBlendEquationEXT) P(glBlendEquationIndexedAMD) P(glBlendEquationSeparate) P(glBlendEquationSeparateIndexedAMD) P(glBlendEquationSeparateiARB) P(glBlendEquationiARB) P(glBlendFuncIndexedAMD) P(glBlendFuncSeparate) P(glBlendFuncSeparateEXT) P(glBlendFuncSeparateIndexedAMD) P(glBlendFuncSeparateiARB) P(glBlendFunciARB) P(glBlitFramebuffer) P(glBufferData) P(glBufferDataARB) P(glBufferSubData) P(glBufferSubDataARB) P(glCheckFramebufferStatus) P(glCheckFramebufferStatusEXT) P(glClampColor) P(glClampColorARB) P(glClearBufferfi) P(glClearBufferfv) P(glClearBufferiv) P(glClearBufferuiv) P(glClearColorIiEXT) P(glClearColorIuiEXT) P(glClearDepthf) P(glClientWaitSync) P(glColorFragmentOp1ATI) P(glColorFragmentOp2ATI) P(glColorFragmentOp3ATI) P(glColorMaskIndexedEXT) P(glColorMaski) P(glColorP3ui) P(glColorP3uiv) P(glColorP4ui) P(glColorP4uiv) P(glColorPointerEXT) P(glColorTableEXT) P(glCompileShader) P(glCompileShaderARB) P(glCompressedTexImage1DARB) P(glCompressedTexImage2DARB) P(glCompressedTexImage3DARB) P(glCompressedTexSubImage1DARB) P(glCompressedTexSubImage2DARB) P(glCompressedTexSubImage3DARB) P(glCopyBufferSubData) P(glCopyTexImage1DEXT) P(glCopyTexImage2DEXT) P(glCopyTexSubImage1DEXT) P(glCopyTexSubImage2DEXT) P(glCopyTexSubImage3DEXT) P(glCreateProgram) P(glCreateProgramObjectARB) P(glCreateShader) P(glCreateShaderObjectARB) P(glCreateShaderProgramEXT) P(glDebugMessageCallbackARB) P(glDebugMessageControlARB) P(glDebugMessageInsertARB) P(glDeleteBuffers) P(glDeleteBuffersARB) P(glDeleteFragmentShaderATI) P(glDeleteFramebuffers) P(glDeleteFramebuffersEXT) P(glDeleteObjectARB) P(glDeleteProgram) P(glDeleteProgramsARB) P(glDeleteProgramsNV) P(glDeleteQueries) P(glDeleteQueriesARB) P(glDeleteRenderbuffers) P(glDeleteRenderbuffersEXT) P(glDeleteSamplers) P(glDeleteShader) P(glDeleteSync) P(glDeleteTexturesEXT) P(glDeleteTransformFeedbacks) P(glDeleteVertexArrays) P(glDeleteVertexArraysOES) P(glDepthRangef) P(glDetachObjectARB) P(glDetachShader) P(glDisableIndexedEXT) P(glDisableVertexAttribArray) P(glDisableVertexAttribArrayARB) P(glDisablei) P(glDrawArraysEXT) P(glDrawArraysInstanced) P(glDrawArraysInstancedARB) P(glDrawArraysInstancedBaseInstance) P(glDrawArraysInstancedEXT) P(glDrawBuffers) P(glDrawBuffersARB) P(glDrawBuffersATI) P(glDrawBuffersNV) P(glDrawElementsBaseVertex) P(glDrawElementsInstanced) P(glDrawElementsInstancedARB) P(glDrawElementsInstancedBaseInstance) P(glDrawElementsInstancedBaseVertex) P(glDrawElementsInstancedBaseVertexBaseInstance) P(glDrawElementsInstancedEXT) P(glDrawRangeElementsBaseVertex) P(glDrawRangeElementsEXT) P(glDrawTransformFeedback) P(glDrawTransformFeedbackInstanced) P(glDrawTransformFeedbackStream) P(glDrawTransformFeedbackStreamInstanced) P(glEGLImageTargetRenderbufferStorageOES) P(glEGLImageTargetTexture2DOES) P(glEdgeFlagPointerEXT) P(glEnableIndexedEXT) P(glEnableVertexAttribArray) P(glEnableVertexAttribArrayARB) P(glEnablei) P(glEndConditionalRender) P(glEndConditionalRenderNV) P(glEndFragmentShaderATI) P(glEndQuery) P(glEndQueryARB) P(glEndQueryIndexed) P(glEndTransformFeedback) P(glEndTransformFeedbackEXT) P(glExecuteProgramNV) P(glFenceSync) P(glFlushMappedBufferRange) P(glFogCoordPointer) P(glFogCoordPointerEXT) P(glFogCoordd) P(glFogCoorddEXT) P(glFogCoorddv) P(glFogCoorddvEXT) P(glFogCoordf) P(glFogCoordfEXT) P(glFogCoordfv) P(glFogCoordfvEXT) P(glFramebufferRenderbuffer) P(glFramebufferRenderbufferEXT) P(glFramebufferTexture) P(glFramebufferTexture1D) P(glFramebufferTexture1DEXT) P(glFramebufferTexture2D) P(glFramebufferTexture2DEXT) P(glFramebufferTexture3D) P(glFramebufferTexture3DEXT) P(glFramebufferTextureARB) P(glFramebufferTextureFaceARB) P(glFramebufferTextureLayer) P(glFramebufferTextureLayerARB) P(glFramebufferTextureLayerEXT) P(glGenBuffers) P(glGenBuffersARB) P(glGenFragmentShadersATI) P(glGenFramebuffers) P(glGenFramebuffersEXT) P(glGenProgramsARB) P(glGenProgramsNV) P(glGenQueries) P(glGenQueriesARB) P(glGenRenderbuffers) P(glGenRenderbuffersEXT) P(glGenSamplers) P(glGenTexturesEXT) P(glGenTransformFeedbacks) P(glGenVertexArrays) P(glGenVertexArraysOES) P(glGenerateMipmap) P(glGenerateMipmapEXT) P(glGetActiveAttrib) P(glGetActiveAttribARB) P(glGetActiveUniform) P(glGetActiveUniformARB) P(glGetActiveUniformBlockName) P(glGetActiveUniformBlockiv) P(glGetActiveUniformName) P(glGetActiveUniformsiv) P(glGetAttachedObjectsARB) P(glGetAttachedShaders) P(glGetAttribLocation) P(glGetAttribLocationARB) P(glGetBooleanIndexedvEXT) P(glGetBooleani_v) P(glGetBufferParameteri64v) P(glGetBufferParameteriv) P(glGetBufferParameterivARB) P(glGetBufferPointerv) P(glGetBufferPointervARB) P(glGetBufferSubData) P(glGetBufferSubDataARB) P(glGetColorTableEXT) P(glGetColorTableParameterfvEXT) P(glGetColorTableParameterivEXT) P(glGetCompressedTexImageARB) P(glGetDebugMessageLogARB) P(glGetFragDataIndex) P(glGetFragDataLocation) P(glGetFragDataLocationEXT) P(glGetFramebufferAttachmentParameteriv) P(glGetFramebufferAttachmentParameterivEXT) P(glGetGraphicsResetStatusARB) P(glGetHandleARB) P(glGetInfoLogARB) P(glGetInteger64i_v) P(glGetInteger64v) P(glGetIntegerIndexedvEXT) P(glGetIntegeri_v) P(glGetObjectParameterfvARB) P(glGetObjectParameterivAPPLE) P(glGetObjectParameterivARB) P(glGetPointervEXT) P(glGetProgramEnvParameterdvARB) P(glGetProgramEnvParameterfvARB) P(glGetProgramInfoLog) P(glGetProgramLocalParameterdvARB) P(glGetProgramLocalParameterfvARB) P(glGetProgramNamedParameterdvNV) P(glGetProgramNamedParameterfvNV) P(glGetProgramParameterdvNV) P(glGetProgramParameterfvNV) P(glGetProgramStringARB) P(glGetProgramStringNV) P(glGetProgramiv) P(glGetProgramivARB) P(glGetProgramivNV) P(glGetQueryIndexediv) P(glGetQueryObjectiv) P(glGetQueryObjectivARB) P(glGetQueryObjectuiv) P(glGetQueryObjectuivARB) P(glGetQueryiv) P(glGetQueryivARB) P(glGetRenderbufferParameteriv) P(glGetRenderbufferParameterivEXT) P(glGetSamplerParameterIiv) P(glGetSamplerParameterIuiv) P(glGetSamplerParameterfv) P(glGetSamplerParameteriv) P(glGetShaderInfoLog) P(glGetShaderPrecisionFormat) P(glGetShaderSource) P(glGetShaderSourceARB) P(glGetShaderiv) P(glGetStringi) P(glGetSynciv) P(glGetTexBumpParameterfvATI) P(glGetTexBumpParameterivATI) P(glGetTexParameterIiv) P(glGetTexParameterIivEXT) P(glGetTexParameterIuiv) P(glGetTexParameterIuivEXT) P(glGetTrackMatrixivNV) P(glGetTransformFeedbackVarying) P(glGetTransformFeedbackVaryingEXT) P(glGetUniformBlockIndex) P(glGetUniformIndices) P(glGetUniformLocation) P(glGetUniformLocationARB) P(glGetUniformfv) P(glGetUniformfvARB) P(glGetUniformiv) P(glGetUniformivARB) P(glGetUniformuiv) P(glGetUniformuivEXT) P(glGetVertexAttribIiv) P(glGetVertexAttribIivEXT) P(glGetVertexAttribIuiv) P(glGetVertexAttribIuivEXT) P(glGetVertexAttribPointerv) P(glGetVertexAttribPointervARB) P(glGetVertexAttribPointervNV) P(glGetVertexAttribdv) P(glGetVertexAttribdvARB) P(glGetVertexAttribdvNV) P(glGetVertexAttribfv) P(glGetVertexAttribfvARB) P(glGetVertexAttribfvNV) P(glGetVertexAttribiv) P(glGetVertexAttribivARB) P(glGetVertexAttribivNV) P(glGetnColorTableARB) P(glGetnCompressedTexImageARB) P(glGetnConvolutionFilterARB) P(glGetnHistogramARB) P(glGetnMapdvARB) P(glGetnMapfvARB) P(glGetnMapivARB) P(glGetnMinmaxARB) P(glGetnPixelMapfvARB) P(glGetnPixelMapuivARB) P(glGetnPixelMapusvARB) P(glGetnPolygonStippleARB) P(glGetnSeparableFilterARB) P(glGetnTexImageARB) P(glGetnUniformdvARB) P(glGetnUniformfvARB) P(glGetnUniformivARB) P(glGetnUniformuivARB) P(glIndexPointerEXT) P(glInvalidateBufferData) P(glInvalidateBufferSubData) P(glInvalidateFramebuffer) P(glInvalidateSubFramebuffer) P(glInvalidateTexImage) P(glInvalidateTexSubImage) P(glIsBuffer) P(glIsBufferARB) P(glIsEnabledIndexedEXT) P(glIsEnabledi) P(glIsFramebuffer) P(glIsFramebufferEXT) P(glIsProgram) P(glIsProgramARB) P(glIsProgramNV) P(glIsQuery) P(glIsQueryARB) P(glIsRenderbuffer) P(glIsRenderbufferEXT) P(glIsSampler) P(glIsShader) P(glIsSync) P(glIsTextureEXT) P(glIsTransformFeedback) P(glIsVertexArray) P(glIsVertexArrayOES) P(glLinkProgram) P(glLinkProgramARB) P(glLoadProgramNV) P(glLoadTransposeMatrixdARB) P(glLoadTransposeMatrixfARB) P(glLockArraysEXT) P(glMapBuffer) P(glMapBufferARB) P(glMapBufferRange) P(glMultTransposeMatrixdARB) P(glMultTransposeMatrixfARB) P(glMultiDrawArrays) P(glMultiDrawArraysEXT) P(glMultiDrawElements) P(glMultiDrawElementsBaseVertex) P(glMultiDrawElementsEXT) P(glMultiTexCoordP1ui) P(glMultiTexCoordP1uiv) P(glMultiTexCoordP2ui) P(glMultiTexCoordP2uiv) P(glMultiTexCoordP3ui) P(glMultiTexCoordP3uiv) P(glMultiTexCoordP4ui) P(glMultiTexCoordP4uiv) P(glNormalP3ui) P(glNormalP3uiv) P(glNormalPointerEXT) P(glObjectPurgeableAPPLE) P(glObjectUnpurgeableAPPLE) P(glPassTexCoordATI) P(glPauseTransformFeedback) P(glPointParameterf) P(glPointParameterfARB) P(glPointParameterfEXT) P(glPointParameterfv) P(glPointParameterfvARB) P(glPointParameterfvEXT) P(glPointParameteri) P(glPointParameteriNV) P(glPointParameteriv) P(glPointParameterivNV) P(glPolygonOffsetEXT) P(glPrimitiveRestartIndex) P(glPrimitiveRestartIndexNV) P(glPrimitiveRestartNV) P(glPrioritizeTexturesEXT) P(glProgramEnvParameter4dARB) P(glProgramEnvParameter4dvARB) P(glProgramEnvParameter4fARB) P(glProgramEnvParameter4fvARB) P(glProgramLocalParameter4dARB) P(glProgramLocalParameter4dvARB) P(glProgramLocalParameter4fARB) P(glProgramLocalParameter4fvARB) P(glProgramNamedParameter4dNV) P(glProgramNamedParameter4dvNV) P(glProgramNamedParameter4fNV) P(glProgramNamedParameter4fvNV) P(glProgramParameter4dNV) P(glProgramParameter4dvNV) P(glProgramParameter4fNV) P(glProgramParameter4fvNV) P(glProgramParameteriARB) P(glProgramParameters4dvNV) P(glProgramParameters4fvNV) P(glProgramStringARB) P(glProvokingVertex) P(glProvokingVertexEXT) P(glReadBufferNV) P(glReadnPixelsARB) P(glReleaseShaderCompiler) P(glRenderbufferStorage) P(glRenderbufferStorageEXT) P(glRenderbufferStorageMultisample) P(glRenderbufferStorageMultisampleEXT) P(glRequestResidentProgramsNV) P(glResumeTransformFeedback) P(glSampleCoverageARB) P(glSampleMapATI) P(glSamplerParameterIiv) P(glSamplerParameterIuiv) P(glSamplerParameterf) P(glSamplerParameterfv) P(glSamplerParameteri) P(glSamplerParameteriv) P(glSecondaryColor3b) P(glSecondaryColor3bEXT) P(glSecondaryColor3bv) P(glSecondaryColor3bvEXT) P(glSecondaryColor3d) P(glSecondaryColor3dEXT) P(glSecondaryColor3dv) P(glSecondaryColor3dvEXT) P(glSecondaryColor3f) P(glSecondaryColor3fEXT) P(glSecondaryColor3fv) P(glSecondaryColor3fvEXT) P(glSecondaryColor3i) P(glSecondaryColor3iEXT) P(glSecondaryColor3iv) P(glSecondaryColor3ivEXT) P(glSecondaryColor3s) P(glSecondaryColor3sEXT) P(glSecondaryColor3sv) P(glSecondaryColor3svEXT) P(glSecondaryColor3ub) P(glSecondaryColor3ubEXT) P(glSecondaryColor3ubv) P(glSecondaryColor3ubvEXT) P(glSecondaryColor3ui) P(glSecondaryColor3uiEXT) P(glSecondaryColor3uiv) P(glSecondaryColor3uivEXT) P(glSecondaryColor3us) P(glSecondaryColor3usEXT) P(glSecondaryColor3usv) P(glSecondaryColor3usvEXT) P(glSecondaryColorP3ui) P(glSecondaryColorP3uiv) P(glSecondaryColorPointer) P(glSecondaryColorPointerEXT) P(glSetFragmentShaderConstantATI) P(glShaderBinary) P(glShaderSource) P(glShaderSourceARB) P(glStencilFuncSeparate) P(glStencilMaskSeparate) P(glStencilOpSeparate) P(glTexBuffer) P(glTexBufferARB) P(glTexBumpParameterfvATI) P(glTexBumpParameterivATI) P(glTexCoordP1ui) P(glTexCoordP1uiv) P(glTexCoordP2ui) P(glTexCoordP2uiv) P(glTexCoordP3ui) P(glTexCoordP3uiv) P(glTexCoordP4ui) P(glTexCoordP4uiv) P(glTexCoordPointerEXT) P(glTexImage3DEXT) P(glTexParameterIiv) P(glTexParameterIivEXT) P(glTexParameterIuiv) P(glTexParameterIuivEXT) P(glTexStorage1D) P(glTexStorage2D) P(glTexStorage3D) P(glTexSubImage1DEXT) P(glTexSubImage2DEXT) P(glTexSubImage3DEXT) P(glTextureBarrierNV) P(glTextureStorage1DEXT) P(glTextureStorage2DEXT) P(glTextureStorage3DEXT) P(glTrackMatrixNV) P(glTransformFeedbackVaryings) P(glTransformFeedbackVaryingsEXT) P(glUniform1f) P(glUniform1fARB) P(glUniform1fv) P(glUniform1fvARB) P(glUniform1i) P(glUniform1iARB) P(glUniform1iv) P(glUniform1ivARB) P(glUniform1ui) P(glUniform1uiEXT) P(glUniform1uiv) P(glUniform1uivEXT) P(glUniform2f) P(glUniform2fARB) P(glUniform2fv) P(glUniform2fvARB) P(glUniform2i) P(glUniform2iARB) P(glUniform2iv) P(glUniform2ivARB) P(glUniform2ui) P(glUniform2uiEXT) P(glUniform2uiv) P(glUniform2uivEXT) P(glUniform3f) P(glUniform3fARB) P(glUniform3fv) P(glUniform3fvARB) P(glUniform3i) P(glUniform3iARB) P(glUniform3iv) P(glUniform3ivARB) P(glUniform3ui) P(glUniform3uiEXT) P(glUniform3uiv) P(glUniform3uivEXT) P(glUniform4f) P(glUniform4fARB) P(glUniform4fv) P(glUniform4fvARB) P(glUniform4i) P(glUniform4iARB) P(glUniform4iv) P(glUniform4ivARB) P(glUniform4ui) P(glUniform4uiEXT) P(glUniform4uiv) P(glUniform4uivEXT) P(glUniformBlockBinding) P(glUniformMatrix2fv) P(glUniformMatrix2fvARB) P(glUniformMatrix2x3fv) P(glUniformMatrix2x4fv) P(glUniformMatrix3fv) P(glUniformMatrix3fvARB) P(glUniformMatrix3x2fv) P(glUniformMatrix3x4fv) P(glUniformMatrix4fv) P(glUniformMatrix4fvARB) P(glUniformMatrix4x2fv) P(glUniformMatrix4x3fv) P(glUnlockArraysEXT) P(glUnmapBuffer) P(glUnmapBufferARB) P(glUseProgram) P(glUseProgramObjectARB) P(glUseShaderProgramEXT) P(glValidateProgram) P(glValidateProgramARB) P(glVertexAttrib1d) P(glVertexAttrib1dARB) P(glVertexAttrib1dNV) P(glVertexAttrib1dv) P(glVertexAttrib1dvARB) P(glVertexAttrib1dvNV) P(glVertexAttrib1f) P(glVertexAttrib1fARB) P(glVertexAttrib1fNV) P(glVertexAttrib1fv) P(glVertexAttrib1fvARB) P(glVertexAttrib1fvNV) P(glVertexAttrib1s) P(glVertexAttrib1sARB) P(glVertexAttrib1sNV) P(glVertexAttrib1sv) P(glVertexAttrib1svARB) P(glVertexAttrib1svNV) P(glVertexAttrib2d) P(glVertexAttrib2dARB) P(glVertexAttrib2dNV) P(glVertexAttrib2dv) P(glVertexAttrib2dvARB) P(glVertexAttrib2dvNV) P(glVertexAttrib2f) P(glVertexAttrib2fARB) P(glVertexAttrib2fNV) P(glVertexAttrib2fv) P(glVertexAttrib2fvARB) P(glVertexAttrib2fvNV) P(glVertexAttrib2s) P(glVertexAttrib2sARB) P(glVertexAttrib2sNV) P(glVertexAttrib2sv) P(glVertexAttrib2svARB) P(glVertexAttrib2svNV) P(glVertexAttrib3d) P(glVertexAttrib3dARB) P(glVertexAttrib3dNV) P(glVertexAttrib3dv) P(glVertexAttrib3dvARB) P(glVertexAttrib3dvNV) P(glVertexAttrib3f) P(glVertexAttrib3fARB) P(glVertexAttrib3fNV) P(glVertexAttrib3fv) P(glVertexAttrib3fvARB) P(glVertexAttrib3fvNV) P(glVertexAttrib3s) P(glVertexAttrib3sARB) P(glVertexAttrib3sNV) P(glVertexAttrib3sv) P(glVertexAttrib3svARB) P(glVertexAttrib3svNV) P(glVertexAttrib4Nbv) P(glVertexAttrib4NbvARB) P(glVertexAttrib4Niv) P(glVertexAttrib4NivARB) P(glVertexAttrib4Nsv) P(glVertexAttrib4NsvARB) P(glVertexAttrib4Nub) P(glVertexAttrib4NubARB) P(glVertexAttrib4Nubv) P(glVertexAttrib4NubvARB) P(glVertexAttrib4Nuiv) P(glVertexAttrib4NuivARB) P(glVertexAttrib4Nusv) P(glVertexAttrib4NusvARB) P(glVertexAttrib4bv) P(glVertexAttrib4bvARB) P(glVertexAttrib4d) P(glVertexAttrib4dARB) P(glVertexAttrib4dNV) P(glVertexAttrib4dv) P(glVertexAttrib4dvARB) P(glVertexAttrib4dvNV) P(glVertexAttrib4f) P(glVertexAttrib4fARB) P(glVertexAttrib4fNV) P(glVertexAttrib4fv) P(glVertexAttrib4fvARB) P(glVertexAttrib4fvNV) P(glVertexAttrib4iv) P(glVertexAttrib4ivARB) P(glVertexAttrib4s) P(glVertexAttrib4sARB) P(glVertexAttrib4sNV) P(glVertexAttrib4sv) P(glVertexAttrib4svARB) P(glVertexAttrib4svNV) P(glVertexAttrib4ubNV) P(glVertexAttrib4ubv) P(glVertexAttrib4ubvARB) P(glVertexAttrib4ubvNV) P(glVertexAttrib4uiv) P(glVertexAttrib4uivARB) P(glVertexAttrib4usv) P(glVertexAttrib4usvARB) P(glVertexAttribDivisor) P(glVertexAttribDivisorARB) P(glVertexAttribI1i) P(glVertexAttribI1iEXT) P(glVertexAttribI1iv) P(glVertexAttribI1ivEXT) P(glVertexAttribI1ui) P(glVertexAttribI1uiEXT) P(glVertexAttribI1uiv) P(glVertexAttribI1uivEXT) P(glVertexAttribI2i) P(glVertexAttribI2iEXT) P(glVertexAttribI2iv) P(glVertexAttribI2ivEXT) P(glVertexAttribI2ui) P(glVertexAttribI2uiEXT) P(glVertexAttribI2uiv) P(glVertexAttribI2uivEXT) P(glVertexAttribI3i) P(glVertexAttribI3iEXT) P(glVertexAttribI3iv) P(glVertexAttribI3ivEXT) P(glVertexAttribI3ui) P(glVertexAttribI3uiEXT) P(glVertexAttribI3uiv) P(glVertexAttribI3uivEXT) P(glVertexAttribI4bv) P(glVertexAttribI4bvEXT) P(glVertexAttribI4i) P(glVertexAttribI4iEXT) P(glVertexAttribI4iv) P(glVertexAttribI4ivEXT) P(glVertexAttribI4sv) P(glVertexAttribI4svEXT) P(glVertexAttribI4ubv) P(glVertexAttribI4ubvEXT) P(glVertexAttribI4ui) P(glVertexAttribI4uiEXT) P(glVertexAttribI4uiv) P(glVertexAttribI4uivEXT) P(glVertexAttribI4usv) P(glVertexAttribI4usvEXT) P(glVertexAttribIPointer) P(glVertexAttribIPointerEXT) P(glVertexAttribP1ui) P(glVertexAttribP1uiv) P(glVertexAttribP2ui) P(glVertexAttribP2uiv) P(glVertexAttribP3ui) P(glVertexAttribP3uiv) P(glVertexAttribP4ui) P(glVertexAttribP4uiv) P(glVertexAttribPointer) P(glVertexAttribPointerARB) P(glVertexAttribPointerNV) P(glVertexAttribs1dvNV) P(glVertexAttribs1fvNV) P(glVertexAttribs1svNV) P(glVertexAttribs2dvNV) P(glVertexAttribs2fvNV) P(glVertexAttribs2svNV) P(glVertexAttribs3dvNV) P(glVertexAttribs3fvNV) P(glVertexAttribs3svNV) P(glVertexAttribs4dvNV) P(glVertexAttribs4fvNV) P(glVertexAttribs4svNV) P(glVertexAttribs4ubvNV) P(glVertexP2ui) P(glVertexP2uiv) P(glVertexP3ui) P(glVertexP3uiv) P(glVertexP4ui) P(glVertexP4uiv) P(glVertexPointerEXT) P(glWaitSync) P(glWindowPos2d) P(glWindowPos2dARB) P(glWindowPos2dv) P(glWindowPos2dvARB) P(glWindowPos2f) P(glWindowPos2fARB) P(glWindowPos2fv) P(glWindowPos2fvARB) P(glWindowPos2i) P(glWindowPos2iARB) P(glWindowPos2iv) P(glWindowPos2ivARB) P(glWindowPos2s) P(glWindowPos2sARB) P(glWindowPos2sv) P(glWindowPos2svARB) P(glWindowPos3d) P(glWindowPos3dARB) P(glWindowPos3dv) P(glWindowPos3dvARB) P(glWindowPos3f) P(glWindowPos3fARB) P(glWindowPos3fv) P(glWindowPos3fvARB) P(glWindowPos3i) P(glWindowPos3iARB) P(glWindowPos3iv) P(glWindowPos3ivARB) P(glWindowPos3s) P(glWindowPos3sARB) P(glWindowPos3sv) P(glWindowPos3svARB) primus-0~20150328/gl-passthru.def0000644000175000017500000012021212555052336016410 0ustar vincentvincent// Prototypes for auto-generating forwarders for OpenGL functions DEF_GLX_PROTO(void, glClearIndex,(GLfloat c), c) DEF_GLX_PROTO(void, glClearColor,(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha), red, green, blue, alpha) DEF_GLX_PROTO(void, glClear,(GLbitfield mask), mask) DEF_GLX_PROTO(void, glIndexMask,(GLuint mask), mask) DEF_GLX_PROTO(void, glColorMask,(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha), red, green, blue, alpha) DEF_GLX_PROTO(void, glAlphaFunc,(GLenum func, GLclampf ref), func, ref) DEF_GLX_PROTO(void, glBlendFunc,(GLenum sfactor, GLenum dfactor), sfactor, dfactor) DEF_GLX_PROTO(void, glLogicOp,(GLenum opcode), opcode) DEF_GLX_PROTO(void, glCullFace,(GLenum mode), mode) DEF_GLX_PROTO(void, glFrontFace,(GLenum mode), mode) DEF_GLX_PROTO(void, glPointSize,(GLfloat size), size) DEF_GLX_PROTO(void, glLineWidth,(GLfloat width), width) DEF_GLX_PROTO(void, glLineStipple,(GLint factor, GLushort pattern), factor, pattern) DEF_GLX_PROTO(void, glPolygonMode,(GLenum face, GLenum mode), face, mode) DEF_GLX_PROTO(void, glPolygonOffset,(GLfloat factor, GLfloat units), factor, units) DEF_GLX_PROTO(void, glPolygonStipple,(const GLubyte *mask), mask) DEF_GLX_PROTO(void, glGetPolygonStipple,(GLubyte *mask), mask) DEF_GLX_PROTO(void, glEdgeFlag,(GLboolean flag), flag) DEF_GLX_PROTO(void, glEdgeFlagv,(const GLboolean *flag), flag) DEF_GLX_PROTO(void, glScissor,(GLint x, GLint y, GLsizei width, GLsizei height), x, y, width, height) DEF_GLX_PROTO(void, glClipPlane,(GLenum plane, const GLdouble *equation), plane, equation) DEF_GLX_PROTO(void, glGetClipPlane,(GLenum plane, GLdouble *equation), plane, equation) DEF_GLX_PROTO(void, glDrawBuffer,(GLenum mode), mode) DEF_GLX_PROTO(void, glReadBuffer,(GLenum mode), mode) DEF_GLX_PROTO(void, glEnable,(GLenum cap), cap) DEF_GLX_PROTO(void, glDisable,(GLenum cap), cap) DEF_GLX_PROTO(GLboolean, glIsEnabled,(GLenum cap), cap) DEF_GLX_PROTO(void, glEnableClientState,(GLenum cap), cap) DEF_GLX_PROTO(void, glDisableClientState,(GLenum cap), cap) DEF_GLX_PROTO(void, glGetBooleanv,(GLenum pname, GLboolean *params), pname, params) DEF_GLX_PROTO(void, glGetDoublev,(GLenum pname, GLdouble *params), pname, params) DEF_GLX_PROTO(void, glGetFloatv,(GLenum pname, GLfloat *params), pname, params) DEF_GLX_PROTO(void, glGetIntegerv,(GLenum pname, GLint *params), pname, params) DEF_GLX_PROTO(void, glPushAttrib,(GLbitfield mask), mask) DEF_GLX_PROTO(void, glPopAttrib,(void)) DEF_GLX_PROTO(void, glPushClientAttrib,(GLbitfield mask), mask) DEF_GLX_PROTO(void, glPopClientAttrib,(void)) DEF_GLX_PROTO(GLint, glRenderMode,(GLenum mode), mode) DEF_GLX_PROTO(GLenum, glGetError,(void)) DEF_GLX_PROTO(const GLubyte *, glGetString,(GLenum name), name) DEF_GLX_PROTO(void, glFinish,(void)) DEF_GLX_PROTO(void, glFlush,(void)) DEF_GLX_PROTO(void, glHint,(GLenum target, GLenum mode), target, mode) DEF_GLX_PROTO(void, glClearDepth,(GLclampd depth), depth) DEF_GLX_PROTO(void, glDepthFunc,(GLenum func), func) DEF_GLX_PROTO(void, glDepthMask,(GLboolean flag), flag) DEF_GLX_PROTO(void, glDepthRange,(GLclampd near_val, GLclampd far_val), near_val, far_val) DEF_GLX_PROTO(void, glClearAccum,(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha), red, green, blue, alpha) DEF_GLX_PROTO(void, glAccum,(GLenum op, GLfloat value), op, value) DEF_GLX_PROTO(void, glMatrixMode,(GLenum mode), mode) DEF_GLX_PROTO(void, glOrtho,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val), left, right, bottom, top, near_val, far_val) DEF_GLX_PROTO(void, glFrustum,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val), left, right, bottom, top, near_val, far_val) DEF_GLX_PROTO(void, glViewport,(GLint x, GLint y, GLsizei width, GLsizei height), x, y, width, height) DEF_GLX_PROTO(void, glPushMatrix,(void)) DEF_GLX_PROTO(void, glPopMatrix,(void)) DEF_GLX_PROTO(void, glLoadIdentity,(void)) DEF_GLX_PROTO(void, glLoadMatrixd,(const GLdouble *m), m) DEF_GLX_PROTO(void, glLoadMatrixf,(const GLfloat *m), m) DEF_GLX_PROTO(void, glMultMatrixd,(const GLdouble *m), m) DEF_GLX_PROTO(void, glMultMatrixf,(const GLfloat *m), m) DEF_GLX_PROTO(void, glRotated,(GLdouble angle, GLdouble x, GLdouble y, GLdouble z), angle, x, y, z) DEF_GLX_PROTO(void, glRotatef,(GLfloat angle, GLfloat x, GLfloat y, GLfloat z), angle, x, y, z) DEF_GLX_PROTO(void, glScaled,(GLdouble x, GLdouble y, GLdouble z), x, y, z) DEF_GLX_PROTO(void, glScalef,(GLfloat x, GLfloat y, GLfloat z), x, y, z) DEF_GLX_PROTO(void, glTranslated,(GLdouble x, GLdouble y, GLdouble z), x, y, z) DEF_GLX_PROTO(void, glTranslatef,(GLfloat x, GLfloat y, GLfloat z), x, y, z) DEF_GLX_PROTO(GLboolean, glIsList,(GLuint list), list) DEF_GLX_PROTO(void, glDeleteLists,(GLuint list, GLsizei range), list, range) DEF_GLX_PROTO(GLuint, glGenLists,(GLsizei range), range) DEF_GLX_PROTO(void, glNewList,(GLuint list, GLenum mode), list, mode) DEF_GLX_PROTO(void, glEndList,(void)) DEF_GLX_PROTO(void, glCallList,(GLuint list), list) DEF_GLX_PROTO(void, glCallLists,(GLsizei n, GLenum type, const GLvoid *lists), n, type, lists) DEF_GLX_PROTO(void, glListBase,(GLuint base), base) DEF_GLX_PROTO(void, glBegin,(GLenum mode), mode) DEF_GLX_PROTO(void, glEnd,(void)) DEF_GLX_PROTO(void, glVertex2d,(GLdouble x, GLdouble y), x, y) DEF_GLX_PROTO(void, glVertex2f,(GLfloat x, GLfloat y), x, y) DEF_GLX_PROTO(void, glVertex2i,(GLint x, GLint y), x, y) DEF_GLX_PROTO(void, glVertex2s,(GLshort x, GLshort y), x, y) DEF_GLX_PROTO(void, glVertex3d,(GLdouble x, GLdouble y, GLdouble z), x, y, z) DEF_GLX_PROTO(void, glVertex3f,(GLfloat x, GLfloat y, GLfloat z), x, y, z) DEF_GLX_PROTO(void, glVertex3i,(GLint x, GLint y, GLint z), x, y, z) DEF_GLX_PROTO(void, glVertex3s,(GLshort x, GLshort y, GLshort z), x, y, z) DEF_GLX_PROTO(void, glVertex4d,(GLdouble x, GLdouble y, GLdouble z, GLdouble w), x, y, z, w) DEF_GLX_PROTO(void, glVertex4f,(GLfloat x, GLfloat y, GLfloat z, GLfloat w), x, y, z, w) DEF_GLX_PROTO(void, glVertex4i,(GLint x, GLint y, GLint z, GLint w), x, y, z, w) DEF_GLX_PROTO(void, glVertex4s,(GLshort x, GLshort y, GLshort z, GLshort w), x, y, z, w) DEF_GLX_PROTO(void, glVertex2dv,(const GLdouble *v), v) DEF_GLX_PROTO(void, glVertex2fv,(const GLfloat *v), v) DEF_GLX_PROTO(void, glVertex2iv,(const GLint *v), v) DEF_GLX_PROTO(void, glVertex2sv,(const GLshort *v), v) DEF_GLX_PROTO(void, glVertex3dv,(const GLdouble *v), v) DEF_GLX_PROTO(void, glVertex3fv,(const GLfloat *v), v) DEF_GLX_PROTO(void, glVertex3iv,(const GLint *v), v) DEF_GLX_PROTO(void, glVertex3sv,(const GLshort *v), v) DEF_GLX_PROTO(void, glVertex4dv,(const GLdouble *v), v) DEF_GLX_PROTO(void, glVertex4fv,(const GLfloat *v), v) DEF_GLX_PROTO(void, glVertex4iv,(const GLint *v), v) DEF_GLX_PROTO(void, glVertex4sv,(const GLshort *v), v) DEF_GLX_PROTO(void, glNormal3b,(GLbyte nx, GLbyte ny, GLbyte nz), nx, ny, nz) DEF_GLX_PROTO(void, glNormal3d,(GLdouble nx, GLdouble ny, GLdouble nz), nx, ny, nz) DEF_GLX_PROTO(void, glNormal3f,(GLfloat nx, GLfloat ny, GLfloat nz), nx, ny, nz) DEF_GLX_PROTO(void, glNormal3i,(GLint nx, GLint ny, GLint nz), nx, ny, nz) DEF_GLX_PROTO(void, glNormal3s,(GLshort nx, GLshort ny, GLshort nz), nx, ny, nz) DEF_GLX_PROTO(void, glNormal3bv,(const GLbyte *v), v) DEF_GLX_PROTO(void, glNormal3dv,(const GLdouble *v), v) DEF_GLX_PROTO(void, glNormal3fv,(const GLfloat *v), v) DEF_GLX_PROTO(void, glNormal3iv,(const GLint *v), v) DEF_GLX_PROTO(void, glNormal3sv,(const GLshort *v), v) DEF_GLX_PROTO(void, glIndexd,(GLdouble c), c) DEF_GLX_PROTO(void, glIndexf,(GLfloat c), c) DEF_GLX_PROTO(void, glIndexi,(GLint c), c) DEF_GLX_PROTO(void, glIndexs,(GLshort c), c) DEF_GLX_PROTO(void, glIndexub,(GLubyte c), c) DEF_GLX_PROTO(void, glIndexdv,(const GLdouble *c), c) DEF_GLX_PROTO(void, glIndexfv,(const GLfloat *c), c) DEF_GLX_PROTO(void, glIndexiv,(const GLint *c), c) DEF_GLX_PROTO(void, glIndexsv,(const GLshort *c), c) DEF_GLX_PROTO(void, glIndexubv,(const GLubyte *c), c) DEF_GLX_PROTO(void, glColor3b,(GLbyte red, GLbyte green, GLbyte blue), red, green, blue) DEF_GLX_PROTO(void, glColor3d,(GLdouble red, GLdouble green, GLdouble blue), red, green, blue) DEF_GLX_PROTO(void, glColor3f,(GLfloat red, GLfloat green, GLfloat blue), red, green, blue) DEF_GLX_PROTO(void, glColor3i,(GLint red, GLint green, GLint blue), red, green, blue) DEF_GLX_PROTO(void, glColor3s,(GLshort red, GLshort green, GLshort blue), red, green, blue) DEF_GLX_PROTO(void, glColor3ub,(GLubyte red, GLubyte green, GLubyte blue), red, green, blue) DEF_GLX_PROTO(void, glColor3ui,(GLuint red, GLuint green, GLuint blue), red, green, blue) DEF_GLX_PROTO(void, glColor3us,(GLushort red, GLushort green, GLushort blue), red, green, blue) DEF_GLX_PROTO(void, glColor4b,(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha), red, green, blue, alpha) DEF_GLX_PROTO(void, glColor4d,(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha), red, green, blue, alpha) DEF_GLX_PROTO(void, glColor4f,(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha), red, green, blue, alpha) DEF_GLX_PROTO(void, glColor4i,(GLint red, GLint green, GLint blue, GLint alpha), red, green, blue, alpha) DEF_GLX_PROTO(void, glColor4s,(GLshort red, GLshort green, GLshort blue, GLshort alpha), red, green, blue, alpha) DEF_GLX_PROTO(void, glColor4ub,(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha), red, green, blue, alpha) DEF_GLX_PROTO(void, glColor4ui,(GLuint red, GLuint green, GLuint blue, GLuint alpha), red, green, blue, alpha) DEF_GLX_PROTO(void, glColor4us,(GLushort red, GLushort green, GLushort blue, GLushort alpha), red, green, blue, alpha) DEF_GLX_PROTO(void, glColor3bv,(const GLbyte *v), v) DEF_GLX_PROTO(void, glColor3dv,(const GLdouble *v), v) DEF_GLX_PROTO(void, glColor3fv,(const GLfloat *v), v) DEF_GLX_PROTO(void, glColor3iv,(const GLint *v), v) DEF_GLX_PROTO(void, glColor3sv,(const GLshort *v), v) DEF_GLX_PROTO(void, glColor3ubv,(const GLubyte *v), v) DEF_GLX_PROTO(void, glColor3uiv,(const GLuint *v), v) DEF_GLX_PROTO(void, glColor3usv,(const GLushort *v), v) DEF_GLX_PROTO(void, glColor4bv,(const GLbyte *v), v) DEF_GLX_PROTO(void, glColor4dv,(const GLdouble *v), v) DEF_GLX_PROTO(void, glColor4fv,(const GLfloat *v), v) DEF_GLX_PROTO(void, glColor4iv,(const GLint *v), v) DEF_GLX_PROTO(void, glColor4sv,(const GLshort *v), v) DEF_GLX_PROTO(void, glColor4ubv,(const GLubyte *v), v) DEF_GLX_PROTO(void, glColor4uiv,(const GLuint *v), v) DEF_GLX_PROTO(void, glColor4usv,(const GLushort *v), v) DEF_GLX_PROTO(void, glTexCoord1d,(GLdouble s), s) DEF_GLX_PROTO(void, glTexCoord1f,(GLfloat s), s) DEF_GLX_PROTO(void, glTexCoord1i,(GLint s), s) DEF_GLX_PROTO(void, glTexCoord1s,(GLshort s), s) DEF_GLX_PROTO(void, glTexCoord2d,(GLdouble s, GLdouble t), s, t) DEF_GLX_PROTO(void, glTexCoord2f,(GLfloat s, GLfloat t), s, t) DEF_GLX_PROTO(void, glTexCoord2i,(GLint s, GLint t), s, t) DEF_GLX_PROTO(void, glTexCoord2s,(GLshort s, GLshort t), s, t) DEF_GLX_PROTO(void, glTexCoord3d,(GLdouble s, GLdouble t, GLdouble r), s, t, r) DEF_GLX_PROTO(void, glTexCoord3f,(GLfloat s, GLfloat t, GLfloat r), s, t, r) DEF_GLX_PROTO(void, glTexCoord3i,(GLint s, GLint t, GLint r), s, t, r) DEF_GLX_PROTO(void, glTexCoord3s,(GLshort s, GLshort t, GLshort r), s, t, r) DEF_GLX_PROTO(void, glTexCoord4d,(GLdouble s, GLdouble t, GLdouble r, GLdouble q), s, t, r, q) DEF_GLX_PROTO(void, glTexCoord4f,(GLfloat s, GLfloat t, GLfloat r, GLfloat q), s, t, r, q) DEF_GLX_PROTO(void, glTexCoord4i,(GLint s, GLint t, GLint r, GLint q), s, t, r, q) DEF_GLX_PROTO(void, glTexCoord4s,(GLshort s, GLshort t, GLshort r, GLshort q), s, t, r, q) DEF_GLX_PROTO(void, glTexCoord1dv,(const GLdouble *v), v) DEF_GLX_PROTO(void, glTexCoord1fv,(const GLfloat *v), v) DEF_GLX_PROTO(void, glTexCoord1iv,(const GLint *v), v) DEF_GLX_PROTO(void, glTexCoord1sv,(const GLshort *v), v) DEF_GLX_PROTO(void, glTexCoord2dv,(const GLdouble *v), v) DEF_GLX_PROTO(void, glTexCoord2fv,(const GLfloat *v), v) DEF_GLX_PROTO(void, glTexCoord2iv,(const GLint *v), v) DEF_GLX_PROTO(void, glTexCoord2sv,(const GLshort *v), v) DEF_GLX_PROTO(void, glTexCoord3dv,(const GLdouble *v), v) DEF_GLX_PROTO(void, glTexCoord3fv,(const GLfloat *v), v) DEF_GLX_PROTO(void, glTexCoord3iv,(const GLint *v), v) DEF_GLX_PROTO(void, glTexCoord3sv,(const GLshort *v), v) DEF_GLX_PROTO(void, glTexCoord4dv,(const GLdouble *v), v) DEF_GLX_PROTO(void, glTexCoord4fv,(const GLfloat *v), v) DEF_GLX_PROTO(void, glTexCoord4iv,(const GLint *v), v) DEF_GLX_PROTO(void, glTexCoord4sv,(const GLshort *v), v) DEF_GLX_PROTO(void, glRasterPos2d,(GLdouble x, GLdouble y), x, y) DEF_GLX_PROTO(void, glRasterPos2f,(GLfloat x, GLfloat y), x, y) DEF_GLX_PROTO(void, glRasterPos2i,(GLint x, GLint y), x, y) DEF_GLX_PROTO(void, glRasterPos2s,(GLshort x, GLshort y), x, y) DEF_GLX_PROTO(void, glRasterPos3d,(GLdouble x, GLdouble y, GLdouble z), x, y, z) DEF_GLX_PROTO(void, glRasterPos3f,(GLfloat x, GLfloat y, GLfloat z), x, y, z) DEF_GLX_PROTO(void, glRasterPos3i,(GLint x, GLint y, GLint z), x, y, z) DEF_GLX_PROTO(void, glRasterPos3s,(GLshort x, GLshort y, GLshort z), x, y, z) DEF_GLX_PROTO(void, glRasterPos4d,(GLdouble x, GLdouble y, GLdouble z, GLdouble w), x, y, z, w) DEF_GLX_PROTO(void, glRasterPos4f,(GLfloat x, GLfloat y, GLfloat z, GLfloat w), x, y, z, w) DEF_GLX_PROTO(void, glRasterPos4i,(GLint x, GLint y, GLint z, GLint w), x, y, z, w) DEF_GLX_PROTO(void, glRasterPos4s,(GLshort x, GLshort y, GLshort z, GLshort w), x, y, z, w) DEF_GLX_PROTO(void, glRasterPos2dv,(const GLdouble *v), v) DEF_GLX_PROTO(void, glRasterPos2fv,(const GLfloat *v), v) DEF_GLX_PROTO(void, glRasterPos2iv,(const GLint *v), v) DEF_GLX_PROTO(void, glRasterPos2sv,(const GLshort *v), v) DEF_GLX_PROTO(void, glRasterPos3dv,(const GLdouble *v), v) DEF_GLX_PROTO(void, glRasterPos3fv,(const GLfloat *v), v) DEF_GLX_PROTO(void, glRasterPos3iv,(const GLint *v), v) DEF_GLX_PROTO(void, glRasterPos3sv,(const GLshort *v), v) DEF_GLX_PROTO(void, glRasterPos4dv,(const GLdouble *v), v) DEF_GLX_PROTO(void, glRasterPos4fv,(const GLfloat *v), v) DEF_GLX_PROTO(void, glRasterPos4iv,(const GLint *v), v) DEF_GLX_PROTO(void, glRasterPos4sv,(const GLshort *v), v) DEF_GLX_PROTO(void, glRectd,(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2), x1, y1, x2, y2) DEF_GLX_PROTO(void, glRectf,(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2), x1, y1, x2, y2) DEF_GLX_PROTO(void, glRecti,(GLint x1, GLint y1, GLint x2, GLint y2), x1, y1, x2, y2) DEF_GLX_PROTO(void, glRects,(GLshort x1, GLshort y1, GLshort x2, GLshort y2), x1, y1, x2, y2) DEF_GLX_PROTO(void, glRectdv,(const GLdouble *v1, const GLdouble *v2), v1, v2) DEF_GLX_PROTO(void, glRectfv,(const GLfloat *v1, const GLfloat *v2), v1, v2) DEF_GLX_PROTO(void, glRectiv,(const GLint *v1, const GLint *v2), v1, v2) DEF_GLX_PROTO(void, glRectsv,(const GLshort *v1, const GLshort *v2), v1, v2) DEF_GLX_PROTO(void, glVertexPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr), size, type, stride, ptr) DEF_GLX_PROTO(void, glNormalPointer,(GLenum type, GLsizei stride, const GLvoid *ptr), type, stride, ptr) DEF_GLX_PROTO(void, glColorPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr), size, type, stride, ptr) DEF_GLX_PROTO(void, glIndexPointer,(GLenum type, GLsizei stride, const GLvoid *ptr), type, stride, ptr) DEF_GLX_PROTO(void, glTexCoordPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr), size, type, stride, ptr) DEF_GLX_PROTO(void, glEdgeFlagPointer,(GLsizei stride, const GLvoid *ptr), stride, ptr) DEF_GLX_PROTO(void, glGetPointerv,(GLenum pname, GLvoid **params), pname, params) DEF_GLX_PROTO(void, glArrayElement,(GLint i), i) DEF_GLX_PROTO(void, glDrawArrays,(GLenum mode, GLint first, GLsizei count), mode, first, count) DEF_GLX_PROTO(void, glDrawElements,(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices), mode, count, type, indices) DEF_GLX_PROTO(void, glInterleavedArrays,(GLenum format, GLsizei stride, const GLvoid *pointer), format, stride, pointer) DEF_GLX_PROTO(void, glShadeModel,(GLenum mode), mode) DEF_GLX_PROTO(void, glLightf,(GLenum light, GLenum pname, GLfloat param), light, pname, param) DEF_GLX_PROTO(void, glLighti,(GLenum light, GLenum pname, GLint param), light, pname, param) DEF_GLX_PROTO(void, glLightfv,(GLenum light, GLenum pname, const GLfloat *params), light, pname, params) DEF_GLX_PROTO(void, glLightiv,(GLenum light, GLenum pname, const GLint *params), light, pname, params) DEF_GLX_PROTO(void, glGetLightfv,(GLenum light, GLenum pname, GLfloat *params), light, pname, params) DEF_GLX_PROTO(void, glGetLightiv,(GLenum light, GLenum pname, GLint *params), light, pname, params) DEF_GLX_PROTO(void, glLightModelf,(GLenum pname, GLfloat param), pname, param) DEF_GLX_PROTO(void, glLightModeli,(GLenum pname, GLint param), pname, param) DEF_GLX_PROTO(void, glLightModelfv,(GLenum pname, const GLfloat *params), pname, params) DEF_GLX_PROTO(void, glLightModeliv,(GLenum pname, const GLint *params), pname, params) DEF_GLX_PROTO(void, glMaterialf,(GLenum face, GLenum pname, GLfloat param), face, pname, param) DEF_GLX_PROTO(void, glMateriali,(GLenum face, GLenum pname, GLint param), face, pname, param) DEF_GLX_PROTO(void, glMaterialfv,(GLenum face, GLenum pname, const GLfloat *params), face, pname, params) DEF_GLX_PROTO(void, glMaterialiv,(GLenum face, GLenum pname, const GLint *params), face, pname, params) DEF_GLX_PROTO(void, glGetMaterialfv,(GLenum face, GLenum pname, GLfloat *params), face, pname, params) DEF_GLX_PROTO(void, glGetMaterialiv,(GLenum face, GLenum pname, GLint *params), face, pname, params) DEF_GLX_PROTO(void, glColorMaterial,(GLenum face, GLenum mode), face, mode) DEF_GLX_PROTO(void, glPixelZoom,(GLfloat xfactor, GLfloat yfactor), xfactor, yfactor) DEF_GLX_PROTO(void, glPixelStoref,(GLenum pname, GLfloat param), pname, param) DEF_GLX_PROTO(void, glPixelStorei,(GLenum pname, GLint param), pname, param) DEF_GLX_PROTO(void, glPixelTransferf,(GLenum pname, GLfloat param), pname, param) DEF_GLX_PROTO(void, glPixelTransferi,(GLenum pname, GLint param), pname, param) DEF_GLX_PROTO(void, glPixelMapfv,(GLenum map, GLsizei mapsize, const GLfloat *values), map, mapsize, values) DEF_GLX_PROTO(void, glPixelMapuiv,(GLenum map, GLsizei mapsize, const GLuint *values), map, mapsize, values) DEF_GLX_PROTO(void, glPixelMapusv,(GLenum map, GLsizei mapsize, const GLushort *values), map, mapsize, values) DEF_GLX_PROTO(void, glGetPixelMapfv,(GLenum map, GLfloat *values), map, values) DEF_GLX_PROTO(void, glGetPixelMapuiv,(GLenum map, GLuint *values), map, values) DEF_GLX_PROTO(void, glGetPixelMapusv,(GLenum map, GLushort *values), map, values) DEF_GLX_PROTO(void, glBitmap,(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap), width, height, xorig, yorig, xmove, ymove, bitmap) DEF_GLX_PROTO(void, glReadPixels,(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels), x, y, width, height, format, type, pixels) DEF_GLX_PROTO(void, glDrawPixels,(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels), width, height, format, type, pixels) DEF_GLX_PROTO(void, glCopyPixels,(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type), x, y, width, height, type) DEF_GLX_PROTO(void, glStencilFunc,(GLenum func, GLint ref, GLuint mask), func, ref, mask) DEF_GLX_PROTO(void, glStencilMask,(GLuint mask), mask) DEF_GLX_PROTO(void, glStencilOp,(GLenum fail, GLenum zfail, GLenum zpass), fail, zfail, zpass) DEF_GLX_PROTO(void, glClearStencil,(GLint s), s) DEF_GLX_PROTO(void, glTexGend,(GLenum coord, GLenum pname, GLdouble param), coord, pname, param) DEF_GLX_PROTO(void, glTexGenf,(GLenum coord, GLenum pname, GLfloat param), coord, pname, param) DEF_GLX_PROTO(void, glTexGeni,(GLenum coord, GLenum pname, GLint param), coord, pname, param) DEF_GLX_PROTO(void, glTexGendv,(GLenum coord, GLenum pname, const GLdouble *params), coord, pname, params) DEF_GLX_PROTO(void, glTexGenfv,(GLenum coord, GLenum pname, const GLfloat *params), coord, pname, params) DEF_GLX_PROTO(void, glTexGeniv,(GLenum coord, GLenum pname, const GLint *params), coord, pname, params) DEF_GLX_PROTO(void, glGetTexGendv,(GLenum coord, GLenum pname, GLdouble *params), coord, pname, params) DEF_GLX_PROTO(void, glGetTexGenfv,(GLenum coord, GLenum pname, GLfloat *params), coord, pname, params) DEF_GLX_PROTO(void, glGetTexGeniv,(GLenum coord, GLenum pname, GLint *params), coord, pname, params) DEF_GLX_PROTO(void, glTexEnvf,(GLenum target, GLenum pname, GLfloat param), target, pname, param) DEF_GLX_PROTO(void, glTexEnvi,(GLenum target, GLenum pname, GLint param), target, pname, param) DEF_GLX_PROTO(void, glTexEnvfv,(GLenum target, GLenum pname, const GLfloat *params), target, pname, params) DEF_GLX_PROTO(void, glTexEnviv,(GLenum target, GLenum pname, const GLint *params), target, pname, params) DEF_GLX_PROTO(void, glGetTexEnvfv,(GLenum target, GLenum pname, GLfloat *params), target, pname, params) DEF_GLX_PROTO(void, glGetTexEnviv,(GLenum target, GLenum pname, GLint *params), target, pname, params) DEF_GLX_PROTO(void, glTexParameterf,(GLenum target, GLenum pname, GLfloat param), target, pname, param) DEF_GLX_PROTO(void, glTexParameteri,(GLenum target, GLenum pname, GLint param), target, pname, param) DEF_GLX_PROTO(void, glTexParameterfv,(GLenum target, GLenum pname, const GLfloat *params), target, pname, params) DEF_GLX_PROTO(void, glTexParameteriv,(GLenum target, GLenum pname, const GLint *params), target, pname, params) DEF_GLX_PROTO(void, glGetTexParameterfv,(GLenum target, GLenum pname, GLfloat *params), target, pname, params) DEF_GLX_PROTO(void, glGetTexParameteriv,(GLenum target, GLenum pname, GLint *params), target, pname, params) DEF_GLX_PROTO(void, glGetTexLevelParameterfv,(GLenum target, GLint level, GLenum pname, GLfloat *params), target, level, pname, params) DEF_GLX_PROTO(void, glGetTexLevelParameteriv,(GLenum target, GLint level, GLenum pname, GLint *params), target, level, pname, params) DEF_GLX_PROTO(void, glTexImage1D,(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels), target, level, internalFormat, width, border, format, type, pixels) DEF_GLX_PROTO(void, glTexImage2D,(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels), target, level, internalFormat, width, height, border, format, type, pixels) DEF_GLX_PROTO(void, glGetTexImage,(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels), target, level, format, type, pixels) DEF_GLX_PROTO(void, glGenTextures,(GLsizei n, GLuint *textures), n, textures) DEF_GLX_PROTO(void, glDeleteTextures,(GLsizei n, const GLuint *textures), n, textures) DEF_GLX_PROTO(void, glBindTexture,(GLenum target, GLuint texture), target, texture) DEF_GLX_PROTO(void, glPrioritizeTextures,(GLsizei n, const GLuint *textures, const GLclampf *priorities), n, textures, priorities) DEF_GLX_PROTO(GLboolean, glAreTexturesResident,(GLsizei n, const GLuint *textures, GLboolean *residences), n, textures, residences) DEF_GLX_PROTO(GLboolean, glIsTexture,(GLuint texture), texture) DEF_GLX_PROTO(void, glTexSubImage1D,(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels), target, level, xoffset, width, format, type, pixels) DEF_GLX_PROTO(void, glTexSubImage2D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels), target, level, xoffset, yoffset, width, height, format, type, pixels) DEF_GLX_PROTO(void, glCopyTexImage1D,(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border), target, level, internalformat, x, y, width, border) DEF_GLX_PROTO(void, glCopyTexImage2D,(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border), target, level, internalformat, x, y, width, height, border) DEF_GLX_PROTO(void, glCopyTexSubImage1D,(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width), target, level, xoffset, x, y, width) DEF_GLX_PROTO(void, glCopyTexSubImage2D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height), target, level, xoffset, yoffset, x, y, width, height) DEF_GLX_PROTO(void, glMap1d,(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points), target, u1, u2, stride, order, points) DEF_GLX_PROTO(void, glMap1f,(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points), target, u1, u2, stride, order, points) DEF_GLX_PROTO(void, glMap2d,(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points), target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points) DEF_GLX_PROTO(void, glMap2f,(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points), target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points) DEF_GLX_PROTO(void, glGetMapdv,(GLenum target, GLenum query, GLdouble *v), target, query, v) DEF_GLX_PROTO(void, glGetMapfv,(GLenum target, GLenum query, GLfloat *v), target, query, v) DEF_GLX_PROTO(void, glGetMapiv,(GLenum target, GLenum query, GLint *v), target, query, v) DEF_GLX_PROTO(void, glEvalCoord1d,(GLdouble u), u) DEF_GLX_PROTO(void, glEvalCoord1f,(GLfloat u), u) DEF_GLX_PROTO(void, glEvalCoord1dv,(const GLdouble *u), u) DEF_GLX_PROTO(void, glEvalCoord1fv,(const GLfloat *u), u) DEF_GLX_PROTO(void, glEvalCoord2d,(GLdouble u, GLdouble v), u, v) DEF_GLX_PROTO(void, glEvalCoord2f,(GLfloat u, GLfloat v), u, v) DEF_GLX_PROTO(void, glEvalCoord2dv,(const GLdouble *u), u) DEF_GLX_PROTO(void, glEvalCoord2fv,(const GLfloat *u), u) DEF_GLX_PROTO(void, glMapGrid1d,(GLint un, GLdouble u1, GLdouble u2), un, u1, u2) DEF_GLX_PROTO(void, glMapGrid1f,(GLint un, GLfloat u1, GLfloat u2), un, u1, u2) DEF_GLX_PROTO(void, glMapGrid2d,(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2), un, u1, u2, vn, v1, v2) DEF_GLX_PROTO(void, glMapGrid2f,(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2), un, u1, u2, vn, v1, v2) DEF_GLX_PROTO(void, glEvalPoint1,(GLint i), i) DEF_GLX_PROTO(void, glEvalPoint2,(GLint i, GLint j), i, j) DEF_GLX_PROTO(void, glEvalMesh1,(GLenum mode, GLint i1, GLint i2), mode, i1, i2) DEF_GLX_PROTO(void, glEvalMesh2,(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2), mode, i1, i2, j1, j2) DEF_GLX_PROTO(void, glFogf,(GLenum pname, GLfloat param), pname, param) DEF_GLX_PROTO(void, glFogi,(GLenum pname, GLint param), pname, param) DEF_GLX_PROTO(void, glFogfv,(GLenum pname, const GLfloat *params), pname, params) DEF_GLX_PROTO(void, glFogiv,(GLenum pname, const GLint *params), pname, params) DEF_GLX_PROTO(void, glFeedbackBuffer,(GLsizei size, GLenum type, GLfloat *buffer), size, type, buffer) DEF_GLX_PROTO(void, glPassThrough,(GLfloat token), token) DEF_GLX_PROTO(void, glSelectBuffer,(GLsizei size, GLuint *buffer), size, buffer) DEF_GLX_PROTO(void, glInitNames,(void)) DEF_GLX_PROTO(void, glLoadName,(GLuint name), name) DEF_GLX_PROTO(void, glPushName,(GLuint name), name) DEF_GLX_PROTO(void, glPopName,(void)) DEF_GLX_PROTO(void, glDrawRangeElements,(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices), mode, start, end, count, type, indices) DEF_GLX_PROTO(void, glTexImage3D,(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels), target, level, internalFormat, width, height, depth, border, format, type, pixels) DEF_GLX_PROTO(void, glTexSubImage3D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels), target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) DEF_GLX_PROTO(void, glCopyTexSubImage3D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height), target, level, xoffset, yoffset, zoffset, x, y, width, height) DEF_GLX_PROTO(void, glColorTable,(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table), target, internalformat, width, format, type, table) DEF_GLX_PROTO(void, glColorSubTable,(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data), target, start, count, format, type, data) DEF_GLX_PROTO(void, glColorTableParameteriv,(GLenum target, GLenum pname, const GLint *params), target, pname, params) DEF_GLX_PROTO(void, glColorTableParameterfv,(GLenum target, GLenum pname, const GLfloat *params), target, pname, params) DEF_GLX_PROTO(void, glCopyColorSubTable,(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width), target, start, x, y, width) DEF_GLX_PROTO(void, glCopyColorTable,(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width), target, internalformat, x, y, width) DEF_GLX_PROTO(void, glGetColorTable,(GLenum target, GLenum format, GLenum type, GLvoid *table), target, format, type, table) DEF_GLX_PROTO(void, glGetColorTableParameterfv,(GLenum target, GLenum pname, GLfloat *params), target, pname, params) DEF_GLX_PROTO(void, glGetColorTableParameteriv,(GLenum target, GLenum pname, GLint *params), target, pname, params) DEF_GLX_PROTO(void, glBlendEquation,(GLenum mode), mode) DEF_GLX_PROTO(void, glBlendColor,(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha), red, green, blue, alpha) DEF_GLX_PROTO(void, glHistogram,(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink), target, width, internalformat, sink) DEF_GLX_PROTO(void, glResetHistogram,(GLenum target), target) DEF_GLX_PROTO(void, glGetHistogram,(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values), target, reset, format, type, values) DEF_GLX_PROTO(void, glGetHistogramParameterfv,(GLenum target, GLenum pname, GLfloat *params), target, pname, params) DEF_GLX_PROTO(void, glGetHistogramParameteriv,(GLenum target, GLenum pname, GLint *params), target, pname, params) DEF_GLX_PROTO(void, glMinmax,(GLenum target, GLenum internalformat, GLboolean sink), target, internalformat, sink) DEF_GLX_PROTO(void, glResetMinmax,(GLenum target), target) DEF_GLX_PROTO(void, glGetMinmax,(GLenum target, GLboolean reset, GLenum format, GLenum types, GLvoid *values), target, reset, format, types, values) DEF_GLX_PROTO(void, glGetMinmaxParameterfv,(GLenum target, GLenum pname, GLfloat *params), target, pname, params) DEF_GLX_PROTO(void, glGetMinmaxParameteriv,(GLenum target, GLenum pname, GLint *params), target, pname, params) DEF_GLX_PROTO(void, glConvolutionFilter1D,(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image), target, internalformat, width, format, type, image) DEF_GLX_PROTO(void, glConvolutionFilter2D,(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image), target, internalformat, width, height, format, type, image) DEF_GLX_PROTO(void, glConvolutionParameterf,(GLenum target, GLenum pname, GLfloat params), target, pname, params) DEF_GLX_PROTO(void, glConvolutionParameterfv,(GLenum target, GLenum pname, const GLfloat *params), target, pname, params) DEF_GLX_PROTO(void, glConvolutionParameteri,(GLenum target, GLenum pname, GLint params), target, pname, params) DEF_GLX_PROTO(void, glConvolutionParameteriv,(GLenum target, GLenum pname, const GLint *params), target, pname, params) DEF_GLX_PROTO(void, glCopyConvolutionFilter1D,(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width), target, internalformat, x, y, width) DEF_GLX_PROTO(void, glCopyConvolutionFilter2D,(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height), target, internalformat, x, y, width, height) DEF_GLX_PROTO(void, glGetConvolutionFilter,(GLenum target, GLenum format, GLenum type, GLvoid *image), target, format, type, image) DEF_GLX_PROTO(void, glGetConvolutionParameterfv,(GLenum target, GLenum pname, GLfloat *params), target, pname, params) DEF_GLX_PROTO(void, glGetConvolutionParameteriv,(GLenum target, GLenum pname, GLint *params), target, pname, params) DEF_GLX_PROTO(void, glSeparableFilter2D,(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column), target, internalformat, width, height, format, type, row, column) DEF_GLX_PROTO(void, glGetSeparableFilter,(GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span), target, format, type, row, column, span) DEF_GLX_PROTO(void, glActiveTexture,(GLenum texture), texture) DEF_GLX_PROTO(void, glClientActiveTexture,(GLenum texture), texture) DEF_GLX_PROTO(void, glCompressedTexImage1D,(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data), target, level, internalformat, width, border, imageSize, data) DEF_GLX_PROTO(void, glCompressedTexImage2D,(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data), target, level, internalformat, width, height, border, imageSize, data) DEF_GLX_PROTO(void, glCompressedTexImage3D,(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data), target, level, internalformat, width, height, depth, border, imageSize, data) DEF_GLX_PROTO(void, glCompressedTexSubImage1D,(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data), target, level, xoffset, width, format, imageSize, data) DEF_GLX_PROTO(void, glCompressedTexSubImage2D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data), target, level, xoffset, yoffset, width, height, format, imageSize, data) DEF_GLX_PROTO(void, glCompressedTexSubImage3D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data), target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data) DEF_GLX_PROTO(void, glGetCompressedTexImage,(GLenum target, GLint lod, GLvoid *img), target, lod, img) DEF_GLX_PROTO(void, glMultiTexCoord1d,(GLenum target, GLdouble s), target, s) DEF_GLX_PROTO(void, glMultiTexCoord1dv,(GLenum target, const GLdouble *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord1f,(GLenum target, GLfloat s), target, s) DEF_GLX_PROTO(void, glMultiTexCoord1fv,(GLenum target, const GLfloat *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord1i,(GLenum target, GLint s), target, s) DEF_GLX_PROTO(void, glMultiTexCoord1iv,(GLenum target, const GLint *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord1s,(GLenum target, GLshort s), target, s) DEF_GLX_PROTO(void, glMultiTexCoord1sv,(GLenum target, const GLshort *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord2d,(GLenum target, GLdouble s, GLdouble t), target, s, t) DEF_GLX_PROTO(void, glMultiTexCoord2dv,(GLenum target, const GLdouble *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord2f,(GLenum target, GLfloat s, GLfloat t), target, s, t) DEF_GLX_PROTO(void, glMultiTexCoord2fv,(GLenum target, const GLfloat *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord2i,(GLenum target, GLint s, GLint t), target, s, t) DEF_GLX_PROTO(void, glMultiTexCoord2iv,(GLenum target, const GLint *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord2s,(GLenum target, GLshort s, GLshort t), target, s, t) DEF_GLX_PROTO(void, glMultiTexCoord2sv,(GLenum target, const GLshort *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord3d,(GLenum target, GLdouble s, GLdouble t, GLdouble r), target, s, t, r) DEF_GLX_PROTO(void, glMultiTexCoord3dv,(GLenum target, const GLdouble *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord3f,(GLenum target, GLfloat s, GLfloat t, GLfloat r), target, s, t, r) DEF_GLX_PROTO(void, glMultiTexCoord3fv,(GLenum target, const GLfloat *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord3i,(GLenum target, GLint s, GLint t, GLint r), target, s, t, r) DEF_GLX_PROTO(void, glMultiTexCoord3iv,(GLenum target, const GLint *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord3s,(GLenum target, GLshort s, GLshort t, GLshort r), target, s, t, r) DEF_GLX_PROTO(void, glMultiTexCoord3sv,(GLenum target, const GLshort *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord4d,(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q), target, s, t, r, q) DEF_GLX_PROTO(void, glMultiTexCoord4dv,(GLenum target, const GLdouble *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord4f,(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q), target, s, t, r, q) DEF_GLX_PROTO(void, glMultiTexCoord4fv,(GLenum target, const GLfloat *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord4i,(GLenum target, GLint s, GLint t, GLint r, GLint q), target, s, t, r, q) DEF_GLX_PROTO(void, glMultiTexCoord4iv,(GLenum target, const GLint *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord4s,(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q), target, s, t, r, q) DEF_GLX_PROTO(void, glMultiTexCoord4sv,(GLenum target, const GLshort *v), target, v) DEF_GLX_PROTO(void, glLoadTransposeMatrixd,(const GLdouble m[16]), m) DEF_GLX_PROTO(void, glLoadTransposeMatrixf,(const GLfloat m[16]), m) DEF_GLX_PROTO(void, glMultTransposeMatrixd,(const GLdouble m[16]), m) DEF_GLX_PROTO(void, glMultTransposeMatrixf,(const GLfloat m[16]), m) DEF_GLX_PROTO(void, glSampleCoverage,(GLclampf value, GLboolean invert), value, invert) DEF_GLX_PROTO(void, glActiveTextureARB,(GLenum texture), texture) DEF_GLX_PROTO(void, glClientActiveTextureARB,(GLenum texture), texture) DEF_GLX_PROTO(void, glMultiTexCoord1dARB,(GLenum target, GLdouble s), target, s) DEF_GLX_PROTO(void, glMultiTexCoord1dvARB,(GLenum target, const GLdouble *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord1fARB,(GLenum target, GLfloat s), target, s) DEF_GLX_PROTO(void, glMultiTexCoord1fvARB,(GLenum target, const GLfloat *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord1iARB,(GLenum target, GLint s), target, s) DEF_GLX_PROTO(void, glMultiTexCoord1ivARB,(GLenum target, const GLint *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord1sARB,(GLenum target, GLshort s), target, s) DEF_GLX_PROTO(void, glMultiTexCoord1svARB,(GLenum target, const GLshort *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord2dARB,(GLenum target, GLdouble s, GLdouble t), target, s, t) DEF_GLX_PROTO(void, glMultiTexCoord2dvARB,(GLenum target, const GLdouble *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord2fARB,(GLenum target, GLfloat s, GLfloat t), target, s, t) DEF_GLX_PROTO(void, glMultiTexCoord2fvARB,(GLenum target, const GLfloat *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord2iARB,(GLenum target, GLint s, GLint t), target, s, t) DEF_GLX_PROTO(void, glMultiTexCoord2ivARB,(GLenum target, const GLint *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord2sARB,(GLenum target, GLshort s, GLshort t), target, s, t) DEF_GLX_PROTO(void, glMultiTexCoord2svARB,(GLenum target, const GLshort *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord3dARB,(GLenum target, GLdouble s, GLdouble t, GLdouble r), target, s, t, r) DEF_GLX_PROTO(void, glMultiTexCoord3dvARB,(GLenum target, const GLdouble *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord3fARB,(GLenum target, GLfloat s, GLfloat t, GLfloat r), target, s, t, r) DEF_GLX_PROTO(void, glMultiTexCoord3fvARB,(GLenum target, const GLfloat *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord3iARB,(GLenum target, GLint s, GLint t, GLint r), target, s, t, r) DEF_GLX_PROTO(void, glMultiTexCoord3ivARB,(GLenum target, const GLint *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord3sARB,(GLenum target, GLshort s, GLshort t, GLshort r), target, s, t, r) DEF_GLX_PROTO(void, glMultiTexCoord3svARB,(GLenum target, const GLshort *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord4dARB,(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q), target, s, t, r, q) DEF_GLX_PROTO(void, glMultiTexCoord4dvARB,(GLenum target, const GLdouble *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord4fARB,(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q), target, s, t, r, q) DEF_GLX_PROTO(void, glMultiTexCoord4fvARB,(GLenum target, const GLfloat *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord4iARB,(GLenum target, GLint s, GLint t, GLint r, GLint q), target, s, t, r, q) DEF_GLX_PROTO(void, glMultiTexCoord4ivARB,(GLenum target, const GLint *v), target, v) DEF_GLX_PROTO(void, glMultiTexCoord4sARB,(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q), target, s, t, r, q) DEF_GLX_PROTO(void, glMultiTexCoord4svARB,(GLenum target, const GLshort *v), target, v) primus-0~20150328/gl-needed.def0000644000175000017500000000147712555052336015776 0ustar vincentvincent// OpenGL extension functions needed by primus itself DEF_GLX_PROTO(void, glGenBuffers, (GLsizei n, GLuint *buffers)) DEF_GLX_PROTO(void, glDeleteBuffers, (GLsizei n, const GLuint *buffers)) DEF_GLX_PROTO(void, glBindBuffer, (GLenum target, GLuint buffer)) DEF_GLX_PROTO(void, glBufferData, (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)) DEF_GLX_PROTO(void, glBufferSubData, (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)) DEF_GLX_PROTO(GLvoid*, glMapBuffer, (GLenum target, GLenum access)) DEF_GLX_PROTO(GLboolean,glUnmapBuffer,(GLenum target)) DEF_GLX_PROTO(GLsync, glFenceSync, (GLenum condition, GLbitfield flags)) DEF_GLX_PROTO(void, glDeleteSync,(GLsync sync)) DEF_GLX_PROTO(void, glWaitSync, (GLsync sync, GLbitfield flags, GLuint64 timeout)) primus-0~20150328/README.md0000644000175000017500000000600212555052336014736 0ustar vincentvincentprimus ====== Primus is a shared library that provides OpenGL and GLX APIs and implements low-overhead local-only client-side OpenGL offloading via GLX forking, similar to VirtualGL. It intercepts GLX calls and redirects GL rendering to a secondary X display, presumably driven by a faster GPU. On swapping buffers, rendered contents are read back using a PBO and copied onto the drawable it was supposed to be rendered on in the first place. For more information, refer to [technotes.md] (https://github.com/amonakov/primus/blob/master/technotes.md). To use, install or build from source and use `primusrun` wrapper script. In distributions ---------------- * Arch: [primus-git](https://aur.archlinux.org/packages.php?ID=63239) and [lib32-primus-git](https://aur.archlinux.org/packages.php?ID=63240) in AUR * Gentoo: `primus-9999.ebuild` in the `bumblebee` overlay * Ubuntu: in the [Bumblebee PPA](https://launchpad.net/~bumblebee/+archive/stable) Building for multilib (32-bit + 64-bit) systems ----------------------------------------------- LIBDIR=lib make && CXX=g++\ -m32 LIBDIR=lib32 make Adjust `LIBDIR` variables above as appropriate for your distribution (reflecting how `/usr/lib*` are named): * Arch needs `lib` and `lib32` as above * Gentoo needs `lib64` and `lib32` * RPM-based may need `lib64` and `lib` * Debian (with multiarch) needs `lib/x86_64-linux-gnu` and `lib/i386-linux-gnu` * Ubuntu (with multiarch) seems rather inconsistent. The dynamic linker expands `$LIB` to `x86_64-linux-gnu`/`i386-linux-gnu` (without `lib/`), but Nvidia drivers are installed into `/usr/lib{,32}/nvidia-current`. Something like the following is needed: export PRIMUS_libGLd='/usr/lib/$$LIB/mesa/libGL.so.1' LIBDIR=x86_64-linux-gnu make LIBDIR=i386-linux-gnu CXX=g++\ -m32 make unset PRIMUS_libGLd Starting from 13.04, Ubuntu needs the same `LIBDIR` paths as Debian (with leading `lib/`); consequently, `lib/` in `PRIMUS_libGLd` should be omitted. Furthermore, `libnvidia-tls.so` is not present in default shared library search directories. Uncomment the corresponding line in `primusrun`. Issues under compositing WMs ---------------------------- Since compositing hurts performance, invoking primus when a compositing WM is active is not recommended. If you need to use primus with compositing and see flickering or bad performance, synchronizing primus' display thread with the application's rendering thread may help (can anyone investigate why?): PRIMUS_SYNC=1 primusrun ... This makes primus display the previously rendered frame. Alternatively, with `PRIMUS_SYNC=2` primus will display the latest rendered frame, trading frame rate for reduced visual latency. FAQ --- Q: Performance does not exceed 60 fps, I was getting more with optirun/VirtualGL. A: This is the effect of vblank synchronisation. For benchmarking, you can use `vblank_mode=0 primusrun ...`, but in practice this will probably only waste power, as your LCD panel does not display more than 60 frames per second anyway. primus-0~20150328/Makefile0000644000175000017500000000226212555052336015123 0ustar vincentvincentCXX ?= g++ CXXFLAGS ?= -Wall -g CXXFLAGS += -Werror=missing-declarations CXXFLAGS += -Werror=attributes # On multilib systems, this needs to point to distribution-specific library # subdir like in /usr (lib or lib64 for 64-bit, lib32 or lib for 32-bit) LIBDIR ?= lib BUMBLEBEE_SOCKET ?= /var/run/bumblebee.socket PRIMUS_SYNC ?= 0 PRIMUS_VERBOSE ?= 1 PRIMUS_UPLOAD ?= 0 PRIMUS_SLEEP ?= 90 PRIMUS_DISPLAY ?= :8 PRIMUS_LOAD_GLOBAL ?= libglapi.so.0 PRIMUS_libGLa ?= /usr/$$LIB/nvidia/libGL.so.1 PRIMUS_libGLd ?= /usr/$$LIB/libGL.so.1 CXXFLAGS += -DBUMBLEBEE_SOCKET='"$(BUMBLEBEE_SOCKET)"' CXXFLAGS += -DPRIMUS_SYNC='"$(PRIMUS_SYNC)"' CXXFLAGS += -DPRIMUS_VERBOSE='"$(PRIMUS_VERBOSE)"' CXXFLAGS += -DPRIMUS_UPLOAD='"$(PRIMUS_UPLOAD)"' CXXFLAGS += -DPRIMUS_SLEEP='"$(PRIMUS_SLEEP)"' CXXFLAGS += -DPRIMUS_DISPLAY='"$(PRIMUS_DISPLAY)"' CXXFLAGS += -DPRIMUS_LOAD_GLOBAL='"$(PRIMUS_LOAD_GLOBAL)"' CXXFLAGS += -DPRIMUS_libGLa='"$(PRIMUS_libGLa)"' CXXFLAGS += -DPRIMUS_libGLd='"$(PRIMUS_libGLd)"' $(LIBDIR)/libGL.so.1: libglfork.cpp mkdir -p $(LIBDIR) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -fvisibility=hidden -fPIC -shared -Wl,-Bsymbolic -o $@ $< -lX11 -lpthread -lrt primus-0~20150328/LICENSE.txt0000644000175000017500000000136612555052336015312 0ustar vincentvincentCopyright (c) 2012, Alexander Monakov Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.