Browse Source

Merge branch 'master' of ssh://people.freedesktop.org/~jbarnes/mesa

Conflicts due to DRI1 removal:
	src/mesa/drivers/dri/intel/intel_context.c
	src/mesa/drivers/dri/intel/intel_screen.c
tags/7.8-rc1
Jesse Barnes 15 years ago
parent
commit
c6ef705e41

+ 1
- 1
configure.ac View File

@@ -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

+ 19
- 0
include/GL/glx.h View File

@@ -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;


+ 8
- 0
include/GL/glxext.h View File

@@ -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

+ 13
- 1
include/GL/internal/dri_interface.h View File

@@ -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);
};



+ 1
- 0
progs/xdemos/.gitignore View File

@@ -26,3 +26,4 @@ xdemo
xfont
xrotfontdemo
yuvrect_client
msctest

+ 1
- 0
progs/xdemos/Makefile View File

@@ -29,6 +29,7 @@ PROGS = \
glxsnoop \
glxswapcontrol \
manywin \
msctest \
multictx \
offset \
overlay \

+ 70
- 41
progs/xdemos/glsync.c View File

@@ -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);

+ 202
- 0
progs/xdemos/msctest.c View File

@@ -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;
}

+ 242
- 2
src/glx/x11/dri2.c View File

@@ -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 */

+ 18
- 0
src/glx/x11/dri2.h View File

@@ -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

+ 95
- 19
src/glx/x11/dri2_glx.c View File

@@ -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;

+ 71
- 38
src/glx/x11/dri_common.c View File

@@ -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


+ 3
- 1
src/glx/x11/dri_common.h View File

@@ -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 */

+ 9
- 5
src/glx/x11/dri_glx.c View File

@@ -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;


+ 2
- 1
src/glx/x11/drisw_glx.c View File

@@ -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);

+ 29
- 20
src/glx/x11/glxclient.h View File

@@ -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

+ 143
- 99
src/glx/x11/glxcmds.c View File

@@ -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;
}


+ 89
- 2
src/glx/x11/glxext.c View File

@@ -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

+ 1
- 0
src/glx/x11/glxextensions.c View File

@@ -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 }
};


+ 2
- 1
src/glx/x11/glxextensions.h View File

@@ -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

+ 1
- 0
src/mesa/drivers/dri/common/dri_util.c View File

@@ -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)) {

+ 2
- 0
src/mesa/drivers/dri/common/dri_util.h View File

@@ -376,6 +376,8 @@ struct __DRIdrawableRec {
* GLX_MESA_swap_control.
*/
unsigned int swap_interval;

GLboolean validBuffers;
};

/**

+ 2
- 3
src/mesa/drivers/dri/intel/intel_context.c View File

@@ -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);

+ 1
- 0
src/mesa/drivers/dri/intel/intel_context.h View File

@@ -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);


+ 3
- 0
src/mesa/drivers/dri/intel/intel_extensions.h View File

@@ -32,5 +32,8 @@
extern void
intelInitExtensions(GLcontext *ctx);

extern void
intelFlushDrawable(__DRIdrawable *drawable);


#endif

+ 29
- 4
src/mesa/drivers/dri/intel/intel_screen.c View File

@@ -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;

+ 2
- 1
src/mesa/drivers/dri/intel/intel_tex_image.c View File

@@ -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

+ 3
- 0
src/mesa/drivers/x11/glxapi.c View File

@@ -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
};

Loading…
Cancel
Save