Bug #3652: Server-side GLX support for GLX_SGIX_swap_barrier and
GLX_SGIX_hyperpipe extensions. (Eric Kunze, SGI)
This commit is contained in:
parent
e891d9c078
commit
61cd478b54
|
@ -53,6 +53,7 @@ __GLXcontext *__glXLastContext;
|
|||
RESTYPE __glXContextRes;
|
||||
RESTYPE __glXClientRes;
|
||||
RESTYPE __glXPixmapRes;
|
||||
RESTYPE __glXSwapBarrierRes;
|
||||
|
||||
/*
|
||||
** Error codes with the extension error base already added in.
|
||||
|
|
245
GL/glx/glxcmds.c
245
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:
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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_ */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user