diff options
author | Adam Jackson <ajax@nwnk.net> | 2005-10-05 22:39:41 +0000 |
---|---|---|
committer | Adam Jackson <ajax@nwnk.net> | 2005-10-05 22:39:41 +0000 |
commit | 61cd478b545de0313271cf6852e2df770e8f5914 (patch) | |
tree | 85008627fa96f7464fdc99e9609cac2098729e83 | |
parent | e891d9c078bd31447ae3e1fc7f8c15953b0bb916 (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.c | 1 | ||||
-rw-r--r-- | GL/glx/glxcmds.c | 245 | ||||
-rw-r--r-- | GL/glx/glxext.c | 14 | ||||
-rw-r--r-- | GL/glx/glxext.h | 20 | ||||
-rw-r--r-- | GL/glx/glxscreens.c | 58 |
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; } |