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