Conflicts due to DRI1 removal: src/mesa/drivers/dri/intel/intel_context.c src/mesa/drivers/dri/intel/intel_screen.ctags/7.8-rc1
@@ -20,7 +20,7 @@ AC_CANONICAL_HOST | |||
dnl Versions for external dependencies | |||
LIBDRM_REQUIRED=2.4.15 | |||
LIBDRM_RADEON_REQUIRED=2.4.17 | |||
DRI2PROTO_REQUIRED=1.99.3 | |||
DRI2PROTO_REQUIRED=2.2 | |||
dnl Check for progs | |||
AC_PROG_CPP |
@@ -186,6 +186,16 @@ typedef XID GLXWindow; | |||
typedef XID GLXPbuffer; | |||
/* | |||
** Events. | |||
** __GLX_NUMBER_EVENTS is set to 17 to account for the BufferClobberSGIX | |||
** event - this helps initialization if the server supports the pbuffer | |||
** extension and the client doesn't. | |||
*/ | |||
#define GLX_PbufferClobber 0 | |||
#define GLX_BufferSwapComplete 1 | |||
#define __GLX_NUMBER_EVENTS 17 | |||
extern XVisualInfo* glXChooseVisual( Display *dpy, int screen, | |||
int *attribList ); | |||
@@ -507,8 +517,17 @@ typedef struct { | |||
int count; /* if nonzero, at least this many more */ | |||
} GLXPbufferClobberEvent; | |||
typedef struct { | |||
int event_type; | |||
GLXDrawable drawable; | |||
int64_t ust; | |||
int64_t msc; | |||
int64_t sbc; | |||
} GLXBufferSwapComplete; | |||
typedef union __GLXEvent { | |||
GLXPbufferClobberEvent glxpbufferclobber; | |||
GLXBufferSwapComplete glxbufferswapcomplete; | |||
long pad[24]; | |||
} GLXEvent; | |||
@@ -696,6 +696,14 @@ extern void glXJoinSwapGroupSGIX (Display *, GLXDrawable, GLXDrawable); | |||
typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member); | |||
#endif | |||
#ifndef GLX_INTEL_swap_event | |||
#define GLX_INTEL_swap_event | |||
#define GLX_BUFFER_SWAP_COMPLETE_MASK 0x10000000 | |||
#define GLX_EXCHANGE_COMPLETE 0x8024 | |||
#define GLX_BLIT_COMPLETE 0x8025 | |||
#define GLX_FLIP_COMPLETE 0x8026 | |||
#endif | |||
#ifndef GLX_SGIX_swap_barrier | |||
#define GLX_SGIX_swap_barrier 1 | |||
#ifdef GLX_GLXEXT_PROTOTYPES |
@@ -262,10 +262,22 @@ struct __DRItexBufferExtensionRec { | |||
* Used by drivers that implement DRI2 | |||
*/ | |||
#define __DRI2_FLUSH "DRI2_Flush" | |||
#define __DRI2_FLUSH_VERSION 1 | |||
#define __DRI2_FLUSH_VERSION 2 | |||
struct __DRI2flushExtensionRec { | |||
__DRIextension base; | |||
void (*flush)(__DRIdrawable *drawable); | |||
/** | |||
* Flush all rendering queue in the driver to the drm and | |||
* invalidate all buffers. The driver will call out to | |||
* getBuffers/getBuffersWithFormat before it starts rendering | |||
* again. | |||
* | |||
* \param drawable the drawable to flush and invalidate | |||
* | |||
* \since 2 | |||
*/ | |||
void (*flushInvalidate)(__DRIdrawable *drawable); | |||
}; | |||
@@ -26,3 +26,4 @@ xdemo | |||
xfont | |||
xrotfontdemo | |||
yuvrect_client | |||
msctest |
@@ -29,6 +29,7 @@ PROGS = \ | |||
glxsnoop \ | |||
glxswapcontrol \ | |||
manywin \ | |||
msctest \ | |||
multictx \ | |||
offset \ | |||
overlay \ |
@@ -59,6 +59,7 @@ | |||
void (*video_sync_get)(); | |||
void (*video_sync)(); | |||
void (*swap_interval)(); | |||
static int GLXExtensionSupported(Display *dpy, const char *extension) | |||
{ | |||
@@ -84,7 +85,7 @@ static int GLXExtensionSupported(Display *dpy, const char *extension) | |||
extern char *optarg; | |||
extern int optind, opterr, optopt; | |||
static char optstr[] = "w:h:s:v"; | |||
static char optstr[] = "w:h:s:vi:"; | |||
enum sync_type { | |||
none = 0, | |||
@@ -100,6 +101,7 @@ static void usage(char *name) | |||
printf("\t\tn: none\n"); | |||
printf("\t\ts: SGI video sync extension\n"); | |||
printf("\t\tb: buffer swap\n"); | |||
printf("\t-i<swap interval>\n"); | |||
printf("\t-v: verbose (print count)\n"); | |||
exit(-1); | |||
} | |||
@@ -109,16 +111,28 @@ int main(int argc, char *argv[]) | |||
Display *disp; | |||
XVisualInfo *pvi; | |||
XSetWindowAttributes swa; | |||
int attrib[14]; | |||
GLint last_val = -1, count = 0; | |||
Window winGL; | |||
GLXContext context; | |||
int dummy; | |||
Atom wmDelete; | |||
enum sync_type waitforsync = none; | |||
int width = 500, height = 500, verbose = 0, | |||
countonly = 0; | |||
int width = 500, height = 500, verbose = 0, interval = 1; | |||
int c, i = 1; | |||
int ret; | |||
int attribs[] = { GLX_RGBA, | |||
GLX_RED_SIZE, 1, | |||
GLX_GREEN_SIZE, 1, | |||
GLX_BLUE_SIZE, 1, | |||
None }; | |||
int db_attribs[] = { GLX_RGBA, | |||
GLX_RED_SIZE, 1, | |||
GLX_GREEN_SIZE, 1, | |||
GLX_BLUE_SIZE, 1, | |||
GLX_DOUBLEBUFFER, | |||
GLX_DEPTH_SIZE, 1, | |||
None }; | |||
XSizeHints sizehints; | |||
opterr = 0; | |||
while ((c = getopt(argc, argv, optstr)) != -1) { | |||
@@ -148,6 +162,9 @@ int main(int argc, char *argv[]) | |||
case 'v': | |||
verbose = 1; | |||
break; | |||
case 'i': | |||
interval = atoi(optarg); | |||
break; | |||
default: | |||
usage(argv[0]); | |||
break; | |||
@@ -170,34 +187,17 @@ int main(int argc, char *argv[]) | |||
return -1; | |||
} | |||
attrib[0] = GLX_RGBA; | |||
attrib[1] = 1; | |||
attrib[2] = GLX_RED_SIZE; | |||
attrib[3] = 1; | |||
attrib[4] = GLX_GREEN_SIZE; | |||
attrib[5] = 1; | |||
attrib[6] = GLX_BLUE_SIZE; | |||
attrib[7] = 1; | |||
if (waitforsync != buffer_swap) | |||
attrib[8] = None; | |||
else { | |||
attrib[8] = GLX_DOUBLEBUFFER; | |||
attrib[9] = 1; | |||
attrib[10] = None; | |||
if (waitforsync != buffer_swap) { | |||
pvi = glXChooseVisual(disp, DefaultScreen(disp), attribs); | |||
} else { | |||
pvi = glXChooseVisual(disp, DefaultScreen(disp), db_attribs); | |||
} | |||
pvi = glXChooseVisual(disp, DefaultScreen(disp), attrib); | |||
if (!pvi) { | |||
fprintf(stderr, "failed to choose visual, exiting\n"); | |||
return -1; | |||
} | |||
context = glXCreateContext(disp, pvi, None, GL_TRUE); | |||
if (!context) { | |||
fprintf(stderr, "failed to create glx context\n"); | |||
return -1; | |||
} | |||
pvi->screen = DefaultScreen(disp); | |||
swa.colormap = XCreateColormap(disp, RootWindow(disp, pvi->screen), | |||
@@ -217,24 +217,58 @@ int main(int argc, char *argv[]) | |||
wmDelete = XInternAtom(disp, "WM_DELETE_WINDOW", True); | |||
XSetWMProtocols(disp, winGL, &wmDelete, 1); | |||
sizehints.x = 0; | |||
sizehints.y = 0; | |||
sizehints.width = width; | |||
sizehints.height = height; | |||
sizehints.flags = USSize | USPosition; | |||
XSetNormalHints(disp, winGL, &sizehints); | |||
XSetStandardProperties(disp, winGL, "glsync test", "glsync text", | |||
None, NULL, 0, NULL); | |||
None, NULL, 0, &sizehints); | |||
XMapRaised(disp, winGL); | |||
context = glXCreateContext(disp, pvi, NULL, GL_TRUE); | |||
if (!context) { | |||
fprintf(stderr, "failed to create glx context\n"); | |||
return -1; | |||
} | |||
glXMakeCurrent(disp, winGL, context); | |||
XMapWindow(disp, winGL); | |||
ret = glXMakeCurrent(disp, winGL, context); | |||
if (ret) { | |||
fprintf(stderr, "failed to make context current: %d\n", ret); | |||
} | |||
video_sync_get = glXGetProcAddress((unsigned char *)"glXGetVideoSyncSGI"); | |||
video_sync = glXGetProcAddress((unsigned char *)"glXWaitVideoSyncSGI"); | |||
if (!video_sync_get || !video_sync) { | |||
swap_interval = glXGetProcAddress((unsigned char *)"glXSwapIntervalSGI"); | |||
if (!video_sync_get || !video_sync || !swap_interval) { | |||
fprintf(stderr, "failed to get sync functions\n"); | |||
return -1; | |||
} | |||
if (waitforsync == buffer_swap) { | |||
swap_interval(interval); | |||
fprintf(stderr, "set swap interval to %d\n", interval); | |||
} | |||
video_sync_get(&count); | |||
count++; | |||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |||
while (i++) { | |||
/* Alternate colors to make tearing obvious */ | |||
if (i & 1) { | |||
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); | |||
glColor3f(1.0f, 1.0f, 1.0f); | |||
} else { | |||
glClearColor(1.0f, 0.0f, 0.0f, 0.0f); | |||
glColor3f(1.0f, 0.0f, 0.0f); | |||
} | |||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |||
glRectf(0, 0, width, height); | |||
/* Wait for vsync */ | |||
if (waitforsync == sgi_video_sync) { | |||
if (verbose) | |||
@@ -245,24 +279,19 @@ int main(int argc, char *argv[]) | |||
if (count == last_val) | |||
fprintf(stderr, "error: count didn't change: %d\n", count); | |||
last_val = count; | |||
glFlush(); | |||
} else if (waitforsync == buffer_swap) { | |||
glXSwapBuffers(disp, winGL); | |||
} else { | |||
video_sync_get(&count); | |||
sleep(1); | |||
glFinish(); | |||
} | |||
if (countonly) { | |||
video_sync(2, 1, &count); | |||
if (verbose) { | |||
video_sync_get(&count); | |||
fprintf(stderr, "current count: %d\n", count); | |||
sleep(1); | |||
continue; | |||
} | |||
/* Alternate colors to make tearing obvious */ | |||
if (i & 1) | |||
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); | |||
else | |||
glClearColor(1.0f, 0.0f, 0.0f, 0.0f); | |||
glClear(GL_COLOR_BUFFER_BIT); | |||
glFlush(); | |||
} | |||
XDestroyWindow(disp, winGL); |
@@ -0,0 +1,202 @@ | |||
/* | |||
* Copyright © 2009 Intel Corporation | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |||
* IN THE SOFTWARE. | |||
* | |||
* Authors: | |||
* Jesse Barnes <jesse.barnes@intel.com> | |||
* | |||
*/ | |||
/** @file msctest.c | |||
* Simple test for MSC functionality. | |||
*/ | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <unistd.h> | |||
#include <GL/gl.h> | |||
#include <GL/glu.h> | |||
#include <GL/glx.h> | |||
#include <GL/glxext.h> | |||
#include <X11/X.h> | |||
#include <X11/Xlib.h> | |||
#include <X11/Xutil.h> | |||
void (*get_sync_values)(Display *dpy, Window winGL, int64_t *ust, int64_t *msc, int64_t *sbc); | |||
void (*wait_sync)(Display *dpy, Window winGL, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc); | |||
static int GLXExtensionSupported(Display *dpy, const char *extension) | |||
{ | |||
const char *extensionsString, *client_extensions, *pos; | |||
extensionsString = glXQueryExtensionsString(dpy, DefaultScreen(dpy)); | |||
client_extensions = glXGetClientString(dpy, GLX_EXTENSIONS); | |||
pos = strstr(extensionsString, extension); | |||
if (pos != NULL && (pos == extensionsString || pos[-1] == ' ') && | |||
(pos[strlen(extension)] == ' ' || pos[strlen(extension)] == '\0')) | |||
return 1; | |||
pos = strstr(client_extensions, extension); | |||
if (pos != NULL && (pos == extensionsString || pos[-1] == ' ') && | |||
(pos[strlen(extension)] == ' ' || pos[strlen(extension)] == '\0')) | |||
return 1; | |||
return 0; | |||
} | |||
extern char *optarg; | |||
extern int optind, opterr, optopt; | |||
static char optstr[] = "v"; | |||
static void usage(char *name) | |||
{ | |||
printf("usage: %s\n", name); | |||
exit(-1); | |||
} | |||
int main(int argc, char *argv[]) | |||
{ | |||
Display *disp; | |||
XVisualInfo *pvi; | |||
XSetWindowAttributes swa; | |||
int attrib[14]; | |||
Window winGL; | |||
GLXContext context; | |||
int dummy; | |||
Atom wmDelete; | |||
int verbose = 0, width = 200, height = 200; | |||
int c, i = 1; | |||
int64_t ust, msc, sbc; | |||
opterr = 0; | |||
while ((c = getopt(argc, argv, optstr)) != -1) { | |||
switch (c) { | |||
case 'v': | |||
verbose = 1; | |||
break; | |||
default: | |||
usage(argv[0]); | |||
break; | |||
} | |||
} | |||
disp = XOpenDisplay(NULL); | |||
if (!disp) { | |||
fprintf(stderr, "failed to open display\n"); | |||
return -1; | |||
} | |||
if (!glXQueryExtension(disp, &dummy, &dummy)) { | |||
fprintf(stderr, "glXQueryExtension failed\n"); | |||
return -1; | |||
} | |||
if (!GLXExtensionSupported(disp, "GLX_OML_sync_control")) { | |||
fprintf(stderr, "GLX_OML_sync_control not supported, exiting\n"); | |||
return -1; | |||
} | |||
attrib[0] = GLX_RGBA; | |||
attrib[1] = 1; | |||
attrib[2] = GLX_RED_SIZE; | |||
attrib[3] = 1; | |||
attrib[4] = GLX_GREEN_SIZE; | |||
attrib[5] = 1; | |||
attrib[6] = GLX_BLUE_SIZE; | |||
attrib[7] = 1; | |||
attrib[8] = GLX_DOUBLEBUFFER; | |||
attrib[9] = 1; | |||
attrib[10] = None; | |||
pvi = glXChooseVisual(disp, DefaultScreen(disp), attrib); | |||
if (!pvi) { | |||
fprintf(stderr, "failed to choose visual, exiting\n"); | |||
return -1; | |||
} | |||
context = glXCreateContext(disp, pvi, None, GL_TRUE); | |||
if (!context) { | |||
fprintf(stderr, "failed to create glx context\n"); | |||
return -1; | |||
} | |||
pvi->screen = DefaultScreen(disp); | |||
swa.colormap = XCreateColormap(disp, RootWindow(disp, pvi->screen), | |||
pvi->visual, AllocNone); | |||
swa.border_pixel = 0; | |||
swa.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | | |||
StructureNotifyMask; | |||
winGL = XCreateWindow(disp, RootWindow(disp, pvi->screen), | |||
0, 0, | |||
width, height, | |||
0, pvi->depth, InputOutput, pvi->visual, | |||
CWBorderPixel | CWColormap | CWEventMask, &swa); | |||
if (!winGL) { | |||
fprintf(stderr, "window creation failed\n"); | |||
return -1; | |||
} | |||
wmDelete = XInternAtom(disp, "WM_DELETE_WINDOW", True); | |||
XSetWMProtocols(disp, winGL, &wmDelete, 1); | |||
XSetStandardProperties(disp, winGL, "msc test", "msc text", | |||
None, NULL, 0, NULL); | |||
XMapRaised(disp, winGL); | |||
glXMakeCurrent(disp, winGL, context); | |||
get_sync_values = glXGetProcAddress((unsigned char *)"glXGetSyncValuesOML"); | |||
wait_sync = glXGetProcAddress((unsigned char *)"glXWaitForMscOML"); | |||
if (!get_sync_values || !wait_sync) { | |||
fprintf(stderr, "failed to get sync values function\n"); | |||
return -1; | |||
} | |||
while (i++) { | |||
get_sync_values(disp, winGL, &ust, &msc, &sbc); | |||
fprintf(stderr, "ust: %llu, msc: %llu, sbc: %llu\n", ust, msc, | |||
sbc); | |||
/* Alternate colors to make tearing obvious */ | |||
if (i & 1) | |||
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); | |||
else | |||
glClearColor(1.0f, 0.0f, 0.0f, 0.0f); | |||
glClear(GL_COLOR_BUFFER_BIT); | |||
glXSwapBuffers(disp, winGL); | |||
wait_sync(disp, winGL, 0, 60, 0, &ust, &msc, &sbc); | |||
fprintf(stderr, | |||
"wait returned ust: %llu, msc: %llu, sbc: %llu\n", | |||
ust, msc, sbc); | |||
sleep(1); | |||
} | |||
XDestroyWindow(disp, winGL); | |||
glXDestroyContext(disp, context); | |||
XCloseDisplay(disp); | |||
return 0; | |||
} |
@@ -34,12 +34,15 @@ | |||
#ifdef GLX_DIRECT_RENDERING | |||
#define NEED_REPLIES | |||
#include <stdio.h> | |||
#include <X11/Xlibint.h> | |||
#include <X11/extensions/Xext.h> | |||
#include <X11/extensions/extutil.h> | |||
#include <X11/extensions/dri2proto.h> | |||
#include "xf86drm.h" | |||
#include "dri2.h" | |||
#include "glxclient.h" | |||
#include "GL/glxext.h" | |||
/* Allow the build to work with an older versions of dri2proto.h and | |||
* dri2tokens.h. | |||
@@ -55,6 +58,11 @@ static char dri2ExtensionName[] = DRI2_NAME; | |||
static XExtensionInfo *dri2Info; | |||
static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info) | |||
static Bool | |||
DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire); | |||
static Status | |||
DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire); | |||
static /* const */ XExtensionHooks dri2ExtensionHooks = { | |||
NULL, /* create_gc */ | |||
NULL, /* copy_gc */ | |||
@@ -63,8 +71,8 @@ static /* const */ XExtensionHooks dri2ExtensionHooks = { | |||
NULL, /* create_font */ | |||
NULL, /* free_font */ | |||
DRI2CloseDisplay, /* close_display */ | |||
NULL, /* wire_to_event */ | |||
NULL, /* event_to_wire */ | |||
DRI2WireToEvent, /* wire_to_event */ | |||
DRI2EventToWire, /* event_to_wire */ | |||
NULL, /* error */ | |||
NULL, /* error_string */ | |||
}; | |||
@@ -75,6 +83,65 @@ static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, | |||
&dri2ExtensionHooks, | |||
0, NULL) | |||
static Bool | |||
DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) | |||
{ | |||
XExtDisplayInfo *info = DRI2FindDisplay(dpy); | |||
XextCheckExtension(dpy, info, dri2ExtensionName, False); | |||
switch ((wire->u.u.type & 0x7f) - info->codes->first_event) { | |||
case DRI2_BufferSwapComplete: | |||
{ | |||
GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event; | |||
xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire; | |||
switch (awire->type) { | |||
case DRI2_EXCHANGE_COMPLETE: | |||
aevent->event_type = GLX_EXCHANGE_COMPLETE; | |||
break; | |||
case DRI2_BLIT_COMPLETE: | |||
aevent->event_type = GLX_BLIT_COMPLETE; | |||
break; | |||
case DRI2_FLIP_COMPLETE: | |||
aevent->event_type = GLX_FLIP_COMPLETE; | |||
break; | |||
default: | |||
/* unknown swap completion type */ | |||
return False; | |||
} | |||
aevent->drawable = awire->drawable; | |||
aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo; | |||
aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo; | |||
aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo; | |||
return True; | |||
} | |||
default: | |||
/* client doesn't support server event */ | |||
break; | |||
} | |||
return False; | |||
} | |||
/* We don't actually support this. It doesn't make sense for clients to | |||
* send each other DRI2 events. | |||
*/ | |||
static Status | |||
DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire) | |||
{ | |||
XExtDisplayInfo *info = DRI2FindDisplay(dpy); | |||
XextCheckExtension(dpy, info, dri2ExtensionName, False); | |||
switch (event->type) { | |||
default: | |||
/* client doesn't support server event */ | |||
break; | |||
} | |||
return Success; | |||
} | |||
Bool | |||
DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase) | |||
{ | |||
@@ -380,4 +447,177 @@ DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region, | |||
SyncHandle(); | |||
} | |||
static void | |||
load_swap_req(xDRI2SwapBuffersReq *req, CARD64 target, CARD64 divisor, | |||
CARD64 remainder) | |||
{ | |||
req->target_msc_hi = target >> 32; | |||
req->target_msc_lo = target & 0xffffffff; | |||
req->divisor_hi = divisor >> 32; | |||
req->divisor_lo = divisor & 0xffffffff; | |||
req->remainder_hi = remainder >> 32; | |||
req->remainder_lo = remainder & 0xffffffff; | |||
} | |||
static CARD64 | |||
vals_to_card64(CARD32 lo, CARD32 hi) | |||
{ | |||
return (CARD64)hi << 32 | lo; | |||
} | |||
void DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc, | |||
CARD64 divisor, CARD64 remainder, CARD64 *count) | |||
{ | |||
XExtDisplayInfo *info = DRI2FindDisplay(dpy); | |||
xDRI2SwapBuffersReq *req; | |||
xDRI2SwapBuffersReply rep; | |||
XextSimpleCheckExtension (dpy, info, dri2ExtensionName); | |||
LockDisplay(dpy); | |||
GetReq(DRI2SwapBuffers, req); | |||
req->reqType = info->codes->major_opcode; | |||
req->dri2ReqType = X_DRI2SwapBuffers; | |||
req->drawable = drawable; | |||
load_swap_req(req, target_msc, divisor, remainder); | |||
_XReply(dpy, (xReply *)&rep, 0, xFalse); | |||
*count = vals_to_card64(rep.swap_lo, rep.swap_hi); | |||
UnlockDisplay(dpy); | |||
SyncHandle(); | |||
} | |||
Bool DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc, | |||
CARD64 *sbc) | |||
{ | |||
XExtDisplayInfo *info = DRI2FindDisplay(dpy); | |||
xDRI2GetMSCReq *req; | |||
xDRI2MSCReply rep; | |||
XextCheckExtension (dpy, info, dri2ExtensionName, False); | |||
LockDisplay(dpy); | |||
GetReq(DRI2GetMSC, req); | |||
req->reqType = info->codes->major_opcode; | |||
req->dri2ReqType = X_DRI2GetMSC; | |||
req->drawable = drawable; | |||
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { | |||
UnlockDisplay(dpy); | |||
SyncHandle(); | |||
return False; | |||
} | |||
*ust = vals_to_card64(rep.ust_lo, rep.ust_hi); | |||
*msc = vals_to_card64(rep.msc_lo, rep.msc_hi); | |||
*sbc = vals_to_card64(rep.sbc_lo, rep.sbc_hi); | |||
UnlockDisplay(dpy); | |||
SyncHandle(); | |||
return True; | |||
} | |||
static void | |||
load_msc_req(xDRI2WaitMSCReq *req, CARD64 target, CARD64 divisor, | |||
CARD64 remainder) | |||
{ | |||
req->target_msc_hi = target >> 32; | |||
req->target_msc_lo = target & 0xffffffff; | |||
req->divisor_hi = divisor >> 32; | |||
req->divisor_lo = divisor & 0xffffffff; | |||
req->remainder_hi = remainder >> 32; | |||
req->remainder_lo = remainder & 0xffffffff; | |||
} | |||
Bool DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor, | |||
CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc) | |||
{ | |||
XExtDisplayInfo *info = DRI2FindDisplay(dpy); | |||
xDRI2WaitMSCReq *req; | |||
xDRI2MSCReply rep; | |||
XextCheckExtension (dpy, info, dri2ExtensionName, False); | |||
LockDisplay(dpy); | |||
GetReq(DRI2WaitMSC, req); | |||
req->reqType = info->codes->major_opcode; | |||
req->dri2ReqType = X_DRI2WaitMSC; | |||
req->drawable = drawable; | |||
load_msc_req(req, target_msc, divisor, remainder); | |||
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { | |||
UnlockDisplay(dpy); | |||
SyncHandle(); | |||
return False; | |||
} | |||
*ust = ((CARD64)rep.ust_hi << 32) | (CARD64)rep.ust_lo; | |||
*msc = ((CARD64)rep.msc_hi << 32) | (CARD64)rep.msc_lo; | |||
*sbc = ((CARD64)rep.sbc_hi << 32) | (CARD64)rep.sbc_lo; | |||
UnlockDisplay(dpy); | |||
SyncHandle(); | |||
return True; | |||
} | |||
static void | |||
load_sbc_req(xDRI2WaitSBCReq *req, CARD64 target) | |||
{ | |||
req->target_sbc_hi = target >> 32; | |||
req->target_sbc_lo = target & 0xffffffff; | |||
} | |||
Bool DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust, | |||
CARD64 *msc, CARD64 *sbc) | |||
{ | |||
XExtDisplayInfo *info = DRI2FindDisplay(dpy); | |||
xDRI2WaitSBCReq *req; | |||
xDRI2MSCReply rep; | |||
XextCheckExtension (dpy, info, dri2ExtensionName, False); | |||
LockDisplay(dpy); | |||
GetReq(DRI2WaitSBC, req); | |||
req->reqType = info->codes->major_opcode; | |||
req->dri2ReqType = X_DRI2WaitSBC; | |||
req->drawable = drawable; | |||
load_sbc_req(req, target_sbc); | |||
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { | |||
UnlockDisplay(dpy); | |||
SyncHandle(); | |||
return False; | |||
} | |||
*ust = ((CARD64)rep.ust_hi << 32) | rep.ust_lo; | |||
*msc = ((CARD64)rep.msc_hi << 32) | rep.msc_lo; | |||
*sbc = ((CARD64)rep.sbc_hi << 32) | rep.sbc_lo; | |||
UnlockDisplay(dpy); | |||
SyncHandle(); | |||
return True; | |||
} | |||
void DRI2SwapInterval(Display *dpy, XID drawable, int interval) | |||
{ | |||
XExtDisplayInfo *info = DRI2FindDisplay(dpy); | |||
xDRI2SwapIntervalReq *req; | |||
XextSimpleCheckExtension (dpy, info, dri2ExtensionName); | |||
LockDisplay(dpy); | |||
GetReq(DRI2SwapInterval, req); | |||
req->reqType = info->codes->major_opcode; | |||
req->dri2ReqType = X_DRI2SwapInterval; | |||
req->drawable = drawable; | |||
req->interval = interval; | |||
UnlockDisplay(dpy); | |||
SyncHandle(); | |||
} | |||
#endif /* GLX_DIRECT_RENDERING */ |
@@ -85,4 +85,22 @@ DRI2CopyRegion(Display * dpy, XID drawable, | |||
XserverRegion region, | |||
CARD32 dest, CARD32 src); | |||
extern void | |||
DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor, | |||
CARD64 remainder, CARD64 *count); | |||
extern Bool | |||
DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc, CARD64 *sbc); | |||
extern Bool | |||
DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor, | |||
CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc); | |||
extern Bool | |||
DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust, | |||
CARD64 *msc, CARD64 *sbc); | |||
extern void | |||
DRI2SwapInterval(Display *dpy, XID drawable, int interval); | |||
#endif |
@@ -35,6 +35,7 @@ | |||
#include <X11/Xlib.h> | |||
#include <X11/extensions/Xfixes.h> | |||
#include <X11/extensions/Xdamage.h> | |||
#include "glapi.h" | |||
#include "glxclient.h" | |||
#include "glcontextmodes.h" | |||
#include "xf86dri.h" | |||
@@ -46,6 +47,7 @@ | |||
#include "xf86drm.h" | |||
#include "dri2.h" | |||
#include "dri_common.h" | |||
#include "../../mesa/drivers/dri/common/dri_util.h" | |||
#undef DRI2_MINOR | |||
#define DRI2_MINOR 1 | |||
@@ -64,6 +66,7 @@ struct __GLXDRIdisplayPrivateRec | |||
int driMajor; | |||
int driMinor; | |||
int driPatch; | |||
int swapAvailable; | |||
}; | |||
struct __GLXDRIcontextPrivateRec | |||
@@ -81,6 +84,7 @@ struct __GLXDRIdrawablePrivateRec | |||
int width, height; | |||
int have_back; | |||
int have_fake_front; | |||
int swap_interval; | |||
}; | |||
static void dri2WaitX(__GLXDRIdrawable * pdraw); | |||
@@ -197,9 +201,31 @@ dri2CreateDrawable(__GLXscreenConfigs * psc, | |||
return &pdraw->base; | |||
} | |||
static int | |||
dri2DrawableGetMSC(__GLXscreenConfigs *psc, __GLXDRIdrawable *pdraw, | |||
int64_t *ust, int64_t *msc, int64_t *sbc) | |||
{ | |||
return DRI2GetMSC(psc->dpy, pdraw->drawable, ust, msc, sbc); | |||
} | |||
static int | |||
dri2WaitForMSC(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, | |||
int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc) | |||
{ | |||
return DRI2WaitMSC(pdraw->psc->dpy, pdraw->drawable, target_msc, divisor, | |||
remainder, ust, msc, sbc); | |||
} | |||
static int | |||
dri2WaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust, | |||
int64_t *msc, int64_t *sbc) | |||
{ | |||
return DRI2WaitSBC(pdraw->psc->dpy, pdraw->drawable, target_sbc, ust, msc, | |||
sbc); | |||
} | |||
static void | |||
dri2CopySubBuffer(__GLXDRIdrawable * pdraw, | |||
int x, int y, int width, int height) | |||
dri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y, int width, int height) | |||
{ | |||
__GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; | |||
XRectangle xrect; | |||
@@ -232,15 +258,7 @@ dri2CopySubBuffer(__GLXDRIdrawable * pdraw, | |||
} | |||
static void | |||
dri2SwapBuffers(__GLXDRIdrawable * pdraw) | |||
{ | |||
__GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; | |||
dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height); | |||
} | |||
static void | |||
dri2WaitX(__GLXDRIdrawable * pdraw) | |||
dri2WaitX(__GLXDRIdrawable *pdraw) | |||
{ | |||
__GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; | |||
XRectangle xrect; | |||
@@ -342,6 +360,38 @@ process_buffers(__GLXDRIdrawablePrivate * pdraw, DRI2Buffer * buffers, | |||
} | |||
static int64_t | |||
dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, | |||
int64_t remainder) | |||
{ | |||
__GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; | |||
__GLXdisplayPrivate *dpyPriv = __glXInitialize(priv->base.psc->dpy); | |||
__GLXDRIdisplayPrivate *pdp = | |||
(__GLXDRIdisplayPrivate *)dpyPriv->dri2Display; | |||
int64_t ret; | |||
#ifdef __DRI2_FLUSH | |||
if (pdraw->psc->f) | |||
(*pdraw->psc->f->flush)(pdraw->driDrawable); | |||
#endif | |||
/* Old servers can't handle swapbuffers */ | |||
if (!pdp->swapAvailable) { | |||
dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height); | |||
return 0; | |||
} | |||
DRI2SwapBuffers(pdraw->psc->dpy, pdraw->drawable, target_msc, divisor, | |||
remainder, &ret); | |||
#if __DRI2_FLUSH_VERSION >= 2 | |||
if (pdraw->psc->f) | |||
(*pdraw->psc->f->flushInvalidate)(pdraw->driDrawable); | |||
#endif | |||
return ret; | |||
} | |||
static __DRIbuffer * | |||
dri2GetBuffers(__DRIdrawable * driDrawable, | |||
int *width, int *height, | |||
@@ -390,6 +440,23 @@ dri2GetBuffersWithFormat(__DRIdrawable * driDrawable, | |||
return pdraw->buffers; | |||
} | |||
static void | |||
dri2SetSwapInterval(__GLXDRIdrawable *pdraw, int interval) | |||
{ | |||
__GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; | |||
DRI2SwapInterval(priv->base.psc->dpy, pdraw->xDrawable, interval); | |||
priv->swap_interval = interval; | |||
} | |||
static unsigned int | |||
dri2GetSwapInterval(__GLXDRIdrawable *pdraw) | |||
{ | |||
__GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; | |||
return priv->swap_interval; | |||
} | |||
static const __DRIdri2LoaderExtension dri2LoaderExtension = { | |||
{__DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION}, | |||
dri2GetBuffers, | |||
@@ -437,7 +504,7 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, | |||
psc->ext_list_first_time = GL_TRUE; | |||
if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen), | |||
&driverName, &deviceName)) | |||
&driverName, &deviceName)) | |||
return NULL; | |||
psc->driver = driOpenDriver(driverName); | |||
@@ -454,9 +521,9 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, | |||
for (i = 0; extensions[i]; i++) { | |||
if (strcmp(extensions[i]->name, __DRI_CORE) == 0) | |||
psc->core = (__DRIcoreExtension *) extensions[i]; | |||
psc->core = (__DRIcoreExtension *) extensions[i]; | |||
if (strcmp(extensions[i]->name, __DRI_DRI2) == 0) | |||
psc->dri2 = (__DRIdri2Extension *) extensions[i]; | |||
psc->dri2 = (__DRIdri2Extension *) extensions[i]; | |||
} | |||
if (psc->core == NULL || psc->dri2 == NULL) { | |||
@@ -485,16 +552,17 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, | |||
*/ | |||
psc->__driScreen = | |||
psc->dri2->createNewScreen(screen, psc->fd, ((pdp->driMinor < 1) | |||
? loader_extensions_old | |||
: loader_extensions), | |||
&driver_configs, psc); | |||
? loader_extensions_old | |||
: loader_extensions), | |||
&driver_configs, psc); | |||
if (psc->__driScreen == NULL) { | |||
ErrorMessageF("failed to create dri screen\n"); | |||
return NULL; | |||
} | |||
driBindExtensions(psc, 1); | |||
driBindCommonExtensions(psc); | |||
dri2BindExtensions(psc); | |||
psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs); | |||
psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs); | |||
@@ -507,6 +575,11 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, | |||
psp->swapBuffers = dri2SwapBuffers; | |||
psp->waitGL = dri2WaitGL; | |||
psp->waitX = dri2WaitX; | |||
psp->getDrawableMSC = dri2DrawableGetMSC; | |||
psp->waitForMSC = dri2WaitForMSC; | |||
psp->waitForSBC = dri2WaitForSBC; | |||
psp->setSwapInterval = dri2SetSwapInterval; | |||
psp->getSwapInterval = dri2GetSwapInterval; | |||
/* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always | |||
* available.*/ | |||
@@ -518,7 +591,7 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, | |||
return psp; | |||
handle_error: | |||
handle_error: | |||
Xfree(driverName); | |||
Xfree(deviceName); | |||
@@ -559,6 +632,9 @@ dri2CreateDisplay(Display * dpy) | |||
} | |||
pdp->driPatch = 0; | |||
pdp->swapAvailable = 0; | |||
if (pdp->driMinor >= 2) | |||
pdp->swapAvailable = 1; | |||
pdp->base.destroyDisplay = dri2DestroyDisplay; | |||
pdp->base.createScreen = dri2CreateScreen; |
@@ -336,8 +336,9 @@ driConvertConfigs(const __DRIcoreExtension * core, | |||
return head.next; | |||
} | |||
/* Bind DRI1 specific extensions */ | |||
_X_HIDDEN void | |||
driBindExtensions(__GLXscreenConfigs * psc, int dri2) | |||
driBindExtensions(__GLXscreenConfigs *psc) | |||
{ | |||
const __DRIextension **extensions; | |||
int i; | |||
@@ -345,35 +346,13 @@ driBindExtensions(__GLXscreenConfigs * psc, int dri2) | |||
extensions = psc->core->getExtensions(psc->__driScreen); | |||
for (i = 0; extensions[i]; i++) { | |||
#ifdef __DRI_COPY_SUB_BUFFER | |||
if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { | |||
psc->driCopySubBuffer = | |||
(__DRIcopySubBufferExtension *) extensions[i]; | |||
__glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer"); | |||
} | |||
#endif | |||
#ifdef __DRI_SWAP_CONTROL | |||
/* No DRI2 support for swap_control at the moment, since SwapBuffers | |||
* is done by the X server */ | |||
if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0 && !dri2) { | |||
psc->swapControl = (__DRIswapControlExtension *) extensions[i]; | |||
__glXEnableDirectExtension(psc, "GLX_SGI_swap_control"); | |||
__glXEnableDirectExtension(psc, "GLX_MESA_swap_control"); | |||
} | |||
#endif | |||
#ifdef __DRI_ALLOCATE | |||
if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) { | |||
psc->allocate = (__DRIallocateExtension *) extensions[i]; | |||
__glXEnableDirectExtension(psc, "GLX_MESA_allocate_memory"); | |||
} | |||
#endif | |||
#ifdef __DRI_FRAME_TRACKING | |||
if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) { | |||
psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i]; | |||
__glXEnableDirectExtension(psc, "GLX_MESA_swap_frame_usage"); | |||
if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) { | |||
psc->swapControl = (__DRIswapControlExtension *) extensions[i]; | |||
__glXEnableDirectExtension(psc, "GLX_SGI_swap_control"); | |||
__glXEnableDirectExtension(psc, "GLX_MESA_swap_control"); | |||
} | |||
#endif | |||
@@ -390,23 +369,77 @@ driBindExtensions(__GLXscreenConfigs * psc, int dri2) | |||
* GLX_OML_sync_control if implemented. */ | |||
#endif | |||
#ifdef __DRI_READ_DRAWABLE | |||
if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { | |||
__glXEnableDirectExtension(psc, "GLX_SGI_make_current_read"); | |||
} | |||
#endif | |||
/* Ignore unknown extensions */ | |||
} | |||
} | |||
/* Bind DRI2 specific extensions */ | |||
_X_HIDDEN void | |||
dri2BindExtensions(__GLXscreenConfigs *psc) | |||
{ | |||
const __DRIextension **extensions; | |||
int i; | |||
extensions = psc->core->getExtensions(psc->__driScreen); | |||
for (i = 0; extensions[i]; i++) { | |||
#ifdef __DRI_TEX_BUFFER | |||
if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) && dri2) { | |||
psc->texBuffer = (__DRItexBufferExtension *) extensions[i]; | |||
__glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap"); | |||
if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) { | |||
psc->texBuffer = (__DRItexBufferExtension *) extensions[i]; | |||
__glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap"); | |||
} | |||
#endif | |||
__glXEnableDirectExtension(psc, "GLX_SGI_video_sync"); | |||
__glXEnableDirectExtension(psc, "GLX_SGI_swap_control"); | |||
__glXEnableDirectExtension(psc, "GLX_MESA_swap_control"); | |||
/* FIXME: if DRI2 version supports it... */ | |||
__glXEnableDirectExtension(psc, "INTEL_swap_event"); | |||
#ifdef __DRI2_FLUSH | |||
if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0) && dri2) { | |||
psc->f = (__DRI2flushExtension *) extensions[i]; | |||
/* internal driver extension, no GL extension exposed */ | |||
if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) { | |||
psc->f = (__DRI2flushExtension *) extensions[i]; | |||
/* internal driver extension, no GL extension exposed */ | |||
} | |||
#endif | |||
} | |||
} | |||
/* Bind extensions common to DRI1 and DRI2 */ | |||
_X_HIDDEN void | |||
driBindCommonExtensions(__GLXscreenConfigs *psc) | |||
{ | |||
const __DRIextension **extensions; | |||
int i; | |||
extensions = psc->core->getExtensions(psc->__driScreen); | |||
for (i = 0; extensions[i]; i++) { | |||
#ifdef __DRI_COPY_SUB_BUFFER | |||
if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { | |||
psc->driCopySubBuffer = (__DRIcopySubBufferExtension *) extensions[i]; | |||
__glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer"); | |||
} | |||
#endif | |||
#ifdef __DRI_ALLOCATE | |||
if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) { | |||
psc->allocate = (__DRIallocateExtension *) extensions[i]; | |||
__glXEnableDirectExtension(psc, "GLX_MESA_allocate_memory"); | |||
} | |||
#endif | |||
#ifdef __DRI_FRAME_TRACKING | |||
if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) { | |||
psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i]; | |||
__glXEnableDirectExtension(psc, "GLX_MESA_swap_frame_usage"); | |||
} | |||
#endif | |||
#ifdef __DRI_READ_DRAWABLE | |||
if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { | |||
__glXEnableDirectExtension(psc, "GLX_SGI_make_current_read"); | |||
} | |||
#endif | |||
@@ -56,6 +56,8 @@ extern void ErrorMessageF(const char *f, ...); | |||
extern void *driOpenDriver(const char *driverName); | |||
extern void driBindExtensions(__GLXscreenConfigs * psc, int dri2); | |||
extern void driBindExtensions(__GLXscreenConfigs * psc); | |||
extern void dri2BindExtensions(__GLXscreenConfigs * psc); | |||
extern void driBindCommonExtensions(__GLXscreenConfigs * psc); | |||
#endif /* _DRI_COMMON_H */ |
@@ -607,10 +607,12 @@ driCreateDrawable(__GLXscreenConfigs * psc, | |||
return pdraw; | |||
} | |||
static void | |||
driSwapBuffers(__GLXDRIdrawable * pdraw) | |||
static int64_t | |||
driSwapBuffers(__GLXDRIdrawable * pdraw, int64_t unused1, int64_t unused2, | |||
int64_t unused3) | |||
{ | |||
(*pdraw->psc->core->swapBuffers) (pdraw->driDrawable); | |||
return 0; | |||
} | |||
static void | |||
@@ -670,9 +672,9 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen, | |||
for (i = 0; extensions[i]; i++) { | |||
if (strcmp(extensions[i]->name, __DRI_CORE) == 0) | |||
psc->core = (__DRIcoreExtension *) extensions[i]; | |||
psc->core = (__DRIcoreExtension *) extensions[i]; | |||
if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0) | |||
psc->legacy = (__DRIlegacyExtension *) extensions[i]; | |||
psc->legacy = (__DRIlegacyExtension *) extensions[i]; | |||
} | |||
if (psc->core == NULL || psc->legacy == NULL) { | |||
@@ -688,7 +690,9 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen, | |||
return NULL; | |||
} | |||
driBindExtensions(psc, 0); | |||
driBindExtensions(psc); | |||
driBindCommonExtensions(psc); | |||
if (psc->driCopySubBuffer) | |||
psp->copySubBuffer = driCopySubBuffer; | |||
@@ -398,7 +398,8 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen, | |||
goto handle_error; | |||
} | |||
driBindExtensions(psc, 0); | |||
driBindExtensions(psc); | |||
driBindCommonExtensions(psc); | |||
psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs); | |||
psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs); |
@@ -121,26 +121,35 @@ struct __GLXDRIdisplayRec | |||
__GLXdisplayPrivate * priv); | |||
}; | |||
struct __GLXDRIscreenRec | |||
{ | |||
void (*destroyScreen) (__GLXscreenConfigs * psc); | |||
__GLXDRIcontext *(*createContext) (__GLXscreenConfigs * psc, | |||
const __GLcontextModes * mode, | |||
GLXContext gc, | |||
GLXContext shareList, int renderType); | |||
__GLXDRIdrawable *(*createDrawable) (__GLXscreenConfigs * psc, | |||
XID drawable, | |||
GLXDrawable glxDrawable, | |||
const __GLcontextModes * modes); | |||
void (*swapBuffers) (__GLXDRIdrawable * pdraw); | |||
void (*copySubBuffer) (__GLXDRIdrawable * pdraw, | |||
int x, int y, int width, int height); | |||
void (*waitX) (__GLXDRIdrawable * pdraw); | |||
void (*waitGL) (__GLXDRIdrawable * pdraw); | |||
struct __GLXDRIscreenRec { | |||
void (*destroyScreen)(__GLXscreenConfigs *psc); | |||
__GLXDRIcontext *(*createContext)(__GLXscreenConfigs *psc, | |||
const __GLcontextModes *mode, | |||
GLXContext gc, | |||
GLXContext shareList, int renderType); | |||
__GLXDRIdrawable *(*createDrawable)(__GLXscreenConfigs *psc, | |||
XID drawable, | |||
GLXDrawable glxDrawable, | |||
const __GLcontextModes *modes); | |||
int64_t (*swapBuffers)(__GLXDRIdrawable *pdraw, int64_t target_msc, | |||
int64_t divisor, int64_t remainder); | |||
void (*copySubBuffer)(__GLXDRIdrawable *pdraw, | |||
int x, int y, int width, int height); | |||
void (*waitX)(__GLXDRIdrawable *pdraw); | |||
void (*waitGL)(__GLXDRIdrawable *pdraw); | |||
int (*getDrawableMSC)(__GLXscreenConfigs *psc, __GLXDRIdrawable *pdraw, | |||
int64_t *ust, int64_t *msc, int64_t *sbc); | |||
int (*waitForMSC)(__GLXDRIdrawable *pdraw, int64_t target_msc, | |||
int64_t divisor, int64_t remainder, int64_t *ust, | |||
int64_t *msc, int64_t *sbc); | |||
int (*waitForSBC)(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust, | |||
int64_t *msc, int64_t *sbc); | |||
void (*setSwapInterval)(__GLXDRIdrawable *pdraw, int interval); | |||
int (*getSwapInterval)(__GLXDRIdrawable *pdraw); | |||
}; | |||
struct __GLXDRIcontextRec |
@@ -982,7 +982,7 @@ glXSwapBuffers(Display * dpy, GLXDrawable drawable) | |||
if (pdraw != NULL) { | |||
glFlush(); | |||
(*pdraw->psc->driScreen->swapBuffers) (pdraw); | |||
(*pdraw->psc->driScreen->swapBuffers)(pdraw, 0, 0, 0); | |||
return; | |||
} | |||
#endif | |||
@@ -1884,6 +1884,7 @@ __glXSwapIntervalSGI(int interval) | |||
{ | |||
xGLXVendorPrivateReq *req; | |||
GLXContext gc = __glXGetCurrentContext(); | |||
__GLXscreenConfigs *psc; | |||
Display *dpy; | |||
CARD32 *interval_ptr; | |||
CARD8 opcode; | |||
@@ -1898,20 +1899,30 @@ __glXSwapIntervalSGI(int interval) | |||
#ifdef __DRI_SWAP_CONTROL | |||
if (gc->driContext) { | |||
__GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy, | |||
gc->screen); | |||
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, | |||
gc->screen ); | |||
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, | |||
gc->currentDrawable, | |||
NULL); | |||
gc->currentDrawable, | |||
NULL); | |||
if (psc->swapControl != NULL && pdraw != NULL) { | |||
psc->swapControl->setSwapInterval(pdraw->driDrawable, interval); | |||
return 0; | |||
psc->swapControl->setSwapInterval(pdraw->driDrawable, interval); | |||
return 0; | |||
} | |||
else { | |||
return GLX_BAD_CONTEXT; | |||
else if (pdraw == NULL) { | |||
return GLX_BAD_CONTEXT; | |||
} | |||
} | |||
#endif | |||
psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); | |||
if (gc->driContext && psc->driScreen && psc->driScreen->setSwapInterval) { | |||
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, | |||
gc->currentDrawable, | |||
NULL); | |||
psc->driScreen->setSwapInterval(pdraw, interval); | |||
return 0; | |||
} | |||
dpy = gc->currentDpy; | |||
opcode = __glXSetupForCommand(dpy); | |||
if (!opcode) { | |||
@@ -1943,13 +1954,13 @@ __glXSwapIntervalSGI(int interval) | |||
static int | |||
__glXSwapIntervalMESA(unsigned int interval) | |||
{ | |||
#ifdef __DRI_SWAP_CONTROL | |||
GLXContext gc = __glXGetCurrentContext(); | |||
if (interval < 0) { | |||
return GLX_BAD_VALUE; | |||
} | |||
#ifdef __DRI_SWAP_CONTROL | |||
if (gc != NULL && gc->driContext) { | |||
__GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy, | |||
gc->screen); | |||
@@ -1963,10 +1974,20 @@ __glXSwapIntervalMESA(unsigned int interval) | |||
} | |||
} | |||
} | |||
#else | |||
(void) interval; | |||
#endif | |||
if (gc != NULL && gc->driContext) { | |||
__GLXscreenConfigs *psc; | |||
psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); | |||
if (psc->driScreen && psc->driScreen->setSwapInterval) { | |||
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, | |||
gc->currentDrawable, NULL); | |||
psc->driScreen->setSwapInterval(pdraw, interval); | |||
return 0; | |||
} | |||
} | |||
return GLX_BAD_CONTEXT; | |||
} | |||
@@ -1990,6 +2011,16 @@ __glXGetSwapIntervalMESA(void) | |||
} | |||
} | |||
#endif | |||
if (gc != NULL && gc->driContext) { | |||
__GLXscreenConfigs *psc; | |||
psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); | |||
if (psc->driScreen && psc->driScreen->getSwapInterval) { | |||
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, | |||
gc->currentDrawable, NULL); | |||
return psc->driScreen->getSwapInterval(pdraw); | |||
} | |||
} | |||
return 0; | |||
} | |||
@@ -2102,64 +2133,73 @@ __glXQueryFrameTrackingMESA(Display * dpy, GLXDrawable drawable, | |||
static int | |||
__glXGetVideoSyncSGI(unsigned int *count) | |||
{ | |||
int64_t ust, msc, sbc; | |||
int ret; | |||
GLXContext gc = __glXGetCurrentContext(); | |||
__GLXscreenConfigs *psc; | |||
__GLXDRIdrawable *pdraw; | |||
if (!gc || !gc->driContext) | |||
return GLX_BAD_CONTEXT; | |||
psc = GetGLXScreenConfigs(gc->currentDpy, gc->screen); | |||
pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); | |||
/* FIXME: Looking at the GLX_SGI_video_sync spec in the extension registry, | |||
* FIXME: there should be a GLX encoding for this call. I can find no | |||
* FIXME: documentation for the GLX encoding. | |||
*/ | |||
#ifdef __DRI_MEDIA_STREAM_COUNTER | |||
GLXContext gc = __glXGetCurrentContext(); | |||
if (gc != NULL && gc->driContext) { | |||
__GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy, | |||
gc->screen); | |||
if (psc->msc && psc->driScreen) { | |||
__GLXDRIdrawable *pdraw = | |||
GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); | |||
int64_t temp; | |||
int ret; | |||
if ( psc->msc && psc->driScreen ) { | |||
ret = (*psc->msc->getDrawableMSC)(psc->__driScreen, | |||
pdraw->driDrawable, &msc); | |||
*count = (unsigned) msc; | |||
ret = (*psc->msc->getDrawableMSC) (psc->__driScreen, | |||
pdraw->driDrawable, &temp); | |||
*count = (unsigned) temp; | |||
return (ret == 0) ? 0 : GLX_BAD_CONTEXT; | |||
} | |||
return (ret == 0) ? 0 : GLX_BAD_CONTEXT; | |||
} | |||
#else | |||
(void) count; | |||
#endif | |||
if (psc->driScreen && psc->driScreen->getDrawableMSC) { | |||
ret = psc->driScreen->getDrawableMSC(psc, pdraw, &ust, &msc, &sbc); | |||
*count = (unsigned) msc; | |||
return (ret == True) ? 0 : GLX_BAD_CONTEXT; | |||
} | |||
return GLX_BAD_CONTEXT; | |||
} | |||
static int | |||
__glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) | |||
{ | |||
#ifdef __DRI_MEDIA_STREAM_COUNTER | |||
GLXContext gc = __glXGetCurrentContext(); | |||
__GLXscreenConfigs *psc; | |||
__GLXDRIdrawable *pdraw; | |||
int64_t ust, msc, sbc; | |||
int ret; | |||
if (divisor <= 0 || remainder < 0) | |||
return GLX_BAD_VALUE; | |||
if (gc != NULL && gc->driContext) { | |||
__GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy, | |||
gc->screen); | |||
if (psc->msc != NULL && psc->driScreen) { | |||
__GLXDRIdrawable *pdraw = | |||
GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); | |||
int ret; | |||
int64_t msc; | |||
int64_t sbc; | |||
ret = (*psc->msc->waitForMSC) (pdraw->driDrawable, 0, | |||
divisor, remainder, &msc, &sbc); | |||
*count = (unsigned) msc; | |||
return (ret == 0) ? 0 : GLX_BAD_CONTEXT; | |||
} | |||
if (!gc || !gc->driContext) | |||
return GLX_BAD_CONTEXT; | |||
psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); | |||
pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); | |||
#ifdef __DRI_MEDIA_STREAM_COUNTER | |||
if (psc->msc != NULL && psc->driScreen ) { | |||
ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, 0, | |||
divisor, remainder, &msc, &sbc); | |||
*count = (unsigned) msc; | |||
return (ret == 0) ? 0 : GLX_BAD_CONTEXT; | |||
} | |||
#else | |||
(void) count; | |||
#endif | |||
if (psc->driScreen && psc->driScreen->waitForMSC) { | |||
ret = psc->driScreen->waitForMSC(pdraw, 0, divisor, remainder, &ust, &msc, | |||
&sbc); | |||
*count = (unsigned) msc; | |||
return (ret == True) ? 0 : GLX_BAD_CONTEXT; | |||
} | |||
return GLX_BAD_CONTEXT; | |||
} | |||
@@ -2312,27 +2352,29 @@ static Bool | |||
__glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable, | |||
int64_t * ust, int64_t * msc, int64_t * sbc) | |||
{ | |||
#if defined(__DRI_SWAP_BUFFER_COUNTER) && defined(__DRI_MEDIA_STREAM_COUNTER) | |||
__GLXdisplayPrivate *const priv = __glXInitialize(dpy); | |||
__GLXdisplayPrivate * const priv = __glXInitialize(dpy); | |||
int i, ret; | |||
__GLXDRIdrawable *pdraw; | |||
__GLXscreenConfigs *psc; | |||
if (priv != NULL) { | |||
int i; | |||
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &i); | |||
__GLXscreenConfigs *const psc = &priv->screenConfigs[i]; | |||
if (!priv) | |||
return False; | |||
assert((pdraw == NULL) || (i != -1)); | |||
return ((pdraw && psc->sbc && psc->msc) | |||
&& ((*psc->msc->getMSC) (psc->driScreen, msc) == 0) | |||
&& ((*psc->sbc->getSBC) (pdraw->driDrawable, sbc) == 0) | |||
&& (__glXGetUST(ust) == 0)); | |||
} | |||
#else | |||
(void) dpy; | |||
(void) drawable; | |||
(void) ust; | |||
(void) msc; | |||
(void) sbc; | |||
pdraw = GetGLXDRIDrawable(dpy, drawable, &i); | |||
psc = &priv->screenConfigs[i]; | |||
#if defined(__DRI_SWAP_BUFFER_COUNTER) && defined(__DRI_MEDIA_STREAM_COUNTER) | |||
if (pdraw && psc->sbc && psc->sbc) | |||
return ( (pdraw && psc->sbc && psc->msc) | |||
&& ((*psc->msc->getMSC)(psc->driScreen, msc) == 0) | |||
&& ((*psc->sbc->getSBC)(pdraw->driDrawable, sbc) == 0) | |||
&& (__glXGetUST(ust) == 0) ); | |||
#endif | |||
if (pdraw && psc && psc->driScreen && psc->driScreen->getDrawableMSC) { | |||
ret = psc->driScreen->getDrawableMSC(psc, pdraw, ust, msc, sbc); | |||
return ret; | |||
} | |||
return False; | |||
} | |||
@@ -2440,11 +2482,14 @@ static int64_t | |||
__glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable, | |||
int64_t target_msc, int64_t divisor, int64_t remainder) | |||
{ | |||
#ifdef __DRI_SWAP_BUFFER_COUNTER | |||
GLXContext gc = __glXGetCurrentContext(); | |||
int screen; | |||
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); | |||
__GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen); | |||
if (!pdraw || !gc->driContext) /* no GLX for this */ | |||
return -1; | |||
/* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE | |||
* error", but it also says "It [glXSwapBuffersMscOML] will return a value | |||
* of -1 if the function failed because of errors detected in the input | |||
@@ -2455,18 +2500,19 @@ __glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable, | |||
if (divisor > 0 && remainder >= divisor) | |||
return -1; | |||
if (pdraw != NULL && psc->counters != NULL) | |||
return (*psc->sbc->swapBuffersMSC) (pdraw->driDrawable, target_msc, | |||
divisor, remainder); | |||
#ifdef __DRI_SWAP_BUFFER_COUNTER | |||
if (psc->counters != NULL) | |||
return (*psc->sbc->swapBuffersMSC)(pdraw->driDrawable, target_msc, | |||
divisor, remainder); | |||
#endif | |||
#else | |||
(void) dpy; | |||
(void) drawable; | |||
(void) target_msc; | |||
(void) divisor; | |||
(void) remainder; | |||
#ifdef GLX_DIRECT_RENDERING | |||
if (psc->driScreen && psc->driScreen->swapBuffers) | |||
return (*psc->driScreen->swapBuffers)(pdraw, target_msc, divisor, | |||
remainder); | |||
#endif | |||
return 0; | |||
return -1; | |||
} | |||
@@ -2476,12 +2522,14 @@ __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, | |||
int64_t remainder, int64_t * ust, | |||
int64_t * msc, int64_t * sbc) | |||
{ | |||
#ifdef __DRI_MEDIA_STREAM_COUNTER | |||
int screen = 0; | |||
int screen; | |||
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); | |||
__GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen); | |||
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); | |||
int ret; | |||
fprintf(stderr, "waitmsc: %lld, %lld, %lld\n", target_msc, divisor, | |||
remainder); | |||
/* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE | |||
* error", but the return type in the spec is Bool. | |||
*/ | |||
@@ -2490,7 +2538,9 @@ __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, | |||
if (divisor > 0 && remainder >= divisor) | |||
return False; | |||
#ifdef __DRI_MEDIA_STREAM_COUNTER | |||
if (pdraw != NULL && psc->msc != NULL) { | |||
fprintf(stderr, "dri1 msc\n"); | |||
ret = (*psc->msc->waitForMSC) (pdraw->driDrawable, target_msc, | |||
divisor, remainder, msc, sbc); | |||
@@ -2499,16 +2549,14 @@ __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, | |||
*/ | |||
return ((ret == 0) && (__glXGetUST(ust) == 0)); | |||
} | |||
#else | |||
(void) dpy; | |||
(void) drawable; | |||
(void) target_msc; | |||
(void) divisor; | |||
(void) remainder; | |||
(void) ust; | |||
(void) msc; | |||
(void) sbc; | |||
#endif | |||
if (pdraw && psc->driScreen && psc->driScreen->waitForMSC) { | |||
ret = psc->driScreen->waitForMSC(pdraw, target_msc, divisor, remainder, | |||
ust, msc, sbc); | |||
return ret; | |||
} | |||
fprintf(stderr, "no drawable??\n"); | |||
return False; | |||
} | |||
@@ -2518,7 +2566,6 @@ __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, | |||
int64_t target_sbc, int64_t * ust, | |||
int64_t * msc, int64_t * sbc) | |||
{ | |||
#ifdef __DRI_SWAP_BUFFER_COUNTER | |||
int screen; | |||
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); | |||
__GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen); | |||
@@ -2529,7 +2576,7 @@ __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, | |||
*/ | |||
if (target_sbc < 0) | |||
return False; | |||
#ifdef __DRI_SWAP_BUFFER_COUNTER | |||
if (pdraw != NULL && psc->sbc != NULL) { | |||
ret = | |||
(*psc->sbc->waitForSBC) (pdraw->driDrawable, target_sbc, msc, sbc); | |||
@@ -2539,14 +2586,11 @@ __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, | |||
*/ | |||
return ((ret == 0) && (__glXGetUST(ust) == 0)); | |||
} | |||
#else | |||
(void) dpy; | |||
(void) drawable; | |||
(void) target_sbc; | |||
(void) ust; | |||
(void) msc; | |||
(void) sbc; | |||
#endif | |||
if (pdraw && psc->driScreen && psc->driScreen->waitForMSC) { | |||
ret = psc->driScreen->waitForSBC(pdraw, target_sbc, ust, msc, sbc); | |||
return ret; | |||
} | |||
return False; | |||
} | |||
@@ -101,6 +101,10 @@ __glXCloseDisplay(Display * dpy, XExtCodes * codes) | |||
static | |||
XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName, | |||
__GLX_NUMBER_ERRORS, error_list) | |||
static Bool | |||
__glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire); | |||
static Status | |||
__glXEventToWire(Display *dpy, XEvent *event, xEvent *wire); | |||
static /* const */ XExtensionHooks __glXExtensionHooks = { | |||
NULL, /* create_gc */ | |||
@@ -110,8 +114,8 @@ static /* const */ XExtensionHooks __glXExtensionHooks = { | |||
NULL, /* create_font */ | |||
NULL, /* free_font */ | |||
__glXCloseDisplay, /* close_display */ | |||
NULL, /* wire_to_event */ | |||
NULL, /* event_to_wire */ | |||
__glXWireToEvent, /* wire_to_event */ | |||
__glXEventToWire, /* event_to_wire */ | |||
NULL, /* error */ | |||
__glXErrorString, /* error_string */ | |||
}; | |||
@@ -121,6 +125,89 @@ XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, | |||
__glXExtensionName, &__glXExtensionHooks, | |||
__GLX_NUMBER_EVENTS, NULL) | |||
/* | |||
* GLX events are a bit funky. We don't stuff the X event code into | |||
* our user exposed (via XNextEvent) structure. Instead we use the GLX | |||
* private event code namespace (and hope it doesn't conflict). Clients | |||
* have to know that bit 15 in the event type field means they're getting | |||
* a GLX event, and then handle the various sub-event types there, rather | |||
* than simply checking the event code and handling it directly. | |||
*/ | |||
static Bool | |||
__glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire) | |||
{ | |||
XExtDisplayInfo *info = __glXFindDisplay(dpy); | |||
XextCheckExtension(dpy, info, __glXExtensionName, False); | |||
switch ((wire->u.u.type & 0x7f) - info->codes->first_event) { | |||
case GLX_PbufferClobber: | |||
{ | |||
GLXPbufferClobberEvent *aevent = (GLXPbufferClobberEvent *)event; | |||
xGLXPbufferClobberEvent *awire = (xGLXPbufferClobberEvent *)wire; | |||
aevent->event_type = awire->type; | |||
aevent->serial = awire->sequenceNumber; | |||
aevent->event_type = awire->event_type; | |||
aevent->draw_type = awire->draw_type; | |||
aevent->drawable = awire->drawable; | |||
aevent->buffer_mask = awire->buffer_mask; | |||
aevent->aux_buffer = awire->aux_buffer; | |||
aevent->x = awire->x; | |||
aevent->y = awire->y; | |||
aevent->width = awire->width; | |||
aevent->height = awire->height; | |||
aevent->count = awire->count; | |||
return True; | |||
} | |||
case GLX_BufferSwapComplete: | |||
{ | |||
GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event; | |||
xGLXBufferSwapComplete *awire = (xGLXBufferSwapComplete *)wire; | |||
aevent->event_type = awire->event_type; | |||
aevent->drawable = awire->drawable; | |||
aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo; | |||
aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo; | |||
aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo; | |||
return True; | |||
} | |||
default: | |||
/* client doesn't support server event */ | |||
break; | |||
} | |||
return False; | |||
} | |||
/* We don't actually support this. It doesn't make sense for clients to | |||
* send each other GLX events. | |||
*/ | |||
static Status | |||
__glXEventToWire(Display *dpy, XEvent *event, xEvent *wire) | |||
{ | |||
XExtDisplayInfo *info = __glXFindDisplay(dpy); | |||
XextCheckExtension(dpy, info, __glXExtensionName, False); | |||
switch (event->type) { | |||
case GLX_DAMAGED: | |||
break; | |||
case GLX_SAVED: | |||
break; | |||
case GLX_EXCHANGE_COMPLETE: | |||
break; | |||
case GLX_BLIT_COMPLETE: | |||
break; | |||
case GLX_FLIP_COMPLETE: | |||
break; | |||
default: | |||
/* client doesn't support server event */ | |||
break; | |||
} | |||
return Success; | |||
} | |||
/************************************************************************/ | |||
/* | |||
** Free the per screen configs data as well as the array of |
@@ -104,6 +104,7 @@ static const struct extension_info known_glx_extensions[] = { | |||
{ GLX(SGIX_swap_group), VER(0,0), N, N, N, N }, | |||
{ GLX(SGIX_visual_select_group), VER(0,0), Y, Y, N, N }, | |||
{ GLX(EXT_texture_from_pixmap), VER(0,0), Y, N, N, N }, | |||
{ GLX(INTEL_swap_event), VER(1,4), Y, Y, N, N }, | |||
{ NULL } | |||
}; | |||
@@ -65,7 +65,8 @@ enum | |||
SGIX_swap_barrier_bit, | |||
SGIX_swap_group_bit, | |||
SGIX_visual_select_group_bit, | |||
EXT_texture_from_pixmap_bit | |||
EXT_texture_from_pixmap_bit, | |||
INTEL_swap_event_bit, | |||
}; | |||
enum |
@@ -454,6 +454,7 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config, | |||
pdp->driScreenPriv = psp; | |||
pdp->driContextPriv = &psp->dummyContextPriv; | |||
pdp->validBuffers = GL_FALSE; | |||
if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes, | |||
renderType == GLX_PIXMAP_BIT)) { |
@@ -376,6 +376,8 @@ struct __DRIdrawableRec { | |||
* GLX_MESA_swap_control. | |||
*/ | |||
unsigned int swap_interval; | |||
GLboolean validBuffers; | |||
}; | |||
/** |
@@ -70,8 +70,6 @@ int INTEL_DEBUG = (0); | |||
#define DRIVER_DATE_GEM "GEM " DRIVER_DATE | |||
static void intel_flush(GLcontext *ctx, GLboolean needs_mi_flush); | |||
static const GLubyte * | |||
intelGetString(GLcontext * ctx, GLenum name) | |||
{ | |||
@@ -378,6 +376,7 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) | |||
} | |||
} | |||
drawable->validBuffers = GL_TRUE; | |||
driUpdateFramebufferSize(&intel->ctx, drawable); | |||
} | |||
@@ -461,7 +460,7 @@ intelInvalidateState(GLcontext * ctx, GLuint new_state) | |||
intel->vtbl.invalidate_state( intel, new_state ); | |||
} | |||
static void | |||
void | |||
intel_flush(GLcontext *ctx, GLboolean needs_mi_flush) | |||
{ | |||
struct intel_context *intel = intel_context(ctx); |
@@ -412,6 +412,7 @@ extern GLboolean intelInitContext(struct intel_context *intel, | |||
extern void intelFinish(GLcontext * ctx); | |||
extern void intelFlush(GLcontext * ctx); | |||
extern void intel_flush(GLcontext * ctx, GLboolean needs_mi_flush); | |||
extern void intelInitDriverFunctions(struct dd_function_table *functions); | |||
@@ -32,5 +32,8 @@ | |||
extern void | |||
intelInitExtensions(GLcontext *ctx); | |||
extern void | |||
intelFlushDrawable(__DRIdrawable *drawable); | |||
#endif |
@@ -113,10 +113,36 @@ static const __DRItexBufferExtension intelTexBufferExtension = { | |||
intelSetTexBuffer2, | |||
}; | |||
static void | |||
intelDRI2Flush(__DRIdrawable *drawable) | |||
{ | |||
struct intel_context *intel = drawable->driContextPriv->driverPrivate; | |||
if (intel->gen < 4) | |||
INTEL_FIREVERTICES(intel); | |||
if (intel->batch->map != intel->batch->ptr) | |||
intel_batchbuffer_flush(intel->batch); | |||
} | |||
static void | |||
intelDRI2FlushInvalidate(__DRIdrawable *drawable) | |||
{ | |||
intelDRI2Flush(drawable); | |||
drawable->validBuffers = GL_FALSE; | |||
} | |||
static const struct __DRI2flushExtensionRec intelFlushExtension = { | |||
{ __DRI2_FLUSH, __DRI2_FLUSH_VERSION }, | |||
intelDRI2Flush, | |||
intelDRI2FlushInvalidate, | |||
}; | |||
static const __DRIextension *intelScreenExtensions[] = { | |||
&driReadDrawableExtension, | |||
&intelTexOffsetExtension.base, | |||
&intelTexBufferExtension.base, | |||
&intelFlushExtension.base, | |||
NULL | |||
}; | |||
@@ -311,11 +337,10 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp) | |||
intelScreenPrivate *intelScreen; | |||
GLenum fb_format[3]; | |||
GLenum fb_type[3]; | |||
/* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't | |||
* support pageflipping at all. | |||
*/ | |||
static const GLenum back_buffer_modes[] = { | |||
GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML | |||
GLX_NONE, GLX_SWAP_UNDEFINED_OML, | |||
GLX_SWAP_EXCHANGE_OML, GLX_SWAP_COPY_OML | |||
}; | |||
uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1]; | |||
int color; |
@@ -742,7 +742,8 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, | |||
if (!intelObj) | |||
return; | |||
intel_update_renderbuffers(pDRICtx, dPriv); | |||
if (!dPriv->validBuffers) | |||
intel_update_renderbuffers(pDRICtx, dPriv); | |||
rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); | |||
/* If the region isn't set, then intel_update_renderbuffers was unable |
@@ -1172,6 +1172,9 @@ _glxapi_get_extensions(void) | |||
#endif | |||
#ifdef GLX_EXT_texture_from_pixmap | |||
"GLX_EXT_texture_from_pixmap", | |||
#endif | |||
#ifdef GLX_INTEL_swap_event | |||
"GLX_INTEL_swap_event", | |||
#endif | |||
NULL | |||
}; |