X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglx%2Fglxext.c;h=34e86ae734d46d1f3904f63546c8ed4757877026;hb=aeba69deaa536776452ec8b22a3131f187e82cac;hp=8704c484f9687bd69b59e7f7683b0ac7b4893f43;hpb=4df137691ee29bb812347fa2c5f19095243ede22;p=mesa.git diff --git a/src/glx/glxext.c b/src/glx/glxext.c index 8704c484f96..34e86ae734d 100644 --- a/src/glx/glxext.c +++ b/src/glx/glxext.c @@ -38,20 +38,25 @@ */ #include +#include + #include "glxclient.h" #include #include #ifdef GLX_USE_APPLEGL -#include "apple_glx.h" -#include "apple_visual.h" +#include "apple/apple_glx.h" +#include "apple/apple_visual.h" #endif #include "glxextensions.h" -#ifdef USE_XCB +#include "util/debug.h" +#ifndef GLX_USE_APPLEGL +#include "dri_common.h" +#endif + #include #include #include -#endif #ifdef DEBUG @@ -67,7 +72,7 @@ _X_HIDDEN int __glXDebug = 0; /* Extension required boiler plate */ static const char __glXExtensionName[] = GLX_EXTENSION_NAME; - static struct glx_display *glx_displays; +static struct glx_display *glx_displays; static /* const */ char *error_list[] = { "GLXBadContext", @@ -83,6 +88,7 @@ static /* const */ char *error_list[] = { "GLXBadPbuffer", "GLXBadCurrentDrawable", "GLXBadWindow", + "GLXBadProfileARB", }; #ifdef GLX_USE_APPLEGL @@ -135,16 +141,25 @@ __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire) GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event; xGLXBufferSwapComplete2 *awire = (xGLXBufferSwapComplete2 *)wire; struct glx_drawable *glxDraw = GetGLXDrawable(dpy, awire->drawable); - aevent->event_type = awire->event_type; - aevent->drawable = awire->drawable; - aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo; - aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo; if (!glxDraw) return False; - if (awire->sbc < glxDraw->lastEventSbc) - glxDraw->eventSbcWrap += 0x100000000; + aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire); + aevent->send_event = (awire->type & 0x80) != 0; + aevent->display = dpy; + aevent->event_type = awire->event_type; + aevent->drawable = glxDraw->xDrawable; + aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo; + aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo; + + /* Handle 32-Bit wire sbc wraparound in both directions to cope with out + * of sequence 64-Bit sbc's + */ + if ((int64_t) awire->sbc < ((int64_t) glxDraw->lastEventSbc - 0x40000000)) + glxDraw->eventSbcWrap += 0x100000000; + if ((int64_t) awire->sbc > ((int64_t) glxDraw->lastEventSbc + 0x40000000)) + glxDraw->eventSbcWrap -= 0x100000000; glxDraw->lastEventSbc = awire->sbc; aevent->sbc = awire->sbc + glxDraw->eventSbcWrap; return True; @@ -202,19 +217,21 @@ FreeScreenConfigs(struct glx_display * priv) screens = ScreenCount(priv->dpy); for (i = 0; i < screens; i++) { psc = priv->screens[i]; + if (!psc) + continue; glx_screen_cleanup(psc); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) if (psc->driScreen) { psc->driScreen->destroyScreen(psc); } else { - Xfree(psc); + free(psc); } #else - Xfree(psc); + free(psc); #endif } - XFree((char *) priv->screens); + free((char *) priv->screens); priv->screens = NULL; } @@ -230,10 +247,8 @@ glx_display_free(struct glx_display *priv) } FreeScreenConfigs(priv); - if (priv->serverGLXvendor) - Xfree((char *) priv->serverGLXvendor); - if (priv->serverGLXversion) - Xfree((char *) priv->serverGLXversion); + free((char *) priv->serverGLXvendor); + free((char *) priv->serverGLXversion); __glxHashDestroy(priv->glXDrawHash); @@ -245,6 +260,7 @@ glx_display_free(struct glx_display *priv) (*priv->driswDisplay->destroyDisplay) (priv->driswDisplay); priv->driswDisplay = NULL; +#if defined (GLX_USE_DRM) if (priv->driDisplay) (*priv->driDisplay->destroyDisplay) (priv->driDisplay); priv->driDisplay = NULL; @@ -252,33 +268,41 @@ glx_display_free(struct glx_display *priv) if (priv->dri2Display) (*priv->dri2Display->destroyDisplay) (priv->dri2Display); priv->dri2Display = NULL; -#endif - Xfree((char *) priv); + if (priv->dri3Display) + (*priv->dri3Display->destroyDisplay) (priv->dri3Display); + priv->dri3Display = NULL; +#endif /* GLX_USE_DRM */ + +#if defined(GLX_USE_WINDOWSGL) + if (priv->windowsdriDisplay) + (*priv->windowsdriDisplay->destroyDisplay) (priv->windowsdriDisplay); + priv->windowsdriDisplay = NULL; +#endif /* GLX_USE_WINDOWSGL */ + +#endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */ + + free((char *) priv); } static int __glXCloseDisplay(Display * dpy, XExtCodes * codes) { - struct glx_display *priv, **prev, *next; + struct glx_display *priv, **prev; _XLockMutex(_Xglobal_lock); prev = &glx_displays; for (priv = glx_displays; priv; prev = &priv->next, priv = priv->next) { if (priv->dpy == dpy) { + *prev = priv->next; break; } } - - /* Only remove the display from the list after it's destroyed. The cleanup - * code (e.g. driReleaseDrawables()) ends up calling __glXInitialize(), - * which would create a new glx_display while we're trying to destroy this - * one. */ - next = priv->next; - glx_display_free(priv); - *prev = next; _XUnlockMutex(_Xglobal_lock); + if (priv != NULL) + glx_display_free(priv); + return 1; } @@ -289,7 +313,6 @@ __glXCloseDisplay(Display * dpy, XExtCodes * codes) static Bool QueryVersion(Display * dpy, int opcode, int *major, int *minor) { -#ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); xcb_glx_query_version_reply_t *reply = xcb_glx_query_version_reply(c, xcb_glx_query_version @@ -298,6 +321,9 @@ QueryVersion(Display * dpy, int opcode, int *major, int *minor) GLX_MINOR_VERSION), NULL); + if (!reply) + return GL_FALSE; + if (reply->major_version != GLX_MAJOR_VERSION) { free(reply); return GL_FALSE; @@ -306,32 +332,6 @@ QueryVersion(Display * dpy, int opcode, int *major, int *minor) *minor = min(reply->minor_version, GLX_MINOR_VERSION); free(reply); return GL_TRUE; -#else - xGLXQueryVersionReq *req; - xGLXQueryVersionReply reply; - - /* Send the glXQueryVersion request */ - LockDisplay(dpy); - GetReq(GLXQueryVersion, req); - req->reqType = opcode; - req->glxCode = X_GLXQueryVersion; - req->majorVersion = GLX_MAJOR_VERSION; - req->minorVersion = GLX_MINOR_VERSION; - _XReply(dpy, (xReply *) & reply, 0, False); - UnlockDisplay(dpy); - SyncHandle(); - - if (reply.majorVersion != GLX_MAJOR_VERSION) { - /* - ** The server does not support the same major release as this - ** client. - */ - return GL_FALSE; - } - *major = reply.majorVersion; - *minor = min(reply.minorVersion, GLX_MINOR_VERSION); - return GL_TRUE; -#endif /* USE_XCB */ } /* @@ -348,9 +348,12 @@ static GLint convert_from_x_visual_type(int visualType) { static const int glx_visual_types[] = { - GLX_STATIC_GRAY, GLX_GRAY_SCALE, - GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, - GLX_TRUE_COLOR, GLX_DIRECT_COLOR + [StaticGray] = GLX_STATIC_GRAY, + [GrayScale] = GLX_GRAY_SCALE, + [StaticColor] = GLX_STATIC_COLOR, + [PseudoColor] = GLX_PSEUDO_COLOR, + [TrueColor] = GLX_TRUE_COLOR, + [DirectColor] = GLX_DIRECT_COLOR, }; if (visualType < ARRAY_SIZE(glx_visual_types)) @@ -376,7 +379,7 @@ __glXInitializeVisualConfigFromTags(struct glx_config * config, int count, config->visualType = convert_from_x_visual_type(*bp++); - config->rgbMode = *bp++; + config->renderType = *bp++ ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; config->redBits = *bp++; config->greenBits = *bp++; @@ -420,7 +423,10 @@ __glXInitializeVisualConfigFromTags(struct glx_config * config, int count, switch (tag) { case GLX_RGBA: - FETCH_OR_SET(rgbMode); + if (fbconfig_style_tags) + config->renderType = *bp++ ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; + else + config->renderType = GLX_RGBA_BIT; break; case GLX_BUFFER_SIZE: config->rgbBits = *bp++; @@ -501,7 +507,7 @@ __glXInitializeVisualConfigFromTags(struct glx_config * config, int count, config->drawableType |= GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; #endif break; - case GLX_RENDER_TYPE: + case GLX_RENDER_TYPE: /* fbconfig render type bits */ config->renderType = *bp++; break; case GLX_X_RENDERABLE: @@ -530,7 +536,17 @@ __glXInitializeVisualConfigFromTags(struct glx_config * config, int count, config->visualSelectGroup = *bp++; break; case GLX_SWAP_METHOD_OML: - config->swapMethod = *bp++; + if (*bp == GLX_SWAP_UNDEFINED_OML || + *bp == GLX_SWAP_COPY_OML || + *bp == GLX_SWAP_EXCHANGE_OML) { + config->swapMethod = *bp++; + } else { + /* X servers with old HW drivers may return any value here, so + * assume GLX_SWAP_METHOD_UNDEFINED. + */ + config->swapMethod = GLX_SWAP_UNDEFINED_OML; + bp++; + } break; #endif case GLX_SAMPLE_BUFFERS_SGIS: @@ -573,7 +589,7 @@ __glXInitializeVisualConfigFromTags(struct glx_config * config, int count, i = count; break; default: - if(getenv("LIBGL_DIAGNOSTIC")) { + if(env_var_as_boolean("LIBGL_DIAGNOSTIC", false)) { long int tagvalue = *bp++; fprintf(stderr, "WARNING: unknown GLX tag from server: " "tag 0x%lx value 0x%lx\n", tag, tagvalue); @@ -585,8 +601,14 @@ __glXInitializeVisualConfigFromTags(struct glx_config * config, int count, } } - config->renderType = - (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; + /* The GLX_ARB_fbconfig_float spec says: + * + * "Note that floating point rendering is only supported for + * GLXPbuffer drawables." + */ + if (config->renderType & + (GLX_RGBA_FLOAT_BIT_ARB|GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT)) + config->drawableType &= GLX_PBUFFER_BIT; } static struct glx_config * @@ -616,7 +638,7 @@ createConfigsFromProperties(Display * dpy, int nvisuals, int nprops, if (prop_size <= sizeof(buf)) props = buf; else - props = Xmalloc(prop_size); + props = malloc(prop_size); /* Read each config structure and convert it into our format */ m = modes; @@ -633,6 +655,8 @@ createConfigsFromProperties(Display * dpy, int nvisuals, int nprops, */ m->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; #endif + /* Older X servers don't send this so we default it here. */ + m->sRGBCapable = GL_FALSE; __glXInitializeVisualConfigFromTags(m, nprops, props, tagged_only, GL_TRUE); m->screen = screen; @@ -640,7 +664,7 @@ createConfigsFromProperties(Display * dpy, int nvisuals, int nprops, } if (props != buf) - Xfree(props); + free(props); return modes; } @@ -686,10 +710,15 @@ static GLboolean psc->serverGLXexts = __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS); + if (psc->serverGLXexts == NULL) { + return GL_FALSE; + } + LockDisplay(dpy); psc->configs = NULL; - if (atof(priv->serverGLXversion) >= 1.3) { + if (priv->majorVersion > 1 || + (priv->majorVersion == 1 && priv->minorVersion >= 3)) { GetReq(GLXGetFBConfigs, fb_req); fb_req->reqType = priv->majorOpcode; fb_req->glxCode = X_GLXGetFBConfigs; @@ -731,8 +760,11 @@ glx_screen_init(struct glx_screen *psc, psc->dpy = priv->dpy; psc->display = priv; - getVisualConfigs(psc, priv, screen); - getFBConfigs(psc, priv, screen); + if (!getVisualConfigs(psc, priv, screen)) + return GL_FALSE; + + if (!getFBConfigs(psc, priv, screen)) + return GL_FALSE; return GL_TRUE; } @@ -742,15 +774,14 @@ glx_screen_cleanup(struct glx_screen *psc) { if (psc->configs) { glx_config_destroy_list(psc->configs); - if (psc->effectiveGLXexts) - Xfree(psc->effectiveGLXexts); + free(psc->effectiveGLXexts); psc->configs = NULL; /* NOTE: just for paranoia */ } if (psc->visuals) { glx_config_destroy_list(psc->visuals); psc->visuals = NULL; /* NOTE: just for paranoia */ } - Xfree((char *) psc->serverGLXexts); + free((char *) psc->serverGLXexts); } /* @@ -767,7 +798,7 @@ AllocAndFetchScreenConfigs(Display * dpy, struct glx_display * priv) ** First allocate memory for the array of per screen configs. */ screens = ScreenCount(dpy); - priv->screens = Xmalloc(screens * sizeof *priv->screens); + priv->screens = calloc(screens, sizeof *priv->screens); if (!priv->screens) return GL_FALSE; @@ -781,13 +812,26 @@ AllocAndFetchScreenConfigs(Display * dpy, struct glx_display * priv) for (i = 0; i < screens; i++, psc++) { psc = NULL; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (priv->dri2Display) +#if defined(GLX_USE_DRM) +#if defined(HAVE_DRI3) + if (priv->dri3Display) + psc = (*priv->dri3Display->createScreen) (i, priv); +#endif /* HAVE_DRI3 */ + if (psc == NULL && priv->dri2Display) psc = (*priv->dri2Display->createScreen) (i, priv); if (psc == NULL && priv->driDisplay) psc = (*priv->driDisplay->createScreen) (i, priv); +#endif /* GLX_USE_DRM */ + +#ifdef GLX_USE_WINDOWSGL + if (psc == NULL && priv->windowsdriDisplay) + psc = (*priv->windowsdriDisplay->createScreen) (i, priv); +#endif + if (psc == NULL && priv->driswDisplay) psc = (*priv->driswDisplay->createScreen) (i, priv); -#endif +#endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */ + #if defined(GLX_USE_APPLEGL) if (psc == NULL) psc = applegl_create_screen(i, priv); @@ -825,14 +869,13 @@ __glXInitialize(Display * dpy) /* Drop the lock while we create the display private. */ _XUnlockMutex(_Xglobal_lock); - dpyPriv = Xcalloc(1, sizeof *dpyPriv); + dpyPriv = calloc(1, sizeof *dpyPriv); if (!dpyPriv) return NULL; dpyPriv->codes = XInitExtension(dpy, __glXExtensionName); if (!dpyPriv->codes) { - Xfree(dpyPriv); - _XUnlockMutex(_Xglobal_lock); + free(dpyPriv); return NULL; } @@ -841,11 +884,13 @@ __glXInitialize(Display * dpy) dpyPriv->serverGLXvendor = 0x0; dpyPriv->serverGLXversion = 0x0; - /* See if the versions are compatible */ + /* See if the versions are compatible. This GLX implementation does not + * work with servers that only support GLX 1.0. + */ if (!QueryVersion(dpy, dpyPriv->majorOpcode, - &dpyPriv->majorVersion, &dpyPriv->minorVersion)) { - Xfree(dpyPriv); - _XUnlockMutex(_Xglobal_lock); + &dpyPriv->majorVersion, &dpyPriv->minorVersion) + || (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion < 1)) { + free(dpyPriv); return NULL; } @@ -855,42 +900,58 @@ __glXInitialize(Display * dpy) } XESetCloseDisplay(dpy, dpyPriv->codes->extension, __glXCloseDisplay); - XESetErrorString (dpy, dpyPriv->codes->extension,__glXErrorString); + XESetErrorString (dpy, dpyPriv->codes->extension, __glXErrorString); dpyPriv->glXDrawHash = __glxHashCreate(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - glx_direct = (getenv("LIBGL_ALWAYS_INDIRECT") == NULL); - glx_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL); + glx_direct = !env_var_as_boolean("LIBGL_ALWAYS_INDIRECT", false); + glx_accel = !env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false); dpyPriv->drawHash = __glxHashCreate(); +#ifndef GLX_USE_APPLEGL + /* Set the logger before the *CreateDisplay functions. */ + loader_set_logger(dri_message); +#endif + /* ** Initialize the direct rendering per display data and functions. ** Note: This _must_ be done before calling any other DRI routines ** (e.g., those called in AllocAndFetchScreenConfigs). */ +#if defined(GLX_USE_DRM) if (glx_direct && glx_accel) { +#if defined(HAVE_DRI3) + if (!env_var_as_boolean("LIBGL_DRI3_DISABLE", false)) + dpyPriv->dri3Display = dri3_create_display(dpy); +#endif /* HAVE_DRI3 */ dpyPriv->dri2Display = dri2CreateDisplay(dpy); dpyPriv->driDisplay = driCreateDisplay(dpy); } +#endif /* GLX_USE_DRM */ if (glx_direct) dpyPriv->driswDisplay = driswCreateDisplay(dpy); -#endif +#endif /* GLX_DIRECT_RENDERING && !GLX_USE_APPLEGL */ #ifdef GLX_USE_APPLEGL if (!applegl_create_display(dpyPriv)) { - Xfree(dpyPriv); + free(dpyPriv); return NULL; } #endif + +#ifdef GLX_USE_WINDOWSGL + if (glx_direct && glx_accel) + dpyPriv->windowsdriDisplay = driwindowsCreateDisplay(dpy); +#endif + if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) { - Xfree(dpyPriv); + free(dpyPriv); return NULL; } - if (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion >= 1) - __glXClientInfo(dpy, dpyPriv->majorOpcode); + __glX_send_client_info(dpyPriv); /* Grab the lock again and add the dispay private, unless somebody * beat us to initializing on this display in the meantime. */ @@ -907,7 +968,7 @@ __glXInitialize(Display * dpy) dpyPriv->next = glx_displays; glx_displays = dpyPriv; - _XUnlockMutex(_Xglobal_lock); + _XUnlockMutex(_Xglobal_lock); return dpyPriv; } @@ -962,29 +1023,12 @@ _X_HIDDEN GLubyte * __glXFlushRenderBuffer(struct glx_context * ctx, GLubyte * pc) { Display *const dpy = ctx->currentDpy; -#ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); -#else - xGLXRenderReq *req; -#endif /* USE_XCB */ const GLint size = pc - ctx->buf; if ((dpy != NULL) && (size > 0)) { -#ifdef USE_XCB xcb_glx_render(c, ctx->currentContextTag, size, (const uint8_t *) ctx->buf); -#else - /* Send the entire buffer as an X request */ - LockDisplay(dpy); - GetReq(GLXRender, req); - req->reqType = ctx->majorOpcode; - req->glxCode = X_GLXRender; - req->contextTag = ctx->currentContextTag; - req->length += (size + 3) >> 2; - _XSend(dpy, (char *) ctx->buf, size); - UnlockDisplay(dpy); - SyncHandle(); -#endif } /* Reset pointer and return it */ @@ -1014,32 +1058,9 @@ __glXSendLargeChunk(struct glx_context * gc, GLint requestNumber, GLint totalRequests, const GLvoid * data, GLint dataLen) { Display *dpy = gc->currentDpy; -#ifdef USE_XCB xcb_connection_t *c = XGetXCBConnection(dpy); xcb_glx_render_large(c, gc->currentContextTag, requestNumber, totalRequests, dataLen, data); -#else - xGLXRenderLargeReq *req; - - if (requestNumber == 1) { - LockDisplay(dpy); - } - - GetReq(GLXRenderLarge, req); - req->reqType = gc->majorOpcode; - req->glxCode = X_GLXRenderLarge; - req->contextTag = gc->currentContextTag; - req->length += (dataLen + 3) >> 2; - req->requestNumber = requestNumber; - req->requestTotal = totalRequests; - req->dataBytes = dataLen; - Data(dpy, data, dataLen); - - if (requestNumber == totalRequests) { - UnlockDisplay(dpy); - SyncHandle(); - } -#endif /* USE_XCB */ }