2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
31 #ifdef HAVE_DIX_CONFIG_H
32 #include <dix-config.h>
38 #include "glxserver.h"
39 #include <GL/glxtokens.h>
41 #include <pixmapstr.h>
42 #include <windowstr.h>
45 #include "indirect_dispatch.h"
46 #include "indirect_table.h"
47 #include "indirect_util.h"
49 static char GLXServerVendorName
[] = "SGI";
52 validGlxScreen(ClientPtr client
, int screen
, __GLXscreen
** pGlxScreen
,
56 ** Check if screen exists.
58 if (screen
< 0 || screen
>= screenInfo
.numScreens
) {
59 client
->errorValue
= screen
;
63 *pGlxScreen
= glxGetScreen(screenInfo
.screens
[screen
]);
69 validGlxFBConfig(ClientPtr client
, __GLXscreen
* pGlxScreen
, XID id
,
70 __GLXconfig
** config
, int *err
)
74 for (m
= pGlxScreen
->fbconfigs
; m
!= NULL
; m
= m
->next
)
75 if (m
->fbconfigID
== id
) {
80 client
->errorValue
= id
;
81 *err
= __glXError(GLXBadFBConfig
);
87 validGlxVisual(ClientPtr client
, __GLXscreen
* pGlxScreen
, XID id
,
88 __GLXconfig
** config
, int *err
)
92 for (i
= 0; i
< pGlxScreen
->numVisuals
; i
++)
93 if (pGlxScreen
->visuals
[i
]->visualID
== id
) {
94 *config
= pGlxScreen
->visuals
[i
];
98 client
->errorValue
= id
;
105 validGlxFBConfigForWindow(ClientPtr client
, __GLXconfig
* config
,
106 DrawablePtr pDraw
, int *err
)
108 ScreenPtr pScreen
= pDraw
->pScreen
;
109 VisualPtr pVisual
= NULL
;
113 vid
= wVisual((WindowPtr
) pDraw
);
114 for (i
= 0; i
< pScreen
->numVisuals
; i
++) {
115 if (pScreen
->visuals
[i
].vid
== vid
) {
116 pVisual
= &pScreen
->visuals
[i
];
121 /* FIXME: What exactly should we check here... */
122 if (pVisual
->class != glxConvertToXVisualType(config
->visualType
) ||
123 !(config
->drawableType
& GLX_WINDOW_BIT
)) {
124 client
->errorValue
= pDraw
->id
;
133 validGlxContext(ClientPtr client
, XID id
, int access_mode
,
134 __GLXcontext
** context
, int *err
)
136 *err
= dixLookupResourceByType((pointer
*) context
, id
,
137 __glXContextRes
, client
, access_mode
);
138 if (*err
!= Success
|| (*context
)->idExists
== GL_FALSE
) {
139 client
->errorValue
= id
;
140 if (*err
== BadValue
|| *err
== Success
)
141 *err
= __glXError(GLXBadContext
);
149 validGlxDrawable(ClientPtr client
, XID id
, int type
, int access_mode
,
150 __GLXdrawable
** drawable
, int *err
)
154 rc
= dixLookupResourceByType((pointer
*) drawable
, id
,
155 __glXDrawableRes
, client
, access_mode
);
156 if (rc
!= Success
&& rc
!= BadValue
) {
158 client
->errorValue
= id
;
162 /* If the ID of the glx drawable we looked up doesn't match the id
163 * we looked for, it's because we looked it up under the X
164 * drawable ID (see DoCreateGLXDrawable). */
165 if (rc
== BadValue
||
166 (*drawable
)->drawId
!= id
||
167 (type
!= GLX_DRAWABLE_ANY
&& type
!= (*drawable
)->type
)) {
168 client
->errorValue
= id
;
170 case GLX_DRAWABLE_WINDOW
:
171 *err
= __glXError(GLXBadWindow
);
173 case GLX_DRAWABLE_PIXMAP
:
174 *err
= __glXError(GLXBadPixmap
);
176 case GLX_DRAWABLE_PBUFFER
:
177 *err
= __glXError(GLXBadPbuffer
);
179 case GLX_DRAWABLE_ANY
:
180 *err
= __glXError(GLXBadDrawable
);
189 __glXContextDestroy(__GLXcontext
* context
)
191 __glXFlushContextCache();
195 __glXdirectContextDestroy(__GLXcontext
* context
)
197 __glXContextDestroy(context
);
201 _X_HIDDEN __GLXcontext
*
202 __glXdirectContextCreate(__GLXscreen
* screen
,
203 __GLXconfig
* modes
, __GLXcontext
* shareContext
)
205 __GLXcontext
*context
;
207 context
= calloc(1, sizeof(__GLXcontext
));
211 context
->destroy
= __glXdirectContextDestroy
;
217 * Create a GL context with the given properties. This routine is used
218 * to implement \c glXCreateContext, \c glXCreateNewContext, and
219 * \c glXCreateContextWithConfigSGIX. This works becuase of the hack way
220 * that GLXFBConfigs are implemented. Basically, the FBConfigID is the
221 * same as the VisualID.
225 DoCreateContext(__GLXclientState
* cl
, GLXContextID gcId
,
226 GLXContextID shareList
, __GLXconfig
* config
,
227 __GLXscreen
* pGlxScreen
, GLboolean isDirect
)
229 ClientPtr client
= cl
->client
;
230 __GLXcontext
*glxc
, *shareglxc
;
233 LEGAL_NEW_RESOURCE(gcId
, client
);
236 ** Find the display list space that we want to share.
238 ** NOTE: In a multithreaded X server, we would need to keep a reference
239 ** count for each display list so that if one client detroyed a list that
240 ** another client was using, the list would not really be freed until it
241 ** was no longer in use. Since this sample implementation has no support
242 ** for multithreaded servers, we don't do this.
244 if (shareList
== None
) {
248 if (!validGlxContext(client
, shareList
, DixReadAccess
,
252 /* Page 26 (page 32 of the PDF) of the GLX 1.4 spec says:
254 * "The server context state for all sharing contexts must exist
255 * in a single address space or a BadMatch error is generated."
257 * If the share context is indirect, force the new context to also be
258 * indirect. If the shard context is direct but the new context
259 * cannot be direct, generate BadMatch.
261 if (shareglxc
->isDirect
&& !isDirect
) {
262 client
->errorValue
= shareList
;
265 else if (!shareglxc
->isDirect
) {
267 ** Create an indirect context regardless of what the client asked
268 ** for; this way we can share display list space with shareList.
275 ** Allocate memory for the new context
278 /* Without any attributes, the only error that the driver should be
279 * able to generate is BadAlloc. As result, just drop the error
280 * returned from the driver on the floor.
282 glxc
= pGlxScreen
->createContext(pGlxScreen
, config
, shareglxc
,
286 glxc
= __glXdirectContextCreate(pGlxScreen
, config
, shareglxc
);
291 /* Initialize the GLXcontext structure.
293 glxc
->pGlxScreen
= pGlxScreen
;
294 glxc
->config
= config
;
296 glxc
->share_id
= shareList
;
297 glxc
->idExists
= GL_TRUE
;
298 glxc
->currentClient
= NULL
;
299 glxc
->isDirect
= isDirect
;
300 glxc
->hasUnflushedCommands
= GL_FALSE
;
301 glxc
->renderMode
= GL_RENDER
;
302 glxc
->feedbackBuf
= NULL
;
303 glxc
->feedbackBufSize
= 0;
304 glxc
->selectBuf
= NULL
;
305 glxc
->selectBufSize
= 0;
306 glxc
->drawPriv
= NULL
;
307 glxc
->readPriv
= NULL
;
309 /* The GLX_ARB_create_context_robustness spec says:
311 * "The default value for GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB
312 * is GLX_NO_RESET_NOTIFICATION_ARB."
314 * Without using glXCreateContextAttribsARB, there is no way to specify a
315 * non-default reset notification strategy.
317 glxc
->resetNotificationStrategy
= GLX_NO_RESET_NOTIFICATION_ARB
;
319 /* Add the new context to the various global tables of GLX contexts.
321 if (!__glXAddContext(glxc
)) {
322 (*glxc
->destroy
) (glxc
);
323 client
->errorValue
= gcId
;
331 __glXDisp_CreateContext(__GLXclientState
* cl
, GLbyte
* pc
)
333 ClientPtr client
= cl
->client
;
334 xGLXCreateContextReq
*req
= (xGLXCreateContextReq
*) pc
;
336 __GLXscreen
*pGlxScreen
;
339 REQUEST_SIZE_MATCH(xGLXCreateContextReq
);
341 if (!validGlxScreen(cl
->client
, req
->screen
, &pGlxScreen
, &err
))
343 if (!validGlxVisual(cl
->client
, pGlxScreen
, req
->visual
, &config
, &err
))
346 return DoCreateContext(cl
, req
->context
, req
->shareList
,
347 config
, pGlxScreen
, req
->isDirect
);
351 __glXDisp_CreateNewContext(__GLXclientState
* cl
, GLbyte
* pc
)
353 ClientPtr client
= cl
->client
;
354 xGLXCreateNewContextReq
*req
= (xGLXCreateNewContextReq
*) pc
;
356 __GLXscreen
*pGlxScreen
;
359 REQUEST_SIZE_MATCH(xGLXCreateNewContextReq
);
361 if (!validGlxScreen(cl
->client
, req
->screen
, &pGlxScreen
, &err
))
363 if (!validGlxFBConfig(cl
->client
, pGlxScreen
, req
->fbconfig
, &config
, &err
))
366 return DoCreateContext(cl
, req
->context
, req
->shareList
,
367 config
, pGlxScreen
, req
->isDirect
);
371 __glXDisp_CreateContextWithConfigSGIX(__GLXclientState
* cl
, GLbyte
* pc
)
373 ClientPtr client
= cl
->client
;
374 xGLXCreateContextWithConfigSGIXReq
*req
=
375 (xGLXCreateContextWithConfigSGIXReq
*) pc
;
377 __GLXscreen
*pGlxScreen
;
380 REQUEST_SIZE_MATCH(xGLXCreateContextWithConfigSGIXReq
);
382 if (!validGlxScreen(cl
->client
, req
->screen
, &pGlxScreen
, &err
))
384 if (!validGlxFBConfig(cl
->client
, pGlxScreen
, req
->fbconfig
, &config
, &err
))
387 return DoCreateContext(cl
, req
->context
, req
->shareList
,
388 config
, pGlxScreen
, req
->isDirect
);
392 __glXDisp_DestroyContext(__GLXclientState
* cl
, GLbyte
* pc
)
394 ClientPtr client
= cl
->client
;
395 xGLXDestroyContextReq
*req
= (xGLXDestroyContextReq
*) pc
;
399 REQUEST_SIZE_MATCH(xGLXDestroyContextReq
);
401 if (!validGlxContext(cl
->client
, req
->context
, DixDestroyAccess
,
405 FreeResourceByType(req
->context
, __glXContextRes
, FALSE
);
411 * This will return "deleted" contexts, ie, where idExists is GL_FALSE.
412 * Contrast validGlxContext, which will not. We're cheating here and
413 * using the XID as the context tag, which is fine as long as we defer
414 * actually destroying the context until it's no longer referenced, and
415 * block clients from trying to MakeCurrent on contexts that are on the
416 * way to destruction. Notice that DoMakeCurrent calls validGlxContext
417 * for new contexts but __glXLookupContextByTag for previous contexts.
420 __glXLookupContextByTag(__GLXclientState
* cl
, GLXContextTag tag
)
424 if (dixLookupResourceByType((void **) &ret
, tag
, __glXContextRes
,
425 cl
->client
, DixUseAccess
) == Success
)
431 /*****************************************************************************/
434 StopUsingContext(__GLXcontext
* glxc
)
437 if (glxc
== __glXLastContext
) {
438 /* Tell server GL library */
439 __glXLastContext
= 0;
441 glxc
->currentClient
= NULL
;
442 if (!glxc
->idExists
) {
443 FreeResourceByType(glxc
->id
, __glXContextRes
, FALSE
);
449 StartUsingContext(__GLXclientState
* cl
, __GLXcontext
* glxc
)
451 __glXLastContext
= glxc
;
452 glxc
->currentClient
= cl
->client
;
456 * This is a helper function to handle the legacy (pre GLX 1.3) cases
457 * where passing an X window to glXMakeCurrent is valid. Given a
458 * resource ID, look up the GLX drawable if available, otherwise, make
459 * sure it's an X window and create a GLX drawable one the fly.
461 static __GLXdrawable
*
462 __glXGetDrawable(__GLXcontext
* glxc
, GLXDrawable drawId
, ClientPtr client
,
466 __GLXdrawable
*pGlxDraw
;
469 if (validGlxDrawable(client
, drawId
, GLX_DRAWABLE_ANY
,
470 DixWriteAccess
, &pGlxDraw
, &rc
)) {
471 if (glxc
!= NULL
&& pGlxDraw
->config
!= glxc
->config
) {
472 client
->errorValue
= drawId
;
480 /* No active context and an unknown drawable, bail. */
482 client
->errorValue
= drawId
;
487 /* The drawId wasn't a GLX drawable. Make sure it's a window and
488 * create a GLXWindow for it. Check that the drawable screen
489 * matches the context screen and that the context fbconfig is
490 * compatible with the window visual. */
492 rc
= dixLookupDrawable(&pDraw
, drawId
, client
, 0, DixGetAttrAccess
);
493 if (rc
!= Success
|| pDraw
->type
!= DRAWABLE_WINDOW
) {
494 client
->errorValue
= drawId
;
495 *error
= __glXError(GLXBadDrawable
);
499 if (pDraw
->pScreen
!= glxc
->pGlxScreen
->pScreen
) {
500 client
->errorValue
= pDraw
->pScreen
->myNum
;
505 if (!validGlxFBConfigForWindow(client
, glxc
->config
, pDraw
, error
))
508 pGlxDraw
= glxc
->pGlxScreen
->createDrawable(client
, glxc
->pGlxScreen
,
511 drawId
, glxc
->config
);
517 /* since we are creating the drawablePrivate, drawId should be new */
518 if (!AddResource(drawId
, __glXDrawableRes
, pGlxDraw
)) {
519 pGlxDraw
->destroy(pGlxDraw
);
527 /*****************************************************************************/
529 ** Make an OpenGL context and drawable current.
533 DoMakeCurrent(__GLXclientState
* cl
,
534 GLXDrawable drawId
, GLXDrawable readId
,
535 GLXContextID contextId
, GLXContextTag tag
)
537 ClientPtr client
= cl
->client
;
538 xGLXMakeCurrentReply reply
;
539 __GLXcontext
*glxc
, *prevglxc
;
540 __GLXdrawable
*drawPriv
= NULL
;
541 __GLXdrawable
*readPriv
= NULL
;
546 ** If one is None and the other isn't, it's a bad match.
549 mask
= (drawId
== None
) ? (1 << 0) : 0;
550 mask
|= (readId
== None
) ? (1 << 1) : 0;
551 mask
|= (contextId
== None
) ? (1 << 2) : 0;
553 if ((mask
!= 0x00) && (mask
!= 0x07)) {
558 ** Lookup old context. If we have one, it must be in a usable state.
561 prevglxc
= __glXLookupContextByTag(cl
, tag
);
564 ** Tag for previous context is invalid.
566 return __glXError(GLXBadContextTag
);
568 if (prevglxc
->renderMode
!= GL_RENDER
) {
569 /* Oops. Not in render mode render. */
570 client
->errorValue
= prevglxc
->id
;
571 return __glXError(GLXBadContextState
);
579 ** Lookup new context. It must not be current for someone else.
581 if (contextId
!= None
) {
584 if (!validGlxContext(client
, contextId
, DixUseAccess
, &glxc
, &error
))
586 if ((glxc
!= prevglxc
) && glxc
->currentClient
) {
587 /* Context is current to somebody else */
591 assert(drawId
!= None
);
592 assert(readId
!= None
);
594 drawPriv
= __glXGetDrawable(glxc
, drawId
, client
, &status
);
595 if (drawPriv
== NULL
)
598 readPriv
= __glXGetDrawable(glxc
, readId
, client
, &status
);
599 if (readPriv
== NULL
)
604 /* Switching to no context. Ignore new drawable. */
612 ** Flush the previous context if needed.
614 if (prevglxc
->hasUnflushedCommands
) {
615 if (__glXForceCurrent(cl
, tag
, (int *) &error
)) {
617 prevglxc
->hasUnflushedCommands
= GL_FALSE
;
625 ** Make the previous context not current.
627 if (!(*prevglxc
->loseCurrent
) (prevglxc
)) {
628 return __glXError(GLXBadContext
);
630 __glXFlushContextCache();
631 if (!prevglxc
->isDirect
) {
632 prevglxc
->drawPriv
= NULL
;
633 prevglxc
->readPriv
= NULL
;
637 if ((glxc
!= 0) && !glxc
->isDirect
) {
639 glxc
->drawPriv
= drawPriv
;
640 glxc
->readPriv
= readPriv
;
642 /* make the context current */
643 if (!(*glxc
->makeCurrent
) (glxc
)) {
644 glxc
->drawPriv
= NULL
;
645 glxc
->readPriv
= NULL
;
646 return __glXError(GLXBadContext
);
649 glxc
->currentClient
= client
;
652 StopUsingContext(prevglxc
);
654 reply
= (xGLXMakeCurrentReply
) {
656 .sequenceNumber
= client
->sequence
,
662 StartUsingContext(cl
, glxc
);
663 reply
.contextTag
= glxc
->id
;
666 if (client
->swapped
) {
667 __glXSwapMakeCurrentReply(client
, &reply
);
670 WriteToClient(client
, sz_xGLXMakeCurrentReply
, &reply
);
676 __glXDisp_MakeCurrent(__GLXclientState
* cl
, GLbyte
* pc
)
678 ClientPtr client
= cl
->client
;
679 xGLXMakeCurrentReq
*req
= (xGLXMakeCurrentReq
*) pc
;
681 REQUEST_SIZE_MATCH(xGLXMakeCurrentReq
);
683 return DoMakeCurrent(cl
, req
->drawable
, req
->drawable
,
684 req
->context
, req
->oldContextTag
);
688 __glXDisp_MakeContextCurrent(__GLXclientState
* cl
, GLbyte
* pc
)
690 ClientPtr client
= cl
->client
;
691 xGLXMakeContextCurrentReq
*req
= (xGLXMakeContextCurrentReq
*) pc
;
693 REQUEST_SIZE_MATCH(xGLXMakeContextCurrentReq
);
695 return DoMakeCurrent(cl
, req
->drawable
, req
->readdrawable
,
696 req
->context
, req
->oldContextTag
);
700 __glXDisp_MakeCurrentReadSGI(__GLXclientState
* cl
, GLbyte
* pc
)
702 ClientPtr client
= cl
->client
;
703 xGLXMakeCurrentReadSGIReq
*req
= (xGLXMakeCurrentReadSGIReq
*) pc
;
705 REQUEST_SIZE_MATCH(xGLXMakeCurrentReadSGIReq
);
707 return DoMakeCurrent(cl
, req
->drawable
, req
->readable
,
708 req
->context
, req
->oldContextTag
);
712 __glXDisp_IsDirect(__GLXclientState
* cl
, GLbyte
* pc
)
714 ClientPtr client
= cl
->client
;
715 xGLXIsDirectReq
*req
= (xGLXIsDirectReq
*) pc
;
716 xGLXIsDirectReply reply
;
720 REQUEST_SIZE_MATCH(xGLXIsDirectReq
);
722 if (!validGlxContext(cl
->client
, req
->context
, DixReadAccess
, &glxc
, &err
))
725 reply
= (xGLXIsDirectReply
) {
727 .sequenceNumber
= client
->sequence
,
729 .isDirect
= glxc
->isDirect
732 if (client
->swapped
) {
733 __glXSwapIsDirectReply(client
, &reply
);
736 WriteToClient(client
, sz_xGLXIsDirectReply
, &reply
);
743 __glXDisp_QueryVersion(__GLXclientState
* cl
, GLbyte
* pc
)
745 ClientPtr client
= cl
->client
;
746 xGLXQueryVersionReq
*req
= (xGLXQueryVersionReq
*) pc
;
747 xGLXQueryVersionReply reply
;
750 REQUEST_SIZE_MATCH(xGLXQueryVersionReq
);
752 major
= req
->majorVersion
;
753 minor
= req
->minorVersion
;
758 ** Server should take into consideration the version numbers sent by the
759 ** client if it wants to work with older clients; however, in this
760 ** implementation the server just returns its version number.
762 reply
= (xGLXQueryVersionReply
) {
764 .sequenceNumber
= client
->sequence
,
766 .majorVersion
= glxMajorVersion
,
767 .minorVersion
= glxMinorVersion
770 if (client
->swapped
) {
771 __glXSwapQueryVersionReply(client
, &reply
);
774 WriteToClient(client
, sz_xGLXQueryVersionReply
, &reply
);
780 __glXDisp_WaitGL(__GLXclientState
* cl
, GLbyte
* pc
)
782 ClientPtr client
= cl
->client
;
783 xGLXWaitGLReq
*req
= (xGLXWaitGLReq
*) pc
;
785 __GLXcontext
*glxc
= NULL
;
788 REQUEST_SIZE_MATCH(xGLXWaitGLReq
);
790 tag
= req
->contextTag
;
792 glxc
= __glXLookupContextByTag(cl
, tag
);
794 return __glXError(GLXBadContextTag
);
796 if (!__glXForceCurrent(cl
, req
->contextTag
, &error
))
802 if (glxc
&& glxc
->drawPriv
->waitGL
)
803 (*glxc
->drawPriv
->waitGL
) (glxc
->drawPriv
);
809 __glXDisp_WaitX(__GLXclientState
* cl
, GLbyte
* pc
)
811 ClientPtr client
= cl
->client
;
812 xGLXWaitXReq
*req
= (xGLXWaitXReq
*) pc
;
814 __GLXcontext
*glxc
= NULL
;
817 REQUEST_SIZE_MATCH(xGLXWaitXReq
);
819 tag
= req
->contextTag
;
821 glxc
= __glXLookupContextByTag(cl
, tag
);
823 return __glXError(GLXBadContextTag
);
825 if (!__glXForceCurrent(cl
, req
->contextTag
, &error
))
829 if (glxc
&& glxc
->drawPriv
->waitX
)
830 (*glxc
->drawPriv
->waitX
) (glxc
->drawPriv
);
836 __glXDisp_CopyContext(__GLXclientState
* cl
, GLbyte
* pc
)
838 ClientPtr client
= cl
->client
;
839 xGLXCopyContextReq
*req
= (xGLXCopyContextReq
*) pc
;
844 __GLXcontext
*src
, *dst
;
847 REQUEST_SIZE_MATCH(xGLXCopyContextReq
);
849 source
= req
->source
;
851 tag
= req
->contextTag
;
853 if (!validGlxContext(cl
->client
, source
, DixReadAccess
, &src
, &error
))
855 if (!validGlxContext(cl
->client
, dest
, DixWriteAccess
, &dst
, &error
))
859 ** They must be in the same address space, and same screen.
860 ** NOTE: no support for direct rendering contexts here.
862 if (src
->isDirect
|| dst
->isDirect
|| (src
->pGlxScreen
!= dst
->pGlxScreen
)) {
863 client
->errorValue
= source
;
868 ** The destination context must not be current for any client.
870 if (dst
->currentClient
) {
871 client
->errorValue
= dest
;
876 __GLXcontext
*tagcx
= __glXLookupContextByTag(cl
, tag
);
879 return __glXError(GLXBadContextTag
);
883 ** This would be caused by a faulty implementation of the client
889 ** In this case, glXCopyContext is in both GL and X streams, in terms
892 if (__glXForceCurrent(cl
, tag
, &error
)) {
894 ** Do whatever is needed to make sure that all preceding requests
895 ** in both streams are completed before the copy is executed.
898 tagcx
->hasUnflushedCommands
= GL_FALSE
;
905 ** Issue copy. The only reason for failure is a bad mask.
907 if (!(*dst
->copy
) (dst
, src
, mask
)) {
908 client
->errorValue
= mask
;
915 GLX_VIS_CONFIG_UNPAIRED
= 18,
916 GLX_VIS_CONFIG_PAIRED
= 22
920 GLX_VIS_CONFIG_TOTAL
= GLX_VIS_CONFIG_UNPAIRED
+ GLX_VIS_CONFIG_PAIRED
924 __glXDisp_GetVisualConfigs(__GLXclientState
* cl
, GLbyte
* pc
)
926 xGLXGetVisualConfigsReq
*req
= (xGLXGetVisualConfigsReq
*) pc
;
927 ClientPtr client
= cl
->client
;
928 xGLXGetVisualConfigsReply reply
;
929 __GLXscreen
*pGlxScreen
;
931 CARD32 buf
[GLX_VIS_CONFIG_TOTAL
];
934 __GLX_DECLARE_SWAP_VARIABLES
;
935 __GLX_DECLARE_SWAP_ARRAY_VARIABLES
;
937 REQUEST_SIZE_MATCH(xGLXGetVisualConfigsReq
);
939 if (!validGlxScreen(cl
->client
, req
->screen
, &pGlxScreen
, &err
))
942 reply
= (xGLXGetVisualConfigsReply
) {
944 .sequenceNumber
= client
->sequence
,
945 .length
= (pGlxScreen
->numVisuals
*
946 __GLX_SIZE_CARD32
* GLX_VIS_CONFIG_TOTAL
) >> 2,
947 .numVisuals
= pGlxScreen
->numVisuals
,
948 .numProps
= GLX_VIS_CONFIG_TOTAL
951 if (client
->swapped
) {
952 __GLX_SWAP_SHORT(&reply
.sequenceNumber
);
953 __GLX_SWAP_INT(&reply
.length
);
954 __GLX_SWAP_INT(&reply
.numVisuals
);
955 __GLX_SWAP_INT(&reply
.numProps
);
958 WriteToClient(client
, sz_xGLXGetVisualConfigsReply
, &reply
);
960 for (i
= 0; i
< pGlxScreen
->numVisuals
; i
++) {
961 modes
= pGlxScreen
->visuals
[i
];
964 buf
[p
++] = modes
->visualID
;
965 buf
[p
++] = glxConvertToXVisualType(modes
->visualType
);
966 buf
[p
++] = (modes
->renderType
& GLX_RGBA_BIT
) ? GL_TRUE
: GL_FALSE
;
968 buf
[p
++] = modes
->redBits
;
969 buf
[p
++] = modes
->greenBits
;
970 buf
[p
++] = modes
->blueBits
;
971 buf
[p
++] = modes
->alphaBits
;
972 buf
[p
++] = modes
->accumRedBits
;
973 buf
[p
++] = modes
->accumGreenBits
;
974 buf
[p
++] = modes
->accumBlueBits
;
975 buf
[p
++] = modes
->accumAlphaBits
;
977 buf
[p
++] = modes
->doubleBufferMode
;
978 buf
[p
++] = modes
->stereoMode
;
980 buf
[p
++] = modes
->rgbBits
;
981 buf
[p
++] = modes
->depthBits
;
982 buf
[p
++] = modes
->stencilBits
;
983 buf
[p
++] = modes
->numAuxBuffers
;
984 buf
[p
++] = modes
->level
;
986 assert(p
== GLX_VIS_CONFIG_UNPAIRED
);
988 ** Add token/value pairs for extensions.
990 buf
[p
++] = GLX_VISUAL_CAVEAT_EXT
;
991 buf
[p
++] = modes
->visualRating
;
992 buf
[p
++] = GLX_TRANSPARENT_TYPE
;
993 buf
[p
++] = modes
->transparentPixel
;
994 buf
[p
++] = GLX_TRANSPARENT_RED_VALUE
;
995 buf
[p
++] = modes
->transparentRed
;
996 buf
[p
++] = GLX_TRANSPARENT_GREEN_VALUE
;
997 buf
[p
++] = modes
->transparentGreen
;
998 buf
[p
++] = GLX_TRANSPARENT_BLUE_VALUE
;
999 buf
[p
++] = modes
->transparentBlue
;
1000 buf
[p
++] = GLX_TRANSPARENT_ALPHA_VALUE
;
1001 buf
[p
++] = modes
->transparentAlpha
;
1002 buf
[p
++] = GLX_TRANSPARENT_INDEX_VALUE
;
1003 buf
[p
++] = modes
->transparentIndex
;
1004 buf
[p
++] = GLX_SAMPLES_SGIS
;
1005 buf
[p
++] = modes
->samples
;
1006 buf
[p
++] = GLX_SAMPLE_BUFFERS_SGIS
;
1007 buf
[p
++] = modes
->sampleBuffers
;
1008 /* Add attribute only if its value is not default. */
1009 if (modes
->sRGBCapable
!= GL_FALSE
) {
1010 buf
[p
++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT
;
1011 buf
[p
++] = modes
->sRGBCapable
;
1013 /* Don't add visualSelectGroup (GLX_VISUAL_SELECT_GROUP_SGIX)?
1014 * Pad the remaining place with zeroes, so that attributes count is constant. */
1015 while (p
< GLX_VIS_CONFIG_TOTAL
) {
1020 assert(p
== GLX_VIS_CONFIG_TOTAL
);
1021 if (client
->swapped
) {
1022 __GLX_SWAP_INT_ARRAY(buf
, p
);
1024 WriteToClient(client
, __GLX_SIZE_CARD32
* p
, buf
);
1029 #define __GLX_TOTAL_FBCONFIG_ATTRIBS (44)
1030 #define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2)
1032 * Send the set of GLXFBConfigs to the client. There is not currently
1033 * and interface into the driver on the server-side to get GLXFBConfigs,
1034 * so we "invent" some based on the \c __GLXvisualConfig structures that
1035 * the driver does supply.
1037 * The reply format for both \c glXGetFBConfigs and \c glXGetFBConfigsSGIX
1038 * is the same, so this routine pulls double duty.
1042 DoGetFBConfigs(__GLXclientState
* cl
, unsigned screen
)
1044 ClientPtr client
= cl
->client
;
1045 xGLXGetFBConfigsReply reply
;
1046 __GLXscreen
*pGlxScreen
;
1047 CARD32 buf
[__GLX_FBCONFIG_ATTRIBS_LENGTH
];
1051 __GLX_DECLARE_SWAP_VARIABLES
;
1052 __GLX_DECLARE_SWAP_ARRAY_VARIABLES
;
1054 if (!validGlxScreen(cl
->client
, screen
, &pGlxScreen
, &err
))
1057 reply
= (xGLXGetFBConfigsReply
) {
1059 .sequenceNumber
= client
->sequence
,
1060 .length
= __GLX_FBCONFIG_ATTRIBS_LENGTH
* pGlxScreen
->numFBConfigs
,
1061 .numFBConfigs
= pGlxScreen
->numFBConfigs
,
1062 .numAttribs
= __GLX_TOTAL_FBCONFIG_ATTRIBS
1065 if (client
->swapped
) {
1066 __GLX_SWAP_SHORT(&reply
.sequenceNumber
);
1067 __GLX_SWAP_INT(&reply
.length
);
1068 __GLX_SWAP_INT(&reply
.numFBConfigs
);
1069 __GLX_SWAP_INT(&reply
.numAttribs
);
1072 WriteToClient(client
, sz_xGLXGetFBConfigsReply
, &reply
);
1074 for (modes
= pGlxScreen
->fbconfigs
; modes
!= NULL
; modes
= modes
->next
) {
1077 #define WRITE_PAIR(tag,value) \
1078 do { buf[p++] = tag ; buf[p++] = value ; } while( 0 )
1080 WRITE_PAIR(GLX_VISUAL_ID
, modes
->visualID
);
1081 WRITE_PAIR(GLX_FBCONFIG_ID
, modes
->fbconfigID
);
1082 WRITE_PAIR(GLX_X_RENDERABLE
, GL_TRUE
);
1084 WRITE_PAIR(GLX_RGBA
,
1085 (modes
->renderType
& GLX_RGBA_BIT
) ? GL_TRUE
: GL_FALSE
);
1086 WRITE_PAIR(GLX_RENDER_TYPE
, modes
->renderType
);
1087 WRITE_PAIR(GLX_DOUBLEBUFFER
, modes
->doubleBufferMode
);
1088 WRITE_PAIR(GLX_STEREO
, modes
->stereoMode
);
1090 WRITE_PAIR(GLX_BUFFER_SIZE
, modes
->rgbBits
);
1091 WRITE_PAIR(GLX_LEVEL
, modes
->level
);
1092 WRITE_PAIR(GLX_AUX_BUFFERS
, modes
->numAuxBuffers
);
1093 WRITE_PAIR(GLX_RED_SIZE
, modes
->redBits
);
1094 WRITE_PAIR(GLX_GREEN_SIZE
, modes
->greenBits
);
1095 WRITE_PAIR(GLX_BLUE_SIZE
, modes
->blueBits
);
1096 WRITE_PAIR(GLX_ALPHA_SIZE
, modes
->alphaBits
);
1097 WRITE_PAIR(GLX_ACCUM_RED_SIZE
, modes
->accumRedBits
);
1098 WRITE_PAIR(GLX_ACCUM_GREEN_SIZE
, modes
->accumGreenBits
);
1099 WRITE_PAIR(GLX_ACCUM_BLUE_SIZE
, modes
->accumBlueBits
);
1100 WRITE_PAIR(GLX_ACCUM_ALPHA_SIZE
, modes
->accumAlphaBits
);
1101 WRITE_PAIR(GLX_DEPTH_SIZE
, modes
->depthBits
);
1102 WRITE_PAIR(GLX_STENCIL_SIZE
, modes
->stencilBits
);
1103 WRITE_PAIR(GLX_X_VISUAL_TYPE
, modes
->visualType
);
1104 WRITE_PAIR(GLX_CONFIG_CAVEAT
, modes
->visualRating
);
1105 WRITE_PAIR(GLX_TRANSPARENT_TYPE
, modes
->transparentPixel
);
1106 WRITE_PAIR(GLX_TRANSPARENT_RED_VALUE
, modes
->transparentRed
);
1107 WRITE_PAIR(GLX_TRANSPARENT_GREEN_VALUE
, modes
->transparentGreen
);
1108 WRITE_PAIR(GLX_TRANSPARENT_BLUE_VALUE
, modes
->transparentBlue
);
1109 WRITE_PAIR(GLX_TRANSPARENT_ALPHA_VALUE
, modes
->transparentAlpha
);
1110 WRITE_PAIR(GLX_TRANSPARENT_INDEX_VALUE
, modes
->transparentIndex
);
1111 WRITE_PAIR(GLX_SWAP_METHOD_OML
, modes
->swapMethod
);
1112 WRITE_PAIR(GLX_SAMPLES_SGIS
, modes
->samples
);
1113 WRITE_PAIR(GLX_SAMPLE_BUFFERS_SGIS
, modes
->sampleBuffers
);
1114 WRITE_PAIR(GLX_VISUAL_SELECT_GROUP_SGIX
, modes
->visualSelectGroup
);
1115 WRITE_PAIR(GLX_DRAWABLE_TYPE
, modes
->drawableType
);
1116 WRITE_PAIR(GLX_BIND_TO_TEXTURE_RGB_EXT
, modes
->bindToTextureRgb
);
1117 WRITE_PAIR(GLX_BIND_TO_TEXTURE_RGBA_EXT
, modes
->bindToTextureRgba
);
1118 WRITE_PAIR(GLX_BIND_TO_MIPMAP_TEXTURE_EXT
, modes
->bindToMipmapTexture
);
1119 WRITE_PAIR(GLX_BIND_TO_TEXTURE_TARGETS_EXT
,
1120 modes
->bindToTextureTargets
);
1121 /* can't report honestly until mesa is fixed */
1122 WRITE_PAIR(GLX_Y_INVERTED_EXT
, GLX_DONT_CARE
);
1123 if (modes
->drawableType
& GLX_PBUFFER_BIT
) {
1124 WRITE_PAIR(GLX_MAX_PBUFFER_WIDTH
, modes
->maxPbufferWidth
);
1125 WRITE_PAIR(GLX_MAX_PBUFFER_HEIGHT
, modes
->maxPbufferHeight
);
1126 WRITE_PAIR(GLX_MAX_PBUFFER_PIXELS
, modes
->maxPbufferPixels
);
1127 WRITE_PAIR(GLX_OPTIMAL_PBUFFER_WIDTH_SGIX
,
1128 modes
->optimalPbufferWidth
);
1129 WRITE_PAIR(GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX
,
1130 modes
->optimalPbufferHeight
);
1132 /* Add attribute only if its value is not default. */
1133 if (modes
->sRGBCapable
!= GL_FALSE
) {
1134 WRITE_PAIR(GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT
, modes
->sRGBCapable
);
1136 /* Pad the remaining place with zeroes, so that attributes count is constant. */
1137 while (p
< __GLX_FBCONFIG_ATTRIBS_LENGTH
) {
1140 assert(p
== __GLX_FBCONFIG_ATTRIBS_LENGTH
);
1142 if (client
->swapped
) {
1143 __GLX_SWAP_INT_ARRAY(buf
, __GLX_FBCONFIG_ATTRIBS_LENGTH
);
1145 WriteToClient(client
, __GLX_SIZE_CARD32
* __GLX_FBCONFIG_ATTRIBS_LENGTH
,
1152 __glXDisp_GetFBConfigs(__GLXclientState
* cl
, GLbyte
* pc
)
1154 ClientPtr client
= cl
->client
;
1155 xGLXGetFBConfigsReq
*req
= (xGLXGetFBConfigsReq
*) pc
;
1157 REQUEST_SIZE_MATCH(xGLXGetFBConfigsReq
);
1158 return DoGetFBConfigs(cl
, req
->screen
);
1162 __glXDisp_GetFBConfigsSGIX(__GLXclientState
* cl
, GLbyte
* pc
)
1164 ClientPtr client
= cl
->client
;
1165 xGLXGetFBConfigsSGIXReq
*req
= (xGLXGetFBConfigsSGIXReq
*) pc
;
1167 /* work around mesa bug, don't use REQUEST_SIZE_MATCH */
1168 REQUEST_AT_LEAST_SIZE(xGLXGetFBConfigsSGIXReq
);
1169 return DoGetFBConfigs(cl
, req
->screen
);
1173 __glXDrawableInit(__GLXdrawable
* drawable
,
1174 __GLXscreen
* screen
, DrawablePtr pDraw
, int type
,
1175 XID drawId
, __GLXconfig
* config
)
1177 drawable
->pDraw
= pDraw
;
1178 drawable
->type
= type
;
1179 drawable
->drawId
= drawId
;
1180 drawable
->config
= config
;
1181 drawable
->eventMask
= 0;
1187 __glXDrawableRelease(__GLXdrawable
* drawable
)
1192 DoCreateGLXDrawable(ClientPtr client
, __GLXscreen
* pGlxScreen
,
1193 __GLXconfig
* config
, DrawablePtr pDraw
, XID drawableId
,
1194 XID glxDrawableId
, int type
)
1196 __GLXdrawable
*pGlxDraw
;
1198 if (pGlxScreen
->pScreen
!= pDraw
->pScreen
)
1201 pGlxDraw
= pGlxScreen
->createDrawable(client
, pGlxScreen
, pDraw
,
1203 glxDrawableId
, config
);
1204 if (pGlxDraw
== NULL
)
1207 if (!AddResource(glxDrawableId
, __glXDrawableRes
, pGlxDraw
)) {
1208 pGlxDraw
->destroy(pGlxDraw
);
1213 * Windows aren't refcounted, so track both the X and the GLX window
1214 * so we get called regardless of destruction order.
1216 if (drawableId
!= glxDrawableId
&& type
== GLX_DRAWABLE_WINDOW
&&
1217 !AddResource(pDraw
->id
, __glXDrawableRes
, pGlxDraw
)) {
1218 pGlxDraw
->destroy(pGlxDraw
);
1226 DoCreateGLXPixmap(ClientPtr client
, __GLXscreen
* pGlxScreen
,
1227 __GLXconfig
* config
, XID drawableId
, XID glxDrawableId
)
1232 LEGAL_NEW_RESOURCE(glxDrawableId
, client
);
1234 err
= dixLookupDrawable(&pDraw
, drawableId
, client
, 0, DixAddAccess
);
1235 if (err
!= Success
) {
1236 client
->errorValue
= drawableId
;
1239 if (pDraw
->type
!= DRAWABLE_PIXMAP
) {
1240 client
->errorValue
= drawableId
;
1244 err
= DoCreateGLXDrawable(client
, pGlxScreen
, config
, pDraw
, drawableId
,
1245 glxDrawableId
, GLX_DRAWABLE_PIXMAP
);
1248 ((PixmapPtr
) pDraw
)->refcnt
++;
1254 determineTextureTarget(ClientPtr client
, XID glxDrawableID
,
1255 CARD32
*attribs
, CARD32 numAttribs
)
1260 __GLXdrawable
*pGlxDraw
;
1262 if (!validGlxDrawable(client
, glxDrawableID
, GLX_DRAWABLE_PIXMAP
,
1263 DixWriteAccess
, &pGlxDraw
, &err
))
1264 /* We just added it in CreatePixmap, so we should never get here. */
1267 for (i
= 0; i
< numAttribs
; i
++) {
1268 if (attribs
[2 * i
] == GLX_TEXTURE_TARGET_EXT
) {
1269 switch (attribs
[2 * i
+ 1]) {
1270 case GLX_TEXTURE_2D_EXT
:
1271 target
= GL_TEXTURE_2D
;
1273 case GLX_TEXTURE_RECTANGLE_EXT
:
1274 target
= GL_TEXTURE_RECTANGLE_ARB
;
1279 if (attribs
[2 * i
] == GLX_TEXTURE_FORMAT_EXT
)
1280 format
= attribs
[2 * i
+ 1];
1284 int w
= pGlxDraw
->pDraw
->width
, h
= pGlxDraw
->pDraw
->height
;
1286 if (h
& (h
- 1) || w
& (w
- 1))
1287 target
= GL_TEXTURE_RECTANGLE_ARB
;
1289 target
= GL_TEXTURE_2D
;
1292 pGlxDraw
->target
= target
;
1293 pGlxDraw
->format
= format
;
1297 __glXDisp_CreateGLXPixmap(__GLXclientState
* cl
, GLbyte
* pc
)
1299 ClientPtr client
= cl
->client
;
1300 xGLXCreateGLXPixmapReq
*req
= (xGLXCreateGLXPixmapReq
*) pc
;
1301 __GLXconfig
*config
;
1302 __GLXscreen
*pGlxScreen
;
1305 REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapReq
);
1307 if (!validGlxScreen(cl
->client
, req
->screen
, &pGlxScreen
, &err
))
1309 if (!validGlxVisual(cl
->client
, pGlxScreen
, req
->visual
, &config
, &err
))
1312 return DoCreateGLXPixmap(cl
->client
, pGlxScreen
, config
,
1313 req
->pixmap
, req
->glxpixmap
);
1317 __glXDisp_CreatePixmap(__GLXclientState
* cl
, GLbyte
* pc
)
1319 ClientPtr client
= cl
->client
;
1320 xGLXCreatePixmapReq
*req
= (xGLXCreatePixmapReq
*) pc
;
1321 __GLXconfig
*config
;
1322 __GLXscreen
*pGlxScreen
;
1325 REQUEST_AT_LEAST_SIZE(xGLXCreatePixmapReq
);
1326 if (req
->numAttribs
> (UINT32_MAX
>> 3)) {
1327 client
->errorValue
= req
->numAttribs
;
1330 REQUEST_FIXED_SIZE(xGLXCreatePixmapReq
, req
->numAttribs
<< 3);
1332 if (!validGlxScreen(cl
->client
, req
->screen
, &pGlxScreen
, &err
))
1334 if (!validGlxFBConfig(cl
->client
, pGlxScreen
, req
->fbconfig
, &config
, &err
))
1337 err
= DoCreateGLXPixmap(cl
->client
, pGlxScreen
, config
,
1338 req
->pixmap
, req
->glxpixmap
);
1342 determineTextureTarget(cl
->client
, req
->glxpixmap
,
1343 (CARD32
*) (req
+ 1), req
->numAttribs
);
1349 __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState
* cl
, GLbyte
* pc
)
1351 ClientPtr client
= cl
->client
;
1352 xGLXCreateGLXPixmapWithConfigSGIXReq
*req
=
1353 (xGLXCreateGLXPixmapWithConfigSGIXReq
*) pc
;
1354 __GLXconfig
*config
;
1355 __GLXscreen
*pGlxScreen
;
1358 REQUEST_SIZE_MATCH(xGLXCreateGLXPixmapWithConfigSGIXReq
);
1360 if (!validGlxScreen(cl
->client
, req
->screen
, &pGlxScreen
, &err
))
1362 if (!validGlxFBConfig(cl
->client
, pGlxScreen
, req
->fbconfig
, &config
, &err
))
1365 return DoCreateGLXPixmap(cl
->client
, pGlxScreen
,
1366 config
, req
->pixmap
, req
->glxpixmap
);
1370 DoDestroyDrawable(__GLXclientState
* cl
, XID glxdrawable
, int type
)
1372 __GLXdrawable
*pGlxDraw
;
1375 if (!validGlxDrawable(cl
->client
, glxdrawable
, type
,
1376 DixDestroyAccess
, &pGlxDraw
, &err
))
1379 FreeResource(glxdrawable
, FALSE
);
1385 __glXDisp_DestroyGLXPixmap(__GLXclientState
* cl
, GLbyte
* pc
)
1387 ClientPtr client
= cl
->client
;
1388 xGLXDestroyGLXPixmapReq
*req
= (xGLXDestroyGLXPixmapReq
*) pc
;
1390 REQUEST_SIZE_MATCH(xGLXDestroyGLXPixmapReq
);
1392 return DoDestroyDrawable(cl
, req
->glxpixmap
, GLX_DRAWABLE_PIXMAP
);
1396 __glXDisp_DestroyPixmap(__GLXclientState
* cl
, GLbyte
* pc
)
1398 ClientPtr client
= cl
->client
;
1399 xGLXDestroyPixmapReq
*req
= (xGLXDestroyPixmapReq
*) pc
;
1401 /* should be REQUEST_SIZE_MATCH, but mesa's glXDestroyPixmap used to set
1402 * length to 3 instead of 2 */
1403 REQUEST_AT_LEAST_SIZE(xGLXDestroyPixmapReq
);
1405 return DoDestroyDrawable(cl
, req
->glxpixmap
, GLX_DRAWABLE_PIXMAP
);
1409 DoCreatePbuffer(ClientPtr client
, int screenNum
, XID fbconfigId
,
1410 int width
, int height
, XID glxDrawableId
)
1412 __GLXconfig
*config
;
1413 __GLXscreen
*pGlxScreen
;
1417 LEGAL_NEW_RESOURCE(glxDrawableId
, client
);
1419 if (!validGlxScreen(client
, screenNum
, &pGlxScreen
, &err
))
1421 if (!validGlxFBConfig(client
, pGlxScreen
, fbconfigId
, &config
, &err
))
1424 __glXenterServer(GL_FALSE
);
1425 pPixmap
= (*pGlxScreen
->pScreen
->CreatePixmap
) (pGlxScreen
->pScreen
,
1427 config
->rgbBits
, 0);
1428 __glXleaveServer(GL_FALSE
);
1432 /* Assign the pixmap the same id as the pbuffer and add it as a
1433 * resource so it and the DRI2 drawable will be reclaimed when the
1434 * pbuffer is destroyed. */
1435 pPixmap
->drawable
.id
= glxDrawableId
;
1436 if (!AddResource(pPixmap
->drawable
.id
, RT_PIXMAP
, pPixmap
))
1439 return DoCreateGLXDrawable(client
, pGlxScreen
, config
, &pPixmap
->drawable
,
1440 glxDrawableId
, glxDrawableId
,
1441 GLX_DRAWABLE_PBUFFER
);
1445 __glXDisp_CreatePbuffer(__GLXclientState
* cl
, GLbyte
* pc
)
1447 ClientPtr client
= cl
->client
;
1448 xGLXCreatePbufferReq
*req
= (xGLXCreatePbufferReq
*) pc
;
1450 int width
, height
, i
;
1452 REQUEST_AT_LEAST_SIZE(xGLXCreatePbufferReq
);
1453 if (req
->numAttribs
> (UINT32_MAX
>> 3)) {
1454 client
->errorValue
= req
->numAttribs
;
1457 REQUEST_FIXED_SIZE(xGLXCreatePbufferReq
, req
->numAttribs
<< 3);
1459 attrs
= (CARD32
*) (req
+ 1);
1463 for (i
= 0; i
< req
->numAttribs
; i
++) {
1464 switch (attrs
[i
* 2]) {
1465 case GLX_PBUFFER_WIDTH
:
1466 width
= attrs
[i
* 2 + 1];
1468 case GLX_PBUFFER_HEIGHT
:
1469 height
= attrs
[i
* 2 + 1];
1471 case GLX_LARGEST_PBUFFER
:
1477 return DoCreatePbuffer(cl
->client
, req
->screen
, req
->fbconfig
,
1478 width
, height
, req
->pbuffer
);
1482 __glXDisp_CreateGLXPbufferSGIX(__GLXclientState
* cl
, GLbyte
* pc
)
1484 ClientPtr client
= cl
->client
;
1485 xGLXCreateGLXPbufferSGIXReq
*req
= (xGLXCreateGLXPbufferSGIXReq
*) pc
;
1487 REQUEST_AT_LEAST_SIZE(xGLXCreateGLXPbufferSGIXReq
);
1490 * We should really handle attributes correctly, but this extension
1491 * is so rare I have difficulty caring.
1493 return DoCreatePbuffer(cl
->client
, req
->screen
, req
->fbconfig
,
1494 req
->width
, req
->height
, req
->pbuffer
);
1498 __glXDisp_DestroyPbuffer(__GLXclientState
* cl
, GLbyte
* pc
)
1500 ClientPtr client
= cl
->client
;
1501 xGLXDestroyPbufferReq
*req
= (xGLXDestroyPbufferReq
*) pc
;
1503 REQUEST_SIZE_MATCH(xGLXDestroyPbufferReq
);
1505 return DoDestroyDrawable(cl
, req
->pbuffer
, GLX_DRAWABLE_PBUFFER
);
1509 __glXDisp_DestroyGLXPbufferSGIX(__GLXclientState
* cl
, GLbyte
* pc
)
1511 ClientPtr client
= cl
->client
;
1512 xGLXDestroyGLXPbufferSGIXReq
*req
= (xGLXDestroyGLXPbufferSGIXReq
*) pc
;
1514 REQUEST_SIZE_MATCH(xGLXDestroyGLXPbufferSGIXReq
);
1516 return DoDestroyDrawable(cl
, req
->pbuffer
, GLX_DRAWABLE_PBUFFER
);
1520 DoChangeDrawableAttributes(ClientPtr client
, XID glxdrawable
,
1521 int numAttribs
, CARD32
*attribs
)
1523 __GLXdrawable
*pGlxDraw
;
1526 if (!validGlxDrawable(client
, glxdrawable
, GLX_DRAWABLE_ANY
,
1527 DixSetAttrAccess
, &pGlxDraw
, &err
))
1530 for (i
= 0; i
< numAttribs
; i
++) {
1531 switch (attribs
[i
* 2]) {
1532 case GLX_EVENT_MASK
:
1533 /* All we do is to record the event mask so we can send it
1534 * back when queried. We never actually clobber the
1535 * pbuffers, so we never need to send out the event. */
1536 pGlxDraw
->eventMask
= attribs
[i
* 2 + 1];
1545 __glXDisp_ChangeDrawableAttributes(__GLXclientState
* cl
, GLbyte
* pc
)
1547 ClientPtr client
= cl
->client
;
1548 xGLXChangeDrawableAttributesReq
*req
=
1549 (xGLXChangeDrawableAttributesReq
*) pc
;
1551 REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesReq
);
1552 if (req
->numAttribs
> (UINT32_MAX
>> 3)) {
1553 client
->errorValue
= req
->numAttribs
;
1557 /* mesa sends an additional 8 bytes */
1558 REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesReq
, req
->numAttribs
<< 3);
1560 if (((sizeof(xGLXChangeDrawableAttributesReq
) +
1561 (req
->numAttribs
<< 3)) >> 2) < client
->req_len
)
1565 return DoChangeDrawableAttributes(cl
->client
, req
->drawable
,
1566 req
->numAttribs
, (CARD32
*) (req
+ 1));
1570 __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState
* cl
, GLbyte
* pc
)
1572 ClientPtr client
= cl
->client
;
1573 xGLXChangeDrawableAttributesSGIXReq
*req
=
1574 (xGLXChangeDrawableAttributesSGIXReq
*) pc
;
1576 REQUEST_AT_LEAST_SIZE(xGLXChangeDrawableAttributesSGIXReq
);
1577 if (req
->numAttribs
> (UINT32_MAX
>> 3)) {
1578 client
->errorValue
= req
->numAttribs
;
1581 REQUEST_FIXED_SIZE(xGLXChangeDrawableAttributesSGIXReq
,
1582 req
->numAttribs
<< 3);
1584 return DoChangeDrawableAttributes(cl
->client
, req
->drawable
,
1585 req
->numAttribs
, (CARD32
*) (req
+ 1));
1589 __glXDisp_CreateWindow(__GLXclientState
* cl
, GLbyte
* pc
)
1591 xGLXCreateWindowReq
*req
= (xGLXCreateWindowReq
*) pc
;
1592 __GLXconfig
*config
;
1593 __GLXscreen
*pGlxScreen
;
1594 ClientPtr client
= cl
->client
;
1598 REQUEST_AT_LEAST_SIZE(xGLXCreateWindowReq
);
1599 if (req
->numAttribs
> (UINT32_MAX
>> 3)) {
1600 client
->errorValue
= req
->numAttribs
;
1603 REQUEST_FIXED_SIZE(xGLXCreateWindowReq
, req
->numAttribs
<< 3);
1605 LEGAL_NEW_RESOURCE(req
->glxwindow
, client
);
1607 if (!validGlxScreen(client
, req
->screen
, &pGlxScreen
, &err
))
1609 if (!validGlxFBConfig(client
, pGlxScreen
, req
->fbconfig
, &config
, &err
))
1612 err
= dixLookupDrawable(&pDraw
, req
->window
, client
, 0, DixAddAccess
);
1613 if (err
!= Success
|| pDraw
->type
!= DRAWABLE_WINDOW
) {
1614 client
->errorValue
= req
->window
;
1618 if (!validGlxFBConfigForWindow(client
, config
, pDraw
, &err
))
1621 return DoCreateGLXDrawable(client
, pGlxScreen
, config
,
1623 req
->glxwindow
, GLX_DRAWABLE_WINDOW
);
1627 __glXDisp_DestroyWindow(__GLXclientState
* cl
, GLbyte
* pc
)
1629 ClientPtr client
= cl
->client
;
1630 xGLXDestroyWindowReq
*req
= (xGLXDestroyWindowReq
*) pc
;
1632 /* mesa's glXDestroyWindow used to set length to 3 instead of 2 */
1633 REQUEST_AT_LEAST_SIZE(xGLXDestroyWindowReq
);
1635 return DoDestroyDrawable(cl
, req
->glxwindow
, GLX_DRAWABLE_WINDOW
);
1638 /*****************************************************************************/
1641 ** NOTE: There is no portable implementation for swap buffers as of
1642 ** this time that is of value. Consequently, this code must be
1643 ** implemented by somebody other than SGI.
1646 __glXDisp_SwapBuffers(__GLXclientState
* cl
, GLbyte
* pc
)
1648 ClientPtr client
= cl
->client
;
1649 xGLXSwapBuffersReq
*req
= (xGLXSwapBuffersReq
*) pc
;
1652 __GLXcontext
*glxc
= NULL
;
1653 __GLXdrawable
*pGlxDraw
;
1656 REQUEST_SIZE_MATCH(xGLXSwapBuffersReq
);
1658 tag
= req
->contextTag
;
1659 drawId
= req
->drawable
;
1661 glxc
= __glXLookupContextByTag(cl
, tag
);
1663 return __glXError(GLXBadContextTag
);
1666 ** The calling thread is swapping its current drawable. In this case,
1667 ** glxSwapBuffers is in both GL and X streams, in terms of
1670 if (__glXForceCurrent(cl
, tag
, &error
)) {
1672 ** Do whatever is needed to make sure that all preceding requests
1673 ** in both streams are completed before the swap is executed.
1676 glxc
->hasUnflushedCommands
= GL_FALSE
;
1683 pGlxDraw
= __glXGetDrawable(glxc
, drawId
, client
, &error
);
1684 if (pGlxDraw
== NULL
)
1687 if (pGlxDraw
->type
== DRAWABLE_WINDOW
&&
1688 (*pGlxDraw
->swapBuffers
) (cl
->client
, pGlxDraw
) == GL_FALSE
)
1689 return __glXError(GLXBadDrawable
);
1695 DoQueryContext(__GLXclientState
* cl
, GLXContextID gcId
)
1697 ClientPtr client
= cl
->client
;
1699 xGLXQueryContextInfoEXTReply reply
;
1701 int sendBuf
[nProps
* 2];
1705 if (!validGlxContext(cl
->client
, gcId
, DixReadAccess
, &ctx
, &err
))
1708 reply
= (xGLXQueryContextInfoEXTReply
) {
1710 .sequenceNumber
= client
->sequence
,
1711 .length
= nProps
<< 1,
1715 nReplyBytes
= reply
.length
<< 2;
1716 sendBuf
[0] = GLX_SHARE_CONTEXT_EXT
;
1717 sendBuf
[1] = (int) (ctx
->share_id
);
1718 sendBuf
[2] = GLX_VISUAL_ID_EXT
;
1719 sendBuf
[3] = (int) (ctx
->config
->visualID
);
1720 sendBuf
[4] = GLX_SCREEN_EXT
;
1721 sendBuf
[5] = (int) (ctx
->pGlxScreen
->pScreen
->myNum
);
1723 if (client
->swapped
) {
1724 __glXSwapQueryContextInfoEXTReply(client
, &reply
, sendBuf
);
1727 WriteToClient(client
, sz_xGLXQueryContextInfoEXTReply
, &reply
);
1728 WriteToClient(client
, nReplyBytes
, sendBuf
);
1735 __glXDisp_QueryContextInfoEXT(__GLXclientState
* cl
, GLbyte
* pc
)
1737 ClientPtr client
= cl
->client
;
1738 xGLXQueryContextInfoEXTReq
*req
= (xGLXQueryContextInfoEXTReq
*) pc
;
1740 REQUEST_SIZE_MATCH(xGLXQueryContextInfoEXTReq
);
1742 return DoQueryContext(cl
, req
->context
);
1746 __glXDisp_QueryContext(__GLXclientState
* cl
, GLbyte
* pc
)
1748 ClientPtr client
= cl
->client
;
1749 xGLXQueryContextReq
*req
= (xGLXQueryContextReq
*) pc
;
1751 REQUEST_SIZE_MATCH(xGLXQueryContextReq
);
1753 return DoQueryContext(cl
, req
->context
);
1757 __glXDisp_BindTexImageEXT(__GLXclientState
* cl
, GLbyte
* pc
)
1759 xGLXVendorPrivateReq
*req
= (xGLXVendorPrivateReq
*) pc
;
1760 ClientPtr client
= cl
->client
;
1761 __GLXcontext
*context
;
1762 __GLXdrawable
*pGlxDraw
;
1768 if ((sizeof(xGLXVendorPrivateReq
) + 12) >> 2 > client
->req_len
)
1771 pc
+= __GLX_VENDPRIV_HDR_SIZE
;
1773 drawId
= *((CARD32
*) (pc
));
1774 buffer
= *((INT32
*) (pc
+ 4));
1775 num_attribs
= *((CARD32
*) (pc
+ 8));
1776 if (num_attribs
> (UINT32_MAX
>> 3)) {
1777 client
->errorValue
= num_attribs
;
1780 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq
, 12 + (num_attribs
<< 3));
1782 if (buffer
!= GLX_FRONT_LEFT_EXT
)
1783 return __glXError(GLXBadPixmap
);
1785 context
= __glXForceCurrent(cl
, req
->contextTag
, &error
);
1789 if (!validGlxDrawable(client
, drawId
, GLX_DRAWABLE_PIXMAP
,
1790 DixReadAccess
, &pGlxDraw
, &error
))
1793 if (!context
->textureFromPixmap
)
1794 return __glXError(GLXUnsupportedPrivateRequest
);
1796 return context
->textureFromPixmap
->bindTexImage(context
, buffer
, pGlxDraw
);
1800 __glXDisp_ReleaseTexImageEXT(__GLXclientState
* cl
, GLbyte
* pc
)
1802 xGLXVendorPrivateReq
*req
= (xGLXVendorPrivateReq
*) pc
;
1803 ClientPtr client
= cl
->client
;
1804 __GLXdrawable
*pGlxDraw
;
1805 __GLXcontext
*context
;
1810 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq
, 8);
1812 pc
+= __GLX_VENDPRIV_HDR_SIZE
;
1814 drawId
= *((CARD32
*) (pc
));
1815 buffer
= *((INT32
*) (pc
+ 4));
1817 context
= __glXForceCurrent(cl
, req
->contextTag
, &error
);
1821 if (!validGlxDrawable(client
, drawId
, GLX_DRAWABLE_PIXMAP
,
1822 DixReadAccess
, &pGlxDraw
, &error
))
1825 if (!context
->textureFromPixmap
)
1826 return __glXError(GLXUnsupportedPrivateRequest
);
1828 return context
->textureFromPixmap
->releaseTexImage(context
,
1833 __glXDisp_CopySubBufferMESA(__GLXclientState
* cl
, GLbyte
* pc
)
1835 xGLXVendorPrivateReq
*req
= (xGLXVendorPrivateReq
*) pc
;
1836 GLXContextTag tag
= req
->contextTag
;
1837 __GLXcontext
*glxc
= NULL
;
1838 __GLXdrawable
*pGlxDraw
;
1839 ClientPtr client
= cl
->client
;
1842 int x
, y
, width
, height
;
1847 REQUEST_FIXED_SIZE(xGLXVendorPrivateReq
, 20);
1849 pc
+= __GLX_VENDPRIV_HDR_SIZE
;
1851 drawId
= *((CARD32
*) (pc
));
1852 x
= *((INT32
*) (pc
+ 4));
1853 y
= *((INT32
*) (pc
+ 8));
1854 width
= *((INT32
*) (pc
+ 12));
1855 height
= *((INT32
*) (pc
+ 16));
1858 glxc
= __glXLookupContextByTag(cl
, tag
);
1860 return __glXError(GLXBadContextTag
);
1863 ** The calling thread is swapping its current drawable. In this case,
1864 ** glxSwapBuffers is in both GL and X streams, in terms of
1867 if (__glXForceCurrent(cl
, tag
, &error
)) {
1869 ** Do whatever is needed to make sure that all preceding requests
1870 ** in both streams are completed before the swap is executed.
1873 glxc
->hasUnflushedCommands
= GL_FALSE
;
1880 pGlxDraw
= __glXGetDrawable(glxc
, drawId
, client
, &error
);
1884 if (pGlxDraw
== NULL
||
1885 pGlxDraw
->type
!= GLX_DRAWABLE_WINDOW
||
1886 pGlxDraw
->copySubBuffer
== NULL
)
1887 return __glXError(GLXBadDrawable
);
1889 (*pGlxDraw
->copySubBuffer
) (pGlxDraw
, x
, y
, width
, height
);
1895 ** Get drawable attributes
1898 DoGetDrawableAttributes(__GLXclientState
* cl
, XID drawId
)
1900 ClientPtr client
= cl
->client
;
1901 xGLXGetDrawableAttributesReply reply
;
1902 __GLXdrawable
*pGlxDraw
;
1903 CARD32 attributes
[14];
1904 int numAttribs
= 0, error
;
1906 if (!validGlxDrawable(client
, drawId
, GLX_DRAWABLE_ANY
,
1907 DixGetAttrAccess
, &pGlxDraw
, &error
))
1910 attributes
[0] = GLX_TEXTURE_TARGET_EXT
;
1911 attributes
[1] = pGlxDraw
->target
== GL_TEXTURE_2D
? GLX_TEXTURE_2D_EXT
:
1912 GLX_TEXTURE_RECTANGLE_EXT
;
1914 attributes
[2] = GLX_Y_INVERTED_EXT
;
1915 attributes
[3] = GL_FALSE
;
1917 attributes
[4] = GLX_EVENT_MASK
;
1918 attributes
[5] = pGlxDraw
->eventMask
;
1920 attributes
[6] = GLX_WIDTH
;
1921 attributes
[7] = pGlxDraw
->pDraw
->width
;
1923 attributes
[8] = GLX_HEIGHT
;
1924 attributes
[9] = pGlxDraw
->pDraw
->height
;
1926 attributes
[10] = GLX_FBCONFIG_ID
;
1927 attributes
[11] = pGlxDraw
->config
->fbconfigID
;
1929 if (pGlxDraw
->type
== GLX_DRAWABLE_PBUFFER
) {
1930 attributes
[12] = GLX_PRESERVED_CONTENTS
;
1931 attributes
[13] = GL_TRUE
;
1935 reply
= (xGLXGetDrawableAttributesReply
) {
1937 .sequenceNumber
= client
->sequence
,
1938 .length
= numAttribs
<< 1,
1939 .numAttribs
= numAttribs
1942 if (client
->swapped
) {
1943 __glXSwapGetDrawableAttributesReply(client
, &reply
, attributes
);
1946 WriteToClient(client
, sz_xGLXGetDrawableAttributesReply
, &reply
);
1947 WriteToClient(client
, reply
.length
* sizeof(CARD32
), attributes
);
1954 __glXDisp_GetDrawableAttributes(__GLXclientState
* cl
, GLbyte
* pc
)
1956 ClientPtr client
= cl
->client
;
1957 xGLXGetDrawableAttributesReq
*req
= (xGLXGetDrawableAttributesReq
*) pc
;
1959 /* this should be REQUEST_SIZE_MATCH, but mesa sends an additional 4 bytes */
1960 REQUEST_AT_LEAST_SIZE(xGLXGetDrawableAttributesReq
);
1962 return DoGetDrawableAttributes(cl
, req
->drawable
);
1966 __glXDisp_GetDrawableAttributesSGIX(__GLXclientState
* cl
, GLbyte
* pc
)
1968 ClientPtr client
= cl
->client
;
1969 xGLXGetDrawableAttributesSGIXReq
*req
=
1970 (xGLXGetDrawableAttributesSGIXReq
*) pc
;
1972 REQUEST_SIZE_MATCH(xGLXGetDrawableAttributesSGIXReq
);
1974 return DoGetDrawableAttributes(cl
, req
->drawable
);
1977 /************************************************************************/
1980 ** Render and Renderlarge are not in the GLX API. They are used by the GLX
1981 ** client library to send batches of GL rendering commands.
1985 ** Execute all the drawing commands in a request.
1988 __glXDisp_Render(__GLXclientState
* cl
, GLbyte
* pc
)
1991 ClientPtr client
= cl
->client
;
1992 int left
, cmdlen
, error
;
1995 __GLXrenderHeader
*hdr
;
1998 __GLX_DECLARE_SWAP_VARIABLES
;
2000 REQUEST_AT_LEAST_SIZE(xGLXRenderReq
);
2002 req
= (xGLXRenderReq
*) pc
;
2003 if (client
->swapped
) {
2004 __GLX_SWAP_SHORT(&req
->length
);
2005 __GLX_SWAP_INT(&req
->contextTag
);
2008 glxc
= __glXForceCurrent(cl
, req
->contextTag
, &error
);
2014 pc
+= sz_xGLXRenderReq
;
2015 left
= (req
->length
<< 2) - sz_xGLXRenderReq
;
2017 __GLXrenderSizeData entry
;
2019 __GLXdispatchRenderProcPtr proc
;
2022 if (left
< sizeof(__GLXrenderHeader
))
2026 ** Verify that the header length and the overall length agree.
2027 ** Also, each command must be word aligned.
2029 hdr
= (__GLXrenderHeader
*) pc
;
2030 if (client
->swapped
) {
2031 __GLX_SWAP_SHORT(&hdr
->length
);
2032 __GLX_SWAP_SHORT(&hdr
->opcode
);
2034 cmdlen
= hdr
->length
;
2035 opcode
= hdr
->opcode
;
2038 ** Check for core opcodes and grab entry data.
2040 err
= __glXGetProtocolSizeData(&Render_dispatch_info
, opcode
, &entry
);
2041 proc
= (__GLXdispatchRenderProcPtr
)
2042 __glXGetProtocolDecodeFunction(&Render_dispatch_info
,
2043 opcode
, client
->swapped
);
2045 if ((err
< 0) || (proc
== NULL
)) {
2046 client
->errorValue
= commandsDone
;
2047 return __glXError(GLXBadRenderRequest
);
2050 if (entry
.varsize
) {
2051 /* variable size command */
2052 extra
= (*entry
.varsize
) (pc
+ __GLX_RENDER_HDR_SIZE
,
2057 if (cmdlen
!= __GLX_PAD(entry
.bytes
+ extra
)) {
2062 /* constant size command */
2063 if (cmdlen
!= __GLX_PAD(entry
.bytes
)) {
2067 if (left
< cmdlen
) {
2072 ** Skip over the header and execute the command. We allow the
2073 ** caller to trash the command memory. This is useful especially
2074 ** for things that require double alignment - they can just shift
2075 ** the data towards lower memory (trashing the header) by 4 bytes
2076 ** and achieve the required alignment.
2078 (*proc
) (pc
+ __GLX_RENDER_HDR_SIZE
);
2083 glxc
->hasUnflushedCommands
= GL_TRUE
;
2088 ** Execute a large rendering request (one that spans multiple X requests).
2091 __glXDisp_RenderLarge(__GLXclientState
* cl
, GLbyte
* pc
)
2093 xGLXRenderLargeReq
*req
;
2094 ClientPtr client
= cl
->client
;
2096 __GLXrenderLargeHeader
*hdr
;
2101 __GLX_DECLARE_SWAP_VARIABLES
;
2103 req
= (xGLXRenderLargeReq
*) pc
;
2104 if (client
->swapped
) {
2105 __GLX_SWAP_SHORT(&req
->length
);
2106 __GLX_SWAP_INT(&req
->contextTag
);
2107 __GLX_SWAP_INT(&req
->dataBytes
);
2108 __GLX_SWAP_SHORT(&req
->requestNumber
);
2109 __GLX_SWAP_SHORT(&req
->requestTotal
);
2112 glxc
= __glXForceCurrent(cl
, req
->contextTag
, &error
);
2114 /* Reset in case this isn't 1st request. */
2115 __glXResetLargeCommandStatus(cl
);
2118 dataBytes
= req
->dataBytes
;
2121 ** Check the request length.
2123 if ((req
->length
<< 2) != __GLX_PAD(dataBytes
) + sz_xGLXRenderLargeReq
) {
2124 client
->errorValue
= req
->length
;
2125 /* Reset in case this isn't 1st request. */
2126 __glXResetLargeCommandStatus(cl
);
2129 pc
+= sz_xGLXRenderLargeReq
;
2131 if (cl
->largeCmdRequestsSoFar
== 0) {
2132 __GLXrenderSizeData entry
;
2138 ** This is the first request of a multi request command.
2139 ** Make enough space in the buffer, then copy the entire request.
2141 if (req
->requestNumber
!= 1) {
2142 client
->errorValue
= req
->requestNumber
;
2143 return __glXError(GLXBadLargeRequest
);
2146 hdr
= (__GLXrenderLargeHeader
*) pc
;
2147 if (client
->swapped
) {
2148 __GLX_SWAP_INT(&hdr
->length
);
2149 __GLX_SWAP_INT(&hdr
->opcode
);
2151 cmdlen
= hdr
->length
;
2152 opcode
= hdr
->opcode
;
2155 ** Check for core opcodes and grab entry data.
2157 err
= __glXGetProtocolSizeData(&Render_dispatch_info
, opcode
, &entry
);
2159 client
->errorValue
= opcode
;
2160 return __glXError(GLXBadLargeRequest
);
2163 if (entry
.varsize
) {
2165 ** If it's a variable-size command (a command whose length must
2166 ** be computed from its parameters), all the parameters needed
2167 ** will be in the 1st request, so it's okay to do this.
2169 extra
= (*entry
.varsize
) (pc
+ __GLX_RENDER_LARGE_HDR_SIZE
,
2174 /* large command's header is 4 bytes longer, so add 4 */
2175 if (cmdlen
!= __GLX_PAD(entry
.bytes
+ 4 + extra
)) {
2180 /* constant size command */
2181 if (cmdlen
!= __GLX_PAD(entry
.bytes
+ 4)) {
2186 ** Make enough space in the buffer, then copy the entire request.
2188 if (cl
->largeCmdBufSize
< cmdlen
) {
2189 GLbyte
*newbuf
= cl
->largeCmdBuf
;
2191 if (!(newbuf
= realloc(newbuf
, cmdlen
)))
2194 cl
->largeCmdBuf
= newbuf
;
2195 cl
->largeCmdBufSize
= cmdlen
;
2197 memcpy(cl
->largeCmdBuf
, pc
, dataBytes
);
2199 cl
->largeCmdBytesSoFar
= dataBytes
;
2200 cl
->largeCmdBytesTotal
= cmdlen
;
2201 cl
->largeCmdRequestsSoFar
= 1;
2202 cl
->largeCmdRequestsTotal
= req
->requestTotal
;
2208 ** We are receiving subsequent (i.e. not the first) requests of a
2209 ** multi request command.
2213 ** Check the request number and the total request count.
2215 if (req
->requestNumber
!= cl
->largeCmdRequestsSoFar
+ 1) {
2216 client
->errorValue
= req
->requestNumber
;
2217 __glXResetLargeCommandStatus(cl
);
2218 return __glXError(GLXBadLargeRequest
);
2220 if (req
->requestTotal
!= cl
->largeCmdRequestsTotal
) {
2221 client
->errorValue
= req
->requestTotal
;
2222 __glXResetLargeCommandStatus(cl
);
2223 return __glXError(GLXBadLargeRequest
);
2227 ** Check that we didn't get too much data.
2229 if ((cl
->largeCmdBytesSoFar
+ dataBytes
) > cl
->largeCmdBytesTotal
) {
2230 client
->errorValue
= dataBytes
;
2231 __glXResetLargeCommandStatus(cl
);
2232 return __glXError(GLXBadLargeRequest
);
2234 memcpy(cl
->largeCmdBuf
+ cl
->largeCmdBytesSoFar
, pc
, dataBytes
);
2235 cl
->largeCmdBytesSoFar
+= dataBytes
;
2236 cl
->largeCmdRequestsSoFar
++;
2238 if (req
->requestNumber
== cl
->largeCmdRequestsTotal
) {
2239 __GLXdispatchRenderProcPtr proc
;
2242 ** This is the last request; it must have enough bytes to complete
2245 /* NOTE: the two pad macros have been added below; they are needed
2246 ** because the client library pads the total byte count, but not
2247 ** the per-request byte counts. The Protocol Encoding says the
2248 ** total byte count should not be padded, so a proposal will be
2249 ** made to the ARB to relax the padding constraint on the total
2250 ** byte count, thus preserving backward compatibility. Meanwhile,
2251 ** the padding done below fixes a bug that did not allow
2252 ** large commands of odd sizes to be accepted by the server.
2254 if (__GLX_PAD(cl
->largeCmdBytesSoFar
) !=
2255 __GLX_PAD(cl
->largeCmdBytesTotal
)) {
2256 client
->errorValue
= dataBytes
;
2257 __glXResetLargeCommandStatus(cl
);
2258 return __glXError(GLXBadLargeRequest
);
2260 hdr
= (__GLXrenderLargeHeader
*) cl
->largeCmdBuf
;
2262 ** The opcode and length field in the header had already been
2263 ** swapped when the first request was received.
2265 ** Use the opcode to index into the procedure table.
2267 opcode
= hdr
->opcode
;
2269 proc
= (__GLXdispatchRenderProcPtr
)
2270 __glXGetProtocolDecodeFunction(&Render_dispatch_info
, opcode
,
2273 client
->errorValue
= opcode
;
2274 return __glXError(GLXBadLargeRequest
);
2278 ** Skip over the header and execute the command.
2280 (*proc
) (cl
->largeCmdBuf
+ __GLX_RENDER_LARGE_HDR_SIZE
);
2281 glxc
->hasUnflushedCommands
= GL_TRUE
;
2284 ** Reset for the next RenderLarge series.
2286 __glXResetLargeCommandStatus(cl
);
2290 ** This is neither the first nor the last request.
2297 /************************************************************************/
2300 ** No support is provided for the vendor-private requests other than
2301 ** allocating the entry points in the dispatch table.
2305 __glXDisp_VendorPrivate(__GLXclientState
* cl
, GLbyte
* pc
)
2307 ClientPtr client
= cl
->client
;
2308 xGLXVendorPrivateReq
*req
= (xGLXVendorPrivateReq
*) pc
;
2309 GLint vendorcode
= req
->vendorCode
;
2310 __GLXdispatchVendorPrivProcPtr proc
;
2312 REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq
);
2314 proc
= (__GLXdispatchVendorPrivProcPtr
)
2315 __glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info
,
2318 (*proc
) (cl
, (GLbyte
*) req
);
2322 cl
->client
->errorValue
= req
->vendorCode
;
2323 return __glXError(GLXUnsupportedPrivateRequest
);
2327 __glXDisp_VendorPrivateWithReply(__GLXclientState
* cl
, GLbyte
* pc
)
2329 ClientPtr client
= cl
->client
;
2330 xGLXVendorPrivateReq
*req
= (xGLXVendorPrivateReq
*) pc
;
2331 GLint vendorcode
= req
->vendorCode
;
2332 __GLXdispatchVendorPrivProcPtr proc
;
2334 REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq
);
2336 proc
= (__GLXdispatchVendorPrivProcPtr
)
2337 __glXGetProtocolDecodeFunction(&VendorPriv_dispatch_info
,
2340 return (*proc
) (cl
, (GLbyte
*) req
);
2343 cl
->client
->errorValue
= vendorcode
;
2344 return __glXError(GLXUnsupportedPrivateRequest
);
2348 __glXDisp_QueryExtensionsString(__GLXclientState
* cl
, GLbyte
* pc
)
2350 ClientPtr client
= cl
->client
;
2351 xGLXQueryExtensionsStringReq
*req
= (xGLXQueryExtensionsStringReq
*) pc
;
2352 xGLXQueryExtensionsStringReply reply
;
2353 __GLXscreen
*pGlxScreen
;
2358 REQUEST_SIZE_MATCH(xGLXQueryExtensionsStringReq
);
2360 if (!validGlxScreen(client
, req
->screen
, &pGlxScreen
, &err
))
2363 n
= strlen(pGlxScreen
->GLXextensions
) + 1;
2364 length
= __GLX_PAD(n
) >> 2;
2365 reply
= (xGLXQueryExtensionsStringReply
) {
2367 .sequenceNumber
= client
->sequence
,
2372 /* Allocate buffer to make sure it's a multiple of 4 bytes big. */
2373 buf
= calloc(length
, 4);
2376 memcpy(buf
, pGlxScreen
->GLXextensions
, n
);
2378 if (client
->swapped
) {
2379 glxSwapQueryExtensionsStringReply(client
, &reply
, buf
);
2382 WriteToClient(client
, sz_xGLXQueryExtensionsStringReply
, &reply
);
2383 WriteToClient(client
, (int) (length
<< 2), buf
);
2391 __glXDisp_QueryServerString(__GLXclientState
* cl
, GLbyte
* pc
)
2393 ClientPtr client
= cl
->client
;
2394 xGLXQueryServerStringReq
*req
= (xGLXQueryServerStringReq
*) pc
;
2395 xGLXQueryServerStringReply reply
;
2399 __GLXscreen
*pGlxScreen
;
2403 REQUEST_SIZE_MATCH(xGLXQueryServerStringReq
);
2405 if (!validGlxScreen(client
, req
->screen
, &pGlxScreen
, &err
))
2408 switch (req
->name
) {
2410 ptr
= GLXServerVendorName
;
2413 /* Return to the server version rather than the screen version
2414 * to prevent confusion when they do not match.
2416 snprintf(ver_str
, 16, "%d.%d", glxMajorVersion
, glxMinorVersion
);
2419 case GLX_EXTENSIONS
:
2420 ptr
= pGlxScreen
->GLXextensions
;
2426 n
= strlen(ptr
) + 1;
2427 length
= __GLX_PAD(n
) >> 2;
2428 reply
= (xGLXQueryServerStringReply
) {
2430 .sequenceNumber
= client
->sequence
,
2435 buf
= calloc(length
, 4);
2439 memcpy(buf
, ptr
, n
);
2441 if (client
->swapped
) {
2442 glxSwapQueryServerStringReply(client
, &reply
, buf
);
2445 WriteToClient(client
, sz_xGLXQueryServerStringReply
, &reply
);
2446 WriteToClient(client
, (int) (length
<< 2), buf
);
2454 __glXDisp_ClientInfo(__GLXclientState
* cl
, GLbyte
* pc
)
2456 ClientPtr client
= cl
->client
;
2457 xGLXClientInfoReq
*req
= (xGLXClientInfoReq
*) pc
;
2460 REQUEST_AT_LEAST_SIZE(xGLXClientInfoReq
);
2462 buf
= (const char *) (req
+ 1);
2463 if (!memchr(buf
, 0, (client
->req_len
<< 2) - sizeof(xGLXClientInfoReq
)))
2466 free(cl
->GLClientextensions
);
2467 cl
->GLClientextensions
= strdup(buf
);
2472 #include <GL/glxtokens.h>
2475 __glXsendSwapEvent(__GLXdrawable
*drawable
, int type
, CARD64 ust
,
2476 CARD64 msc
, CARD32 sbc
)
2478 ClientPtr client
= clients
[CLIENT_ID(drawable
->drawId
)];
2480 xGLXBufferSwapComplete2 wire
= {
2481 .type
= __glXEventBase
+ GLX_BufferSwapComplete
2487 if (!(drawable
->eventMask
& GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK
))
2490 wire
.event_type
= type
;
2491 wire
.drawable
= drawable
->drawId
;
2492 wire
.ust_hi
= ust
>> 32;
2493 wire
.ust_lo
= ust
& 0xffffffff;
2494 wire
.msc_hi
= msc
>> 32;
2495 wire
.msc_lo
= msc
& 0xffffffff;
2498 WriteEventsToClient(client
, 1, (xEvent
*) &wire
);
2503 __glXpresentCompleteNotify(WindowPtr window
, CARD8 present_mode
, CARD32 serial
,
2504 uint64_t ust
, uint64_t msc
)
2506 __GLXdrawable
*drawable
;
2510 rc
= dixLookupResourceByType((pointer
*) &drawable
, window
->drawable
.id
,
2511 __glXDrawableRes
, serverClient
, DixGetAttrAccess
);
2516 if (present_mode
== PresentCompleteModeFlip
)
2517 glx_type
= GLX_FLIP_COMPLETE_INTEL
;
2519 glx_type
= GLX_BLIT_COMPLETE_INTEL
;
2521 __glXsendSwapEvent(drawable
, glx_type
, ust
, msc
, serial
);
2524 #include <present.h>
2527 __glXregisterPresentCompleteNotify(void)
2529 present_register_complete_notify(__glXpresentCompleteNotify
);