indirect_glx.c revision af69d88d
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 36af69d88dSmrg#ifndef GLX_USE_APPLEGL 37af69d88dSmrg 383464ebd5Sriastradhextern struct _glapi_table *__glXNewIndirectAPI(void); 393464ebd5Sriastradh 403464ebd5Sriastradh/* 413464ebd5Sriastradh** All indirect rendering contexts will share the same indirect dispatch table. 423464ebd5Sriastradh*/ 433464ebd5Sriastradhstatic struct _glapi_table *IndirectAPI = NULL; 443464ebd5Sriastradh 453464ebd5Sriastradhstatic void 463464ebd5Sriastradhindirect_destroy_context(struct glx_context *gc) 473464ebd5Sriastradh{ 483464ebd5Sriastradh __glXFreeVertexArrayState(gc); 493464ebd5Sriastradh 50af69d88dSmrg free((char *) gc->vendor); 51af69d88dSmrg free((char *) gc->renderer); 52af69d88dSmrg free((char *) gc->version); 53af69d88dSmrg free((char *) gc->extensions); 543464ebd5Sriastradh __glFreeAttributeState(gc); 55af69d88dSmrg free((char *) gc->buf); 56af69d88dSmrg free((char *) gc->client_state_private); 57af69d88dSmrg free((char *) gc); 583464ebd5Sriastradh} 593464ebd5Sriastradh 603464ebd5Sriastradhstatic Bool 613464ebd5SriastradhSendMakeCurrentRequest(Display * dpy, CARD8 opcode, 623464ebd5Sriastradh GLXContextID gc_id, GLXContextTag gc_tag, 633464ebd5Sriastradh GLXDrawable draw, GLXDrawable read, 64af69d88dSmrg GLXContextTag *out_tag) 653464ebd5Sriastradh{ 66af69d88dSmrg xGLXMakeCurrentReply reply; 673464ebd5Sriastradh Bool ret; 683464ebd5Sriastradh 693464ebd5Sriastradh LockDisplay(dpy); 703464ebd5Sriastradh 713464ebd5Sriastradh if (draw == read) { 723464ebd5Sriastradh xGLXMakeCurrentReq *req; 733464ebd5Sriastradh 743464ebd5Sriastradh GetReq(GLXMakeCurrent, req); 753464ebd5Sriastradh req->reqType = opcode; 763464ebd5Sriastradh req->glxCode = X_GLXMakeCurrent; 773464ebd5Sriastradh req->drawable = draw; 783464ebd5Sriastradh req->context = gc_id; 793464ebd5Sriastradh req->oldContextTag = gc_tag; 803464ebd5Sriastradh } 813464ebd5Sriastradh else { 823464ebd5Sriastradh struct glx_display *priv = __glXInitialize(dpy); 833464ebd5Sriastradh 843464ebd5Sriastradh /* If the server can support the GLX 1.3 version, we should 853464ebd5Sriastradh * perfer that. Not only that, some servers support GLX 1.3 but 863464ebd5Sriastradh * not the SGI extension. 873464ebd5Sriastradh */ 883464ebd5Sriastradh 893464ebd5Sriastradh if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { 903464ebd5Sriastradh xGLXMakeContextCurrentReq *req; 913464ebd5Sriastradh 923464ebd5Sriastradh GetReq(GLXMakeContextCurrent, req); 933464ebd5Sriastradh req->reqType = opcode; 943464ebd5Sriastradh req->glxCode = X_GLXMakeContextCurrent; 953464ebd5Sriastradh req->drawable = draw; 963464ebd5Sriastradh req->readdrawable = read; 973464ebd5Sriastradh req->context = gc_id; 983464ebd5Sriastradh req->oldContextTag = gc_tag; 993464ebd5Sriastradh } 1003464ebd5Sriastradh else { 1013464ebd5Sriastradh xGLXVendorPrivateWithReplyReq *vpreq; 1023464ebd5Sriastradh xGLXMakeCurrentReadSGIReq *req; 1033464ebd5Sriastradh 1043464ebd5Sriastradh GetReqExtra(GLXVendorPrivateWithReply, 1053464ebd5Sriastradh sz_xGLXMakeCurrentReadSGIReq - 1063464ebd5Sriastradh sz_xGLXVendorPrivateWithReplyReq, vpreq); 1073464ebd5Sriastradh req = (xGLXMakeCurrentReadSGIReq *) vpreq; 1083464ebd5Sriastradh req->reqType = opcode; 1093464ebd5Sriastradh req->glxCode = X_GLXVendorPrivateWithReply; 1103464ebd5Sriastradh req->vendorCode = X_GLXvop_MakeCurrentReadSGI; 1113464ebd5Sriastradh req->drawable = draw; 1123464ebd5Sriastradh req->readable = read; 1133464ebd5Sriastradh req->context = gc_id; 1143464ebd5Sriastradh req->oldContextTag = gc_tag; 1153464ebd5Sriastradh } 1163464ebd5Sriastradh } 1173464ebd5Sriastradh 118af69d88dSmrg ret = _XReply(dpy, (xReply *) &reply, 0, False); 119af69d88dSmrg 120af69d88dSmrg if (out_tag) 121af69d88dSmrg *out_tag = reply.contextTag; 1223464ebd5Sriastradh 1233464ebd5Sriastradh UnlockDisplay(dpy); 1243464ebd5Sriastradh SyncHandle(); 1253464ebd5Sriastradh 1263464ebd5Sriastradh return ret; 1273464ebd5Sriastradh} 1283464ebd5Sriastradh 1293464ebd5Sriastradhstatic int 1303464ebd5Sriastradhindirect_bind_context(struct glx_context *gc, struct glx_context *old, 1313464ebd5Sriastradh GLXDrawable draw, GLXDrawable read) 1323464ebd5Sriastradh{ 1333464ebd5Sriastradh GLXContextTag tag; 1343464ebd5Sriastradh __GLXattribute *state; 1353464ebd5Sriastradh Display *dpy = gc->psc->dpy; 1363464ebd5Sriastradh int opcode = __glXSetupForCommand(dpy); 137af69d88dSmrg Bool sent; 1383464ebd5Sriastradh 1393464ebd5Sriastradh if (old != &dummyContext && !old->isDirect && old->psc->dpy == dpy) { 1403464ebd5Sriastradh tag = old->currentContextTag; 1413464ebd5Sriastradh old->currentContextTag = 0; 1423464ebd5Sriastradh } else { 1433464ebd5Sriastradh tag = 0; 1443464ebd5Sriastradh } 1453464ebd5Sriastradh 146af69d88dSmrg sent = SendMakeCurrentRequest(dpy, opcode, gc->xid, tag, draw, read, 147af69d88dSmrg &gc->currentContextTag); 1483464ebd5Sriastradh 1493464ebd5Sriastradh if (!IndirectAPI) 1503464ebd5Sriastradh IndirectAPI = __glXNewIndirectAPI(); 1513464ebd5Sriastradh _glapi_set_dispatch(IndirectAPI); 1523464ebd5Sriastradh 1533464ebd5Sriastradh state = gc->client_state_private; 1543464ebd5Sriastradh if (state->array_state == NULL) { 1553464ebd5Sriastradh glGetString(GL_EXTENSIONS); 1563464ebd5Sriastradh glGetString(GL_VERSION); 1573464ebd5Sriastradh __glXInitVertexArrayState(gc); 1583464ebd5Sriastradh } 1593464ebd5Sriastradh 160af69d88dSmrg return !sent; 1613464ebd5Sriastradh} 1623464ebd5Sriastradh 1633464ebd5Sriastradhstatic void 1643464ebd5Sriastradhindirect_unbind_context(struct glx_context *gc, struct glx_context *new) 1653464ebd5Sriastradh{ 1663464ebd5Sriastradh Display *dpy = gc->psc->dpy; 1673464ebd5Sriastradh int opcode = __glXSetupForCommand(dpy); 1683464ebd5Sriastradh 1693464ebd5Sriastradh if (gc == new) 1703464ebd5Sriastradh return; 1713464ebd5Sriastradh 1723464ebd5Sriastradh /* We are either switching to no context, away from a indirect 1733464ebd5Sriastradh * context to a direct context or from one dpy to another and have 1743464ebd5Sriastradh * to send a request to the dpy to unbind the previous context. 1753464ebd5Sriastradh */ 1763464ebd5Sriastradh if (!new || new->isDirect || new->psc->dpy != dpy) { 1773464ebd5Sriastradh SendMakeCurrentRequest(dpy, opcode, None, 178af69d88dSmrg gc->currentContextTag, None, None, NULL); 1793464ebd5Sriastradh gc->currentContextTag = 0; 1803464ebd5Sriastradh } 1813464ebd5Sriastradh} 1823464ebd5Sriastradh 1833464ebd5Sriastradhstatic void 1843464ebd5Sriastradhindirect_wait_gl(struct glx_context *gc) 1853464ebd5Sriastradh{ 1863464ebd5Sriastradh xGLXWaitGLReq *req; 1873464ebd5Sriastradh Display *dpy = gc->currentDpy; 1883464ebd5Sriastradh 1893464ebd5Sriastradh /* Flush any pending commands out */ 1903464ebd5Sriastradh __glXFlushRenderBuffer(gc, gc->pc); 1913464ebd5Sriastradh 1923464ebd5Sriastradh /* Send the glXWaitGL request */ 1933464ebd5Sriastradh LockDisplay(dpy); 1943464ebd5Sriastradh GetReq(GLXWaitGL, req); 1953464ebd5Sriastradh req->reqType = gc->majorOpcode; 1963464ebd5Sriastradh req->glxCode = X_GLXWaitGL; 1973464ebd5Sriastradh req->contextTag = gc->currentContextTag; 1983464ebd5Sriastradh UnlockDisplay(dpy); 1993464ebd5Sriastradh SyncHandle(); 2003464ebd5Sriastradh} 2013464ebd5Sriastradh 2023464ebd5Sriastradhstatic void 2033464ebd5Sriastradhindirect_wait_x(struct glx_context *gc) 2043464ebd5Sriastradh{ 2053464ebd5Sriastradh xGLXWaitXReq *req; 2063464ebd5Sriastradh Display *dpy = gc->currentDpy; 2073464ebd5Sriastradh 2083464ebd5Sriastradh /* Flush any pending commands out */ 2093464ebd5Sriastradh __glXFlushRenderBuffer(gc, gc->pc); 2103464ebd5Sriastradh 2113464ebd5Sriastradh LockDisplay(dpy); 2123464ebd5Sriastradh GetReq(GLXWaitX, req); 2133464ebd5Sriastradh req->reqType = gc->majorOpcode; 2143464ebd5Sriastradh req->glxCode = X_GLXWaitX; 2153464ebd5Sriastradh req->contextTag = gc->currentContextTag; 2163464ebd5Sriastradh UnlockDisplay(dpy); 2173464ebd5Sriastradh SyncHandle(); 2183464ebd5Sriastradh} 2193464ebd5Sriastradh 2203464ebd5Sriastradhstatic void 2213464ebd5Sriastradhindirect_use_x_font(struct glx_context *gc, 2223464ebd5Sriastradh Font font, int first, int count, int listBase) 2233464ebd5Sriastradh{ 2243464ebd5Sriastradh xGLXUseXFontReq *req; 2253464ebd5Sriastradh Display *dpy = gc->currentDpy; 2263464ebd5Sriastradh 2273464ebd5Sriastradh /* Flush any pending commands out */ 2283464ebd5Sriastradh __glXFlushRenderBuffer(gc, gc->pc); 2293464ebd5Sriastradh 2303464ebd5Sriastradh /* Send the glXUseFont request */ 2313464ebd5Sriastradh LockDisplay(dpy); 2323464ebd5Sriastradh GetReq(GLXUseXFont, req); 2333464ebd5Sriastradh req->reqType = gc->majorOpcode; 2343464ebd5Sriastradh req->glxCode = X_GLXUseXFont; 2353464ebd5Sriastradh req->contextTag = gc->currentContextTag; 2363464ebd5Sriastradh req->font = font; 2373464ebd5Sriastradh req->first = first; 2383464ebd5Sriastradh req->count = count; 2393464ebd5Sriastradh req->listBase = listBase; 2403464ebd5Sriastradh UnlockDisplay(dpy); 2413464ebd5Sriastradh SyncHandle(); 2423464ebd5Sriastradh} 2433464ebd5Sriastradh 2443464ebd5Sriastradhstatic void 2453464ebd5Sriastradhindirect_bind_tex_image(Display * dpy, 2463464ebd5Sriastradh GLXDrawable drawable, 2473464ebd5Sriastradh int buffer, const int *attrib_list) 2483464ebd5Sriastradh{ 2493464ebd5Sriastradh xGLXVendorPrivateReq *req; 2503464ebd5Sriastradh struct glx_context *gc = __glXGetCurrentContext(); 2513464ebd5Sriastradh CARD32 *drawable_ptr; 2523464ebd5Sriastradh INT32 *buffer_ptr; 2533464ebd5Sriastradh CARD32 *num_attrib_ptr; 2543464ebd5Sriastradh CARD32 *attrib_ptr; 2553464ebd5Sriastradh CARD8 opcode; 2563464ebd5Sriastradh unsigned int i; 2573464ebd5Sriastradh 2583464ebd5Sriastradh i = 0; 2593464ebd5Sriastradh if (attrib_list) { 2603464ebd5Sriastradh while (attrib_list[i * 2] != None) 2613464ebd5Sriastradh i++; 2623464ebd5Sriastradh } 2633464ebd5Sriastradh 2643464ebd5Sriastradh opcode = __glXSetupForCommand(dpy); 2653464ebd5Sriastradh if (!opcode) 2663464ebd5Sriastradh return; 2673464ebd5Sriastradh 2683464ebd5Sriastradh LockDisplay(dpy); 2693464ebd5Sriastradh GetReqExtra(GLXVendorPrivate, 12 + 8 * i, req); 2703464ebd5Sriastradh req->reqType = opcode; 2713464ebd5Sriastradh req->glxCode = X_GLXVendorPrivate; 2723464ebd5Sriastradh req->vendorCode = X_GLXvop_BindTexImageEXT; 2733464ebd5Sriastradh req->contextTag = gc->currentContextTag; 2743464ebd5Sriastradh 2753464ebd5Sriastradh drawable_ptr = (CARD32 *) (req + 1); 2763464ebd5Sriastradh buffer_ptr = (INT32 *) (drawable_ptr + 1); 2773464ebd5Sriastradh num_attrib_ptr = (CARD32 *) (buffer_ptr + 1); 2783464ebd5Sriastradh attrib_ptr = (CARD32 *) (num_attrib_ptr + 1); 2793464ebd5Sriastradh 2803464ebd5Sriastradh *drawable_ptr = drawable; 2813464ebd5Sriastradh *buffer_ptr = buffer; 2823464ebd5Sriastradh *num_attrib_ptr = (CARD32) i; 2833464ebd5Sriastradh 2843464ebd5Sriastradh i = 0; 2853464ebd5Sriastradh if (attrib_list) { 2863464ebd5Sriastradh while (attrib_list[i * 2] != None) { 2873464ebd5Sriastradh *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 0]; 2883464ebd5Sriastradh *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 1]; 2893464ebd5Sriastradh i++; 2903464ebd5Sriastradh } 2913464ebd5Sriastradh } 2923464ebd5Sriastradh 2933464ebd5Sriastradh UnlockDisplay(dpy); 2943464ebd5Sriastradh SyncHandle(); 2953464ebd5Sriastradh} 2963464ebd5Sriastradh 2973464ebd5Sriastradhstatic void 2983464ebd5Sriastradhindirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer) 2993464ebd5Sriastradh{ 3003464ebd5Sriastradh xGLXVendorPrivateReq *req; 3013464ebd5Sriastradh struct glx_context *gc = __glXGetCurrentContext(); 3023464ebd5Sriastradh CARD32 *drawable_ptr; 3033464ebd5Sriastradh INT32 *buffer_ptr; 3043464ebd5Sriastradh CARD8 opcode; 3053464ebd5Sriastradh 3063464ebd5Sriastradh opcode = __glXSetupForCommand(dpy); 3073464ebd5Sriastradh if (!opcode) 3083464ebd5Sriastradh return; 3093464ebd5Sriastradh 3103464ebd5Sriastradh LockDisplay(dpy); 3113464ebd5Sriastradh GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32), req); 3123464ebd5Sriastradh req->reqType = opcode; 3133464ebd5Sriastradh req->glxCode = X_GLXVendorPrivate; 3143464ebd5Sriastradh req->vendorCode = X_GLXvop_ReleaseTexImageEXT; 3153464ebd5Sriastradh req->contextTag = gc->currentContextTag; 3163464ebd5Sriastradh 3173464ebd5Sriastradh drawable_ptr = (CARD32 *) (req + 1); 3183464ebd5Sriastradh buffer_ptr = (INT32 *) (drawable_ptr + 1); 3193464ebd5Sriastradh 3203464ebd5Sriastradh *drawable_ptr = drawable; 3213464ebd5Sriastradh *buffer_ptr = buffer; 3223464ebd5Sriastradh 3233464ebd5Sriastradh UnlockDisplay(dpy); 3243464ebd5Sriastradh SyncHandle(); 3253464ebd5Sriastradh} 3263464ebd5Sriastradh 3273464ebd5Sriastradhstatic const struct glx_context_vtable indirect_context_vtable = { 328af69d88dSmrg .destroy = indirect_destroy_context, 329af69d88dSmrg .bind = indirect_bind_context, 330af69d88dSmrg .unbind = indirect_unbind_context, 331af69d88dSmrg .wait_gl = indirect_wait_gl, 332af69d88dSmrg .wait_x = indirect_wait_x, 333af69d88dSmrg .use_x_font = indirect_use_x_font, 334af69d88dSmrg .bind_tex_image = indirect_bind_tex_image, 335af69d88dSmrg .release_tex_image = indirect_release_tex_image, 336af69d88dSmrg .get_proc_address = NULL, 3373464ebd5Sriastradh}; 3383464ebd5Sriastradh 3393464ebd5Sriastradh/** 3403464ebd5Sriastradh * \todo Eliminate \c __glXInitVertexArrayState. Replace it with a new 3413464ebd5Sriastradh * function called \c __glXAllocateClientState that allocates the memory and 3423464ebd5Sriastradh * does all the initialization (including the pixel pack / unpack). 343af69d88dSmrg * 344af69d88dSmrg * \note 345af69d88dSmrg * This function is \b not the place to validate the context creation 346af69d88dSmrg * parameters. It is just the allocator for the \c glx_context. 3473464ebd5Sriastradh */ 3483464ebd5Sriastradh_X_HIDDEN struct glx_context * 3493464ebd5Sriastradhindirect_create_context(struct glx_screen *psc, 3503464ebd5Sriastradh struct glx_config *mode, 3513464ebd5Sriastradh struct glx_context *shareList, int renderType) 3523464ebd5Sriastradh{ 3533464ebd5Sriastradh struct glx_context *gc; 3543464ebd5Sriastradh int bufSize; 3553464ebd5Sriastradh CARD8 opcode; 3563464ebd5Sriastradh __GLXattribute *state; 3573464ebd5Sriastradh 3583464ebd5Sriastradh opcode = __glXSetupForCommand(psc->dpy); 3593464ebd5Sriastradh if (!opcode) { 3603464ebd5Sriastradh return NULL; 3613464ebd5Sriastradh } 3623464ebd5Sriastradh 3633464ebd5Sriastradh /* Allocate our context record */ 364af69d88dSmrg gc = calloc(1, sizeof *gc); 3653464ebd5Sriastradh if (!gc) { 3663464ebd5Sriastradh /* Out of memory */ 3673464ebd5Sriastradh return NULL; 3683464ebd5Sriastradh } 3693464ebd5Sriastradh 3703464ebd5Sriastradh glx_context_init(gc, psc, mode); 3713464ebd5Sriastradh gc->isDirect = GL_FALSE; 3723464ebd5Sriastradh gc->vtable = &indirect_context_vtable; 373af69d88dSmrg state = calloc(1, sizeof(struct __GLXattributeRec)); 374af69d88dSmrg gc->renderType = renderType; 375af69d88dSmrg 3763464ebd5Sriastradh if (state == NULL) { 3773464ebd5Sriastradh /* Out of memory */ 378af69d88dSmrg free(gc); 3793464ebd5Sriastradh return NULL; 3803464ebd5Sriastradh } 3813464ebd5Sriastradh gc->client_state_private = state; 3823464ebd5Sriastradh state->NoDrawArraysProtocol = (getenv("LIBGL_NO_DRAWARRAYS") != NULL); 3833464ebd5Sriastradh 3843464ebd5Sriastradh /* 3853464ebd5Sriastradh ** Create a temporary buffer to hold GLX rendering commands. The size 3863464ebd5Sriastradh ** of the buffer is selected so that the maximum number of GLX rendering 3873464ebd5Sriastradh ** commands can fit in a single X packet and still have room in the X 3883464ebd5Sriastradh ** packet for the GLXRenderReq header. 3893464ebd5Sriastradh */ 3903464ebd5Sriastradh 3913464ebd5Sriastradh bufSize = (XMaxRequestSize(psc->dpy) * 4) - sz_xGLXRenderReq; 392af69d88dSmrg gc->buf = malloc(bufSize); 3933464ebd5Sriastradh if (!gc->buf) { 394af69d88dSmrg free(gc->client_state_private); 395af69d88dSmrg free(gc); 3963464ebd5Sriastradh return NULL; 3973464ebd5Sriastradh } 3983464ebd5Sriastradh gc->bufSize = bufSize; 3993464ebd5Sriastradh 4003464ebd5Sriastradh /* Fill in the new context */ 4013464ebd5Sriastradh gc->renderMode = GL_RENDER; 4023464ebd5Sriastradh 4033464ebd5Sriastradh state->storePack.alignment = 4; 4043464ebd5Sriastradh state->storeUnpack.alignment = 4; 4053464ebd5Sriastradh 4063464ebd5Sriastradh gc->attributes.stackPointer = &gc->attributes.stack[0]; 4073464ebd5Sriastradh 4083464ebd5Sriastradh /* 4093464ebd5Sriastradh ** PERFORMANCE NOTE: A mode dependent fill image can speed things up. 4103464ebd5Sriastradh */ 4113464ebd5Sriastradh gc->fillImage = __glFillImage; 4123464ebd5Sriastradh gc->pc = gc->buf; 4133464ebd5Sriastradh gc->bufEnd = gc->buf + bufSize; 4143464ebd5Sriastradh gc->isDirect = GL_FALSE; 4153464ebd5Sriastradh if (__glXDebug) { 4163464ebd5Sriastradh /* 4173464ebd5Sriastradh ** Set limit register so that there will be one command per packet 4183464ebd5Sriastradh */ 4193464ebd5Sriastradh gc->limit = gc->buf; 4203464ebd5Sriastradh } 4213464ebd5Sriastradh else { 4223464ebd5Sriastradh gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE; 4233464ebd5Sriastradh } 4243464ebd5Sriastradh gc->majorOpcode = opcode; 4253464ebd5Sriastradh 4263464ebd5Sriastradh /* 4273464ebd5Sriastradh ** Constrain the maximum drawing command size allowed to be 4283464ebd5Sriastradh ** transfered using the X_GLXRender protocol request. First 4293464ebd5Sriastradh ** constrain by a software limit, then constrain by the protocl 4303464ebd5Sriastradh ** limit. 4313464ebd5Sriastradh */ 4323464ebd5Sriastradh if (bufSize > __GLX_RENDER_CMD_SIZE_LIMIT) { 4333464ebd5Sriastradh bufSize = __GLX_RENDER_CMD_SIZE_LIMIT; 4343464ebd5Sriastradh } 4353464ebd5Sriastradh if (bufSize > __GLX_MAX_RENDER_CMD_SIZE) { 4363464ebd5Sriastradh bufSize = __GLX_MAX_RENDER_CMD_SIZE; 4373464ebd5Sriastradh } 4383464ebd5Sriastradh gc->maxSmallRenderCommandSize = bufSize; 4393464ebd5Sriastradh 4403464ebd5Sriastradh 4413464ebd5Sriastradh return gc; 4423464ebd5Sriastradh} 4433464ebd5Sriastradh 444af69d88dSmrg_X_HIDDEN struct glx_context * 445af69d88dSmrgindirect_create_context_attribs(struct glx_screen *base, 446af69d88dSmrg struct glx_config *config_base, 447af69d88dSmrg struct glx_context *shareList, 448af69d88dSmrg unsigned num_attribs, 449af69d88dSmrg const uint32_t *attribs, 450af69d88dSmrg unsigned *error) 451af69d88dSmrg{ 452af69d88dSmrg int renderType = GLX_RGBA_TYPE; 453af69d88dSmrg unsigned i; 454af69d88dSmrg 455af69d88dSmrg /* The error parameter is only used on the server so that correct GLX 456af69d88dSmrg * protocol errors can be generated. On the client, it can be ignored. 457af69d88dSmrg */ 458af69d88dSmrg (void) error; 459af69d88dSmrg 460af69d88dSmrg /* All of the attribute validation for indirect contexts is handled on the 461af69d88dSmrg * server, so there's not much to do here. Still, we need to parse the 462af69d88dSmrg * attributes to correctly set renderType. 463af69d88dSmrg */ 464af69d88dSmrg for (i = 0; i < num_attribs; i++) { 465af69d88dSmrg if (attribs[i * 2] == GLX_RENDER_TYPE) 466af69d88dSmrg renderType = attribs[i * 2 + 1]; 467af69d88dSmrg } 468af69d88dSmrg 469af69d88dSmrg return indirect_create_context(base, config_base, shareList, renderType); 470af69d88dSmrg} 471af69d88dSmrg 472af69d88dSmrgstatic const struct glx_screen_vtable indirect_screen_vtable = { 473af69d88dSmrg .create_context = indirect_create_context, 474af69d88dSmrg .create_context_attribs = indirect_create_context_attribs, 475af69d88dSmrg .query_renderer_integer = NULL, 476af69d88dSmrg .query_renderer_string = NULL, 4773464ebd5Sriastradh}; 4783464ebd5Sriastradh 4793464ebd5Sriastradh_X_HIDDEN struct glx_screen * 4803464ebd5Sriastradhindirect_create_screen(int screen, struct glx_display * priv) 4813464ebd5Sriastradh{ 4823464ebd5Sriastradh struct glx_screen *psc; 4833464ebd5Sriastradh 484af69d88dSmrg psc = calloc(1, sizeof *psc); 4853464ebd5Sriastradh if (psc == NULL) 4863464ebd5Sriastradh return NULL; 4873464ebd5Sriastradh 4883464ebd5Sriastradh glx_screen_init(psc, screen, priv); 4893464ebd5Sriastradh psc->vtable = &indirect_screen_vtable; 4903464ebd5Sriastradh 4913464ebd5Sriastradh return psc; 4923464ebd5Sriastradh} 493af69d88dSmrg 494af69d88dSmrg#endif 495