indirect_glx.c revision 3464ebd5
13464ebd5Sriastradh/*
23464ebd5Sriastradh * Copyright © 2010 Intel Corporation
33464ebd5Sriastradh *
43464ebd5Sriastradh * Permission is hereby granted, free of charge, to any person obtaining a
53464ebd5Sriastradh * copy of this software and associated documentation files (the "Soft-
63464ebd5Sriastradh * ware"), to deal in the Software without restriction, including without
73464ebd5Sriastradh * limitation the rights to use, copy, modify, merge, publish, distribute,
83464ebd5Sriastradh * and/or sell copies of the Software, and to permit persons to whom the
93464ebd5Sriastradh * Software is furnished to do so, provided that the above copyright
103464ebd5Sriastradh * notice(s) and this permission notice appear in all copies of the Soft-
113464ebd5Sriastradh * ware and that both the above copyright notice(s) and this permission
123464ebd5Sriastradh * notice appear in supporting documentation.
133464ebd5Sriastradh *
143464ebd5Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
153464ebd5Sriastradh * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
163464ebd5Sriastradh * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
173464ebd5Sriastradh * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
183464ebd5Sriastradh * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
193464ebd5Sriastradh * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
203464ebd5Sriastradh * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
213464ebd5Sriastradh * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
223464ebd5Sriastradh * MANCE OF THIS SOFTWARE.
233464ebd5Sriastradh *
243464ebd5Sriastradh * Except as contained in this notice, the name of a copyright holder shall
253464ebd5Sriastradh * not be used in advertising or otherwise to promote the sale, use or
263464ebd5Sriastradh * other dealings in this Software without prior written authorization of
273464ebd5Sriastradh * the copyright holder.
283464ebd5Sriastradh *
293464ebd5Sriastradh * Authors:
303464ebd5Sriastradh *   Kristian Høgsberg (krh@bitplanet.net)
313464ebd5Sriastradh */
323464ebd5Sriastradh
333464ebd5Sriastradh#include "glapi.h"
343464ebd5Sriastradh#include "glxclient.h"
353464ebd5Sriastradh
363464ebd5Sriastradhextern struct _glapi_table *__glXNewIndirectAPI(void);
373464ebd5Sriastradh
383464ebd5Sriastradh/*
393464ebd5Sriastradh** All indirect rendering contexts will share the same indirect dispatch table.
403464ebd5Sriastradh*/
413464ebd5Sriastradhstatic struct _glapi_table *IndirectAPI = NULL;
423464ebd5Sriastradh
433464ebd5Sriastradhstatic void
443464ebd5Sriastradhindirect_destroy_context(struct glx_context *gc)
453464ebd5Sriastradh{
463464ebd5Sriastradh   if (!gc->imported && gc->xid)
473464ebd5Sriastradh      glx_send_destroy_context(gc->psc->dpy, gc->xid);
483464ebd5Sriastradh
493464ebd5Sriastradh   __glXFreeVertexArrayState(gc);
503464ebd5Sriastradh
513464ebd5Sriastradh   if (gc->vendor)
523464ebd5Sriastradh      XFree((char *) gc->vendor);
533464ebd5Sriastradh   if (gc->renderer)
543464ebd5Sriastradh      XFree((char *) gc->renderer);
553464ebd5Sriastradh   if (gc->version)
563464ebd5Sriastradh      XFree((char *) gc->version);
573464ebd5Sriastradh   if (gc->extensions)
583464ebd5Sriastradh      XFree((char *) gc->extensions);
593464ebd5Sriastradh   __glFreeAttributeState(gc);
603464ebd5Sriastradh   XFree((char *) gc->buf);
613464ebd5Sriastradh   Xfree((char *) gc->client_state_private);
623464ebd5Sriastradh   XFree((char *) gc);
633464ebd5Sriastradh}
643464ebd5Sriastradh
653464ebd5Sriastradhstatic Bool
663464ebd5SriastradhSendMakeCurrentRequest(Display * dpy, CARD8 opcode,
673464ebd5Sriastradh                       GLXContextID gc_id, GLXContextTag gc_tag,
683464ebd5Sriastradh                       GLXDrawable draw, GLXDrawable read,
693464ebd5Sriastradh                       xGLXMakeCurrentReply * reply)
703464ebd5Sriastradh{
713464ebd5Sriastradh   Bool ret;
723464ebd5Sriastradh
733464ebd5Sriastradh   LockDisplay(dpy);
743464ebd5Sriastradh
753464ebd5Sriastradh   if (draw == read) {
763464ebd5Sriastradh      xGLXMakeCurrentReq *req;
773464ebd5Sriastradh
783464ebd5Sriastradh      GetReq(GLXMakeCurrent, req);
793464ebd5Sriastradh      req->reqType = opcode;
803464ebd5Sriastradh      req->glxCode = X_GLXMakeCurrent;
813464ebd5Sriastradh      req->drawable = draw;
823464ebd5Sriastradh      req->context = gc_id;
833464ebd5Sriastradh      req->oldContextTag = gc_tag;
843464ebd5Sriastradh   }
853464ebd5Sriastradh   else {
863464ebd5Sriastradh      struct glx_display *priv = __glXInitialize(dpy);
873464ebd5Sriastradh
883464ebd5Sriastradh      /* If the server can support the GLX 1.3 version, we should
893464ebd5Sriastradh       * perfer that.  Not only that, some servers support GLX 1.3 but
903464ebd5Sriastradh       * not the SGI extension.
913464ebd5Sriastradh       */
923464ebd5Sriastradh
933464ebd5Sriastradh      if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
943464ebd5Sriastradh         xGLXMakeContextCurrentReq *req;
953464ebd5Sriastradh
963464ebd5Sriastradh         GetReq(GLXMakeContextCurrent, req);
973464ebd5Sriastradh         req->reqType = opcode;
983464ebd5Sriastradh         req->glxCode = X_GLXMakeContextCurrent;
993464ebd5Sriastradh         req->drawable = draw;
1003464ebd5Sriastradh         req->readdrawable = read;
1013464ebd5Sriastradh         req->context = gc_id;
1023464ebd5Sriastradh         req->oldContextTag = gc_tag;
1033464ebd5Sriastradh      }
1043464ebd5Sriastradh      else {
1053464ebd5Sriastradh         xGLXVendorPrivateWithReplyReq *vpreq;
1063464ebd5Sriastradh         xGLXMakeCurrentReadSGIReq *req;
1073464ebd5Sriastradh
1083464ebd5Sriastradh         GetReqExtra(GLXVendorPrivateWithReply,
1093464ebd5Sriastradh                     sz_xGLXMakeCurrentReadSGIReq -
1103464ebd5Sriastradh                     sz_xGLXVendorPrivateWithReplyReq, vpreq);
1113464ebd5Sriastradh         req = (xGLXMakeCurrentReadSGIReq *) vpreq;
1123464ebd5Sriastradh         req->reqType = opcode;
1133464ebd5Sriastradh         req->glxCode = X_GLXVendorPrivateWithReply;
1143464ebd5Sriastradh         req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
1153464ebd5Sriastradh         req->drawable = draw;
1163464ebd5Sriastradh         req->readable = read;
1173464ebd5Sriastradh         req->context = gc_id;
1183464ebd5Sriastradh         req->oldContextTag = gc_tag;
1193464ebd5Sriastradh      }
1203464ebd5Sriastradh   }
1213464ebd5Sriastradh
1223464ebd5Sriastradh   ret = _XReply(dpy, (xReply *) reply, 0, False);
1233464ebd5Sriastradh
1243464ebd5Sriastradh   UnlockDisplay(dpy);
1253464ebd5Sriastradh   SyncHandle();
1263464ebd5Sriastradh
1273464ebd5Sriastradh   return ret;
1283464ebd5Sriastradh}
1293464ebd5Sriastradh
1303464ebd5Sriastradhstatic int
1313464ebd5Sriastradhindirect_bind_context(struct glx_context *gc, struct glx_context *old,
1323464ebd5Sriastradh		      GLXDrawable draw, GLXDrawable read)
1333464ebd5Sriastradh{
1343464ebd5Sriastradh   xGLXMakeCurrentReply reply;
1353464ebd5Sriastradh   GLXContextTag tag;
1363464ebd5Sriastradh   __GLXattribute *state;
1373464ebd5Sriastradh   Display *dpy = gc->psc->dpy;
1383464ebd5Sriastradh   int opcode = __glXSetupForCommand(dpy);
1393464ebd5Sriastradh
1403464ebd5Sriastradh   if (old != &dummyContext && !old->isDirect && old->psc->dpy == dpy) {
1413464ebd5Sriastradh      tag = old->currentContextTag;
1423464ebd5Sriastradh      old->currentContextTag = 0;
1433464ebd5Sriastradh   } else {
1443464ebd5Sriastradh      tag = 0;
1453464ebd5Sriastradh   }
1463464ebd5Sriastradh
1473464ebd5Sriastradh   SendMakeCurrentRequest(dpy, opcode, gc->xid, tag, draw, read, &reply);
1483464ebd5Sriastradh
1493464ebd5Sriastradh   if (!IndirectAPI)
1503464ebd5Sriastradh      IndirectAPI = __glXNewIndirectAPI();
1513464ebd5Sriastradh   _glapi_set_dispatch(IndirectAPI);
1523464ebd5Sriastradh
1533464ebd5Sriastradh   gc->currentContextTag = reply.contextTag;
1543464ebd5Sriastradh   state = gc->client_state_private;
1553464ebd5Sriastradh   if (state->array_state == NULL) {
1563464ebd5Sriastradh      glGetString(GL_EXTENSIONS);
1573464ebd5Sriastradh      glGetString(GL_VERSION);
1583464ebd5Sriastradh      __glXInitVertexArrayState(gc);
1593464ebd5Sriastradh   }
1603464ebd5Sriastradh
1613464ebd5Sriastradh   return Success;
1623464ebd5Sriastradh}
1633464ebd5Sriastradh
1643464ebd5Sriastradhstatic void
1653464ebd5Sriastradhindirect_unbind_context(struct glx_context *gc, struct glx_context *new)
1663464ebd5Sriastradh{
1673464ebd5Sriastradh   Display *dpy = gc->psc->dpy;
1683464ebd5Sriastradh   int opcode = __glXSetupForCommand(dpy);
1693464ebd5Sriastradh   xGLXMakeCurrentReply reply;
1703464ebd5Sriastradh
1713464ebd5Sriastradh   if (gc == new)
1723464ebd5Sriastradh      return;
1733464ebd5Sriastradh
1743464ebd5Sriastradh   /* We are either switching to no context, away from a indirect
1753464ebd5Sriastradh    * context to a direct context or from one dpy to another and have
1763464ebd5Sriastradh    * to send a request to the dpy to unbind the previous context.
1773464ebd5Sriastradh    */
1783464ebd5Sriastradh   if (!new || new->isDirect || new->psc->dpy != dpy) {
1793464ebd5Sriastradh      SendMakeCurrentRequest(dpy, opcode, None,
1803464ebd5Sriastradh			     gc->currentContextTag, None, None, &reply);
1813464ebd5Sriastradh      gc->currentContextTag = 0;
1823464ebd5Sriastradh   }
1833464ebd5Sriastradh}
1843464ebd5Sriastradh
1853464ebd5Sriastradhstatic void
1863464ebd5Sriastradhindirect_wait_gl(struct glx_context *gc)
1873464ebd5Sriastradh{
1883464ebd5Sriastradh   xGLXWaitGLReq *req;
1893464ebd5Sriastradh   Display *dpy = gc->currentDpy;
1903464ebd5Sriastradh
1913464ebd5Sriastradh   /* Flush any pending commands out */
1923464ebd5Sriastradh   __glXFlushRenderBuffer(gc, gc->pc);
1933464ebd5Sriastradh
1943464ebd5Sriastradh   /* Send the glXWaitGL request */
1953464ebd5Sriastradh   LockDisplay(dpy);
1963464ebd5Sriastradh   GetReq(GLXWaitGL, req);
1973464ebd5Sriastradh   req->reqType = gc->majorOpcode;
1983464ebd5Sriastradh   req->glxCode = X_GLXWaitGL;
1993464ebd5Sriastradh   req->contextTag = gc->currentContextTag;
2003464ebd5Sriastradh   UnlockDisplay(dpy);
2013464ebd5Sriastradh   SyncHandle();
2023464ebd5Sriastradh}
2033464ebd5Sriastradh
2043464ebd5Sriastradhstatic void
2053464ebd5Sriastradhindirect_wait_x(struct glx_context *gc)
2063464ebd5Sriastradh{
2073464ebd5Sriastradh   xGLXWaitXReq *req;
2083464ebd5Sriastradh   Display *dpy = gc->currentDpy;
2093464ebd5Sriastradh
2103464ebd5Sriastradh   /* Flush any pending commands out */
2113464ebd5Sriastradh   __glXFlushRenderBuffer(gc, gc->pc);
2123464ebd5Sriastradh
2133464ebd5Sriastradh   LockDisplay(dpy);
2143464ebd5Sriastradh   GetReq(GLXWaitX, req);
2153464ebd5Sriastradh   req->reqType = gc->majorOpcode;
2163464ebd5Sriastradh   req->glxCode = X_GLXWaitX;
2173464ebd5Sriastradh   req->contextTag = gc->currentContextTag;
2183464ebd5Sriastradh   UnlockDisplay(dpy);
2193464ebd5Sriastradh   SyncHandle();
2203464ebd5Sriastradh}
2213464ebd5Sriastradh
2223464ebd5Sriastradhstatic void
2233464ebd5Sriastradhindirect_use_x_font(struct glx_context *gc,
2243464ebd5Sriastradh		    Font font, int first, int count, int listBase)
2253464ebd5Sriastradh{
2263464ebd5Sriastradh   xGLXUseXFontReq *req;
2273464ebd5Sriastradh   Display *dpy = gc->currentDpy;
2283464ebd5Sriastradh
2293464ebd5Sriastradh   /* Flush any pending commands out */
2303464ebd5Sriastradh   __glXFlushRenderBuffer(gc, gc->pc);
2313464ebd5Sriastradh
2323464ebd5Sriastradh   /* Send the glXUseFont request */
2333464ebd5Sriastradh   LockDisplay(dpy);
2343464ebd5Sriastradh   GetReq(GLXUseXFont, req);
2353464ebd5Sriastradh   req->reqType = gc->majorOpcode;
2363464ebd5Sriastradh   req->glxCode = X_GLXUseXFont;
2373464ebd5Sriastradh   req->contextTag = gc->currentContextTag;
2383464ebd5Sriastradh   req->font = font;
2393464ebd5Sriastradh   req->first = first;
2403464ebd5Sriastradh   req->count = count;
2413464ebd5Sriastradh   req->listBase = listBase;
2423464ebd5Sriastradh   UnlockDisplay(dpy);
2433464ebd5Sriastradh   SyncHandle();
2443464ebd5Sriastradh}
2453464ebd5Sriastradh
2463464ebd5Sriastradhstatic void
2473464ebd5Sriastradhindirect_bind_tex_image(Display * dpy,
2483464ebd5Sriastradh			GLXDrawable drawable,
2493464ebd5Sriastradh			int buffer, const int *attrib_list)
2503464ebd5Sriastradh{
2513464ebd5Sriastradh   xGLXVendorPrivateReq *req;
2523464ebd5Sriastradh   struct glx_context *gc = __glXGetCurrentContext();
2533464ebd5Sriastradh   CARD32 *drawable_ptr;
2543464ebd5Sriastradh   INT32 *buffer_ptr;
2553464ebd5Sriastradh   CARD32 *num_attrib_ptr;
2563464ebd5Sriastradh   CARD32 *attrib_ptr;
2573464ebd5Sriastradh   CARD8 opcode;
2583464ebd5Sriastradh   unsigned int i;
2593464ebd5Sriastradh
2603464ebd5Sriastradh   i = 0;
2613464ebd5Sriastradh   if (attrib_list) {
2623464ebd5Sriastradh      while (attrib_list[i * 2] != None)
2633464ebd5Sriastradh         i++;
2643464ebd5Sriastradh   }
2653464ebd5Sriastradh
2663464ebd5Sriastradh   opcode = __glXSetupForCommand(dpy);
2673464ebd5Sriastradh   if (!opcode)
2683464ebd5Sriastradh      return;
2693464ebd5Sriastradh
2703464ebd5Sriastradh   LockDisplay(dpy);
2713464ebd5Sriastradh   GetReqExtra(GLXVendorPrivate, 12 + 8 * i, req);
2723464ebd5Sriastradh   req->reqType = opcode;
2733464ebd5Sriastradh   req->glxCode = X_GLXVendorPrivate;
2743464ebd5Sriastradh   req->vendorCode = X_GLXvop_BindTexImageEXT;
2753464ebd5Sriastradh   req->contextTag = gc->currentContextTag;
2763464ebd5Sriastradh
2773464ebd5Sriastradh   drawable_ptr = (CARD32 *) (req + 1);
2783464ebd5Sriastradh   buffer_ptr = (INT32 *) (drawable_ptr + 1);
2793464ebd5Sriastradh   num_attrib_ptr = (CARD32 *) (buffer_ptr + 1);
2803464ebd5Sriastradh   attrib_ptr = (CARD32 *) (num_attrib_ptr + 1);
2813464ebd5Sriastradh
2823464ebd5Sriastradh   *drawable_ptr = drawable;
2833464ebd5Sriastradh   *buffer_ptr = buffer;
2843464ebd5Sriastradh   *num_attrib_ptr = (CARD32) i;
2853464ebd5Sriastradh
2863464ebd5Sriastradh   i = 0;
2873464ebd5Sriastradh   if (attrib_list) {
2883464ebd5Sriastradh      while (attrib_list[i * 2] != None) {
2893464ebd5Sriastradh         *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 0];
2903464ebd5Sriastradh         *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 1];
2913464ebd5Sriastradh         i++;
2923464ebd5Sriastradh      }
2933464ebd5Sriastradh   }
2943464ebd5Sriastradh
2953464ebd5Sriastradh   UnlockDisplay(dpy);
2963464ebd5Sriastradh   SyncHandle();
2973464ebd5Sriastradh}
2983464ebd5Sriastradh
2993464ebd5Sriastradhstatic void
3003464ebd5Sriastradhindirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
3013464ebd5Sriastradh{
3023464ebd5Sriastradh   xGLXVendorPrivateReq *req;
3033464ebd5Sriastradh   struct glx_context *gc = __glXGetCurrentContext();
3043464ebd5Sriastradh   CARD32 *drawable_ptr;
3053464ebd5Sriastradh   INT32 *buffer_ptr;
3063464ebd5Sriastradh   CARD8 opcode;
3073464ebd5Sriastradh
3083464ebd5Sriastradh   opcode = __glXSetupForCommand(dpy);
3093464ebd5Sriastradh   if (!opcode)
3103464ebd5Sriastradh      return;
3113464ebd5Sriastradh
3123464ebd5Sriastradh   LockDisplay(dpy);
3133464ebd5Sriastradh   GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32), req);
3143464ebd5Sriastradh   req->reqType = opcode;
3153464ebd5Sriastradh   req->glxCode = X_GLXVendorPrivate;
3163464ebd5Sriastradh   req->vendorCode = X_GLXvop_ReleaseTexImageEXT;
3173464ebd5Sriastradh   req->contextTag = gc->currentContextTag;
3183464ebd5Sriastradh
3193464ebd5Sriastradh   drawable_ptr = (CARD32 *) (req + 1);
3203464ebd5Sriastradh   buffer_ptr = (INT32 *) (drawable_ptr + 1);
3213464ebd5Sriastradh
3223464ebd5Sriastradh   *drawable_ptr = drawable;
3233464ebd5Sriastradh   *buffer_ptr = buffer;
3243464ebd5Sriastradh
3253464ebd5Sriastradh   UnlockDisplay(dpy);
3263464ebd5Sriastradh   SyncHandle();
3273464ebd5Sriastradh}
3283464ebd5Sriastradh
3293464ebd5Sriastradhstatic const struct glx_context_vtable indirect_context_vtable = {
3303464ebd5Sriastradh   indirect_destroy_context,
3313464ebd5Sriastradh   indirect_bind_context,
3323464ebd5Sriastradh   indirect_unbind_context,
3333464ebd5Sriastradh   indirect_wait_gl,
3343464ebd5Sriastradh   indirect_wait_x,
3353464ebd5Sriastradh   indirect_use_x_font,
3363464ebd5Sriastradh   indirect_bind_tex_image,
3373464ebd5Sriastradh   indirect_release_tex_image,
3383464ebd5Sriastradh   NULL, /* get_proc_address */
3393464ebd5Sriastradh};
3403464ebd5Sriastradh
3413464ebd5Sriastradh/**
3423464ebd5Sriastradh * \todo Eliminate \c __glXInitVertexArrayState.  Replace it with a new
3433464ebd5Sriastradh * function called \c __glXAllocateClientState that allocates the memory and
3443464ebd5Sriastradh * does all the initialization (including the pixel pack / unpack).
3453464ebd5Sriastradh */
3463464ebd5Sriastradh_X_HIDDEN struct glx_context *
3473464ebd5Sriastradhindirect_create_context(struct glx_screen *psc,
3483464ebd5Sriastradh			struct glx_config *mode,
3493464ebd5Sriastradh			struct glx_context *shareList, int renderType)
3503464ebd5Sriastradh{
3513464ebd5Sriastradh   struct glx_context *gc;
3523464ebd5Sriastradh   int bufSize;
3533464ebd5Sriastradh   CARD8 opcode;
3543464ebd5Sriastradh   __GLXattribute *state;
3553464ebd5Sriastradh
3563464ebd5Sriastradh   opcode = __glXSetupForCommand(psc->dpy);
3573464ebd5Sriastradh   if (!opcode) {
3583464ebd5Sriastradh      return NULL;
3593464ebd5Sriastradh   }
3603464ebd5Sriastradh
3613464ebd5Sriastradh   /* Allocate our context record */
3623464ebd5Sriastradh   gc = Xmalloc(sizeof *gc);
3633464ebd5Sriastradh   if (!gc) {
3643464ebd5Sriastradh      /* Out of memory */
3653464ebd5Sriastradh      return NULL;
3663464ebd5Sriastradh   }
3673464ebd5Sriastradh   memset(gc, 0, sizeof *gc);
3683464ebd5Sriastradh
3693464ebd5Sriastradh   glx_context_init(gc, psc, mode);
3703464ebd5Sriastradh   gc->isDirect = GL_FALSE;
3713464ebd5Sriastradh   gc->vtable = &indirect_context_vtable;
3723464ebd5Sriastradh   state = Xmalloc(sizeof(struct __GLXattributeRec));
3733464ebd5Sriastradh   if (state == NULL) {
3743464ebd5Sriastradh      /* Out of memory */
3753464ebd5Sriastradh      Xfree(gc);
3763464ebd5Sriastradh      return NULL;
3773464ebd5Sriastradh   }
3783464ebd5Sriastradh   gc->client_state_private = state;
3793464ebd5Sriastradh   memset(gc->client_state_private, 0, sizeof(struct __GLXattributeRec));
3803464ebd5Sriastradh   state->NoDrawArraysProtocol = (getenv("LIBGL_NO_DRAWARRAYS") != NULL);
3813464ebd5Sriastradh
3823464ebd5Sriastradh   /*
3833464ebd5Sriastradh    ** Create a temporary buffer to hold GLX rendering commands.  The size
3843464ebd5Sriastradh    ** of the buffer is selected so that the maximum number of GLX rendering
3853464ebd5Sriastradh    ** commands can fit in a single X packet and still have room in the X
3863464ebd5Sriastradh    ** packet for the GLXRenderReq header.
3873464ebd5Sriastradh    */
3883464ebd5Sriastradh
3893464ebd5Sriastradh   bufSize = (XMaxRequestSize(psc->dpy) * 4) - sz_xGLXRenderReq;
3903464ebd5Sriastradh   gc->buf = (GLubyte *) Xmalloc(bufSize);
3913464ebd5Sriastradh   if (!gc->buf) {
3923464ebd5Sriastradh      Xfree(gc->client_state_private);
3933464ebd5Sriastradh      Xfree(gc);
3943464ebd5Sriastradh      return NULL;
3953464ebd5Sriastradh   }
3963464ebd5Sriastradh   gc->bufSize = bufSize;
3973464ebd5Sriastradh
3983464ebd5Sriastradh   /* Fill in the new context */
3993464ebd5Sriastradh   gc->renderMode = GL_RENDER;
4003464ebd5Sriastradh
4013464ebd5Sriastradh   state->storePack.alignment = 4;
4023464ebd5Sriastradh   state->storeUnpack.alignment = 4;
4033464ebd5Sriastradh
4043464ebd5Sriastradh   gc->attributes.stackPointer = &gc->attributes.stack[0];
4053464ebd5Sriastradh
4063464ebd5Sriastradh   /*
4073464ebd5Sriastradh    ** PERFORMANCE NOTE: A mode dependent fill image can speed things up.
4083464ebd5Sriastradh    */
4093464ebd5Sriastradh   gc->fillImage = __glFillImage;
4103464ebd5Sriastradh   gc->pc = gc->buf;
4113464ebd5Sriastradh   gc->bufEnd = gc->buf + bufSize;
4123464ebd5Sriastradh   gc->isDirect = GL_FALSE;
4133464ebd5Sriastradh   if (__glXDebug) {
4143464ebd5Sriastradh      /*
4153464ebd5Sriastradh       ** Set limit register so that there will be one command per packet
4163464ebd5Sriastradh       */
4173464ebd5Sriastradh      gc->limit = gc->buf;
4183464ebd5Sriastradh   }
4193464ebd5Sriastradh   else {
4203464ebd5Sriastradh      gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE;
4213464ebd5Sriastradh   }
4223464ebd5Sriastradh   gc->majorOpcode = opcode;
4233464ebd5Sriastradh
4243464ebd5Sriastradh   /*
4253464ebd5Sriastradh    ** Constrain the maximum drawing command size allowed to be
4263464ebd5Sriastradh    ** transfered using the X_GLXRender protocol request.  First
4273464ebd5Sriastradh    ** constrain by a software limit, then constrain by the protocl
4283464ebd5Sriastradh    ** limit.
4293464ebd5Sriastradh    */
4303464ebd5Sriastradh   if (bufSize > __GLX_RENDER_CMD_SIZE_LIMIT) {
4313464ebd5Sriastradh      bufSize = __GLX_RENDER_CMD_SIZE_LIMIT;
4323464ebd5Sriastradh   }
4333464ebd5Sriastradh   if (bufSize > __GLX_MAX_RENDER_CMD_SIZE) {
4343464ebd5Sriastradh      bufSize = __GLX_MAX_RENDER_CMD_SIZE;
4353464ebd5Sriastradh   }
4363464ebd5Sriastradh   gc->maxSmallRenderCommandSize = bufSize;
4373464ebd5Sriastradh
4383464ebd5Sriastradh
4393464ebd5Sriastradh   return gc;
4403464ebd5Sriastradh}
4413464ebd5Sriastradh
4423464ebd5Sriastradhstruct glx_screen_vtable indirect_screen_vtable = {
4433464ebd5Sriastradh   indirect_create_context
4443464ebd5Sriastradh};
4453464ebd5Sriastradh
4463464ebd5Sriastradh_X_HIDDEN struct glx_screen *
4473464ebd5Sriastradhindirect_create_screen(int screen, struct glx_display * priv)
4483464ebd5Sriastradh{
4493464ebd5Sriastradh   struct glx_screen *psc;
4503464ebd5Sriastradh
4513464ebd5Sriastradh   psc = Xmalloc(sizeof *psc);
4523464ebd5Sriastradh   if (psc == NULL)
4533464ebd5Sriastradh      return NULL;
4543464ebd5Sriastradh
4553464ebd5Sriastradh   memset(psc, 0, sizeof *psc);
4563464ebd5Sriastradh   glx_screen_init(psc, screen, priv);
4573464ebd5Sriastradh   psc->vtable = &indirect_screen_vtable;
4583464ebd5Sriastradh
4593464ebd5Sriastradh   return psc;
4603464ebd5Sriastradh}
461