summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@nwnk.net>2005-10-05 22:39:41 +0000
committerAdam Jackson <ajax@nwnk.net>2005-10-05 22:39:41 +0000
commit61cd478b545de0313271cf6852e2df770e8f5914 (patch)
tree85008627fa96f7464fdc99e9609cac2098729e83
parente891d9c078bd31447ae3e1fc7f8c15953b0bb916 (diff)
Bug #3652: Server-side GLX support for GLX_SGIX_swap_barrier and
GLX_SGIX_hyperpipe extensions. (Eric Kunze, SGI)
-rw-r--r--GL/glx/global.c1
-rw-r--r--GL/glx/glxcmds.c245
-rw-r--r--GL/glx/glxext.c14
-rw-r--r--GL/glx/glxext.h20
-rw-r--r--GL/glx/glxscreens.c58
5 files changed, 338 insertions, 0 deletions
diff --git a/GL/glx/global.c b/GL/glx/global.c
index ef9831ec0..18cd5edc2 100644
--- a/GL/glx/global.c
+++ b/GL/glx/global.c
@@ -53,6 +53,7 @@ __GLXcontext *__glXLastContext;
RESTYPE __glXContextRes;
RESTYPE __glXClientRes;
RESTYPE __glXPixmapRes;
+RESTYPE __glXSwapBarrierRes;
/*
** Error codes with the extension error base already added in.
diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index d23607682..ca5eee82a 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -78,6 +78,14 @@ static int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc);
static int __glXCreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc);
static int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc);
+static int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc);
+static int __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc);
+static int __glxQueryHyperpipeNetworkSGIX(__GLXclientState *cl, GLbyte *pc);
+static int __glxDestroyHyperpipeConfigSGIX (__GLXclientState *cl, GLbyte *pc);
+static int __glxQueryHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc);
+static int __glxHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc);
+
+
/************************************************************************/
/**
@@ -1719,6 +1727,231 @@ int __glXRenderLarge(__GLXclientState *cl, GLbyte *pc)
}
}
+extern RESTYPE __glXSwapBarrierRes;
+
+static int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *) pc;
+ XID drawable = req->drawable;
+ int barrier = req->barrier;
+ DrawablePtr pDraw = (DrawablePtr) LookupDrawable(drawable, client);
+ int screen = pDraw->pScreen->myNum;
+
+
+ if (pDraw && (pDraw->type == DRAWABLE_WINDOW)) {
+ if (__glXSwapBarrierFuncs &&
+ __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc) {
+ int ret = __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc(screen, drawable, barrier);
+ if (ret == Success) {
+ if (barrier)
+ /* add source for cleanup when drawable is gone */
+ AddResource(drawable, __glXSwapBarrierRes, (pointer)screen);
+ else
+ /* delete source */
+ FreeResourceByType(drawable, __glXSwapBarrierRes, FALSE);
+ }
+ return ret;
+ }
+ }
+ client->errorValue = drawable;
+ return __glXBadDrawable;
+}
+
+
+static int __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryMaxSwapBarriersSGIXReq *req =
+ (xGLXQueryMaxSwapBarriersSGIXReq *) pc;
+ xGLXQueryMaxSwapBarriersSGIXReply reply;
+ int screen = req->screen;
+
+ if (__glXSwapBarrierFuncs &&
+ __glXSwapBarrierFuncs[screen].queryMaxSwapBarriersFunc)
+ reply.max = __glXSwapBarrierFuncs[screen].queryMaxSwapBarriersFunc(screen);
+ else
+ reply.max = 0;
+
+
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ }
+
+ WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply,
+ (char *) &reply);
+ return Success;
+}
+
+#define GLX_BAD_HYPERPIPE_SGIX 92
+
+static int __glxQueryHyperpipeNetworkSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryHyperpipeNetworkSGIXReq * req = (xGLXQueryHyperpipeNetworkSGIXReq *) pc;
+ xGLXQueryHyperpipeNetworkSGIXReply reply;
+ int screen = req->screen;
+ void *rdata = NULL;
+
+ int length=0;
+ int npipes=0;
+
+ int n= 0;
+
+ if (__glXHyperpipeFuncs &&
+ __glXHyperpipeFuncs[screen].queryHyperpipeNetworkFunc != NULL) {
+ rdata =
+ (__glXHyperpipeFuncs[screen].queryHyperpipeNetworkFunc(screen, &npipes, &n));
+ }
+ length = __GLX_PAD(n) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = length;
+ reply.n = n;
+ reply.npipes = npipes;
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.n);
+ __GLX_SWAP_INT(&reply.npipes);
+ }
+ WriteToClient(client, sz_xGLXQueryHyperpipeNetworkSGIXReply,
+ (char *) &reply);
+
+ WriteToClient(client, length << 2, (char *)rdata);
+
+ return Success;
+}
+
+static int __glxDestroyHyperpipeConfigSGIX (__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXDestroyHyperpipeConfigSGIXReq * req =
+ (xGLXDestroyHyperpipeConfigSGIXReq *) pc;
+ xGLXDestroyHyperpipeConfigSGIXReply reply;
+ int screen = req->screen;
+ int success = GLX_BAD_HYPERPIPE_SGIX;
+ int hpId ;
+
+ hpId = req->hpId;
+
+
+ if (__glXHyperpipeFuncs &&
+ __glXHyperpipeFuncs[screen].destroyHyperpipeConfigFunc != NULL) {
+ success = __glXHyperpipeFuncs[screen].destroyHyperpipeConfigFunc(screen, hpId);
+ }
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = __GLX_PAD(0) >> 2;
+ reply.n = 0;
+ reply.success = success;
+
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ }
+ WriteToClient(client,
+ sz_xGLXDestroyHyperpipeConfigSGIXReply,
+ (char *) &reply);
+ return Success;
+}
+
+static int __glxQueryHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryHyperpipeConfigSGIXReq * req =
+ (xGLXQueryHyperpipeConfigSGIXReq *) pc;
+ xGLXQueryHyperpipeConfigSGIXReply reply;
+ int screen = req->screen;
+ void *rdata = NULL;
+ int length;
+ int npipes=0;
+ int n= 0;
+ int hpId;
+
+ hpId = req->hpId;
+
+ if (__glXHyperpipeFuncs &&
+ __glXHyperpipeFuncs[screen].queryHyperpipeConfigFunc != NULL) {
+ rdata = __glXHyperpipeFuncs[screen].queryHyperpipeConfigFunc(screen, hpId,&npipes, &n);
+ }
+
+ length = __GLX_PAD(n) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = length;
+ reply.n = n;
+ reply.npipes = npipes;
+
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.n);
+ __GLX_SWAP_INT(&reply.npipes);
+ }
+
+ WriteToClient(client, sz_xGLXQueryHyperpipeConfigSGIXReply,
+ (char *) &reply);
+
+ WriteToClient(client, length << 2, (char *)rdata);
+
+ return Success;
+}
+
+static int __glxHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXHyperpipeConfigSGIXReq * req =
+ (xGLXHyperpipeConfigSGIXReq *) pc;
+ xGLXHyperpipeConfigSGIXReply reply;
+ int screen = req->screen;
+ void *rdata;
+
+ int npipes=0, networkId;
+ int hpId=-1;
+
+ networkId = (int)req->networkId;
+ npipes = (int)req->npipes;
+ rdata = (void *)(req +1);
+
+ if (__glXHyperpipeFuncs &&
+ __glXHyperpipeFuncs[screen].hyperpipeConfigFunc != NULL) {
+ __glXHyperpipeFuncs[screen].hyperpipeConfigFunc(screen,networkId,
+ &hpId, &npipes,
+ (void *) rdata);
+ }
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = __GLX_PAD(0) >> 2;
+ reply.n = 0;
+ reply.npipes = npipes;
+ reply.hpId = hpId;
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.npipes);
+ __GLX_SWAP_INT(&reply.hpId);
+ }
+
+ WriteToClient(client, sz_xGLXHyperpipeConfigSGIXReply,
+ (char *) &reply);
+
+ return Success;
+}
+
/************************************************************************/
@@ -1744,6 +1977,8 @@ int __glXVendorPrivate(__GLXclientState *cl, GLbyte *pc)
case X_GLvop_SamplePatternSGIS:
glSamplePatternSGIS( *(GLenum *)(pc + 4));
return Success;
+ case X_GLXvop_BindSwapBarrierSGIX:
+ return __glXBindSwapBarrierSGIX(cl, pc);
}
#endif
@@ -1773,6 +2008,16 @@ int __glXVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
return __glXQueryContextInfoEXT(cl, pc);
case X_GLXvop_MakeCurrentReadSGI:
return __glXMakeCurrentReadSGI(cl, pc);
+ case X_GLXvop_QueryMaxSwapBarriersSGIX:
+ return __glXQueryMaxSwapBarriersSGIX(cl, pc);
+ case X_GLXvop_QueryHyperpipeNetworkSGIX:
+ return __glxQueryHyperpipeNetworkSGIX(cl, pc);
+ case X_GLXvop_QueryHyperpipeConfigSGIX:
+ return __glxQueryHyperpipeConfigSGIX(cl, pc);
+ case X_GLXvop_DestroyHyperpipeConfigSGIX:
+ return __glxDestroyHyperpipeConfigSGIX(cl, pc);
+ case X_GLXvop_HyperpipeConfigSGIX:
+ return __glxHyperpipeConfigSGIX(cl, pc);
case X_GLXvop_GetFBConfigsSGIX:
return __glXGetFBConfigsSGIX(cl, pc);
case X_GLXvop_CreateContextWithConfigSGIX:
diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c
index 6e0ced935..fa1382983 100644
--- a/GL/glx/glxext.c
+++ b/GL/glx/glxext.c
@@ -180,6 +180,18 @@ GLboolean __glXFreeContext(__GLXcontext *cx)
return GL_TRUE;
}
+extern RESTYPE __glXSwapBarrierRes;
+
+static int SwapBarrierGone(int screen, XID drawable)
+{
+ if (__glXSwapBarrierFuncs &&
+ __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc != NULL) {
+ __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc(screen, drawable, 0);
+ }
+ FreeResourceByType(drawable, __glXSwapBarrierRes, FALSE);
+ return True;
+}
+
/************************************************************************/
/*
@@ -256,6 +268,8 @@ void GlxExtensionInit(void)
__glXUnsupportedPrivateRequest = extEntry->errorBase +
GLXUnsupportedPrivateRequest;
+ __glXSwapBarrierRes = CreateNewResourceType((DeleteType)SwapBarrierGone);
+
/*
** Initialize table of client state. There is never a client 0.
*/
diff --git a/GL/glx/glxext.h b/GL/glx/glxext.h
index 41b4e83e6..5d569899f 100644
--- a/GL/glx/glxext.h
+++ b/GL/glx/glxext.h
@@ -107,5 +107,25 @@ extern int GlxInitVisuals(
int preferredVis
);
+typedef struct {
+ void * (* queryHyperpipeNetworkFunc)(int, int *, int *);
+ void * (* queryHyperpipeConfigFunc)(int, int, int *, int *);
+ int (* destroyHyperpipeConfigFunc)(int, int);
+ void * (* hyperpipeConfigFunc)(int, int, int *, int *, void *);
+} __GLXHyperpipeExtensionFuncs;
+
+extern void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs);
+
+extern __GLXHyperpipeExtensionFuncs *__glXHyperpipeFuncs;
+
+typedef struct {
+ int (* bindSwapBarrierFunc)(int, XID, int);
+ int (* queryMaxSwapBarriersFunc)(int);
+} __GLXSwapBarrierExtensionFuncs;
+
+extern void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs);
+
+extern __GLXSwapBarrierExtensionFuncs *__glXSwapBarrierFuncs;
+
#endif /* _glxext_h_ */
diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c
index 4b228cb4f..58b38b1a2 100644
--- a/GL/glx/glxscreens.c
+++ b/GL/glx/glxscreens.c
@@ -49,6 +49,7 @@
#include "glxserver.h"
#include "glxutil.h"
+#include "glxext.h"
const char GLServerVersion[] = "1.2";
static const char GLServerExtensions[] =
@@ -135,6 +136,8 @@ static char GLXServerExtensions[] =
"GLX_SGI_make_current_read "
#ifndef __DARWIN__
"GLX_SGIS_multisample "
+ "GLX_SGIX_hyperpipe "
+ "GLX_SGIX_swap_barrier "
#endif
"GLX_SGIX_fbconfig "
;
@@ -154,6 +157,12 @@ static GLint __glXNumStaticScreens =
__GLXscreenInfo *__glXActiveScreens;
GLint __glXNumActiveScreens;
+__GLXSwapBarrierExtensionFuncs *__glXSwapBarrierFuncs = NULL;
+static int __glXNumSwapBarrierFuncs = 0;
+__GLXHyperpipeExtensionFuncs *__glXHyperpipeFuncs = NULL;
+static int __glXNumHyperpipeFuncs = 0;
+
+
RESTYPE __glXDrawableRes;
__GLXscreenInfo *__glXgetActiveScreen(int num) {
@@ -270,6 +279,49 @@ static void wrapPositionWindow(int screen)
pScreen->PositionWindow = PositionWindow;
}
+/*
+ * If your DDX driver wants to register support for swap barriers or hyperpipe
+ * topology, it should call __glXHyperpipeInit() or __glXSwapBarrierInit()
+ * with a dispatch table of functions to handle the requests. In the XFree86
+ * DDX, for example, you would call these near the bottom of the driver's
+ * ScreenInit method, after DRI has been initialized.
+ *
+ * This should be replaced with a better method when we teach the server how
+ * to load DRI drivers.
+ */
+
+void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs)
+{
+ if (__glXNumHyperpipeFuncs < screen + 1) {
+ __glXHyperpipeFuncs = __glXRealloc(__glXHyperpipeFuncs,
+ (screen+1) * sizeof(__GLXHyperpipeExtensionFuncs));
+ __glXNumHyperpipeFuncs = screen + 1;
+ }
+
+ __glXHyperpipeFuncs[screen].queryHyperpipeNetworkFunc =
+ *funcs->queryHyperpipeNetworkFunc;
+ __glXHyperpipeFuncs[screen].queryHyperpipeConfigFunc =
+ *funcs->queryHyperpipeConfigFunc;
+ __glXHyperpipeFuncs[screen].destroyHyperpipeConfigFunc =
+ *funcs->destroyHyperpipeConfigFunc;
+ __glXHyperpipeFuncs[screen].hyperpipeConfigFunc =
+ *funcs->hyperpipeConfigFunc;
+}
+
+void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs)
+{
+ if (__glXNumSwapBarrierFuncs < screen + 1) {
+ __glXSwapBarrierFuncs = __glXRealloc(__glXSwapBarrierFuncs,
+ (screen+1) * sizeof(__GLXSwapBarrierExtensionFuncs));
+ __glXNumSwapBarrierFuncs = screen + 1;
+ }
+
+ __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc =
+ funcs->bindSwapBarrierFunc;
+ __glXSwapBarrierFuncs[screen].queryMaxSwapBarriersFunc =
+ funcs->queryMaxSwapBarriersFunc;
+}
+
void __glXScreenInit(GLint numscreens)
{
GLint i,j;
@@ -315,6 +367,12 @@ void __glXScreenReset(void)
__glXFree(__glXActiveScreens[i].GLextensions);
}
xfree(__glXActiveScreens);
+ xfree(__glXHyperpipeFuncs);
+ xfree(__glXSwapBarrierFuncs);
+ __glXNumHyperpipeFuncs = 0;
+ __glXNumSwapBarrierFuncs = 0;
+ __glXHyperpipeFuncs = NULL;
+ __glXSwapBarrierFuncs = NULL;
__glXActiveScreens = NULL;
__glXNumActiveScreens = 0;
}