diff options
author | Eric Anholt <[email protected]> | 2007-10-29 13:24:27 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2007-10-29 13:24:27 -0700 |
commit | b0edb9c38a6c63175e4fafdbb54102c4f4a94e2c (patch) | |
tree | 7dfa294a9c9f40f5f2e81a95dfd0d59cd4d6fbea /src | |
parent | 919f617d08a34d01dd916b08ca4f315bae84f21c (diff) | |
parent | ad8ee7db3b406b23136873fc8c87a22e4d8b94de (diff) |
Merge branch 'origin'
Diffstat (limited to 'src')
94 files changed, 2697 insertions, 576 deletions
diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h index 0709f3ef26e..b464e505fc5 100644 --- a/src/glx/x11/glxclient.h +++ b/src/glx/x11/glxclient.h @@ -500,9 +500,9 @@ struct __GLXscreenConfigsRec { #endif /** - * Linked list of configurations for this screen. + * Linked list of glx visuals and fbconfigs for this screen. */ - __GLcontextModes *configs; + __GLcontextModes *visuals, *configs; /** * Per-screen dynamic GLX extension tracking. The \c direct_support diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c index 3e53dca3199..37bfc2a67cf 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/x11/glxcmds.c @@ -106,6 +106,7 @@ static void GarbageCollectDRIDrawables(Display *dpy, __GLXscreenConfigs *sc) } while (__glxHashNext(sc->drawHash, &draw, (void *)&pdraw) == 1); } + XSync(dpy, GL_FALSE); XSetErrorHandler(oldXErrorHandler); } @@ -903,12 +904,12 @@ PUBLIC int glXGetConfig(Display *dpy, XVisualInfo *vis, int attribute, { __GLXdisplayPrivate *priv; __GLXscreenConfigs *psc; + __GLcontextModes *modes; int status; status = GetGLXPrivScreenConfig( dpy, vis->screen, & priv, & psc ); if ( status == Success ) { - const __GLcontextModes * const modes = _gl_context_modes_find_visual( - psc->configs, vis->visualid ); + modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid); /* Lookup attribute after first finding a match on the visual */ if ( modes != NULL ) { @@ -1286,7 +1287,7 @@ PUBLIC XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *attribList) ** Compute a score for those that do ** Remember which visual, if any, got the highest score */ - for ( modes = psc->configs ; modes != NULL ; modes = modes->next ) { + for ( modes = psc->visuals ; modes != NULL ; modes = modes->next ) { if ( fbconfigs_compatible( & test_config, modes ) && ((best_config == NULL) || (fbconfig_compare( (const __GLcontextModes * const * const)&modes, &best_config ) < 0)) ) { @@ -1654,6 +1655,7 @@ PUBLIC GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements) __GLcontextModes ** config = NULL; int i; + *nelements = 0; if ( (priv->screenConfigs != NULL) && (screen >= 0) && (screen <= ScreenCount(dpy)) && (priv->screenConfigs[screen].configs != NULL) @@ -1940,13 +1942,24 @@ static int __glXGetVideoSyncSGI(unsigned int *count) if ( (gc != NULL) && gc->isDirect ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - if (psc->msc != NULL && psc->driScreen.private != NULL) { - int ret; - int64_t temp; - - ret = psc->msc->getMSC(&psc->driScreen, &temp); - *count = (unsigned) temp; - return (ret == 0) ? 0 : GLX_BAD_CONTEXT; + if ( psc->msc && psc->driScreen.private ) { + __DRIdrawable * const pdraw = + GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); + int64_t temp; + int ret; + + /* + * Try to use getDrawableMSC first so we get the right + * counter... + */ + if (psc->msc->base.version >= 2 && psc->msc->getDrawableMSC) + ret = (*psc->msc->getDrawableMSC)( &psc->driScreen, + pdraw->private, + & temp); + else + ret = (*psc->msc->getMSC)( &psc->driScreen, & temp); + *count = (unsigned) temp; + return (ret == 0) ? 0 : GLX_BAD_CONTEXT; } } #else @@ -1969,16 +1982,14 @@ static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count if (psc->msc != NULL && psc->driScreen.private ) { __DRIdrawable * const pdraw = GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); - if (pdraw != NULL) { - int ret; - int64_t msc; - int64_t sbc; - - ret = (*psc->msc->waitForMSC)(pdraw, 0, - divisor, remainder, &msc, &sbc); - *count = (unsigned) msc; - return (ret == 0) ? 0 : GLX_BAD_CONTEXT; - } + int ret; + int64_t msc; + int64_t sbc; + + ret = (*psc->msc->waitForMSC)(pdraw, 0, divisor, remainder, &msc, + &sbc); + *count = (unsigned) msc; + return (ret == 0) ? 0 : GLX_BAD_CONTEXT; } } #else diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c index 7b25ad717a3..4b78ca85c68 100644 --- a/src/glx/x11/glxext.c +++ b/src/glx/x11/glxext.c @@ -362,7 +362,8 @@ static void FreeScreenConfigs(__GLXdisplayPrivate *priv) if (psc->driScreen.private) (*psc->driScreen.destroyScreen)(&psc->driScreen); psc->driScreen.private = NULL; - __glxHashDestroy(psc->drawHash); + if (psc->drawHash) + __glxHashDestroy(psc->drawHash); #endif } XFree((char*) priv->screenConfigs); @@ -999,6 +1000,128 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc, #endif /* GLX_DIRECT_RENDERING */ +static __GLcontextModes * +createConfigsFromProperties(Display *dpy, int nvisuals, int nprops, + int screen, GLboolean tagged_only) +{ + INT32 buf[__GLX_TOTAL_CONFIG], *props; + unsigned prop_size; + __GLcontextModes *modes, *m; + int i; + + if (nprops == 0) + return NULL; + + /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */ + + /* Check number of properties */ + if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS) + return NULL; + + /* Allocate memory for our config structure */ + modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes)); + if (!modes) + return NULL; + + prop_size = nprops * __GLX_SIZE_INT32; + if (prop_size <= sizeof(buf)) + props = buf; + else + props = Xmalloc(prop_size); + + /* Read each config structure and convert it into our format */ + m = modes; + for (i = 0; i < nvisuals; i++) { + _XRead(dpy, (char *)props, prop_size); + /* Older X servers don't send this so we default it here. */ + m->drawableType = GLX_WINDOW_BIT; + __glXInitializeVisualConfigFromTags(m, nprops, props, + tagged_only, GL_TRUE); + m->screen = screen; + m = m->next; + } + + if (props != buf) + Xfree(props); + + return modes; +} + +static GLboolean +getVisualConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen) +{ + xGLXGetVisualConfigsReq *req; + __GLXscreenConfigs *psc; + xGLXGetVisualConfigsReply reply; + + LockDisplay(dpy); + + psc = priv->screenConfigs + screen; + psc->visuals = NULL; + GetReq(GLXGetVisualConfigs, req); + req->reqType = priv->majorOpcode; + req->glxCode = X_GLXGetVisualConfigs; + req->screen = screen; + + if (!_XReply(dpy, (xReply*) &reply, 0, False)) + goto out; + + psc->visuals = createConfigsFromProperties(dpy, + reply.numVisuals, + reply.numProps, + screen, GL_FALSE); + + out: + UnlockDisplay(dpy); + return psc->visuals != NULL; +} + +static GLboolean +getFBConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen) +{ + xGLXGetFBConfigsReq *fb_req; + xGLXGetFBConfigsSGIXReq *sgi_req; + xGLXVendorPrivateWithReplyReq *vpreq; + xGLXGetFBConfigsReply reply; + __GLXscreenConfigs *psc; + + psc = priv->screenConfigs + screen; + psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode, + X_GLXQueryServerString, + screen, GLX_EXTENSIONS); + + LockDisplay(dpy); + + psc->configs = NULL; + if (atof(priv->serverGLXversion) >= 1.3) { + GetReq(GLXGetFBConfigs, fb_req); + fb_req->reqType = priv->majorOpcode; + fb_req->glxCode = X_GLXGetFBConfigs; + fb_req->screen = screen; + } else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) { + GetReqExtra(GLXVendorPrivateWithReply, + sz_xGLXGetFBConfigsSGIXReq + + sz_xGLXVendorPrivateWithReplyReq, vpreq); + sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq; + sgi_req->reqType = priv->majorOpcode; + sgi_req->glxCode = X_GLXVendorPrivateWithReply; + sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX; + sgi_req->screen = screen; + } else + goto out; + + if (!_XReply(dpy, (xReply*) &reply, 0, False)) + goto out; + + psc->configs = createConfigsFromProperties(dpy, + reply.numFBConfigs, + reply.numAttribs * 2, + screen, GL_TRUE); + + out: + UnlockDisplay(dpy); + return psc->configs != NULL; +} /* ** Allocate the memory for the per screen configs for each screen. @@ -1006,17 +1129,8 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc, */ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) { - xGLXGetVisualConfigsReq *req; - xGLXGetFBConfigsReq *fb_req; - xGLXVendorPrivateWithReplyReq *vpreq; - xGLXGetFBConfigsSGIXReq *sgi_req; - xGLXGetVisualConfigsReply reply; __GLXscreenConfigs *psc; - __GLcontextModes *config; - GLint i, j, nprops, screens; - INT32 buf[__GLX_TOTAL_CONFIG], *props; - unsigned supported_request = 0; - unsigned prop_size; + GLint i, screens; /* ** First allocate memory for the array of per screen configs. @@ -1030,141 +1144,16 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) priv->screenConfigs = psc; priv->serverGLXversion = __glXGetStringFromServer(dpy, priv->majorOpcode, - X_GLXQueryServerString, - 0, GLX_VERSION); + X_GLXQueryServerString, + 0, GLX_VERSION); if ( priv->serverGLXversion == NULL ) { FreeScreenConfigs(priv); return GL_FALSE; } - if ( atof( priv->serverGLXversion ) >= 1.3 ) { - supported_request = 1; - } - - /* - ** Now fetch each screens configs structures. If a screen supports - ** GL (by returning a numVisuals > 0) then allocate memory for our - ** config structure and then fill it in. - */ for (i = 0; i < screens; i++, psc++) { - if ( supported_request != 1 ) { - psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode, - X_GLXQueryServerString, - i, GLX_EXTENSIONS); - if ( strstr( psc->serverGLXexts, "GLX_SGIX_fbconfig" ) != NULL ) { - supported_request = 2; - } - else { - supported_request = 3; - } - } - - - LockDisplay(dpy); - switch( supported_request ) { - case 1: - GetReq(GLXGetFBConfigs,fb_req); - fb_req->reqType = priv->majorOpcode; - fb_req->glxCode = X_GLXGetFBConfigs; - fb_req->screen = i; - break; - - case 2: - GetReqExtra(GLXVendorPrivateWithReply, - sz_xGLXGetFBConfigsSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq); - sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq; - sgi_req->reqType = priv->majorOpcode; - sgi_req->glxCode = X_GLXVendorPrivateWithReply; - sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX; - sgi_req->screen = i; - break; - - case 3: - GetReq(GLXGetVisualConfigs,req); - req->reqType = priv->majorOpcode; - req->glxCode = X_GLXGetVisualConfigs; - req->screen = i; - break; - } - - if (!_XReply(dpy, (xReply*) &reply, 0, False)) { - /* Something is busted. Punt. */ - UnlockDisplay(dpy); - SyncHandle(); - FreeScreenConfigs(priv); - return GL_FALSE; - } - - if (!reply.numVisuals) { - /* This screen does not support GL rendering */ - UnlockDisplay(dpy); - continue; - } - - /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for - * FIXME: FBconfigs? - */ - /* Check number of properties */ - nprops = reply.numProps; - if ((nprops < __GLX_MIN_CONFIG_PROPS) || - (nprops > __GLX_MAX_CONFIG_PROPS)) { - /* Huh? Not in protocol defined limits. Punt */ - UnlockDisplay(dpy); - SyncHandle(); - FreeScreenConfigs(priv); - return GL_FALSE; - } - - /* Allocate memory for our config structure */ - psc->configs = _gl_context_modes_create(reply.numVisuals, - sizeof(__GLcontextModes)); - if (!psc->configs) { - UnlockDisplay(dpy); - SyncHandle(); - FreeScreenConfigs(priv); - return GL_FALSE; - } - - /* Allocate memory for the properties, if needed */ - if ( supported_request != 3 ) { - nprops *= 2; - } - - prop_size = nprops * __GLX_SIZE_INT32; - - if (prop_size <= sizeof(buf)) { - props = buf; - } else { - props = (INT32 *) Xmalloc(prop_size); - } - - /* Read each config structure and convert it into our format */ - config = psc->configs; - for (j = 0; j < reply.numVisuals; j++) { - assert( config != NULL ); - _XRead(dpy, (char *)props, prop_size); - - if ( supported_request != 3 ) { - config->rgbMode = GL_TRUE; - config->drawableType = GLX_WINDOW_BIT; - } - else { - config->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; - } - - __glXInitializeVisualConfigFromTags( config, nprops, props, - (supported_request != 3), - GL_TRUE ); - if ( config->fbconfigID == GLX_DONT_CARE ) { - config->fbconfigID = config->visualID; - } - config->screen = i; - config = config->next; - } - if (props != buf) { - Xfree((char *)props); - } - UnlockDisplay(dpy); + getVisualConfigs(dpy, priv, i); + getFBConfigs(dpy, priv, i); #ifdef GLX_DIRECT_RENDERING psc->scr = i; diff --git a/src/mesa/Makefile b/src/mesa/Makefile index a47cd4c023d..77bb7be4806 100644 --- a/src/mesa/Makefile +++ b/src/mesa/Makefile @@ -153,8 +153,13 @@ depend: $(ALL_SOURCES) subdirs: - @ (cd x86 ; $(MAKE)) - @ (cd x86-64 ; $(MAKE)) + @ if echo "$(ASM_FLAGS)" | grep -q USE_X86_ASM ; then \ + (cd x86 ; $(MAKE)) ; \ + fi + @ if echo "$(ASM_FLAGS)" | grep -q USE_X86_64_ASM ; then \ + (cd x86 ; $(MAKE)) ; \ + (cd x86-64 ; $(MAKE)) ; \ + fi install: default gl.pc diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index d59ea0ddad0..2e2e64c4d18 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -356,10 +356,18 @@ static void driSwapBuffers(__DRIdrawable *drawable) &rect, 1, GL_TRUE); } +static int driDrawableGetMSC( __DRIscreen *screen, void *drawablePrivate, + int64_t *msc ) +{ + __DRIscreenPrivate *sPriv = screen->private; + + return sPriv->DriverAPI.GetDrawableMSC( sPriv, drawablePrivate, msc ); +} + /** * Called directly from a number of higher-level GLX functions. */ -static int driGetMSC( __DRIscreen *screen, int64_t *msc ) +static int driGetMSC( __DRIscreen *screen, void *drawablePrivate, int64_t *msc ) { __DRIscreenPrivate *sPriv = screen->private; @@ -396,6 +404,7 @@ const __DRImediaStreamCounterExtension driMediaStreamCounterExtension = { { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION }, driGetMSC, driWaitForMSC, + driDrawableGetMSC, }; static void driCopySubBuffer(__DRIdrawable *drawable, @@ -471,6 +480,8 @@ static void *driCreateNewDrawable(__DRIscreen *screen, pdp->numBackClipRects = 0; pdp->pClipRects = NULL; pdp->pBackClipRects = NULL; + pdp->vblSeq = 0; + pdp->vblFlags = 0; psp = (__DRIscreenPrivate *)screen->private; pdp->driScreenPriv = psp; @@ -485,6 +496,7 @@ static void *driCreateNewDrawable(__DRIscreen *screen, pdraw->private = pdp; pdraw->destroyDrawable = driDestroyDrawable; pdraw->swapBuffers = driSwapBuffers; /* called by glXSwapBuffers() */ + pdp->msc_base = 0; /* This special default value is replaced with the configured * default value when the drawable is first bound to a direct diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index 91992a9a242..def07758398 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -206,6 +206,14 @@ struct __DriverAPIRec { */ void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname, unsigned long long offset, GLint depth, GLuint pitch); + + /** + * New version of GetMSC so we can pass drawable data to the low level + * DRM driver (e.g. pipe info). + */ + int (*GetDrawableMSC) ( __DRIscreenPrivate * priv, + __DRIdrawablePrivate *drawablePrivate, + int64_t *count); }; @@ -318,6 +326,32 @@ struct __DRIdrawablePrivateRec { /*@}*/ /** + * \name Vertical blank tracking information + * Used for waiting on vertical blank events. + */ + /*@{*/ + unsigned int vblSeq; + unsigned int vblFlags; + /*@}*/ + + /** + * \name Monotonic MSC tracking + * + * Low level driver is responsible for updating msc_base and + * vblSeq values so that higher level code can calculate + * a new msc value or msc target for a WaitMSC call. The new value + * will be: + * msc = msc_base + get_vblank_count() - vblank_base; + * + * And for waiting on a value, core code will use: + * actual_target = target_msc - msc_base + vblank_base; + */ + /*@{*/ + int64_t vblank_base; + int64_t msc_base; + /*@}*/ + + /** * Pointer to context to which this drawable is currently bound. */ __DRIcontextPrivate *driContextPriv; diff --git a/src/mesa/drivers/dri/common/vblank.c b/src/mesa/drivers/dri/common/vblank.c index 3b5acfecb12..05964404632 100644 --- a/src/mesa/drivers/dri/common/vblank.c +++ b/src/mesa/drivers/dri/common/vblank.c @@ -35,6 +35,16 @@ #include "vblank.h" #include "xmlpool.h" +static unsigned int msc_to_vblank(__DRIdrawablePrivate * dPriv, int64_t msc) +{ + return (unsigned int)(msc - dPriv->msc_base + dPriv->vblank_base); +} + +static int64_t vblank_to_msc(__DRIdrawablePrivate * dPriv, unsigned int vblank) +{ + return (int64_t)(vblank - dPriv->vblank_base + dPriv->msc_base); +} + /****************************************************************************/ /** @@ -42,7 +52,7 @@ * * Stores the 64-bit count of vertical refreshes since some (arbitrary) * point in time in \c count. Unless the value wraps around, which it - * may, it will never decrease. + * may, it will never decrease for a given drawable. * * \warning This function is called from \c glXGetVideoSyncSGI, which expects * a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which @@ -50,11 +60,14 @@ * currently always returns a \c sequence of type \c unsigned. * * \param priv Pointer to the DRI screen private struct. + * \param dPriv Pointer to the DRI drawable private struct * \param count Storage to hold MSC counter. * \return Zero is returned on success. A negative errno value * is returned on failure. */ -int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count ) +int driDrawableGetMSC32( __DRIscreenPrivate * priv, + __DRIdrawablePrivate * dPriv, + int64_t * count) { drmVBlank vbl; int ret; @@ -63,13 +76,46 @@ int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count ) vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.sequence = 0; + if ( dPriv && dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; ret = drmWaitVBlank( priv->fd, &vbl ); - *count = (int64_t)vbl.reply.sequence; + + if (dPriv) { + *count = vblank_to_msc(dPriv, vbl.reply.sequence); + } else { + /* Old driver (no knowledge of drawable MSC callback) */ + *count = vbl.reply.sequence; + } return ret; } +/** + * Get the current MSC refresh counter. + * + * Stores the 64-bit count of vertical refreshes since some (arbitrary) + * point in time in \c count. Unless the value wraps around, which it + * may, it will never decrease. + * + * \warning This function is called from \c glXGetVideoSyncSGI, which expects + * a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which + * expects a \c count of type \c int64_t (signed 64-bit). The kernel ioctl + * currently always returns a \c sequence of type \c unsigned. + * + * Since this function doesn't take a drawable, it may end up getting the MSC + * value from a pipe not associated with the caller's context, resuling in + * undesired behavior. + * + * \param priv Pointer to the DRI screen private struct. + * \param count Storage to hold MSC counter. + * \return Zero is returned on success. A negative errno value + * is returned on failure. + */ +int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count ) +{ + return driDrawableGetMSC32(priv, NULL, count); +} /****************************************************************************/ /** @@ -123,7 +169,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, */ vbl.request.type = dont_wait ? DRM_VBLANK_RELATIVE : DRM_VBLANK_ABSOLUTE; - vbl.request.sequence = next; + vbl.request.sequence = next ? msc_to_vblank(priv, next) : 0; + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) { /* FIXME: This doesn't seem like the right thing to return here. @@ -131,8 +179,10 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, return GLX_BAD_CONTEXT; } + *msc = vblank_to_msc(priv, vbl.reply.sequence); + dont_wait = 0; - if (target_msc != 0 && vbl.reply.sequence == target) + if (target_msc != 0 && *msc == target) break; /* Assuming the wait-done test fails, the next refresh to wait for @@ -142,9 +192,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, * If this refresh has already happened, we add divisor to obtain * the next refresh after the current one that will satisfy it. */ - r = (vbl.reply.sequence % (unsigned int)divisor); - next = (vbl.reply.sequence - r + (unsigned int)remainder); - if (next <= vbl.reply.sequence) next += (unsigned int)divisor; + r = (*msc % (unsigned int)divisor); + next = (*msc - r + (unsigned int)remainder); + if (next <= *msc) next += (unsigned int)divisor; } while ( r != (unsigned int)remainder ); } @@ -154,7 +204,10 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, */ vbl.request.type = DRM_VBLANK_ABSOLUTE; - vbl.request.sequence = target_msc; + vbl.request.sequence = target_msc ? msc_to_vblank(priv, target_msc) : 0; + + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) { /* FIXME: This doesn't seem like the right thing to return here. @@ -163,8 +216,8 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, } } - *msc = (target_msc & 0xffffffff00000000LL); - *msc |= vbl.reply.sequence; + *msc = vblank_to_msc(priv, vbl.reply.sequence); + if ( *msc < target_msc ) { *msc += 0x0000000100000000LL; } @@ -252,16 +305,21 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd ) * direct rendering context. */ -void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags, - GLuint *vbl_seq ) +void driDrawableInitVBlank( __DRIdrawablePrivate *priv ) { if ( priv->swap_interval == (unsigned)-1 ) { /* Get current vertical blank sequence */ - drmVBlank vbl = { .request={ .type = DRM_VBLANK_RELATIVE, .sequence = 0 } }; - do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd ); - - priv->swap_interval = (flags & (VBLANK_FLAG_THROTTLE | - VBLANK_FLAG_SYNC)) != 0 ? 1 : 0; + drmVBlank vbl; + + vbl.request.type = DRM_VBLANK_RELATIVE; + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; + vbl.request.sequence = 0; + do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd ); + priv->vblank_base = priv->vblSeq; + + priv->swap_interval = + (priv->vblFlags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) ? 1 : 0; } } diff --git a/src/mesa/drivers/dri/common/vblank.h b/src/mesa/drivers/dri/common/vblank.h index ec83adc78dd..e8550b28124 100644 --- a/src/mesa/drivers/dri/common/vblank.h +++ b/src/mesa/drivers/dri/common/vblank.h @@ -46,11 +46,13 @@ */ extern int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count ); +extern int driDrawableGetMSC32( __DRIscreenPrivate * priv, + __DRIdrawablePrivate * drawablePrivate, + int64_t * count); extern int driWaitForMSC32( __DRIdrawablePrivate *priv, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc ); extern GLuint driGetDefaultVBlankFlags( const driOptionCache *optionCache ); -extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv, GLuint flags, - GLuint *vbl_seq ); +extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv ); extern unsigned driGetVBlankInterval( const __DRIdrawablePrivate *priv, GLuint flags ); extern void driGetCurrentVBlank( const __DRIdrawablePrivate *priv, diff --git a/src/mesa/drivers/dri/ffb/ffb_xmesa.c b/src/mesa/drivers/dri/ffb/ffb_xmesa.c index 3a5551eeb37..173c5fa952a 100644 --- a/src/mesa/drivers/dri/ffb/ffb_xmesa.c +++ b/src/mesa/drivers/dri/ffb/ffb_xmesa.c @@ -615,6 +615,7 @@ static const struct __DriverAPIRec ffbAPI = { .UnbindContext = ffbUnbindContext, .GetSwapInfo = NULL, .GetMSC = NULL, + .GetDrawableMSC = NULL, .WaitForMSC = NULL, .WaitForSBC = NULL, .SwapBuffersMSC = NULL diff --git a/src/mesa/drivers/dri/i810/i810screen.c b/src/mesa/drivers/dri/i810/i810screen.c index 3c7ec96ff3d..1a0d3c33d7b 100644 --- a/src/mesa/drivers/dri/i810/i810screen.c +++ b/src/mesa/drivers/dri/i810/i810screen.c @@ -413,6 +413,7 @@ static const struct __DriverAPIRec i810API = { .UnbindContext = i810UnbindContext, .GetSwapInfo = NULL, .GetMSC = NULL, + .GetDrawableMSC = NULL, .WaitForMSC = NULL, .WaitForSBC = NULL, .SwapBuffersMSC = NULL diff --git a/src/mesa/drivers/dri/i915/i915_debug.c b/src/mesa/drivers/dri/i915/i915_debug.c index c0e1242a0ea..8eb1c5b49e1 100644 --- a/src/mesa/drivers/dri/i915/i915_debug.c +++ b/src/mesa/drivers/dri/i915/i915_debug.c @@ -376,20 +376,25 @@ static void BR13( struct debug_stream *stream, } -static void BR22( struct debug_stream *stream, - GLuint val ) +static void BR2223( struct debug_stream *stream, + GLuint val22, GLuint val23 ) { - PRINTF("\t0x%08x\n", val); - BITS(val, 31, 16, "dest y1"); - BITS(val, 15, 0, "dest x1"); -} + union { GLuint val; short field[2]; } BR22, BR23; -static void BR23( struct debug_stream *stream, - GLuint val ) -{ - PRINTF("\t0x%08x\n", val); - BITS(val, 31, 16, "dest y2"); - BITS(val, 15, 0, "dest x2"); + BR22.val = val22; + BR23.val = val23; + + PRINTF("\t0x%08x\n", val22); + BITS(val22, 31, 16, "dest y1"); + BITS(val22, 15, 0, "dest x1"); + + PRINTF("\t0x%08x\n", val23); + BITS(val23, 31, 16, "dest y2"); + BITS(val23, 15, 0, "dest x2"); + + /* The blit engine may produce unexpected results when these aren't met */ + assert(BR22.field[0] < BR23.field[0]); + assert(BR22.field[1] < BR23.field[1]); } static void BR09( struct debug_stream *stream, @@ -436,8 +441,8 @@ static GLboolean debug_copy_blit( struct debug_stream *stream, PRINTF("\t0x%08x\n", ptr[j++]); BR13(stream, ptr[j++]); - BR22(stream, ptr[j++]); - BR23(stream, ptr[j++]); + BR2223(stream, ptr[j], ptr[j+1]); + j += 2; BR09(stream, ptr[j++]); BR26(stream, ptr[j++]); BR11(stream, ptr[j++]); @@ -459,8 +464,8 @@ static GLboolean debug_color_blit( struct debug_stream *stream, PRINTF("\t0x%08x\n", ptr[j++]); BR13(stream, ptr[j++]); - BR22(stream, ptr[j++]); - BR23(stream, ptr[j++]); + BR2223(stream, ptr[j], ptr[j+1]); + j += 2; BR09(stream, ptr[j++]); BR16(stream, ptr[j++]); diff --git a/src/mesa/drivers/dri/i915/intel_blit.c b/src/mesa/drivers/dri/i915/intel_blit.c index b00b0d9e1b5..2d4d00edefd 100644 --- a/src/mesa/drivers/dri/i915/intel_blit.c +++ b/src/mesa/drivers/dri/i915/intel_blit.c @@ -402,6 +402,9 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask) b = *box; } + if (b.x1 >= b.x2 || b.y1 >= b.y2) + continue; + if (0) _mesa_printf("clear %d,%d..%d,%d, mask %x\n", b.x1, b.y1, b.x2, b.y2, mask); diff --git a/src/mesa/drivers/dri/i915/intel_buffers.c b/src/mesa/drivers/dri/i915/intel_buffers.c index 46a67b141e7..faa13adbcb3 100644 --- a/src/mesa/drivers/dri/i915/intel_buffers.c +++ b/src/mesa/drivers/dri/i915/intel_buffers.c @@ -243,7 +243,7 @@ intelWindowMoved(struct intel_context *intel) .y2 = sarea->planeB_y + sarea->planeB_h }; GLint areaA = driIntersectArea( drw_rect, planeA_rect ); GLint areaB = driIntersectArea( drw_rect, planeB_rect ); - GLuint flags = intel_fb->vblank_flags; + GLuint flags = dPriv->vblFlags; GLboolean pf_active; GLint pf_planes; @@ -311,19 +311,24 @@ intelWindowMoved(struct intel_context *intel) /* Update vblank info */ if (areaB > areaA || (areaA == areaB && areaB > 0)) { - flags = intel_fb->vblank_flags | VBLANK_FLAG_SECONDARY; + flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY; } else { - flags = intel_fb->vblank_flags & ~VBLANK_FLAG_SECONDARY; + flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY; } - if (flags != intel_fb->vblank_flags && intel_fb->vblank_flags && - !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ)) { + /* Check to see if we changed pipes */ + if (flags != dPriv->vblFlags && dPriv->vblFlags && + !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) { + int64_t count; drmVBlank vbl; int i; + /* + * Deal with page flipping + */ vbl.request.type = DRM_VBLANK_ABSOLUTE; - if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) { + if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) { vbl.request.type |= DRM_VBLANK_SECONDARY; } @@ -337,9 +342,19 @@ intelWindowMoved(struct intel_context *intel) drmWaitVBlank(intel->driFd, &vbl); } - intel_fb->vblank_flags = flags; - driGetCurrentVBlank(dPriv, intel_fb->vblank_flags, &intel_fb->vbl_seq); - intel_fb->vbl_waited = intel_fb->vbl_seq; + /* + * Update msc_base from old pipe + */ + driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count); + dPriv->msc_base = count; + /* + * Then get new vblank_base and vblSeq values + */ + dPriv->vblFlags = flags; + driGetCurrentVBlank(dPriv, dPriv->vblFlags, &dPriv->vblSeq); + dPriv->vblank_base = dPriv->vblSeq; + + intel_fb->vbl_waited = dPriv->vblSeq; for (i = 0; i < intel_fb->pf_num_pages; i++) { if (intel_fb->color_rb[i]) @@ -347,7 +362,7 @@ intelWindowMoved(struct intel_context *intel) } } } else { - intel_fb->vblank_flags &= ~VBLANK_FLAG_SECONDARY; + dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY; } /* Update Mesa's notion of window size */ @@ -820,10 +835,10 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv) */ static GLboolean -intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target) +intelScheduleSwap(__DRIdrawablePrivate * dPriv, GLboolean *missed_target) { struct intel_framebuffer *intel_fb = dPriv->driverPrivate; - unsigned int interval = driGetVBlankInterval(dPriv, intel_fb->vblank_flags); + unsigned int interval = driGetVBlankInterval(dPriv, dPriv->vblFlags); struct intel_context *intel = intelScreenContext(dPriv->driScreenPriv->private); const intelScreenPrivate *intelScreen = intel->intelScreen; @@ -831,24 +846,24 @@ intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target) drm_i915_vblank_swap_t swap; GLboolean ret; - if (!intel_fb->vblank_flags || - (intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) || + if (!dPriv->vblFlags || + (dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) || intelScreen->current_rotation != 0 || intelScreen->drmMinor < (intel_fb->pf_active ? 9 : 6)) return GL_FALSE; swap.seqtype = DRM_VBLANK_ABSOLUTE; - if (intel_fb->vblank_flags & VBLANK_FLAG_SYNC) { + if (dPriv->vblFlags & VBLANK_FLAG_SYNC) { swap.seqtype |= DRM_VBLANK_NEXTONMISS; } else if (interval == 0) { return GL_FALSE; } swap.drawable = dPriv->hHWDrawable; - target = swap.sequence = intel_fb->vbl_seq + interval; + target = swap.sequence = dPriv->vblSeq + interval; - if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) { + if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) { swap.seqtype |= DRM_VBLANK_SECONDARY; } @@ -866,14 +881,14 @@ intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target) if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap, sizeof(swap))) { - intel_fb->vbl_seq = swap.sequence; + dPriv->vblSeq = swap.sequence; swap.sequence -= target; *missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23); intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->vbl_pending = intel_get_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT)->vbl_pending = - intel_fb->vbl_seq; + dPriv->vblSeq; if (swap.seqtype & DRM_VBLANK_FLIP) { intel_flip_renderbuffers(intel_fb); @@ -918,7 +933,7 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv) if (screen->current_rotation != 0 || !intelScheduleSwap(dPriv, &missed_target)) { - driWaitForVBlank(dPriv, &intel_fb->vbl_seq, intel_fb->vblank_flags, + driWaitForVBlank(dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target); if (screen->current_rotation != 0 || !intelPageFlip(dPriv)) { diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index d7af432ad6b..b85b0c2939c 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -616,18 +616,17 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv, if (driDrawPriv->swap_interval == (unsigned)-1) { int i; - intel_fb->vblank_flags = (intel->intelScreen->irq_active != 0) + driDrawPriv->vblFlags = (intel->intelScreen->irq_active != 0) ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ; (*dri_interface->getUST) (&intel_fb->swap_ust); - driDrawableInitVBlank(driDrawPriv, intel_fb->vblank_flags, - &intel_fb->vbl_seq); - intel_fb->vbl_waited = intel_fb->vbl_seq; + driDrawableInitVBlank(driDrawPriv); + intel_fb->vbl_waited = driDrawPriv->vblSeq; for (i = 0; i < (intel->intelScreen->third.handle ? 3 : 2); i++) { if (intel_fb->color_rb[i]) - intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_seq; + intel_fb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq; } } intel->driDrawable = driDrawPriv; @@ -731,6 +730,7 @@ intelContendedLock(struct intel_context *intel, GLuint flags) */ void LOCK_HARDWARE( struct intel_context *intel ) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; char __ret=0; struct intel_framebuffer *intel_fb = NULL; struct intel_renderbuffer *intel_rb = NULL; @@ -748,14 +748,14 @@ void LOCK_HARDWARE( struct intel_context *intel ) BUFFER_BACK_LEFT); } - if (intel_rb && intel_fb->vblank_flags && - !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) && + if (intel_rb && dPriv->vblFlags && + !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) && (intel_fb->vbl_waited - intel_rb->vbl_pending) > (1<<23)) { drmVBlank vbl; vbl.request.type = DRM_VBLANK_ABSOLUTE; - if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) { + if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) { vbl.request.type |= DRM_VBLANK_SECONDARY; } diff --git a/src/mesa/drivers/dri/i915/intel_fbo.h b/src/mesa/drivers/dri/i915/intel_fbo.h index 411d6342317..f9a11d02e30 100644 --- a/src/mesa/drivers/dri/i915/intel_fbo.h +++ b/src/mesa/drivers/dri/i915/intel_fbo.h @@ -50,8 +50,6 @@ struct intel_framebuffer /* VBI */ - GLuint vbl_seq; - GLuint vblank_flags; GLuint vbl_waited; int64_t swap_ust; diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c index 8be5d910a0b..25f5efa7bcf 100644 --- a/src/mesa/drivers/dri/i915/intel_screen.c +++ b/src/mesa/drivers/dri/i915/intel_screen.c @@ -790,6 +790,7 @@ static const struct __DriverAPIRec intelAPI = { .UnbindContext = intelUnbindContext, .GetSwapInfo = intelGetSwapInfo, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL, diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 73cc9667c64..d7a2b46e1cf 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -69,6 +69,7 @@ DRIVER_SOURCES = \ brw_wm_emit.c \ brw_wm_fp.c \ brw_wm_iz.c \ + brw_wm_glsl.c \ brw_wm_pass0.c \ brw_wm_pass1.c \ brw_wm_pass2.c \ diff --git a/src/mesa/drivers/dri/i965/brw_clip.h b/src/mesa/drivers/dri/i965/brw_clip.h index 49b2770a514..2a65697325b 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.h +++ b/src/mesa/drivers/dri/i965/brw_clip.h @@ -42,7 +42,7 @@ * up polygon offset and flatshading at this point: */ struct brw_clip_prog_key { - GLuint attrs:16; + GLuint attrs:32; GLuint primitive:4; GLuint nr_userclip:3; GLuint do_flat_shading:1; @@ -51,7 +51,7 @@ struct brw_clip_prog_key { GLuint fill_ccw:2; /* includes cull information */ GLuint offset_cw:1; GLuint offset_ccw:1; - GLuint pad0:1; + GLuint pad0:17; GLuint copy_bfc_cw:1; GLuint copy_bfc_ccw:1; diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index 0ccdd8a6610..6231cba3f93 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -43,6 +43,8 @@ #include "api_noop.h" #include "vtxfmt.h" +#include "shader/shader_api.h" + /*************************************** * Mesa's Driver Functions ***************************************/ @@ -59,12 +61,37 @@ static const struct dri_extension brw_extensions[] = { NULL, NULL } }; +static void brwUseProgram(GLcontext *ctx, GLuint program) +{ + struct brw_context *brw = brw_context(ctx); + struct gl_shader_program *sh_prog; + _mesa_use_program(ctx, program); + sh_prog = ctx->Shader.CurrentProgram; + if (sh_prog) { + if (sh_prog->VertexProgram) { + brw->attribs.VertexProgram->Current = sh_prog->VertexProgram; + ctx->VertexProgram.Enabled = GL_TRUE; + }else + ctx->VertexProgram.Enabled = GL_FALSE; + + if (sh_prog->FragmentProgram) { + brw->attribs.FragmentProgram->Current = sh_prog->FragmentProgram; + ctx->FragmentProgram.Enabled = GL_TRUE; + } else + ctx->FragmentProgram.Enabled = GL_FALSE; + } +} +static void brwInitProgFuncs( struct dd_function_table *functions ) +{ + functions->UseProgram = brwUseProgram; +} static void brwInitDriverFunctions( struct dd_function_table *functions ) { intelInitDriverFunctions( functions ); brwInitTextureFuncs( functions ); brwInitFragProgFuncs( functions ); + brwInitProgFuncs( functions ); } diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h index 52f89d577ca..5c98767c3e5 100644 --- a/src/mesa/drivers/dri/i965/brw_eu.h +++ b/src/mesa/drivers/dri/i965/brw_eu.h @@ -648,6 +648,11 @@ static __inline struct brw_reg deref_1uw(struct brw_indirect ptr, GLint offset) return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW); } +static __inline struct brw_reg deref_1ud(struct brw_indirect ptr, GLint offset) +{ + return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD); +} + static __inline struct brw_reg get_addr_reg(struct brw_indirect ptr) { return brw_address_reg(ptr.addr_subnr); @@ -668,7 +673,10 @@ static __inline struct brw_indirect brw_indirect( GLuint addr_subnr, GLint offse return ptr; } - +static __inline struct brw_instruction *current_insn( struct brw_compile *p) +{ + return &p->store[p->nr_insn]; +} void brw_pop_insn_state( struct brw_compile *p ); void brw_push_insn_state( struct brw_compile *p ); @@ -808,9 +816,11 @@ void brw_ENDIF(struct brw_compile *p, struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size); -void brw_WHILE(struct brw_compile *p, +struct brw_instruction *brw_WHILE(struct brw_compile *p, struct brw_instruction *patch_insn); +struct brw_instruction *brw_BREAK(struct brw_compile *p); +struct brw_instruction *brw_CONT(struct brw_compile *p); /* Forward jumps: */ void brw_land_fwd_jump(struct brw_compile *p, @@ -860,5 +870,6 @@ void brw_math_invert( struct brw_compile *p, struct brw_reg dst, struct brw_reg src); - +void brw_set_src1( struct brw_instruction *insn, + struct brw_reg reg ); #endif diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c index 9992b47d8ae..95f9f027530 100644 --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c @@ -164,7 +164,7 @@ static void brw_set_src0( struct brw_instruction *insn, } -static void brw_set_src1( struct brw_instruction *insn, +void brw_set_src1( struct brw_instruction *insn, struct brw_reg reg ) { assert(reg.file != BRW_MESSAGE_REGISTER_FILE); @@ -186,7 +186,7 @@ static void brw_set_src1( struct brw_instruction *insn, * in the future: */ assert (reg.address_mode == BRW_ADDRESS_DIRECT); - assert (reg.file == BRW_GENERAL_REGISTER_FILE); + //assert (reg.file == BRW_GENERAL_REGISTER_FILE); if (insn->header.access_mode == BRW_ALIGN_1) { insn->bits3.da1.src1_subreg_nr = reg.subnr; @@ -597,6 +597,34 @@ void brw_ENDIF(struct brw_compile *p, } } +struct brw_instruction *brw_BREAK(struct brw_compile *p) +{ + struct brw_instruction *insn; + insn = next_insn(p, BRW_OPCODE_BREAK); + brw_set_dest(insn, brw_ip_reg()); + brw_set_src0(insn, brw_ip_reg()); + brw_set_src1(insn, brw_imm_d(0x0)); + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.execution_size = BRW_EXECUTE_8; + insn->header.mask_control = BRW_MASK_DISABLE; + insn->bits3.if_else.pad0 = 0; + return insn; +} + +struct brw_instruction *brw_CONT(struct brw_compile *p) +{ + struct brw_instruction *insn; + insn = next_insn(p, BRW_OPCODE_CONTINUE); + brw_set_dest(insn, brw_ip_reg()); + brw_set_src0(insn, brw_ip_reg()); + brw_set_src1(insn, brw_imm_d(0x0)); + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.execution_size = BRW_EXECUTE_8; + insn->header.mask_control = BRW_MASK_DISABLE; + insn->bits3.if_else.pad0 = 0; + return insn; +} + /* DO/WHILE loop: */ struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size) @@ -608,13 +636,15 @@ struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size) /* Override the defaults for this instruction: */ - brw_set_dest(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD)); - brw_set_src0(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD)); - brw_set_src1(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD)); + brw_set_dest(insn, brw_null_reg()); + brw_set_src0(insn, brw_null_reg()); + brw_set_src1(insn, brw_null_reg()); insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.execution_size = execute_size; + insn->header.predicate_control = BRW_PREDICATE_NONE; /* insn->header.mask_control = BRW_MASK_ENABLE; */ + insn->header.mask_control = BRW_MASK_DISABLE; return insn; } @@ -622,7 +652,7 @@ struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size) -void brw_WHILE(struct brw_compile *p, +struct brw_instruction *brw_WHILE(struct brw_compile *p, struct brw_instruction *do_insn) { struct brw_instruction *insn; @@ -653,7 +683,9 @@ void brw_WHILE(struct brw_compile *p, /* insn->header.mask_control = BRW_MASK_ENABLE; */ + insn->header.mask_control = BRW_MASK_DISABLE; p->current->header.predicate_control = BRW_PREDICATE_NONE; + return insn; } diff --git a/src/mesa/drivers/dri/i965/brw_gs.h b/src/mesa/drivers/dri/i965/brw_gs.h index 29a4e80ce1b..18a4537c323 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.h +++ b/src/mesa/drivers/dri/i965/brw_gs.h @@ -40,11 +40,11 @@ #define MAX_GS_VERTS (4) struct brw_gs_prog_key { + GLuint attrs:32; GLuint primitive:4; - GLuint attrs:16; GLuint hint_gs_always:1; GLuint need_gs_prog:1; - GLuint pad:10; + GLuint pad:26; }; struct brw_gs_compile { diff --git a/src/mesa/drivers/dri/i965/brw_sf.h b/src/mesa/drivers/dri/i965/brw_sf.h index e8946511dd4..385f1eea136 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.h +++ b/src/mesa/drivers/dri/i965/brw_sf.h @@ -45,10 +45,10 @@ #define SF_UNFILLED_TRIS 3 struct brw_sf_prog_key { + GLuint attrs:32; GLuint primitive:2; GLuint do_twoside_color:1; GLuint do_flat_shading:1; - GLuint attrs:16; GLuint frontface_ccw:1; GLuint do_point_sprite:1; GLuint pad:10; diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h index 8843f816f9c..41a33ffe387 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.h +++ b/src/mesa/drivers/dri/i965/brw_vs.h @@ -67,6 +67,12 @@ struct brw_vs_compile { struct brw_reg r1; struct brw_reg regs[PROGRAM_ADDRESS+1][128]; struct brw_reg tmp; + struct brw_reg stack; + + struct { + GLboolean used_in_src; + struct brw_reg reg; + } output_regs[128]; struct brw_reg userplane[6]; diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 8733b470c25..e62de186ae3 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -134,6 +134,16 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) WRITEMASK_X); reg++; } + + for (i = 0; i < 128; i++) { + if (c->output_regs[i].used_in_src) { + c->output_regs[i].reg = brw_vec8_grf(reg, 0); + reg++; + } + } + + c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg, 0); + reg += 2; /* Some opcodes need an internal temporary: @@ -213,57 +223,68 @@ static void unalias2( struct brw_vs_compile *c, } } +static void emit_sop( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1, + GLuint cond) +{ + brw_push_insn_state(p); + brw_CMP(p, brw_null_reg(), cond, arg0, arg1); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_MOV(p, dst, brw_imm_f(1.0f)); + brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); + brw_MOV(p, dst, brw_imm_f(0.0f)); + brw_pop_insn_state(p); +} +static void emit_seq( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1 ) +{ + emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_EQ); +} - +static void emit_sne( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1 ) +{ + emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_NEQ); +} static void emit_slt( struct brw_compile *p, struct brw_reg dst, struct brw_reg arg0, struct brw_reg arg1 ) { - /* Could be done with an if/else/endif, but this method uses half - * the instructions. Note that we are careful to reference the - * arguments before writing the dest. That means we emit the - * instructions in an odd order and have to play with the flag - * values. - */ - brw_push_insn_state(p); - brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0, arg1); - - /* Write all values to 1: - */ - brw_set_predicate_control(p, BRW_PREDICATE_NONE); - brw_MOV(p, dst, brw_imm_f(1.0)); + emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_L); +} - /* Where the test succeeded, overwite with zero: - */ - brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); - brw_MOV(p, dst, brw_imm_f(0.0)); - brw_pop_insn_state(p); +static void emit_sle( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1 ) +{ + emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_LE); } +static void emit_sgt( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1 ) +{ + emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_G); +} static void emit_sge( struct brw_compile *p, struct brw_reg dst, struct brw_reg arg0, struct brw_reg arg1 ) { - brw_push_insn_state(p); - brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0, arg1); - - /* Write all values to zero: - */ - brw_set_predicate_control(p, BRW_PREDICATE_NONE); - brw_MOV(p, dst, brw_imm_f(0)); - - /* Where the test succeeded, overwite with 1: - */ - brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); - brw_MOV(p, dst, brw_imm_f(1.0)); - brw_pop_insn_state(p); + emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_GE); } - static void emit_max( struct brw_compile *p, struct brw_reg dst, struct brw_reg arg0, @@ -592,9 +613,13 @@ static struct brw_reg get_reg( struct brw_vs_compile *c, case PROGRAM_TEMPORARY: case PROGRAM_INPUT: case PROGRAM_OUTPUT: - case PROGRAM_STATE_VAR: assert(c->regs[file][index].nr != 0); return c->regs[file][index]; + case PROGRAM_STATE_VAR: + case PROGRAM_CONSTANT: + case PROGRAM_UNIFORM: + assert(c->regs[PROGRAM_STATE_VAR][index].nr != 0); + return c->regs[PROGRAM_STATE_VAR][index]; case PROGRAM_ADDRESS: assert(index == 0); return c->regs[file][index]; @@ -668,28 +693,28 @@ static void emit_arl( struct brw_vs_compile *c, * account. */ static struct brw_reg get_arg( struct brw_vs_compile *c, - struct prog_src_register src ) + struct prog_src_register *src ) { struct brw_reg reg; - if (src.File == PROGRAM_UNDEFINED) + if (src->File == PROGRAM_UNDEFINED) return brw_null_reg(); - if (src.RelAddr) - reg = deref(c, c->regs[PROGRAM_STATE_VAR][0], src.Index); + if (src->RelAddr) + reg = deref(c, c->regs[PROGRAM_STATE_VAR][0], src->Index); else - reg = get_reg(c, src.File, src.Index); + reg = get_reg(c, src->File, src->Index); /* Convert 3-bit swizzle to 2-bit. */ - reg.dw1.bits.swizzle = BRW_SWIZZLE4(GET_SWZ(src.Swizzle, 0), - GET_SWZ(src.Swizzle, 1), - GET_SWZ(src.Swizzle, 2), - GET_SWZ(src.Swizzle, 3)); + reg.dw1.bits.swizzle = BRW_SWIZZLE4(GET_SWZ(src->Swizzle, 0), + GET_SWZ(src->Swizzle, 1), + GET_SWZ(src->Swizzle, 2), + GET_SWZ(src->Swizzle, 3)); /* Note this is ok for non-swizzle instructions: */ - reg.negate = src.NegateBase ? 1 : 0; + reg.negate = src->NegateBase ? 1 : 0; return reg; } @@ -891,17 +916,50 @@ static void emit_vertex_write( struct brw_vs_compile *c) } - - +static void +post_vs_emit( struct brw_vs_compile *c, struct brw_instruction *end_inst ) +{ + GLuint nr_insns = c->vp->program.Base.NumInstructions; + GLuint insn, target_insn; + struct prog_instruction *inst1, *inst2; + struct brw_instruction *brw_inst1, *brw_inst2; + int offset; + for (insn = 0; insn < nr_insns; insn++) { + inst1 = &c->vp->program.Base.Instructions[insn]; + brw_inst1 = inst1->Data; + switch (inst1->Opcode) { + case OPCODE_CAL: + case OPCODE_BRA: + target_insn = inst1->BranchTarget; + inst2 = &c->vp->program.Base.Instructions[target_insn]; + brw_inst2 = inst2->Data; + offset = brw_inst2 - brw_inst1; + brw_set_src1(brw_inst1, brw_imm_d(offset*16)); + break; + case OPCODE_END: + offset = end_inst - brw_inst1; + brw_set_src1(brw_inst1, brw_imm_d(offset*16)); + break; + default: + break; + } + } +} /* Emit the fragment program instructions here. */ -void brw_vs_emit( struct brw_vs_compile *c ) +void brw_vs_emit(struct brw_vs_compile *c ) { +#define MAX_IFSN 32 struct brw_compile *p = &c->func; GLuint nr_insns = c->vp->program.Base.NumInstructions; - GLuint insn; + GLuint insn, if_insn = 0; + struct brw_instruction *end_inst; + struct brw_instruction *if_inst[MAX_IFSN]; + struct brw_indirect stack_index = brw_indirect(0, 0); + GLuint index; + GLuint file; if (INTEL_DEBUG & DEBUG_VS) { _mesa_printf("\n\n\nvs-emit:\n"); @@ -912,9 +970,24 @@ void brw_vs_emit( struct brw_vs_compile *c ) brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_access_mode(p, BRW_ALIGN_16); + /* Message registers can't be read, so copy the output into GRF register + if they are used in source registers */ + for (insn = 0; insn < nr_insns; insn++) { + GLuint i; + struct prog_instruction *inst = &c->vp->program.Base.Instructions[insn]; + for (i = 0; i < 3; i++) { + struct prog_src_register *src = &inst->SrcReg[i]; + GLuint index = src->Index; + GLuint file = src->File; + if (file == PROGRAM_OUTPUT && index != VERT_RESULT_HPOS) + c->output_regs[index].used_in_src = GL_TRUE; + } + } + /* Static register allocation */ brw_vs_alloc_regs(c); + brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack)); for (insn = 0; insn < nr_insns; insn++) { @@ -924,17 +997,29 @@ void brw_vs_emit( struct brw_vs_compile *c ) /* Get argument regs. SWZ is special and does this itself. */ + inst->Data = &p->store[p->nr_insn]; if (inst->Opcode != OPCODE_SWZ) - for (i = 0; i < 3; i++) - args[i] = get_arg(c, inst->SrcReg[i]); + for (i = 0; i < 3; i++) { + struct prog_src_register *src = &inst->SrcReg[i]; + index = src->Index; + file = src->File; + if (file == PROGRAM_OUTPUT&&c->output_regs[index].used_in_src) + args[i] = c->output_regs[index].reg; + else + args[i] = get_arg(c, src); + } /* Get dest regs. Note that it is possible for a reg to be both * dst and arg, given the static allocation of registers. So * care needs to be taken emitting multi-operation instructions. - */ - dst = get_dst(c, inst->DstReg); + */ + index = inst->DstReg.Index; + file = inst->DstReg.File; + if (file == PROGRAM_OUTPUT && c->output_regs[index].used_in_src) + dst = c->output_regs[index].reg; + else + dst = get_dst(c, inst->DstReg); - switch (inst->Opcode) { case OPCODE_ABS: brw_MOV(p, dst, brw_abs(args[0])); @@ -1003,12 +1088,25 @@ void brw_vs_emit( struct brw_vs_compile *c ) case OPCODE_RSQ: emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, args[0], BRW_MATH_PRECISION_FULL); break; + + case OPCODE_SEQ: + emit_seq(p, dst, args[0], args[1]); + break; + case OPCODE_SNE: + emit_sne(p, dst, args[0], args[1]); + break; case OPCODE_SGE: emit_sge(p, dst, args[0], args[1]); break; + case OPCODE_SGT: + emit_sgt(p, dst, args[0], args[1]); + break; case OPCODE_SLT: emit_slt(p, dst, args[0], args[1]); break; + case OPCODE_SLE: + emit_sle(p, dst, args[0], args[1]); + break; case OPCODE_SUB: brw_ADD(p, dst, args[0], negate(args[1])); break; @@ -1021,21 +1119,60 @@ void brw_vs_emit( struct brw_vs_compile *c ) case OPCODE_XPD: emit_xpd(p, dst, args[0], args[1]); break; + case OPCODE_IF: + assert(if_insn < MAX_IFSN); + if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8); + break; + case OPCODE_ELSE: + if_inst[if_insn-1] = brw_ELSE(p, if_inst[if_insn-1]); + break; + case OPCODE_ENDIF: + assert(if_insn > 0); + brw_ENDIF(p, if_inst[--if_insn]); + break; + case OPCODE_BRA: + brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); + brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16)); + brw_set_predicate_control_flag_value(p, 0xff); + break; + case OPCODE_CAL: + brw_set_access_mode(p, BRW_ALIGN_1); + brw_ADD(p, deref_1uw(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16)); + brw_set_access_mode(p, BRW_ALIGN_16); + brw_ADD(p, get_addr_reg(stack_index), + get_addr_reg(stack_index), brw_imm_d(4)); + inst->Data = &p->store[p->nr_insn]; + brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16)); + break; + case OPCODE_RET: + brw_ADD(p, get_addr_reg(stack_index), + get_addr_reg(stack_index), brw_imm_d(-4)); + brw_set_access_mode(p, BRW_ALIGN_1); + brw_MOV(p, brw_ip_reg(), deref_1uw(stack_index, 0)); + brw_set_access_mode(p, BRW_ALIGN_16); case OPCODE_END: + brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16)); + break; case OPCODE_PRINT: + case OPCODE_BGNSUB: + case OPCODE_ENDSUB: break; default: + _mesa_printf("Unsupport opcode %d in vertex shader\n", inst->Opcode); break; } + if (inst->DstReg.File == PROGRAM_OUTPUT + &&inst->DstReg.Index != VERT_RESULT_HPOS + &&c->output_regs[inst->DstReg.Index].used_in_src) + brw_MOV(p, get_dst(c, inst->DstReg), dst); + release_tmps(c); } + end_inst = &p->store[p->nr_insn]; emit_vertex_write(c); - + post_vs_emit(c, end_inst); + for (insn = 0; insn < nr_insns; insn++) + c->vp->program.Base.Instructions[insn].Data = NULL; } - - - - - diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c index 27210d1a374..aecdd4bc31a 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c +++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c @@ -855,7 +855,7 @@ static struct ureg calculate_light_attenuation( struct tnl_program *p, struct ureg slt = get_temp(p); emit_op2(p, OPCODE_DP3, spot, 0, ureg_negate(VPpli), spot_dir_norm); - emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir_norm,W), spot); + emit_op2(p, OPCODE_SLT, slt, 0, spot, swizzle1(spot_dir_norm,W)); emit_op2(p, OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W)); emit_op2(p, OPCODE_MUL, att, 0, slt, spot); diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 904c00bef87..2d6249e3b56 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -66,7 +66,11 @@ GLuint brw_wm_nr_args( GLuint opcode ) case OPCODE_POW: case OPCODE_SUB: case OPCODE_SGE: + case OPCODE_SGT: + case OPCODE_SLE: case OPCODE_SLT: + case OPCODE_SEQ: + case OPCODE_SNE: case OPCODE_ADD: case OPCODE_MAX: case OPCODE_MIN: @@ -150,47 +154,49 @@ static void do_wm_prog( struct brw_context *brw, c->fp = fp; c->env_param = brw->intel.ctx.FragmentProgram.Parameters; - - /* Augment fragment program. Add instructions for pre- and - * post-fragment-program tasks such as interpolation and fogging. - */ - brw_wm_pass_fp(c); - - /* Translate to intermediate representation. Build register usage - * chains. - */ - brw_wm_pass0(c); - - /* Dead code removal. - */ - brw_wm_pass1(c); - - /* Hal optimization - */ - brw_wm_pass_hal (c); - - /* Register allocation. - */ - c->grf_limit = BRW_WM_MAX_GRF/2; - - /* This is where we start emitting gen4 code: - */ - brw_init_compile(&c->func); - - brw_wm_pass2(c); - - c->prog_data.total_grf = c->max_wm_grf; - if (c->last_scratch) { - c->prog_data.total_scratch = - c->last_scratch + 0x40; + if (brw_wm_is_glsl(&c->fp->program)) { + brw_wm_glsl_emit(c); } else { - c->prog_data.total_scratch = 0; + /* Augment fragment program. Add instructions for pre- and + * post-fragment-program tasks such as interpolation and fogging. + */ + brw_wm_pass_fp(c); + + /* Translate to intermediate representation. Build register usage + * chains. + */ + brw_wm_pass0(c); + + /* Dead code removal. + */ + brw_wm_pass1(c); + + /* Hal optimization + */ + brw_wm_pass_hal (c); + + /* Register allocation. + */ + c->grf_limit = BRW_WM_MAX_GRF/2; + + /* This is where we start emitting gen4 code: + */ + brw_init_compile(&c->func); + + brw_wm_pass2(c); + + c->prog_data.total_grf = c->max_wm_grf; + if (c->last_scratch) { + c->prog_data.total_scratch = + c->last_scratch + 0x40; + } else { + c->prog_data.total_scratch = 0; + } + + /* Emit GEN4 code. + */ + brw_wm_emit(c); } - - /* Emit GEN4 code. - */ - brw_wm_emit(c); - /* get the program */ program = brw_get_program(&c->func, &program_size); diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index 6dcf4732a9f..440b5357d5a 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -194,6 +194,7 @@ struct brw_wm_compile { GLuint nr_fp_insns; GLuint fp_temp; GLuint fp_interp_emitted; + GLuint fp_deriv_emitted; struct prog_src_register pixel_xy; struct prog_src_register delta_xy; @@ -231,6 +232,15 @@ struct brw_wm_compile { GLuint grf_limit; GLuint max_wm_grf; GLuint last_scratch; + + struct { + GLboolean inited; + struct brw_reg reg; + } wm_regs[PROGRAM_PAYLOAD+1][256][4]; + struct brw_reg stack; + struct brw_reg emit_mask_reg; + GLuint reg_index; + GLuint tmp_index; }; @@ -259,4 +269,6 @@ void brw_wm_lookup_iz( GLuint line_aa, GLuint lookup, struct brw_wm_prog_key *key ); +GLboolean brw_wm_is_glsl(struct gl_fragment_program *fp); +void brw_wm_glsl_emit(struct brw_wm_compile *c); #endif diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c index fd605159727..1f7158f7a78 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_emit.c +++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c @@ -229,20 +229,20 @@ static void emit_cinterp( struct brw_compile *p, GLuint mask, const struct brw_reg *arg0 ) { - struct brw_reg interp[4]; - GLuint nr = arg0[0].nr; - GLuint i; - - interp[0] = brw_vec1_grf(nr, 0); - interp[1] = brw_vec1_grf(nr, 4); - interp[2] = brw_vec1_grf(nr+1, 0); - interp[3] = brw_vec1_grf(nr+1, 4); - - for(i = 0; i < 4; i++ ) { - if (mask & (1<<i)) { - brw_MOV(p, dst[i], suboffset(interp[i],3)); /* TODO: optimize away like other moves */ - } - } + struct brw_reg interp[4]; + GLuint nr = arg0[0].nr; + GLuint i; + + interp[0] = brw_vec1_grf(nr, 0); + interp[1] = brw_vec1_grf(nr, 4); + interp[2] = brw_vec1_grf(nr+1, 0); + interp[3] = brw_vec1_grf(nr+1, 4); + + for(i = 0; i < 4; i++ ) { + if (mask & (1<<i)) { + brw_MOV(p, dst[i], suboffset(interp[i],3)); /* TODO: optimize away like other moves */ + } + } } @@ -343,11 +343,10 @@ static void emit_lrp( struct brw_compile *p, } } } - - -static void emit_slt( struct brw_compile *p, +static void emit_sop( struct brw_compile *p, const struct brw_reg *dst, GLuint mask, + GLuint cond, const struct brw_reg *arg0, const struct brw_reg *arg1 ) { @@ -356,34 +355,66 @@ static void emit_slt( struct brw_compile *p, for (i = 0; i < 4; i++) { if (mask & (1<<i)) { brw_MOV(p, dst[i], brw_imm_f(0)); - brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0[i], arg1[i]); + brw_CMP(p, brw_null_reg(), cond, arg0[i], arg1[i]); brw_MOV(p, dst[i], brw_imm_f(1.0)); brw_set_predicate_control_flag_value(p, 0xff); } } } -/* Isn't this just the same as the above with the args swapped? - */ -static void emit_sge( struct brw_compile *p, +static void emit_slt( struct brw_compile *p, const struct brw_reg *dst, GLuint mask, const struct brw_reg *arg0, const struct brw_reg *arg1 ) { - GLuint i; + emit_sop(p, dst, mask, BRW_CONDITIONAL_L, arg0, arg1); +} - for (i = 0; i < 4; i++) { - if (mask & (1<<i)) { - brw_MOV(p, dst[i], brw_imm_f(0)); - brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0[i], arg1[i]); - brw_MOV(p, dst[i], brw_imm_f(1.0)); - brw_set_predicate_control_flag_value(p, 0xff); - } - } +static void emit_sle( struct brw_compile *p, + const struct brw_reg *dst, + GLuint mask, + const struct brw_reg *arg0, + const struct brw_reg *arg1 ) +{ + emit_sop(p, dst, mask, BRW_CONDITIONAL_LE, arg0, arg1); +} + +static void emit_sgt( struct brw_compile *p, + const struct brw_reg *dst, + GLuint mask, + const struct brw_reg *arg0, + const struct brw_reg *arg1 ) +{ + emit_sop(p, dst, mask, BRW_CONDITIONAL_G, arg0, arg1); +} + +static void emit_sge( struct brw_compile *p, + const struct brw_reg *dst, + GLuint mask, + const struct brw_reg *arg0, + const struct brw_reg *arg1 ) +{ + emit_sop(p, dst, mask, BRW_CONDITIONAL_GE, arg0, arg1); } +static void emit_seq( struct brw_compile *p, + const struct brw_reg *dst, + GLuint mask, + const struct brw_reg *arg0, + const struct brw_reg *arg1 ) +{ + emit_sop(p, dst, mask, BRW_CONDITIONAL_EQ, arg0, arg1); +} +static void emit_sne( struct brw_compile *p, + const struct brw_reg *dst, + GLuint mask, + const struct brw_reg *arg0, + const struct brw_reg *arg1 ) +{ + emit_sop(p, dst, mask, BRW_CONDITIONAL_NEQ, arg0, arg1); +} static void emit_cmp( struct brw_compile *p, const struct brw_reg *dst, @@ -543,8 +574,8 @@ static void emit_math1( struct brw_compile *p, GLuint mask, const struct brw_reg *arg0 ) { - assert((mask & WRITEMASK_XYZW) == WRITEMASK_X || - function == BRW_MATH_FUNCTION_SINCOS); + //assert((mask & WRITEMASK_XYZW) == WRITEMASK_X || + // function == BRW_MATH_FUNCTION_SINCOS); brw_MOV(p, brw_message_reg(2), arg0[0]); @@ -671,6 +702,8 @@ static void emit_tex( struct brw_wm_compile *c, msgLength, 0); + if (shadow) + brw_MOV(p, dst[3], brw_imm_f(1.0)); } @@ -1208,9 +1241,21 @@ void brw_wm_emit( struct brw_wm_compile *c ) emit_slt(p, dst, dst_flags, args[0], args[1]); break; + case OPCODE_SLE: + emit_sle(p, dst, dst_flags, args[0], args[1]); + break; + case OPCODE_SGT: + emit_sgt(p, dst, dst_flags, args[0], args[1]); + break; case OPCODE_SGE: emit_sge(p, dst, dst_flags, args[0], args[1]); break; + case OPCODE_SEQ: + emit_seq(p, dst, dst_flags, args[0], args[1]); + break; + case OPCODE_SNE: + emit_sne(p, dst, dst_flags, args[0], args[1]); + break; case OPCODE_LIT: emit_lit(p, dst, dst_flags, args[0]); @@ -1231,7 +1276,8 @@ void brw_wm_emit( struct brw_wm_compile *c ) break; default: - assert(0); + _mesa_printf("unsupport opcode %d in fragment program\n", + inst->opcode); } for (i = 0; i < 4; i++) diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c index 67154c1b13a..1b26005169a 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_fp.c +++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c @@ -176,6 +176,7 @@ static struct prog_instruction *emit_insn(struct brw_wm_compile *c, { struct prog_instruction *inst = get_fp_inst(c); *inst = *inst0; + inst->Data = (void *)inst0; return inst; } @@ -201,7 +202,6 @@ static struct prog_instruction * emit_op(struct brw_wm_compile *c, inst->SrcReg[0] = src0; inst->SrcReg[1] = src1; inst->SrcReg[2] = src2; - return inst; } @@ -361,6 +361,37 @@ static void emit_interp( struct brw_wm_compile *c, c->fp_interp_emitted |= 1<<idx; } +static void emit_ddx( struct brw_wm_compile *c, + const struct prog_instruction *inst ) +{ + GLuint idx = inst->SrcReg[0].Index; + struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx); + + c->fp_deriv_emitted |= 1<<idx; + emit_op(c, + OPCODE_DDX, + inst->DstReg, + 0, 0, 0, + interp, + get_pixel_w(c), + src_undef()); +} + +static void emit_ddy( struct brw_wm_compile *c, + const struct prog_instruction *inst ) +{ + GLuint idx = inst->SrcReg[0].Index; + struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx); + + c->fp_deriv_emitted |= 1<<idx; + emit_op(c, + OPCODE_DDY, + inst->DstReg, + 0, 0, 0, + interp, + get_pixel_w(c), + src_undef()); +} /*********************************************************************** * Hacks to extend the program parameter and constant lists. @@ -957,8 +988,16 @@ void brw_wm_pass_fp( struct brw_wm_compile *c ) */ out->DstReg.WriteMask = 0; break; - + case OPCODE_DDX: + emit_ddx(c, inst); + break; + case OPCODE_DDY: + emit_ddy(c, inst); + break; case OPCODE_END: + emit_fog(c); + emit_fb_write(c); + break; case OPCODE_PRINT: break; @@ -967,15 +1006,11 @@ void brw_wm_pass_fp( struct brw_wm_compile *c ) break; } } - - emit_fog(c); - emit_fb_write(c); - if (INTEL_DEBUG & DEBUG_WM) { - _mesa_printf("\n\n\npass_fp:\n"); - print_insns( c->prog_instructions, c->nr_fp_insns ); - _mesa_printf("\n"); + _mesa_printf("\n\n\npass_fp:\n"); + print_insns( c->prog_instructions, c->nr_fp_insns ); + _mesa_printf("\n"); } } diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c new file mode 100644 index 00000000000..4b273fefe92 --- /dev/null +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -0,0 +1,1354 @@ +#include "macros.h" +#include "shader/prog_parameter.h" +#include "brw_context.h" +#include "brw_eu.h" +#include "brw_wm.h" + +/* Only guess, need a flag in gl_fragment_program later */ +GLboolean brw_wm_is_glsl(struct gl_fragment_program *fp) +{ + int i; + for (i = 0; i < fp->Base.NumInstructions; i++) { + struct prog_instruction *inst = &fp->Base.Instructions[i]; + switch (inst->Opcode) { + case OPCODE_IF: + case OPCODE_INT: + case OPCODE_ENDIF: + case OPCODE_CAL: + case OPCODE_BRK: + case OPCODE_RET: + case OPCODE_DDX: + case OPCODE_DDY: + case OPCODE_BGNLOOP: + return GL_TRUE; + default: + break; + } + } + return GL_FALSE; +} + +static void set_reg(struct brw_wm_compile *c, int file, int index, + int component, struct brw_reg reg) +{ + c->wm_regs[file][index][component].reg = reg; + c->wm_regs[file][index][component].inited = GL_TRUE; +} + +static int get_scalar_dst_index(struct prog_instruction *inst) +{ + int i; + for (i = 0; i < 4; i++) + if (inst->DstReg.WriteMask & (1<<i)) + break; + return i; +} + +static struct brw_reg alloc_tmp(struct brw_wm_compile *c) +{ + struct brw_reg reg; + reg = brw_vec8_grf(c->tmp_index--, 0); + return reg; +} + +static void release_tmps(struct brw_wm_compile *c) +{ + c->tmp_index = 127; +} + +static struct brw_reg +get_reg(struct brw_wm_compile *c, int file, int index, int component, int nr, GLuint neg, GLuint abs) +{ + struct brw_reg reg; + switch (file) { + case PROGRAM_STATE_VAR: + case PROGRAM_CONSTANT: + case PROGRAM_UNIFORM: + file = PROGRAM_STATE_VAR; + break; + case PROGRAM_UNDEFINED: + return brw_null_reg(); + default: + break; + } + + if(c->wm_regs[file][index][component].inited) + reg = c->wm_regs[file][index][component].reg; + else + reg = brw_vec8_grf(c->reg_index, 0); + + if(!c->wm_regs[file][index][component].inited) { + set_reg(c, file, index, component, reg); + c->reg_index++; + } + + if (neg & (1<< component)) { + reg = negate(reg); + } + if (abs) + reg = brw_abs(reg); + return reg; +} + +static void prealloc_reg(struct brw_wm_compile *c) +{ + int i, j; + struct brw_reg reg; + int nr_interp_regs = 0; + GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted | c->fp_deriv_emitted; + + for (i = 0; i < 4; i++) { + reg = (i < c->key.nr_depth_regs) + ? brw_vec8_grf(i*2, 0) : brw_vec8_grf(0, 0); + set_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, i, reg); + } + c->reg_index += 2*c->key.nr_depth_regs; + { + int nr_params = c->fp->program.Base.Parameters->NumParameters; + struct gl_program_parameter_list *plist = + c->fp->program.Base.Parameters; + int index = 0; + c->prog_data.nr_params = 4*nr_params; + for (i = 0; i < nr_params; i++) { + for (j = 0; j < 4; j++, index++) { + reg = brw_vec1_grf(c->reg_index + index/8, + index%8); + c->prog_data.param[index] = + &plist->ParameterValues[i][j]; + set_reg(c, PROGRAM_STATE_VAR, i, j, reg); + } + } + c->nr_creg = 2*((4*nr_params+15)/16); + c->reg_index += c->nr_creg; + } + for (i = 0; i < FRAG_ATTRIB_MAX; i++) { + if (inputs & (1<<i)) { + nr_interp_regs++; + reg = brw_vec8_grf(c->reg_index, 0); + for (j = 0; j < 4; j++) + set_reg(c, PROGRAM_PAYLOAD, i, j, reg); + c->reg_index += 2; + + } + } + c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2; + c->prog_data.urb_read_length = nr_interp_regs * 2; + c->prog_data.curb_read_length = c->nr_creg; + c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0); + c->reg_index++; + c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0); + c->reg_index += 2; +} + +static struct brw_reg get_dst_reg(struct brw_wm_compile *c, + struct prog_instruction *inst, int component, int nr) +{ + return get_reg(c, inst->DstReg.File, inst->DstReg.Index, component, nr, + 0, 0); +} + +static struct brw_reg get_src_reg(struct brw_wm_compile *c, + struct prog_src_register *src, int index, int nr) +{ + int component = GET_SWZ(src->Swizzle, index); + return get_reg(c, src->File, src->Index, component, nr, + src->NegateBase, src->Abs); +} + +static void emit_abs( struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + int i; + struct brw_compile *p = &c->func; + brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF); + for (i = 0; i < 4; i++) { + if (inst->DstReg.WriteMask & (1<<i)) { + struct brw_reg src, dst; + dst = get_dst_reg(c, inst, i, 1); + src = get_src_reg(c, &inst->SrcReg[0], i, 1); + brw_MOV(p, dst, brw_abs(src)); + } + } + brw_set_saturate(p, 0); +} + +static void emit_int( struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + int i; + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF); + for (i = 0; i < 4; i++) { + if (mask & (1<<i)) { + struct brw_reg src, dst; + dst = get_dst_reg(c, inst, i, 1) ; + src = get_src_reg(c, &inst->SrcReg[0], i, 1); + brw_RNDD(p, dst, src); + } + } + brw_set_saturate(p, 0); +} + +static void emit_mov( struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + int i; + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF); + for (i = 0; i < 4; i++) { + if (mask & (1<<i)) { + struct brw_reg src, dst; + dst = get_dst_reg(c, inst, i, 1); + src = get_src_reg(c, &inst->SrcReg[0], i, 1); + brw_MOV(p, dst, src); + } + } + brw_set_saturate(p, 0); +} + +static void emit_pixel_xy(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_reg r1 = brw_vec1_grf(1, 0); + struct brw_reg r1_uw = retype(r1, BRW_REGISTER_TYPE_UW); + + struct brw_reg dst0, dst1; + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + + dst0 = get_dst_reg(c, inst, 0, 1); + dst1 = get_dst_reg(c, inst, 1, 1); + /* Calculate pixel centers by adding 1 or 0 to each of the + * micro-tile coordinates passed in r1. + */ + if (mask & WRITEMASK_X) { + brw_ADD(p, + vec8(retype(dst0, BRW_REGISTER_TYPE_UW)), + stride(suboffset(r1_uw, 4), 2, 4, 0), + brw_imm_v(0x10101010)); + } + + if (mask & WRITEMASK_Y) { + brw_ADD(p, + vec8(retype(dst1, BRW_REGISTER_TYPE_UW)), + stride(suboffset(r1_uw, 5), 2, 4, 0), + brw_imm_v(0x11001100)); + } + +} + +static void emit_delta_xy(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_reg r1 = brw_vec1_grf(1, 0); + struct brw_reg dst0, dst1, src0, src1; + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + + dst0 = get_dst_reg(c, inst, 0, 1); + dst1 = get_dst_reg(c, inst, 1, 1); + src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); + src1 = get_src_reg(c, &inst->SrcReg[0], 1, 1); + /* Calc delta X,Y by subtracting origin in r1 from the pixel + * centers. + */ + if (mask & WRITEMASK_X) { + brw_ADD(p, + dst0, + retype(src0, BRW_REGISTER_TYPE_UW), + negate(r1)); + } + + if (mask & WRITEMASK_Y) { + brw_ADD(p, + dst1, + retype(src1, BRW_REGISTER_TYPE_UW), + negate(suboffset(r1,1))); + + } + +} + + +static void fire_fb_write( struct brw_wm_compile *c, + GLuint base_reg, + GLuint nr ) +{ + struct brw_compile *p = &c->func; + + /* Pass through control information: + */ + /* mov (8) m1.0<1>:ud r1.0<8;8,1>:ud { Align1 NoMask } */ + { + brw_push_insn_state(p); + brw_set_mask_control(p, BRW_MASK_DISABLE); /* ? */ + brw_MOV(p, + brw_message_reg(base_reg + 1), + brw_vec8_grf(1, 0)); + brw_pop_insn_state(p); + } + /* Send framebuffer write message: */ + brw_fb_WRITE(p, + retype(vec8(brw_null_reg()), BRW_REGISTER_TYPE_UW), + base_reg, + retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW), + 0, /* render surface always 0 */ + nr, + 0, + 1); +} + +static void emit_fb_write(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + int nr = 2; + int channel; + struct brw_reg src0;//, src1, src2, dst; + + /* Reserve a space for AA - may not be needed: + */ + if (c->key.aa_dest_stencil_reg) + nr += 1; + { + brw_push_insn_state(p); + for (channel = 0; channel < 4; channel++) { + src0 = get_src_reg(c, &inst->SrcReg[0], channel, 1); + /* mov (8) m2.0<1>:ud r28.0<8;8,1>:ud { Align1 } */ + /* mov (8) m6.0<1>:ud r29.0<8;8,1>:ud { Align1 SecHalf } */ + brw_MOV(p, brw_message_reg(nr + channel), src0); + } + /* skip over the regs populated above: */ + nr += 8; + brw_pop_insn_state(p); + } + fire_fb_write(c, 0, nr); +} + +static void emit_pixel_w( struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + if (mask & WRITEMASK_W) { + struct brw_reg dst, src0, delta0, delta1; + struct brw_reg interp3; + + dst = get_dst_reg(c, inst, 3, 1); + src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); + delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1); + delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1); + + interp3 = brw_vec1_grf(src0.nr+1, 4); + /* Calc 1/w - just linterp wpos[3] optimized by putting the + * result straight into a message reg. + */ + brw_LINE(p, brw_null_reg(), interp3, delta0); + brw_MAC(p, brw_message_reg(2), suboffset(interp3, 1), delta1); + + /* Calc w */ + brw_math_16( p, dst, + BRW_MATH_FUNCTION_INV, + BRW_MATH_SATURATE_NONE, + 2, brw_null_reg(), + BRW_MATH_PRECISION_FULL); + } +} + +static void emit_linterp(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + struct brw_reg interp[4]; + struct brw_reg dst, delta0, delta1; + struct brw_reg src0; + + src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); + delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1); + delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1); + GLuint nr = src0.nr; + int i; + + interp[0] = brw_vec1_grf(nr, 0); + interp[1] = brw_vec1_grf(nr, 4); + interp[2] = brw_vec1_grf(nr+1, 0); + interp[3] = brw_vec1_grf(nr+1, 4); + + for(i = 0; i < 4; i++ ) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + brw_LINE(p, brw_null_reg(), interp[i], delta0); + brw_MAC(p, dst, suboffset(interp[i],1), delta1); + } + } +} + +static void emit_cinterp(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + + struct brw_reg interp[4]; + struct brw_reg dst, src0; + + src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); + GLuint nr = src0.nr; + int i; + + interp[0] = brw_vec1_grf(nr, 0); + interp[1] = brw_vec1_grf(nr, 4); + interp[2] = brw_vec1_grf(nr+1, 0); + interp[3] = brw_vec1_grf(nr+1, 4); + + for(i = 0; i < 4; i++ ) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + brw_MOV(p, dst, suboffset(interp[i],3)); + } + } +} + +static void emit_pinterp(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + + struct brw_reg interp[4]; + struct brw_reg dst, delta0, delta1; + struct brw_reg src0, w; + + src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); + delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1); + delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1); + w = get_src_reg(c, &inst->SrcReg[2], 3, 1); + GLuint nr = src0.nr; + int i; + + interp[0] = brw_vec1_grf(nr, 0); + interp[1] = brw_vec1_grf(nr, 4); + interp[2] = brw_vec1_grf(nr+1, 0); + interp[3] = brw_vec1_grf(nr+1, 4); + + for(i = 0; i < 4; i++ ) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + brw_LINE(p, brw_null_reg(), interp[i], delta0); + brw_MAC(p, dst, suboffset(interp[i],1), + delta1); + brw_MUL(p, dst, dst, w); + } + } +} + +static void emit_xpd(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + int i; + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + for (i = 0; i < 4; i++) { + GLuint i2 = (i+2)%3; + GLuint i1 = (i+1)%3; + if (mask & (1<<i)) { + struct brw_reg src0, src1, dst; + dst = get_dst_reg(c, inst, i, 1); + src0 = negate(get_src_reg(c, &inst->SrcReg[0], i2, 1)); + src1 = get_src_reg(c, &inst->SrcReg[1], i1, 1); + brw_MUL(p, brw_null_reg(), src0, src1); + src0 = get_src_reg(c, &inst->SrcReg[0], i1, 1); + src1 = get_src_reg(c, &inst->SrcReg[1], i2, 1); + brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF); + brw_MAC(p, dst, src0, src1); + brw_set_saturate(p, 0); + } + } + brw_set_saturate(p, 0); +} + +static void emit_dp3(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_reg src0[3], src1[3], dst; + int i; + struct brw_compile *p = &c->func; + for (i = 0; i < 3; i++) { + src0[i] = get_src_reg(c, &inst->SrcReg[0], i, 1); + src1[i] = get_src_reg(c, &inst->SrcReg[1], i, 1); + } + + dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1); + brw_MUL(p, brw_null_reg(), src0[0], src1[0]); + brw_MAC(p, brw_null_reg(), src0[1], src1[1]); + brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); + brw_MAC(p, dst, src0[2], src1[2]); + brw_set_saturate(p, 0); +} + +static void emit_dp4(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_reg src0[4], src1[4], dst; + int i; + struct brw_compile *p = &c->func; + for (i = 0; i < 4; i++) { + src0[i] = get_src_reg(c, &inst->SrcReg[0], i, 1); + src1[i] = get_src_reg(c, &inst->SrcReg[1], i, 1); + } + dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1); + brw_MUL(p, brw_null_reg(), src0[0], src1[0]); + brw_MAC(p, brw_null_reg(), src0[1], src1[1]); + brw_MAC(p, brw_null_reg(), src0[2], src1[2]); + brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); + brw_MAC(p, dst, src0[3], src1[3]); + brw_set_saturate(p, 0); +} + +static void emit_dph(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_reg src0[4], src1[4], dst; + int i; + struct brw_compile *p = &c->func; + for (i = 0; i < 4; i++) { + src0[i] = get_src_reg(c, &inst->SrcReg[0], i, 1); + src1[i] = get_src_reg(c, &inst->SrcReg[1], i, 1); + } + dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1); + brw_MUL(p, brw_null_reg(), src0[0], src1[0]); + brw_MAC(p, brw_null_reg(), src0[1], src1[1]); + brw_MAC(p, dst, src0[2], src1[2]); + brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); + brw_ADD(p, dst, src0[3], src1[3]); + brw_set_saturate(p, 0); +} + +static void emit_math1(struct brw_wm_compile *c, + struct prog_instruction *inst, GLuint func) +{ + struct brw_compile *p = &c->func; + struct brw_reg src0, dst; + + src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); + dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1); + brw_MOV(p, brw_message_reg(2), src0); + brw_math(p, + dst, + func, + (inst->SaturateMode != SATURATE_OFF) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE, + 2, + brw_null_reg(), + BRW_MATH_DATA_VECTOR, + BRW_MATH_PRECISION_FULL); +} + +static void emit_rcp(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + emit_math1(c, inst, BRW_MATH_FUNCTION_INV); +} + +static void emit_rsq(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + emit_math1(c, inst, BRW_MATH_FUNCTION_RSQ); +} + +static void emit_sin(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + emit_math1(c, inst, BRW_MATH_FUNCTION_SIN); +} + +static void emit_cos(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + emit_math1(c, inst, BRW_MATH_FUNCTION_COS); +} + +static void emit_ex2(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + emit_math1(c, inst, BRW_MATH_FUNCTION_EXP); +} + +static void emit_lg2(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + emit_math1(c, inst, BRW_MATH_FUNCTION_LOG); +} + +static void emit_add(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + struct brw_reg src0, src1, dst; + GLuint mask = inst->DstReg.WriteMask; + int i; + brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); + for (i = 0 ; i < 4; i++) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + src0 = get_src_reg(c, &inst->SrcReg[0], i, 1); + src1 = get_src_reg(c, &inst->SrcReg[1], i, 1); + brw_ADD(p, dst, src0, src1); + } + } + brw_set_saturate(p, 0); +} + +static void emit_sub(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + struct brw_reg src0, src1, dst; + GLuint mask = inst->DstReg.WriteMask; + int i; + brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); + for (i = 0 ; i < 4; i++) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + src0 = get_src_reg(c, &inst->SrcReg[0], i, 1); + src1 = get_src_reg(c, &inst->SrcReg[1], i, 1); + brw_ADD(p, dst, src0, negate(src1)); + } + } + brw_set_saturate(p, 0); +} + +static void emit_mul(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + struct brw_reg src0, src1, dst; + GLuint mask = inst->DstReg.WriteMask; + int i; + brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); + for (i = 0 ; i < 4; i++) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + src0 = get_src_reg(c, &inst->SrcReg[0], i, 1); + src1 = get_src_reg(c, &inst->SrcReg[1], i, 1); + brw_MUL(p, dst, src0, src1); + } + } + brw_set_saturate(p, 0); +} + +static void emit_frc(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + struct brw_reg src0, dst; + GLuint mask = inst->DstReg.WriteMask; + int i; + brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); + for (i = 0 ; i < 4; i++) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + src0 = get_src_reg(c, &inst->SrcReg[0], i, 1); + brw_FRC(p, dst, src0); + } + } + if (inst->SaturateMode != SATURATE_OFF) + brw_set_saturate(p, 0); +} + +static void emit_flr(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + struct brw_reg src0, dst; + GLuint mask = inst->DstReg.WriteMask; + int i; + brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); + for (i = 0 ; i < 4; i++) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + src0 = get_src_reg(c, &inst->SrcReg[0], i, 1); + brw_RNDD(p, dst, src0); + } + } + brw_set_saturate(p, 0); +} + +static void emit_max(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + struct brw_reg src0, src1, dst; + int i; + brw_push_insn_state(p); + for (i = 0; i < 4; i++) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + src0 = get_src_reg(c, &inst->SrcReg[0], i, 1); + src1 = get_src_reg(c, &inst->SrcReg[1], i, 1); + brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); + brw_MOV(p, dst, src0); + brw_set_saturate(p, 0); + + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src0, src1); + brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); + brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); + brw_MOV(p, dst, src1); + brw_set_saturate(p, 0); + brw_set_predicate_control_flag_value(p, 0xff); + } + } + brw_pop_insn_state(p); +} + +static void emit_min(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + struct brw_reg src0, src1, dst; + int i; + brw_push_insn_state(p); + for (i = 0; i < 4; i++) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + src0 = get_src_reg(c, &inst->SrcReg[0], i, 1); + src1 = get_src_reg(c, &inst->SrcReg[1], i, 1); + brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); + brw_MOV(p, dst, src0); + brw_set_saturate(p, 0); + + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src1, src0); + brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); + brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); + brw_MOV(p, dst, src1); + brw_set_saturate(p, 0); + brw_set_predicate_control_flag_value(p, 0xff); + } + } + brw_pop_insn_state(p); +} + +static void emit_pow(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + struct brw_reg dst, src0, src1; + dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1); + src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); + src1 = get_src_reg(c, &inst->SrcReg[1], 0, 1); + + brw_MOV(p, brw_message_reg(2), src0); + brw_MOV(p, brw_message_reg(3), src1); + + brw_math(p, + dst, + BRW_MATH_FUNCTION_POW, + (inst->SaturateMode != SATURATE_OFF) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE, + 2, + brw_null_reg(), + BRW_MATH_DATA_VECTOR, + BRW_MATH_PRECISION_FULL); +} + +static void emit_lrp(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + struct brw_reg dst, tmp1, tmp2, src0, src1, src2; + int i; + for (i = 0; i < 4; i++) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + src0 = get_src_reg(c, &inst->SrcReg[0], i, 1); + + src1 = get_src_reg(c, &inst->SrcReg[1], i, 1); + + if (src1.nr == dst.nr) { + tmp1 = alloc_tmp(c); + brw_MOV(p, tmp1, src1); + } else + tmp1 = src1; + + src2 = get_src_reg(c, &inst->SrcReg[2], i, 1); + if (src2.nr == dst.nr) { + tmp2 = alloc_tmp(c); + brw_MOV(p, tmp2, src2); + } else + tmp2 = src2; + + brw_ADD(p, dst, negate(src0), brw_imm_f(1.0)); + brw_MUL(p, brw_null_reg(), dst, tmp2); + brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); + brw_MAC(p, dst, src0, tmp1); + brw_set_saturate(p, 0); + } + release_tmps(c); + } +} + +static void emit_kil(struct brw_wm_compile *c) +{ + struct brw_compile *p = &c->func; + struct brw_reg depth = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW); + brw_push_insn_state(p); + brw_set_mask_control(p, BRW_MASK_DISABLE); + brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); //IMASK + brw_AND(p, depth, c->emit_mask_reg, depth); + brw_pop_insn_state(p); +} + +static void emit_mad(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + struct brw_reg dst, src0, src1, src2; + int i; + + for (i = 0; i < 4; i++) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + src0 = get_src_reg(c, &inst->SrcReg[0], i, 1); + src1 = get_src_reg(c, &inst->SrcReg[1], i, 1); + src2 = get_src_reg(c, &inst->SrcReg[2], i, 1); + brw_MUL(p, dst, src0, src1); + + brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); + brw_ADD(p, dst, dst, src2); + brw_set_saturate(p, 0); + } + } +} + +static void emit_sop(struct brw_wm_compile *c, + struct prog_instruction *inst, GLuint cond) +{ + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + struct brw_reg dst, src0, src1; + int i; + + brw_push_insn_state(p); + for (i = 0; i < 4; i++) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + src0 = get_src_reg(c, &inst->SrcReg[0], i, 1); + src1 = get_src_reg(c, &inst->SrcReg[1], i, 1); + brw_CMP(p, brw_null_reg(), cond, src0, src1); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_MOV(p, dst, brw_imm_f(0.0)); + brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); + brw_MOV(p, dst, brw_imm_f(1.0)); + } + } + brw_pop_insn_state(p); +} + +static void emit_slt(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + emit_sop(c, inst, BRW_CONDITIONAL_L); +} + +static void emit_sle(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + emit_sop(c, inst, BRW_CONDITIONAL_LE); +} + +static void emit_sgt(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + emit_sop(c, inst, BRW_CONDITIONAL_G); +} + +static void emit_sge(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + emit_sop(c, inst, BRW_CONDITIONAL_GE); +} + +static void emit_seq(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + emit_sop(c, inst, BRW_CONDITIONAL_EQ); +} + +static void emit_sne(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + emit_sop(c, inst, BRW_CONDITIONAL_NEQ); +} + +static void emit_ddx(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + struct brw_reg interp[4]; + struct brw_reg dst; + struct brw_reg src0, w; + GLuint nr, i; + src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); + w = get_src_reg(c, &inst->SrcReg[1], 3, 1); + nr = src0.nr; + interp[0] = brw_vec1_grf(nr, 0); + interp[1] = brw_vec1_grf(nr, 4); + interp[2] = brw_vec1_grf(nr+1, 0); + interp[3] = brw_vec1_grf(nr+1, 4); + brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF); + for(i = 0; i < 4; i++ ) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + brw_MOV(p, dst, interp[i]); + brw_MUL(p, dst, dst, w); + } + } + brw_set_saturate(p, 0); +} + +static void emit_ddy(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + struct brw_reg interp[4]; + struct brw_reg dst; + struct brw_reg src0, w; + GLuint nr, i; + + src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); + nr = src0.nr; + w = get_src_reg(c, &inst->SrcReg[1], 3, 1); + interp[0] = brw_vec1_grf(nr, 0); + interp[1] = brw_vec1_grf(nr, 4); + interp[2] = brw_vec1_grf(nr+1, 0); + interp[3] = brw_vec1_grf(nr+1, 4); + brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF); + for(i = 0; i < 4; i++ ) { + if (mask & (1<<i)) { + dst = get_dst_reg(c, inst, i, 1); + brw_MOV(p, dst, suboffset(interp[i], 1)); + brw_MUL(p, dst, dst, w); + } + } + brw_set_saturate(p, 0); +} + +static void emit_wpos_xy(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + GLuint mask = inst->DstReg.WriteMask; + struct brw_reg src0[2], dst[2]; + + dst[0] = get_dst_reg(c, inst, 0, 1); + dst[1] = get_dst_reg(c, inst, 1, 1); + + src0[0] = get_src_reg(c, &inst->SrcReg[0], 0, 1); + src0[1] = get_src_reg(c, &inst->SrcReg[0], 1, 1); + + /* Calc delta X,Y by subtracting origin in r1 from the pixel + * centers. + */ + if (mask & WRITEMASK_X) { + brw_MOV(p, + dst[0], + retype(src0[0], BRW_REGISTER_TYPE_UW)); + } + + if (mask & WRITEMASK_Y) { + /* TODO -- window_height - Y */ + brw_MOV(p, + dst[1], + retype(src0[1], BRW_REGISTER_TYPE_UW)); + + } +} + +/* TODO + BIAS on SIMD8 not workind yet... + */ +static void emit_txb(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + struct brw_reg dst[4], src[4], payload_reg; + GLuint i; + payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0); + for (i = 0; i < 4; i++) + dst[i] = get_dst_reg(c, inst, i, 1); + for (i = 0; i < 4; i++) + src[i] = get_src_reg(c, &inst->SrcReg[0], i, 1); + + switch (inst->TexSrcTarget) { + case TEXTURE_1D_INDEX: + brw_MOV(p, brw_message_reg(2), src[0]); + brw_MOV(p, brw_message_reg(3), brw_imm_f(0)); + brw_MOV(p, brw_message_reg(4), brw_imm_f(0)); + break; + case TEXTURE_2D_INDEX: + case TEXTURE_RECT_INDEX: + brw_MOV(p, brw_message_reg(2), src[0]); + brw_MOV(p, brw_message_reg(3), src[1]); + brw_MOV(p, brw_message_reg(4), brw_imm_f(0)); + break; + default: + brw_MOV(p, brw_message_reg(2), src[0]); + brw_MOV(p, brw_message_reg(3), src[1]); + brw_MOV(p, brw_message_reg(4), src[2]); + break; + } + brw_MOV(p, brw_message_reg(5), src[3]); + brw_MOV(p, brw_message_reg(6), brw_imm_f(0)); + brw_SAMPLE(p, + retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW), + 1, + retype(payload_reg, BRW_REGISTER_TYPE_UW), + inst->TexSrcUnit + 1, /* surface */ + inst->TexSrcUnit, /* sampler */ + inst->DstReg.WriteMask, + BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS, + 4, + 4, + 0); +} + +static void emit_tex(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + struct brw_reg dst[4], src[4], payload_reg; + GLuint msg_len; + GLuint i, nr; + GLuint emit; + GLboolean shadow = (c->key.shadowtex_mask & (1<<inst->TexSrcUnit)) ? 1 : 0; + + payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0); + + for (i = 0; i < 4; i++) + dst[i] = get_dst_reg(c, inst, i, 1); + for (i = 0; i < 4; i++) + src[i] = get_src_reg(c, &inst->SrcReg[0], i, 1); + + + switch (inst->TexSrcTarget) { + case TEXTURE_1D_INDEX: + emit = WRITEMASK_X; + nr = 1; + break; + case TEXTURE_2D_INDEX: + case TEXTURE_RECT_INDEX: + emit = WRITEMASK_XY; + nr = 2; + break; + default: + emit = WRITEMASK_XYZ; + nr = 3; + break; + } + msg_len = 1; + + for (i = 0; i < nr; i++) { + static const GLuint swz[4] = {0,1,2,2}; + if (emit & (1<<i)) + brw_MOV(p, brw_message_reg(msg_len+1), src[swz[i]]); + else + brw_MOV(p, brw_message_reg(msg_len+1), brw_imm_f(0)); + msg_len += 1; + } + + if (shadow) { + brw_MOV(p, brw_message_reg(5), brw_imm_f(0)); + brw_MOV(p, brw_message_reg(6), src[2]); + } + + brw_SAMPLE(p, + retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW), + 1, + retype(payload_reg, BRW_REGISTER_TYPE_UW), + inst->TexSrcUnit + 1, /* surface */ + inst->TexSrcUnit, /* sampler */ + inst->DstReg.WriteMask, + BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE, + 4, + shadow ? 6 : 4, + 0); + + if (shadow) + brw_MOV(p, dst[3], brw_imm_f(1.0)); +} + +static void post_wm_emit( struct brw_wm_compile *c ) +{ + GLuint nr_insns = c->fp->program.Base.NumInstructions; + GLuint insn, target_insn; + struct prog_instruction *inst1, *inst2; + struct brw_instruction *brw_inst1, *brw_inst2; + int offset; + for (insn = 0; insn < nr_insns; insn++) { + inst1 = &c->fp->program.Base.Instructions[insn]; + brw_inst1 = inst1->Data; + switch (inst1->Opcode) { + case OPCODE_CAL: + target_insn = inst1->BranchTarget; + inst2 = &c->fp->program.Base.Instructions[target_insn]; + brw_inst2 = inst2->Data; + offset = brw_inst2 - brw_inst1; + brw_set_src1(brw_inst1, brw_imm_d(offset*16)); + break; + default: + break; + } + } +} + +static void brw_wm_emit_glsl(struct brw_wm_compile *c) + +{ +#define MAX_IFSN 32 +#define MAX_LOOP_DEPTH 32 + struct brw_instruction *if_inst[MAX_IFSN], *loop_inst[MAX_LOOP_DEPTH]; + struct brw_instruction *inst0, *inst1; + int i, if_insn = 0, loop_insn = 0; + struct brw_compile *p = &c->func; + struct brw_indirect stack_index = brw_indirect(0, 0); + + brw_init_compile(&c->func); + c->reg_index = 0; + prealloc_reg(c); + brw_set_compression_control(p, BRW_COMPRESSION_NONE); + brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack)); + + for (i = 0; i < c->nr_fp_insns; i++) { + struct prog_instruction *inst = &c->prog_instructions[i]; + struct prog_instruction *orig_inst; + + if ((orig_inst = inst->Data) != 0) + orig_inst->Data = current_insn(p); + + if (inst->CondUpdate) + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + else + brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE); + + switch (inst->Opcode) { + case WM_PIXELXY: + emit_pixel_xy(c, inst); + break; + case WM_DELTAXY: + emit_delta_xy(c, inst); + break; + case WM_PIXELW: + emit_pixel_w(c, inst); + break; + case WM_LINTERP: + emit_linterp(c, inst); + break; + case WM_PINTERP: + emit_pinterp(c, inst); + break; + case WM_CINTERP: + emit_cinterp(c, inst); + break; + case WM_WPOSXY: + emit_wpos_xy(c, inst); + break; + case WM_FB_WRITE: + emit_fb_write(c, inst); + break; + case OPCODE_ABS: + emit_abs(c, inst); + break; + case OPCODE_ADD: + emit_add(c, inst); + break; + case OPCODE_SUB: + emit_sub(c, inst); + break; + case OPCODE_FRC: + emit_frc(c, inst); + break; + case OPCODE_FLR: + emit_flr(c, inst); + break; + case OPCODE_LRP: + emit_lrp(c, inst); + break; + case OPCODE_INT: + emit_int(c, inst); + break; + case OPCODE_MOV: + emit_mov(c, inst); + break; + case OPCODE_DP3: + emit_dp3(c, inst); + break; + case OPCODE_DP4: + emit_dp4(c, inst); + break; + case OPCODE_XPD: + emit_xpd(c, inst); + break; + case OPCODE_DPH: + emit_dph(c, inst); + break; + case OPCODE_RCP: + emit_rcp(c, inst); + break; + case OPCODE_RSQ: + emit_rsq(c, inst); + break; + case OPCODE_SIN: + emit_sin(c, inst); + break; + case OPCODE_COS: + emit_cos(c, inst); + break; + case OPCODE_EX2: + emit_ex2(c, inst); + break; + case OPCODE_LG2: + emit_lg2(c, inst); + break; + case OPCODE_MAX: + emit_max(c, inst); + break; + case OPCODE_MIN: + emit_min(c, inst); + break; + case OPCODE_DDX: + emit_ddx(c, inst); + break; + case OPCODE_DDY: + emit_ddy(c, inst); + break; + case OPCODE_SLT: + emit_slt(c, inst); + break; + case OPCODE_SLE: + emit_sle(c, inst); + break; + case OPCODE_SGT: + emit_sgt(c, inst); + break; + case OPCODE_SGE: + emit_sge(c, inst); + break; + case OPCODE_SEQ: + emit_seq(c, inst); + break; + case OPCODE_SNE: + emit_sne(c, inst); + break; + case OPCODE_MUL: + emit_mul(c, inst); + break; + case OPCODE_POW: + emit_pow(c, inst); + break; + case OPCODE_MAD: + emit_mad(c, inst); + break; + case OPCODE_TEX: + emit_tex(c, inst); + break; + case OPCODE_TXB: + emit_txb(c, inst); + break; + case OPCODE_KIL_NV: + emit_kil(c); + break; + case OPCODE_IF: + assert(if_insn < MAX_IFSN); + if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8); + break; + case OPCODE_ELSE: + if_inst[if_insn-1] = brw_ELSE(p, if_inst[if_insn-1]); + break; + case OPCODE_ENDIF: + assert(if_insn > 0); + brw_ENDIF(p, if_inst[--if_insn]); + break; + case OPCODE_BGNSUB: + case OPCODE_ENDSUB: + break; + case OPCODE_CAL: + brw_push_insn_state(p); + brw_set_mask_control(p, BRW_MASK_DISABLE); + brw_set_access_mode(p, BRW_ALIGN_1); + brw_ADD(p, deref_1ud(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16)); + brw_set_access_mode(p, BRW_ALIGN_16); + brw_ADD(p, get_addr_reg(stack_index), + get_addr_reg(stack_index), brw_imm_d(4)); + orig_inst = inst->Data; + orig_inst->Data = &p->store[p->nr_insn]; + brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16)); + brw_pop_insn_state(p); + break; + + case OPCODE_RET: + brw_push_insn_state(p); + brw_set_mask_control(p, BRW_MASK_DISABLE); + brw_ADD(p, get_addr_reg(stack_index), + get_addr_reg(stack_index), brw_imm_d(-4)); + brw_set_access_mode(p, BRW_ALIGN_1); + brw_MOV(p, brw_ip_reg(), deref_1ud(stack_index, 0)); + brw_set_access_mode(p, BRW_ALIGN_16); + brw_pop_insn_state(p); + + break; + case OPCODE_BGNLOOP: + loop_inst[loop_insn++] = brw_DO(p, BRW_EXECUTE_8); + break; + case OPCODE_BRK: + brw_BREAK(p); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + break; + case OPCODE_CONT: + brw_CONT(p); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + break; + case OPCODE_ENDLOOP: + loop_insn--; + inst0 = inst1 = brw_WHILE(p, loop_inst[loop_insn]); + /* patch all the BREAK instructions from + last BEGINLOOP */ + while (inst0 > loop_inst[loop_insn]) { + inst0--; + if (inst0->header.opcode == BRW_OPCODE_BREAK) { + inst0->bits3.if_else.jump_count = inst1 - inst0 + 1; + inst0->bits3.if_else.pop_count = 0; + } else if (inst0->header.opcode == BRW_OPCODE_CONTINUE) { + inst0->bits3.if_else.jump_count = inst1 - inst0; + inst0->bits3.if_else.pop_count = 0; + } + } + break; + default: + _mesa_printf("unsupported IR in fragment shader %d\n", + inst->Opcode); + } + if (inst->CondUpdate) + brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); + else + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + } + post_wm_emit(c); + for (i = 0; i < c->fp->program.Base.NumInstructions; i++) + c->fp->program.Base.Instructions[i].Data = NULL; +} + +void brw_wm_glsl_emit(struct brw_wm_compile *c) +{ + brw_wm_pass_fp(c); + c->tmp_index = 127; + brw_wm_emit_glsl(c); + c->prog_data.total_grf = c->reg_index; + c->prog_data.total_scratch = 0; +} diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass0.c b/src/mesa/drivers/dri/i965/brw_wm_pass0.c index 00f6f6b9a4f..1bfae5a069b 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_pass0.c +++ b/src/mesa/drivers/dri/i965/brw_wm_pass0.c @@ -168,6 +168,7 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c, case PROGRAM_PAYLOAD: case PROGRAM_TEMPORARY: case PROGRAM_OUTPUT: + case PROGRAM_VARYING: break; case PROGRAM_LOCAL_PARAM: @@ -179,6 +180,8 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c, break; case PROGRAM_STATE_VAR: + case PROGRAM_UNIFORM: + case PROGRAM_CONSTANT: case PROGRAM_NAMED_PARAM: { struct gl_program_parameter_list *plist = c->fp->program.Base.Parameters; @@ -197,6 +200,7 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c, break; case PROGRAM_STATE_VAR: + case PROGRAM_UNIFORM: /* These may change from run to run: */ ref = get_param_ref(c, &plist->ParameterValues[idx][component] ); diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass1.c b/src/mesa/drivers/dri/i965/brw_wm_pass1.c index d668def7007..26c044d4002 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_pass1.c +++ b/src/mesa/drivers/dri/i965/brw_wm_pass1.c @@ -155,7 +155,11 @@ void brw_wm_pass1( struct brw_wm_compile *c ) case OPCODE_SUB: case OPCODE_SLT: + case OPCODE_SLE: case OPCODE_SGE: + case OPCODE_SGT: + case OPCODE_SEQ: + case OPCODE_SNE: case OPCODE_ADD: case OPCODE_MAX: case OPCODE_MIN: @@ -257,7 +261,6 @@ void brw_wm_pass1( struct brw_wm_compile *c ) case OPCODE_DST: case OPCODE_TXP: default: - assert(0); break; } diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass2.c b/src/mesa/drivers/dri/i965/brw_wm_pass2.c index a1edbd6168d..c1ce6a9b6b5 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_pass2.c +++ b/src/mesa/drivers/dri/i965/brw_wm_pass2.c @@ -328,7 +328,7 @@ void brw_wm_pass2( struct brw_wm_compile *c ) c->state = PASS2_DONE; if (INTEL_DEBUG & DEBUG_WM) { - brw_wm_print_program(c, "pass2/done"); + brw_wm_print_program(c, "pass2/done"); } } diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index 351de6d90ef..7856da0896f 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -34,6 +34,7 @@ #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" +#include "brw_wm.h" #include "bufmgr.h" /*********************************************************************** @@ -134,9 +135,13 @@ static void upload_wm_unit(struct brw_context *brw ) if (fp->UsesKill || brw->attribs.Color->AlphaEnabled) wm.wm5.program_uses_killpixel = 1; + + if (brw_wm_is_glsl(fp)) + wm.wm5.enable_8_pix = 1; + else + wm.wm5.enable_16_pix = 1; } - wm.wm5.enable_16_pix = 1; wm.wm5.thread_dispatch_enable = 1; /* AKA: color_write */ wm.wm5.legacy_line_rast = 0; wm.wm5.legacy_global_depth_bias = 0; diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index d1c1c8afb6a..6343f613cc9 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -76,7 +76,8 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, if (!rect) { UNLOCK_HARDWARE( intel ); - driWaitForVBlank( dPriv, &intel->vbl_seq, intel->vblank_flags, & missed_target ); + driWaitForVBlank( dPriv, &dPriv->vblSeq, dPriv->vblFlags, + &missed_target ); LOCK_HARDWARE( intel ); } diff --git a/src/mesa/drivers/dri/i965/intel_buffers.c b/src/mesa/drivers/dri/i965/intel_buffers.c index 6c8b0735026..96ef9d8c208 100644 --- a/src/mesa/drivers/dri/i965/intel_buffers.c +++ b/src/mesa/drivers/dri/i965/intel_buffers.c @@ -33,6 +33,8 @@ #include "context.h" #include "framebuffer.h" #include "macros.h" +#include "utils.h" +#include "vblank.h" #include "swrast/swrast.h" GLboolean intel_intersect_cliprects( drm_clip_rect_t *dst, @@ -190,6 +192,50 @@ void intelWindowMoved( struct intel_context *intel ) } } + /* Get updated plane info so we sync against the right vblank counter */ + if (intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) { + drmI830Sarea *sarea = intel->sarea; + drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w, + .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h }; + drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y, + .x2 = sarea->planeA_x + sarea->planeA_w, + .y2 = sarea->planeA_y + sarea->planeA_h }; + drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y, + .x2 = sarea->planeB_x + sarea->planeB_w, + .y2 = sarea->planeB_y + sarea->planeB_h }; + GLint areaA = driIntersectArea( drw_rect, planeA_rect ); + GLint areaB = driIntersectArea( drw_rect, planeB_rect ); + GLuint flags = dPriv->vblFlags; + + /* Update vblank info + */ + if (areaB > areaA || (areaA == areaB && areaB > 0)) { + flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY; + } else { + flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY; + } + + /* Check to see if we changed pipes */ + if (flags != dPriv->vblFlags && dPriv->vblFlags && + !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) { + int64_t count; + + /* + * Update msc_base from old pipe + */ + driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count); + dPriv->msc_base = count; + /* + * Then get new vblank_base and vblSeq values + */ + dPriv->vblFlags = flags; + driGetCurrentVBlank(dPriv, dPriv->vblFlags, &dPriv->vblSeq); + dPriv->vblank_base = dPriv->vblSeq; + } + } else { + dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY; + } + _mesa_resize_framebuffer(&intel->ctx, (GLframebuffer*)dPriv->driverPrivate, dPriv->w, dPriv->h); diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 7ec316aa8ae..d654d2d30de 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -84,6 +84,11 @@ int INTEL_DEBUG = (0); #define need_GL_EXT_multi_draw_arrays #define need_GL_EXT_secondary_color #define need_GL_EXT_point_parameters +#define need_GL_VERSION_2_0 +#define need_GL_VERSION_2_1 +#define need_GL_ARB_shader_objects +#define need_GL_ARB_vertex_shader + #include "extension_helper.h" #ifndef VERBOSE @@ -190,6 +195,13 @@ const struct dri_extension card_extensions[] = { "GL_MESA_ycbcr_texture", NULL }, { "GL_NV_blend_square", NULL }, { "GL_SGIS_generate_mipmap", NULL }, + { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions}, + { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions}, + { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions}, + { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions}, + { "GL_ARB_fragment_shader", NULL }, + /* XXX not implement yet, to compile builtin glsl lib */ + { "GL_ARB_draw_buffers", NULL }, { NULL, NULL } }; @@ -330,8 +342,8 @@ GLboolean intelInitContext( struct intel_context *intel, GLcontext *shareCtx = (GLcontext *) sharedContextPrivate; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private; - volatile drmI830Sarea *saPriv = (volatile drmI830Sarea *) - (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset); + volatile drmI830Sarea *saPriv = (drmI830Sarea *) + (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset); if (!_mesa_initialize_context(&intel->ctx, mesaVis, shareCtx, @@ -349,9 +361,6 @@ GLboolean intelInitContext( struct intel_context *intel, driParseConfigFiles (&intel->optionCache, &intelScreen->optionCache, intel->driScreen->myNum, "i965"); - intel->vblank_flags = (intel->intelScreen->irq_active != 0) - ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ; - ctx->Const.MaxTextureMaxAnisotropy = 2.0; if (getenv("INTEL_STRICT_CONFORMANCE")) { @@ -559,6 +568,8 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv) #endif /* free the Mesa context */ + intel->ctx.VertexProgram.Current = NULL; + intel->ctx.FragmentProgram.Current = NULL; _mesa_destroy_context(&intel->ctx); } @@ -578,17 +589,19 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv, if (driContextPriv) { struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate; + driDrawPriv->vblFlags = (intel->intelScreen->irq_active != 0) + ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ; + + if (intel->driReadDrawable != driReadPriv) { intel->driReadDrawable = driReadPriv; } if ( intel->driDrawable != driDrawPriv ) { - /* Shouldn't the readbuffer be stored also? */ - driDrawableInitVBlank( driDrawPriv, intel->vblank_flags, - &intel->vbl_seq ); - intel->driDrawable = driDrawPriv; intelWindowMoved( intel ); + /* Shouldn't the readbuffer be stored also? */ + driDrawableInitVBlank( driDrawPriv ); } _mesa_make_current(&intel->ctx, diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index 65898caaa75..5848d0c1ba0 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -231,11 +231,6 @@ struct intel_context */ driOptionCache optionCache; - /* VBI - */ - GLuint vbl_seq; - GLuint vblank_flags; - int64_t swap_ust; int64_t swap_missed_ust; diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index e35f7da9387..77fd9e386a6 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -549,6 +549,7 @@ static const struct __DriverAPIRec intelAPI = { .UnbindContext = intelUnbindContext, .GetSwapInfo = intelGetSwapInfo, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL, diff --git a/src/mesa/drivers/dri/mach64/mach64_context.c b/src/mesa/drivers/dri/mach64/mach64_context.c index ad661e198cd..138e84decb9 100644 --- a/src/mesa/drivers/dri/mach64/mach64_context.c +++ b/src/mesa/drivers/dri/mach64/mach64_context.c @@ -100,6 +100,7 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual, { GLcontext *ctx, *shareCtx; __DRIscreenPrivate *driScreen = driContextPriv->driScreenPriv; + __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv; struct dd_function_table functions; mach64ContextPtr mmesa; mach64ScreenPtr mach64Screen; @@ -253,7 +254,7 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual, mmesa->do_irqs = (mmesa->mach64Screen->irq && !getenv("MACH64_NO_IRQS")); - mmesa->vblank_flags = (mmesa->do_irqs) + dPriv->vblFlags = (mmesa->do_irqs) ? driGetDefaultVBlankFlags(&mmesa->optionCache) : VBLANK_FLAG_NO_IRQ; driContextPriv->driverPrivate = (void *)mmesa; @@ -330,8 +331,7 @@ mach64MakeCurrent( __DRIcontextPrivate *driContextPriv, } - driDrawableInitVBlank( driDrawPriv, newMach64Ctx->vblank_flags, - &newMach64Ctx->vbl_seq ); + driDrawableInitVBlank( driDrawPriv ); if ( newMach64Ctx->driDrawable != driDrawPriv ) { newMach64Ctx->driDrawable = driDrawPriv; diff --git a/src/mesa/drivers/dri/mach64/mach64_context.h b/src/mesa/drivers/dri/mach64/mach64_context.h index 8d89452412b..c6023330245 100644 --- a/src/mesa/drivers/dri/mach64/mach64_context.h +++ b/src/mesa/drivers/dri/mach64/mach64_context.h @@ -263,8 +263,6 @@ struct mach64_context { /* VBI */ - GLuint vbl_seq; - GLuint vblank_flags; GLuint do_irqs; /* Configuration cache diff --git a/src/mesa/drivers/dri/mach64/mach64_ioctl.c b/src/mesa/drivers/dri/mach64/mach64_ioctl.c index 36e7d3c5d3d..7405a27f8eb 100644 --- a/src/mesa/drivers/dri/mach64/mach64_ioctl.c +++ b/src/mesa/drivers/dri/mach64/mach64_ioctl.c @@ -279,7 +279,7 @@ static int mach64WaitForFrameCompletion( mach64ContextPtr mmesa ) /* Copy the back color buffer to the front color buffer. */ -void mach64CopyBuffer( const __DRIdrawablePrivate *dPriv ) +void mach64CopyBuffer( __DRIdrawablePrivate *dPriv ) { mach64ContextPtr mmesa; GLint nbox, i, ret; @@ -320,7 +320,7 @@ void mach64CopyBuffer( const __DRIdrawablePrivate *dPriv ) #endif UNLOCK_HARDWARE( mmesa ); - driWaitForVBlank( dPriv, &mmesa->vbl_seq, mmesa->vblank_flags, &missed_target ); + driWaitForVBlank( dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target ); LOCK_HARDWARE( mmesa ); /* use front buffer cliprects */ diff --git a/src/mesa/drivers/dri/mach64/mach64_ioctl.h b/src/mesa/drivers/dri/mach64/mach64_ioctl.h index 52fe8634845..c28bf31c49f 100644 --- a/src/mesa/drivers/dri/mach64/mach64_ioctl.h +++ b/src/mesa/drivers/dri/mach64/mach64_ioctl.h @@ -78,7 +78,7 @@ extern void mach64FireBlitLocked( mach64ContextPtr mmesa, void *buffer, GLint offset, GLint pitch, GLint format, GLint x, GLint y, GLint width, GLint height ); -extern void mach64CopyBuffer( const __DRIdrawablePrivate *dPriv ); +extern void mach64CopyBuffer( __DRIdrawablePrivate *dPriv ); #if ENABLE_PERF_BOXES extern void mach64PerformanceCounters( mach64ContextPtr mmesa ); extern void mach64PerformanceBoxesLocked( mach64ContextPtr mmesa ); diff --git a/src/mesa/drivers/dri/mach64/mach64_screen.c b/src/mesa/drivers/dri/mach64/mach64_screen.c index 04eb0815149..a04b7754842 100644 --- a/src/mesa/drivers/dri/mach64/mach64_screen.c +++ b/src/mesa/drivers/dri/mach64/mach64_screen.c @@ -484,6 +484,7 @@ static struct __DriverAPIRec mach64API = { .UnbindContext = mach64UnbindContext, .GetSwapInfo = NULL, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c index 99a2ea04911..31042f9739b 100644 --- a/src/mesa/drivers/dri/mga/mga_xmesa.c +++ b/src/mesa/drivers/dri/mga/mga_xmesa.c @@ -75,11 +75,13 @@ #define need_GL_ARB_vertex_buffer_object #define need_GL_ARB_vertex_program #define need_GL_EXT_fog_coord +#define need_GL_EXT_gpu_program_parameters #define need_GL_EXT_multi_draw_arrays #define need_GL_EXT_secondary_color #if 0 #define need_GL_EXT_paletted_texture #endif +#define need_GL_APPLE_vertex_array_object #define need_GL_NV_vertex_program #include "extension_helper.h" @@ -411,13 +413,15 @@ static const struct dri_extension card_extensions[] = #endif { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, { "GL_EXT_stencil_wrap", NULL }, + { "GL_APPLE_vertex_array_object", GL_APPLE_vertex_array_object_functions }, { "GL_MESA_ycbcr_texture", NULL }, { "GL_SGIS_generate_mipmap", NULL }, { NULL, NULL } }; -static const struct dri_extension ARB_vp_extension[] = { +static const struct dri_extension ARB_vp_extensions[] = { { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, + { "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions }, { NULL, NULL } }; @@ -448,6 +452,7 @@ mgaCreateContext( const __GLcontextModes *mesaVis, GLcontext *ctx, *shareCtx; mgaContextPtr mmesa; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv; mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *)sPriv->private; drm_mga_sarea_t *saPriv = (drm_mga_sarea_t *)(((char*)sPriv->pSAREA)+ mgaScreen->sarea_priv_offset); @@ -622,7 +627,7 @@ mgaCreateContext( const __GLcontextModes *mesaVis, } if ( driQueryOptionb( &mmesa->optionCache, "arb_vertex_program" ) ) { - driInitSingleExtension( ctx, ARB_vp_extension ); + driInitExtensions(ctx, ARB_vp_extensions, GL_FALSE); } if ( driQueryOptionb( &mmesa->optionCache, "nv_vertex_program" ) ) { @@ -646,7 +651,7 @@ mgaCreateContext( const __GLcontextModes *mesaVis, debug_control ); #endif - mmesa->vblank_flags = (mmesa->mgaScreen->irq == 0) + dPriv->vblFlags = (mmesa->mgaScreen->irq == 0) ? VBLANK_FLAG_NO_IRQ : driGetDefaultVBlankFlags(&mmesa->optionCache); (*dri_interface->getUST)( & mmesa->swap_ust ); @@ -878,8 +883,8 @@ mgaMakeCurrent(__DRIcontextPrivate *driContextPriv, mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate; if (mmesa->driDrawable != driDrawPriv) { - driDrawableInitVBlank( driDrawPriv, mmesa->vblank_flags, - &mmesa->vbl_seq ); + driDrawableInitVBlank( driDrawPriv ); + mmesa->driDrawable = driDrawPriv; mmesa->dirty = ~0; mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK); @@ -944,6 +949,7 @@ static const struct __DriverAPIRec mgaAPI = { .UnbindContext = mgaUnbindContext, .GetSwapInfo = getSwapInfo, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL @@ -985,7 +991,7 @@ __GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp) driInitExtensions( NULL, card_extensions, GL_FALSE ); driInitExtensions( NULL, g400_extensions, GL_FALSE ); - driInitSingleExtension( NULL, ARB_vp_extension ); + driInitExtensions(NULL, ARB_vp_extensions, GL_FALSE); driInitExtensions( NULL, NV_vp_extensions, GL_FALSE ); if (!mgaInitDriver(psp)) diff --git a/src/mesa/drivers/dri/mga/mgacontext.h b/src/mesa/drivers/dri/mga/mgacontext.h index 2124006ade6..2681976fc2b 100644 --- a/src/mesa/drivers/dri/mga/mgacontext.h +++ b/src/mesa/drivers/dri/mga/mgacontext.h @@ -258,11 +258,6 @@ struct mga_context_t { drmBufPtr vertex_dma_buffer; drmBufPtr iload_buffer; - /* VBI - */ - GLuint vbl_seq; - GLuint vblank_flags; - int64_t swap_ust; int64_t swap_missed_ust; diff --git a/src/mesa/drivers/dri/mga/mgadd.c b/src/mesa/drivers/dri/mga/mgadd.c index b1d5e0c48fc..6d18bd83d8e 100644 --- a/src/mesa/drivers/dri/mga/mgadd.c +++ b/src/mesa/drivers/dri/mga/mgadd.c @@ -41,7 +41,7 @@ #include "mga_xmesa.h" #include "utils.h" -#define DRIVER_DATE "20061030" +#define DRIVER_DATE "20071017" /*************************************** diff --git a/src/mesa/drivers/dri/mga/mgaioctl.c b/src/mesa/drivers/dri/mga/mgaioctl.c index 679d6889259..94126a31f91 100644 --- a/src/mesa/drivers/dri/mga/mgaioctl.c +++ b/src/mesa/drivers/dri/mga/mgaioctl.c @@ -428,8 +428,7 @@ void mgaCopyBuffer( const __DRIdrawablePrivate *dPriv ) FLUSH_BATCH( mmesa ); mgaWaitForFrameCompletion( mmesa ); - driWaitForVBlank( dPriv, & mmesa->vbl_seq, mmesa->vblank_flags, - & missed_target ); + driWaitForVBlank( dPriv, & dPriv->vblSeq, dPriv->vblFlags, & missed_target ); if ( missed_target ) { mmesa->swap_missed_count++; (void) (*dri_interface->getUST)( & mmesa->swap_missed_ust ); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index a8569a9f153..5ef24d82706 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -283,7 +283,7 @@ GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv, struct gl_framebuffer *read_fb = (struct gl_framebuffer*)driReadPriv->driverPrivate; - driDrawableInitVBlank(driDrawPriv, nmesa->vblank_flags, &nmesa->vblank_seq ); + driDrawableInitVBlank(driDrawPriv); nmesa->driDrawable = driDrawPriv; _mesa_resize_framebuffer(nmesa->glCtx, draw_fb, diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 9aff0ee668b..a617dd62826 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -182,10 +182,6 @@ typedef struct nouveau_context { /* Configuration cache */ driOptionCache optionCache; - /* vblank stuff */ - uint32_t vblank_flags; - uint32_t vblank_seq; - GLuint new_state; GLuint new_render_state; GLuint render_index; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 3e7bab63f34..533b4b1e6e1 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -205,6 +205,7 @@ static const struct __DriverAPIRec nouveauAPI = { .UnbindContext = nouveauUnbindContext, .GetSwapInfo = nouveauGetSwapInfo, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL, diff --git a/src/mesa/drivers/dri/r128/r128_context.c b/src/mesa/drivers/dri/r128/r128_context.c index c9fe11f38bd..25efe5e4cd7 100644 --- a/src/mesa/drivers/dri/r128/r128_context.c +++ b/src/mesa/drivers/dri/r128/r128_context.c @@ -113,6 +113,7 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual, { GLcontext *ctx, *shareCtx; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv; struct dd_function_table functions; r128ContextPtr rmesa; r128ScreenPtr r128scrn; @@ -262,7 +263,7 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual, r128DDInitSpanFuncs( ctx ); r128DDInitState( rmesa ); - rmesa->vblank_flags = (rmesa->r128Screen->irq != 0) + dPriv->vblFlags = (rmesa->r128Screen->irq != 0) ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ; driContextPriv->driverPrivate = (void *)rmesa; @@ -347,8 +348,7 @@ r128MakeCurrent( __DRIcontextPrivate *driContextPriv, newR128Ctx->dirty = R128_UPLOAD_ALL; } - driDrawableInitVBlank( driDrawPriv, newR128Ctx->vblank_flags, - &newR128Ctx->vbl_seq ); + driDrawableInitVBlank( driDrawPriv ); newR128Ctx->driDrawable = driDrawPriv; _mesa_make_current( newR128Ctx->glCtx, diff --git a/src/mesa/drivers/dri/r128/r128_context.h b/src/mesa/drivers/dri/r128/r128_context.h index c51dd7fa58d..3f7416e9cc9 100644 --- a/src/mesa/drivers/dri/r128/r128_context.h +++ b/src/mesa/drivers/dri/r128/r128_context.h @@ -210,11 +210,6 @@ struct r128_context { GLuint c_textureBytes; GLuint c_vertexBuffers; - /* VBI - */ - GLuint vbl_seq; - GLuint vblank_flags; - /* Configuration cache */ driOptionCache optionCache; diff --git a/src/mesa/drivers/dri/r128/r128_ioctl.c b/src/mesa/drivers/dri/r128/r128_ioctl.c index b0dba7d04e1..e04c0872f0d 100644 --- a/src/mesa/drivers/dri/r128/r128_ioctl.c +++ b/src/mesa/drivers/dri/r128/r128_ioctl.c @@ -249,7 +249,7 @@ static int r128WaitForFrameCompletion( r128ContextPtr rmesa ) /* Copy the back color buffer to the front color buffer. */ -void r128CopyBuffer( const __DRIdrawablePrivate *dPriv ) +void r128CopyBuffer( __DRIdrawablePrivate *dPriv ) { r128ContextPtr rmesa; GLint nbox, i, ret; @@ -282,7 +282,7 @@ void r128CopyBuffer( const __DRIdrawablePrivate *dPriv ) } UNLOCK_HARDWARE( rmesa ); - driWaitForVBlank( dPriv, &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target ); + driWaitForVBlank( dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target ); LOCK_HARDWARE( rmesa ); nbox = dPriv->numClipRects; /* must be in locked region */ @@ -328,7 +328,7 @@ void r128CopyBuffer( const __DRIdrawablePrivate *dPriv ) #endif } -void r128PageFlip( const __DRIdrawablePrivate *dPriv ) +void r128PageFlip( __DRIdrawablePrivate *dPriv ) { r128ContextPtr rmesa; GLint ret; @@ -359,7 +359,7 @@ void r128PageFlip( const __DRIdrawablePrivate *dPriv ) } UNLOCK_HARDWARE( rmesa ); - driWaitForVBlank( dPriv, &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target ); + driWaitForVBlank( dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target ); LOCK_HARDWARE( rmesa ); /* The kernel will have been initialized to perform page flipping diff --git a/src/mesa/drivers/dri/r128/r128_ioctl.h b/src/mesa/drivers/dri/r128/r128_ioctl.h index 95779f09bef..0f9d11fe699 100644 --- a/src/mesa/drivers/dri/r128/r128_ioctl.h +++ b/src/mesa/drivers/dri/r128/r128_ioctl.h @@ -86,8 +86,8 @@ extern void r128ReadDepthSpanLocked( r128ContextPtr rmesa, extern void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, const GLint x[], const GLint y[] ); -extern void r128CopyBuffer( const __DRIdrawablePrivate *dPriv ); -extern void r128PageFlip( const __DRIdrawablePrivate *dPriv ); +extern void r128CopyBuffer( __DRIdrawablePrivate *dPriv ); +extern void r128PageFlip( __DRIdrawablePrivate *dPriv ); void r128WaitForVBlank( r128ContextPtr rmesa ); extern void r128WaitForIdleLocked( r128ContextPtr rmesa ); diff --git a/src/mesa/drivers/dri/r128/r128_screen.c b/src/mesa/drivers/dri/r128/r128_screen.c index 9d65ebddf7d..719f9367c01 100644 --- a/src/mesa/drivers/dri/r128/r128_screen.c +++ b/src/mesa/drivers/dri/r128/r128_screen.c @@ -411,6 +411,7 @@ static struct __DriverAPIRec r128API = { .UnbindContext = r128UnbindContext, .GetSwapInfo = NULL, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index 8f43a2f3128..2b188897f1e 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -248,6 +248,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, void *sharedContextPrivate) { __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv; radeonScreenPtr screen = (radeonScreenPtr)(sPriv->private); struct dd_function_table functions; r200ContextPtr rmesa; @@ -499,7 +500,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, fthrottle_mode, rmesa->r200Screen->irq); - rmesa->vblank_flags = (rmesa->r200Screen->irq != 0) + dPriv->vblFlags = (rmesa->r200Screen->irq != 0) ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ; rmesa->prefer_gart_client_texturing = @@ -667,8 +668,7 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv, fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)newCtx->glCtx); if ( newCtx->dri.drawable != driDrawPriv ) { - driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags, - &newCtx->vbl_seq ); + driDrawableInitVBlank( driDrawPriv ); } newCtx->dri.readable = driReadPriv; diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index c80180bdbcc..be73507995b 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -893,11 +893,8 @@ struct r200_context { GLuint TexGenCompSel; GLmatrix tmpmat; - /* VBI / buffer swap + /* buffer swap */ - GLuint vbl_seq; - GLuint vblank_flags; - int64_t swap_ust; int64_t swap_missed_ust; diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index c9c5a861722..2ab9ff8a467 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -419,7 +419,7 @@ static void r200WaitForFrameCompletion( r200ContextPtr rmesa ) /* Copy the back color buffer to the front color buffer. */ -void r200CopyBuffer( const __DRIdrawablePrivate *dPriv, +void r200CopyBuffer( __DRIdrawablePrivate *dPriv, const drm_clip_rect_t *rect) { r200ContextPtr rmesa; @@ -449,7 +449,7 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv, if (!rect) { UNLOCK_HARDWARE( rmesa ); - driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target ); + driWaitForVBlank( dPriv, & dPriv->vblSeq, dPriv->vblFlags, & missed_target ); LOCK_HARDWARE( rmesa ); } @@ -513,7 +513,7 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv, } } -void r200PageFlip( const __DRIdrawablePrivate *dPriv ) +void r200PageFlip( __DRIdrawablePrivate *dPriv ) { r200ContextPtr rmesa; GLint ret; @@ -553,7 +553,7 @@ void r200PageFlip( const __DRIdrawablePrivate *dPriv ) */ r200WaitForFrameCompletion( rmesa ); UNLOCK_HARDWARE( rmesa ); - driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target ); + driWaitForVBlank( dPriv, & dPriv->vblSeq, dPriv->vblFlags, & missed_target ); if ( missed_target ) { rmesa->swap_missed_count++; (void) (*dri_interface->getUST)( & rmesa->swap_missed_ust ); diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.h b/src/mesa/drivers/dri/r200/r200_ioctl.h index bf126799472..4521fbabf1d 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.h +++ b/src/mesa/drivers/dri/r200/r200_ioctl.h @@ -89,9 +89,9 @@ extern void r200ReleaseDmaRegion( r200ContextPtr rmesa, struct r200_dma_region *region, const char *caller ); -extern void r200CopyBuffer( const __DRIdrawablePrivate *drawable, +extern void r200CopyBuffer( __DRIdrawablePrivate *drawable, const drm_clip_rect_t *rect); -extern void r200PageFlip( const __DRIdrawablePrivate *drawable ); +extern void r200PageFlip( __DRIdrawablePrivate *drawable ); extern void r200Flush( GLcontext *ctx ); extern void r200Finish( GLcontext *ctx ); extern void r200WaitForIdleLocked( r200ContextPtr rmesa ); diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 14e0f052fd5..d2ed3105d1c 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -93,6 +93,8 @@ int hw_tcl_on = 1; const struct dri_extension card_extensions[] = { /* *INDENT-OFF* */ + {"GL_ARB_depth_texture", NULL}, + {"GL_ARB_fragment_program", NULL}, {"GL_ARB_multisample", GL_ARB_multisample_functions}, {"GL_ARB_multitexture", NULL}, {"GL_ARB_texture_border_clamp", NULL}, @@ -105,7 +107,6 @@ const struct dri_extension card_extensions[] = { {"GL_ARB_texture_mirrored_repeat", NULL}, {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, - {"GL_ARB_fragment_program", NULL}, {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, @@ -130,6 +131,7 @@ const struct dri_extension card_extensions[] = { {"GL_NV_blend_square", NULL}, {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, {"GL_SGIS_generate_mipmap", NULL}, + {"GL_SGIX_depth_texture", NULL}, {NULL, NULL} /* *INDENT-ON* */ }; diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index 1baa74c5269..ee556d347e0 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -886,6 +886,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */ # define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */ # define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */ + + /* These two values are wrong, but they're the only values that + * produce any even vaguely correct results. Can r300 only do 16-bit + * depth textures? + */ +# define R300_TX_FORMAT_X24_Y8 0x1e +# define R300_TX_FORMAT_X32 0x1e + /* 0x16 - some 16 bit green format.. ?? */ # define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */ # define R300_TX_FORMAT_CUBIC_MAP (1 << 26) diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c index 1805cecd0af..adf69a3c257 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.c +++ b/src/mesa/drivers/dri/r300/r300_tex.c @@ -482,6 +482,25 @@ static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx, case GL_RGBA32F_ARB: return &_mesa_texformat_rgba_float32; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: +#if 0 + switch (type) { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT: + return &_mesa_texformat_z16; + case GL_UNSIGNED_INT: + return &_mesa_texformat_z32; + case GL_UNSIGNED_INT_24_8_EXT: + default: + return &_mesa_texformat_z24_s8; + } +#else + return &_mesa_texformat_z16; +#endif + default: _mesa_problem(ctx, "unexpected internalFormat 0x%x in r300ChooseTextureFormat", @@ -1057,6 +1076,19 @@ static void r300TexParameter(GLcontext * ctx, GLenum target, driSwapOutTextureObject((driTextureObject *) t); break; + case GL_DEPTH_TEXTURE_MODE: + if (texObj->Image[0][texObj->BaseLevel]->TexFormat->BaseFormat + == GL_DEPTH_COMPONENT) { + r300SetDepthTexMode(texObj); + break; + } else { + /* If the texture isn't a depth texture, changing this + * state won't cause any changes to the hardware. + * Don't force a flush of texture state. + */ + return; + } + default: return; } diff --git a/src/mesa/drivers/dri/r300/r300_tex.h b/src/mesa/drivers/dri/r300/r300_tex.h index f67a8e6ba65..b86d45bfe05 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.h +++ b/src/mesa/drivers/dri/r300/r300_tex.h @@ -35,6 +35,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef __r300_TEX_H__ #define __r300_TEX_H__ +extern void r300SetDepthTexMode(struct gl_texture_object *tObj); + extern void r300SetTexOffset(__DRIcontext *pDRICtx, GLint texname, unsigned long long offset, GLint depth, GLuint pitch); diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index 1d2909fd214..efa201a52d5 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -115,11 +115,80 @@ static const struct tx_table { _ASSIGN(LUMINANCE_ALPHA_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16)), _ASSIGN(INTENSITY_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, X, FL_I32)), _ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)), + _ASSIGN(Z16, R300_EASY_TX_FORMAT(X, X, X, X, X16)), + _ASSIGN(Z24_S8, R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8)), + _ASSIGN(Z32, R300_EASY_TX_FORMAT(X, X, X, X, X32)), /* *INDENT-ON* */ }; #undef _ASSIGN +void r300SetDepthTexMode(struct gl_texture_object *tObj) +{ + static const GLuint formats[3][3] = { + { + R300_EASY_TX_FORMAT(X, X, X, X, X16), + R300_EASY_TX_FORMAT(X, X, X, ONE, X16), + R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X16), + }, + { + R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8), + R300_EASY_TX_FORMAT(X, X, X, ONE, X24_Y8), + R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X24_Y8), + }, + { + R300_EASY_TX_FORMAT(X, X, X, X, X32), + R300_EASY_TX_FORMAT(X, X, X, ONE, X32), + R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X32), + }, + }; + const GLuint *format; + r300TexObjPtr t; + + if (!tObj) + return; + + t = (r300TexObjPtr) tObj->DriverData; + + + switch (tObj->Image[0][tObj->BaseLevel]->TexFormat->MesaFormat) { + case MESA_FORMAT_Z16: + format = formats[0]; + break; + case MESA_FORMAT_Z24_S8: + format = formats[1]; + break; + case MESA_FORMAT_Z32: + format = formats[2]; + break; + default: + /* Error...which should have already been caught by higher + * levels of Mesa. + */ + ASSERT(0); + return; + } + + switch (tObj->DepthMode) { + case GL_LUMINANCE: + t->format = format[0]; + break; + case GL_INTENSITY: + t->format = format[1]; + break; + case GL_ALPHA: + t->format = format[2]; + break; + default: + /* Error...which should have already been caught by higher + * levels of Mesa. + */ + ASSERT(0); + return; + } +} + + /** * This function computes the number of bytes of storage needed for * the given texture object (all mipmap levels, all cube faces). @@ -146,7 +215,12 @@ static void r300SetTexImages(r300ContextPtr rmesa, */ if (!t->image_override && VALID_FORMAT(baseImage->TexFormat->MesaFormat)) { - t->format = tx_table[baseImage->TexFormat->MesaFormat].format; + if (baseImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) { + r300SetDepthTexMode(tObj); + } else { + t->format = tx_table[baseImage->TexFormat->MesaFormat].format; + } + t->filter |= tx_table[baseImage->TexFormat->MesaFormat].filter; } else if (!t->image_override) { _mesa_problem(NULL, "unexpected texture format in %s", diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c index 6dfaf3c6472..8316b745cef 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.c +++ b/src/mesa/drivers/dri/r300/radeon_context.c @@ -127,6 +127,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon, void *sharedContextPrivate) { __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv; radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private); GLcontext* ctx; GLcontext* shareCtx; @@ -177,7 +178,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon, radeon->do_usleeps ? "usleeps" : "busy waits", fthrottle_mode, radeon->radeonScreen->irq); - radeon->vblank_flags = (radeon->radeonScreen->irq != 0) + dPriv->vblFlags = (radeon->radeonScreen->irq != 0) ? driGetDefaultVBlankFlags(&radeon->optionCache) : VBLANK_FLAG_NO_IRQ; (*dri_interface->getUST) (&radeon->swap_ust); @@ -277,9 +278,7 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, radeon->glCtx); if (radeon->dri.drawable != driDrawPriv) { - driDrawableInitVBlank(driDrawPriv, - radeon->vblank_flags, - &radeon->vbl_seq); + driDrawableInitVBlank(driDrawPriv); } radeon->dri.readable = driReadPriv; diff --git a/src/mesa/drivers/dri/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h index 2f239417a97..38d89306016 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.h +++ b/src/mesa/drivers/dri/r300/radeon_context.h @@ -182,10 +182,7 @@ struct radeon_context { GLuint irqsEmitted; drm_radeon_irq_wait_t iw; - /* VBI / buffer swap */ - GLuint vbl_seq; - GLuint vblank_flags; - + /* buffer swap */ int64_t swap_ust; int64_t swap_missed_ust; diff --git a/src/mesa/drivers/dri/r300/radeon_ioctl.c b/src/mesa/drivers/dri/r300/radeon_ioctl.c index 0b8656b9c1d..eeef71aaaff 100644 --- a/src/mesa/drivers/dri/r300/radeon_ioctl.c +++ b/src/mesa/drivers/dri/r300/radeon_ioctl.c @@ -157,7 +157,7 @@ static void radeonWaitForFrameCompletion(radeonContextPtr radeon) /* Copy the back color buffer to the front color buffer. */ -void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv, +void radeonCopyBuffer(__DRIdrawablePrivate * dPriv, const drm_clip_rect_t * rect) { radeonContextPtr radeon; @@ -187,7 +187,7 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv, if (!rect) { UNLOCK_HARDWARE(radeon); - driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags, + driWaitForVBlank(dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target); LOCK_HARDWARE(radeon); } @@ -253,7 +253,7 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv, } } -void radeonPageFlip(const __DRIdrawablePrivate * dPriv) +void radeonPageFlip(__DRIdrawablePrivate * dPriv) { radeonContextPtr radeon; GLint ret; @@ -293,7 +293,7 @@ void radeonPageFlip(const __DRIdrawablePrivate * dPriv) */ radeonWaitForFrameCompletion(radeon); UNLOCK_HARDWARE(radeon); - driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags, + driWaitForVBlank(dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target); if (missed_target) { radeon->swap_missed_count++; diff --git a/src/mesa/drivers/dri/r300/radeon_ioctl.h b/src/mesa/drivers/dri/r300/radeon_ioctl.h index 3a80d36c622..210001e8e07 100644 --- a/src/mesa/drivers/dri/r300/radeon_ioctl.h +++ b/src/mesa/drivers/dri/r300/radeon_ioctl.h @@ -46,9 +46,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #endif #include "radeon_drm.h" -extern void radeonCopyBuffer(const __DRIdrawablePrivate * drawable, +extern void radeonCopyBuffer(__DRIdrawablePrivate * drawable, const drm_clip_rect_t * rect); -extern void radeonPageFlip(const __DRIdrawablePrivate * drawable); +extern void radeonPageFlip(__DRIdrawablePrivate * drawable); extern void radeonFlush(GLcontext * ctx); extern void radeonFinish(GLcontext * ctx); extern void radeonWaitForIdleLocked(radeonContextPtr radeon); diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index defc82fa26b..fe6d3c21b80 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -594,8 +594,7 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv, if ( newCtx->dri.drawable != driDrawPriv ) { /* XXX we may need to validate the drawable here!!! */ - driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags, - &newCtx->vbl_seq ); + driDrawableInitVBlank( driDrawPriv ); } newCtx->dri.readable = driReadPriv; diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 10d3c2b27ca..4cc87a95aef 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -961,6 +961,7 @@ static struct __DriverAPIRec radeonAPI = { .UnbindContext = radeonUnbindContext, .GetSwapInfo = getSwapInfo, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL, @@ -978,6 +979,7 @@ static const struct __DriverAPIRec r200API = { .UnbindContext = r200UnbindContext, .GetSwapInfo = getSwapInfo, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL, diff --git a/src/mesa/drivers/dri/sis/sis_screen.c b/src/mesa/drivers/dri/sis/sis_screen.c index 79682a72530..671193577d4 100644 --- a/src/mesa/drivers/dri/sis/sis_screen.c +++ b/src/mesa/drivers/dri/sis/sis_screen.c @@ -314,6 +314,7 @@ static struct __DriverAPIRec sisAPI = { .UnbindContext = sisUnbindContext, .GetSwapInfo = NULL, .GetMSC = NULL, + .GetDrawableMSC = NULL, .WaitForMSC = NULL, .WaitForSBC = NULL, .SwapBuffersMSC = NULL diff --git a/src/mesa/drivers/dri/tdfx/tdfx_screen.c b/src/mesa/drivers/dri/tdfx/tdfx_screen.c index 5bdb446d155..6298de82f40 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_screen.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_screen.c @@ -355,6 +355,7 @@ static const struct __DriverAPIRec tdfxAPI = { .UnbindContext = tdfxUnbindContext, .GetSwapInfo = NULL, .GetMSC = NULL, + .GetDrawableMSC = NULL, .WaitForMSC = NULL, .WaitForSBC = NULL, .SwapBuffersMSC = NULL diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c index 66e92cc602e..5d95d97d539 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.c +++ b/src/mesa/drivers/dri/unichrome/via_context.c @@ -465,6 +465,7 @@ viaCreateContext(const __GLcontextModes *visual, GLcontext *ctx, *shareCtx; struct via_context *vmesa; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv; viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private; drm_via_sarea_t *saPriv = (drm_via_sarea_t *) (((GLubyte *)sPriv->pSAREA) + viaScreen->sareaPrivOffset); @@ -658,7 +659,7 @@ viaCreateContext(const __GLcontextModes *visual, driQueryOptionb(&vmesa->optionCache, "no_rast")) FALLBACK(vmesa, VIA_FALLBACK_USER_DISABLE, 1); - vmesa->vblank_flags = + dPriv->vblFlags = vmesa->viaScreen->irqEnabled ? driGetDefaultVBlankFlags(&vmesa->optionCache) : VBLANK_FLAG_NO_IRQ; @@ -838,8 +839,7 @@ viaMakeCurrent(__DRIcontextPrivate *driContextPriv, readBuffer = (GLframebuffer *)driReadPriv->driverPrivate; if (vmesa->driDrawable != driDrawPriv) { - driDrawableInitVBlank(driDrawPriv, vmesa->vblank_flags, - &vmesa->vbl_seq); + driDrawableInitVBlank(driDrawPriv); } if ((vmesa->driDrawable != driDrawPriv) diff --git a/src/mesa/drivers/dri/unichrome/via_context.h b/src/mesa/drivers/dri/unichrome/via_context.h index 63217136882..acd6f2e2b1c 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.h +++ b/src/mesa/drivers/dri/unichrome/via_context.h @@ -321,9 +321,6 @@ struct via_context { */ driOptionCache optionCache; - GLuint vblank_flags; - GLuint vbl_seq; - int64_t swap_ust; int64_t swap_missed_ust; diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c index 4a733fb00c2..3c7dafd0e6b 100644 --- a/src/mesa/drivers/dri/unichrome/via_ioctl.c +++ b/src/mesa/drivers/dri/unichrome/via_ioctl.c @@ -507,7 +507,7 @@ void viaWaitIdleLocked( struct via_context *vmesa, GLboolean light ) * except that WAIT_IDLE() will spin the CPU polling, while this is * IRQ driven. */ -static void viaWaitIdleVBlank( const __DRIdrawablePrivate *dPriv, +static void viaWaitIdleVBlank( __DRIdrawablePrivate *dPriv, struct via_context *vmesa, GLuint value ) { @@ -523,8 +523,8 @@ static void viaWaitIdleVBlank( const __DRIdrawablePrivate *dPriv, vmesa->thrashing) viaSwapOutWork(vmesa); - driWaitForVBlank( dPriv, & vmesa->vbl_seq, - vmesa->vblank_flags, & missed_target ); + driWaitForVBlank( dPriv, & dPriv->vblSeq, dPriv->vblFlags, + & missed_target ); if ( missed_target ) { vmesa->swap_missed_count++; (*dri_interface->getUST)( &vmesa->swap_missed_ust ); @@ -591,7 +591,7 @@ void viaResetPageFlippingLocked(struct via_context *vmesa) /* * Copy the back buffer to the front buffer. */ -void viaCopyBuffer(const __DRIdrawablePrivate *dPriv) +void viaCopyBuffer(__DRIdrawablePrivate *dPriv) { struct via_context *vmesa = (struct via_context *)dPriv->driContextPriv->driverPrivate; @@ -607,7 +607,7 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv) VIA_FLUSH_DMA(vmesa); - if (vmesa->vblank_flags == VBLANK_FLAG_SYNC && + if (dPriv->vblFlags == VBLANK_FLAG_SYNC && vmesa->lastBreadcrumbWrite > 1) viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastBreadcrumbWrite-1); else @@ -634,14 +634,14 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv) } -void viaPageFlip(const __DRIdrawablePrivate *dPriv) +void viaPageFlip(__DRIdrawablePrivate *dPriv) { struct via_context *vmesa = (struct via_context *)dPriv->driContextPriv->driverPrivate; struct via_renderbuffer buffer_tmp; VIA_FLUSH_DMA(vmesa); - if (vmesa->vblank_flags == VBLANK_FLAG_SYNC && + if (dPriv->vblFlags == VBLANK_FLAG_SYNC && vmesa->lastBreadcrumbWrite > 1) viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastBreadcrumbWrite - 1); else diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.h b/src/mesa/drivers/dri/unichrome/via_ioctl.h index a81b427d807..44fc439c9fd 100644 --- a/src/mesa/drivers/dri/unichrome/via_ioctl.h +++ b/src/mesa/drivers/dri/unichrome/via_ioctl.h @@ -33,8 +33,8 @@ void viaFlushDma(struct via_context *vmesa); void viaFlushDmaLocked(struct via_context *vmesa, GLuint flags); void viaInitIoctlFuncs(GLcontext *ctx); -void viaCopyBuffer(const __DRIdrawablePrivate *dpriv); -void viaPageFlip(const __DRIdrawablePrivate *dpriv); +void viaCopyBuffer(__DRIdrawablePrivate *dpriv); +void viaPageFlip(__DRIdrawablePrivate *dpriv); void viaCheckDma(struct via_context *vmesa, GLuint bytes); void viaResetPageFlippingLocked(struct via_context *vmesa); void viaWaitIdle(struct via_context *vmesa, GLboolean light); diff --git a/src/mesa/drivers/dri/unichrome/via_screen.c b/src/mesa/drivers/dri/unichrome/via_screen.c index f3912ac3521..0ad18b43009 100644 --- a/src/mesa/drivers/dri/unichrome/via_screen.c +++ b/src/mesa/drivers/dri/unichrome/via_screen.c @@ -334,6 +334,7 @@ static struct __DriverAPIRec viaAPI = { .UnbindContext = viaUnbindContext, .GetSwapInfo = getSwapInfo, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index c8546236fbf..4c8bf5f656d 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -159,7 +159,6 @@ index_mask( GLcontext *ctx, GLuint mask ) m = (unsigned long) mask; } XMesaSetPlaneMask( xmesa->display, xmbuf->cleargc, m ); - XMesaSetPlaneMask( xmesa->display, xmbuf->gc, m ); } } @@ -191,7 +190,6 @@ color_mask(GLcontext *ctx, if (bmask) m |= GET_BLUEMASK(xmesa->xm_visual); } XMesaSetPlaneMask( xmesa->display, xmbuf->cleargc, m ); - XMesaSetPlaneMask( xmesa->display, xmbuf->gc, m ); } } @@ -450,13 +448,13 @@ xmesa_DrawPixels_8R8G8B( GLcontext *ctx, ctx->_ImageTransferState == 0 && /* no color tables, scale/bias, etc */ ctx->Pixel.ZoomX == 1.0 && /* no zooming */ ctx->Pixel.ZoomY == 1.0 && - xrb->pixmap && + xrb->pixmap && /* drawing to pixmap or window */ xrb->Base.AlphaBits == 0) { const XMesaContext xmesa = XMESA_CONTEXT(ctx); XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); XMesaDisplay *dpy = xmesa->xm_visual->display; - const XMesaGC gc = xmbuf->gc; + const XMesaGC gc = xmbuf->cleargc; /* effected by glColorMask */ int dstX = x; int dstY = y; int w = width; @@ -551,7 +549,7 @@ xmesa_DrawPixels_5R6G5B( GLcontext *ctx, const SWcontext *swrast = SWRAST_CONTEXT( ctx ); XMesaDisplay *dpy = xmesa->xm_visual->display; XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); - const XMesaGC gc = xmbuf->gc; + const XMesaGC gc = xmbuf->cleargc; /* effected by glColorMask */ ASSERT(dpy); ASSERT(gc); @@ -560,7 +558,7 @@ xmesa_DrawPixels_5R6G5B( GLcontext *ctx, if (swrast->NewState) _swrast_validate_derived( ctx ); - if (xrb->pixmap && + if (xrb->pixmap && /* drawing to pixmap or window */ format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 && !ctx->Color.DitherFlag && /* no dithering */ @@ -651,7 +649,8 @@ xmesa_CopyPixels( GLcontext *ctx, const XMesaContext xmesa = XMESA_CONTEXT(ctx); const SWcontext *swrast = SWRAST_CONTEXT( ctx ); XMesaDisplay *dpy = xmesa->xm_visual->display; - const XMesaGC gc = ((XMesaBuffer) ctx->DrawBuffer)->gc; + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + const XMesaGC gc = xmbuf->cleargc; /* effected by glColorMask */ struct xmesa_renderbuffer *srcXrb = xmesa_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer->Wrapped); struct xmesa_renderbuffer *dstXrb diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 3199c9b426b..07ec285eeb7 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -1102,7 +1102,8 @@ _mesa_PopAttrib(void) (GLint) point->CoordReplace[u]); } _mesa_set_enable(ctx, GL_POINT_SPRITE_NV,point->PointSprite); - _mesa_PointParameteriNV(GL_POINT_SPRITE_R_MODE_NV, + if (ctx->Extensions.NV_point_sprite) + _mesa_PointParameteriNV(GL_POINT_SPRITE_R_MODE_NV, ctx->Point.SpriteRMode); _mesa_PointParameterfEXT(GL_POINT_SPRITE_COORD_ORIGIN, (GLfloat)ctx->Point.SpriteOrigin); diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index cbbe3e8698b..d9c18bfaafc 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -140,7 +140,9 @@ _mesa_Clear( GLbitfield mask ) return; } - if (ctx->DrawBuffer->Width == 0 || ctx->DrawBuffer->Height == 0) + if (ctx->DrawBuffer->Width == 0 || ctx->DrawBuffer->Height == 0 || + ctx->DrawBuffer->_Xmin >= ctx->DrawBuffer->_Xmax || + ctx->DrawBuffer->_Ymin >= ctx->DrawBuffer->_Ymax) return; if (ctx->RenderMode == GL_RENDER) { diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 9c84da985e0..a2b9657bbb7 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -35,10 +35,11 @@ #include "texenvprogram.h" /** - * According to Glean's texCombine test, no more than 21 instructions - * are needed. Allow a few extra just in case. + * This MAX is probably a bit generous, but that's OK. There can be + * up to four instructions per texture unit (TEX + 3 for combine), + * then there's fog and specular add. */ -#define MAX_INSTRUCTIONS ((MAX_TEXTURE_UNITS * 6) + 10) /* see bug 9829 */ +#define MAX_INSTRUCTIONS ((MAX_TEXTURE_UNITS * 4) + 12) #define DISASSEM (MESA_VERBOSE & VERBOSE_DISASSEM) @@ -460,8 +461,8 @@ static void emit_dst( struct prog_dst_register *dst, dst->File = ureg.file; dst->Index = ureg.idx; dst->WriteMask = mask; - dst->CondMask = 0; - dst->CondSwizzle = 0; + dst->CondMask = COND_TR; /* always pass cond test */ + dst->CondSwizzle = SWIZZLE_NOOP; } static struct prog_instruction * @@ -476,7 +477,9 @@ emit_op(struct texenv_fragment_program *p, { GLuint nr = p->program->Base.NumInstructions++; struct prog_instruction *inst = &p->program->Base.Instructions[nr]; - + + assert(nr < MAX_INSTRUCTIONS); + _mesa_init_instructions(inst, 1); inst->Opcode = op; @@ -1239,7 +1242,7 @@ _mesa_UpdateTexEnvProgram( GLcontext *ctx ) /* If a conventional fragment program/shader isn't in effect... */ if (!ctx->FragmentProgram._Enabled && - !ctx->Shader.CurrentProgram) { + (!ctx->Shader.CurrentProgram || !ctx->Shader.CurrentProgram->FragmentProgram)) { make_state_key(ctx, &key); hash = hash_key(&key); diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 2097c395918..43e6fb0be02 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -285,6 +285,13 @@ _mesa_init_vertex_program( GLcontext *ctx, struct gl_vertex_program *prog, struct gl_program * _mesa_new_program(GLcontext *ctx, GLenum target, GLuint id) { +#if 0 + /* This was added by Nan hai Zou but disabled by BrianP since it + * causes infinite recursive calls. + */ + if (ctx->Driver.NewProgram) + return ctx->Driver.NewProgram(ctx, target, id); +#endif switch (target) { case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */ return _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program), diff --git a/src/mesa/shader/slang/library/slang_builtin_120_common_gc.h b/src/mesa/shader/slang/library/slang_builtin_120_common_gc.h new file mode 100644 index 00000000000..fc1a9442177 --- /dev/null +++ b/src/mesa/shader/slang/library/slang_builtin_120_common_gc.h @@ -0,0 +1,104 @@ + +/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE FOLLOWING FILE: */ +/* slang_builtin_120_common.gc */ + +3,1,0,26,0,109,97,116,114,105,120,67,111,109,112,77,117,108,116,0,1,0,0,26,109,0,0,1,0,0,26,110,0, +0,0,1,8,58,109,97,116,50,120,51,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0,16,10, +49,0,57,18,110,0,16,10,49,0,57,48,0,0,0,0,1,0,28,0,109,97,116,114,105,120,67,111,109,112,77,117, +108,116,0,1,0,0,28,109,0,0,1,0,0,28,110,0,0,0,1,8,58,109,97,116,50,120,52,0,18,109,0,16,8,48,0,57, +18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,48,0,0,0,0,1,0,27,0,109, +97,116,114,105,120,67,111,109,112,77,117,108,116,0,1,0,0,27,109,0,0,1,0,0,27,110,0,0,0,1,8,58,109, +97,116,51,120,50,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110, +0,16,10,49,0,57,48,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,48,0,0,0,0,1,0,30,0,109,97,116, +114,105,120,67,111,109,112,77,117,108,116,0,1,0,0,30,109,0,0,1,0,0,30,110,0,0,0,1,8,58,109,97,116, +51,120,52,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,16,10, +49,0,57,48,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,48,0,0,0,0,1,0,29,0,109,97,116,114,105, +120,67,111,109,112,77,117,108,116,0,1,0,0,29,109,0,0,1,0,0,29,110,0,0,0,1,8,58,109,97,116,52,120, +50,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0, +57,48,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,48,0,18,109,0,16,10,51,0,57,18,110,0,16,10, +51,0,57,48,0,0,0,0,1,0,31,0,109,97,116,114,105,120,67,111,109,112,77,117,108,116,0,1,0,0,31,109,0, +0,1,0,0,31,110,0,0,0,1,8,58,109,97,116,52,120,51,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48, +0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,48,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57, +48,0,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,48,0,0,0,0,1,0,13,0,111,117,116,101,114,80,114, +111,100,117,99,116,0,1,0,0,10,99,0,0,1,0,0,10,114,0,0,0,1,8,58,109,97,116,50,0,18,99,0,59,120,0,18, +114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0,48, +0,18,99,0,59,121,0,18,114,0,59,121,0,48,0,0,0,0,1,0,14,0,111,117,116,101,114,80,114,111,100,117,99, +116,0,1,0,0,11,99,0,0,1,0,0,11,114,0,0,0,1,8,58,109,97,116,51,0,18,99,0,59,120,0,18,114,0,59,120,0, +48,0,18,99,0,59,121,0,18,114,0,59,120,0,48,0,18,99,0,59,122,0,18,114,0,59,120,0,48,0,18,99,0,59, +120,0,18,114,0,59,121,0,48,0,18,99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,59,122,0,18,114,0,59, +121,0,48,0,18,99,0,59,120,0,18,114,0,59,122,0,48,0,18,99,0,59,121,0,18,114,0,59,122,0,48,0,18,99,0, +59,122,0,18,114,0,59,122,0,48,0,0,0,0,1,0,15,0,111,117,116,101,114,80,114,111,100,117,99,116,0,1,0, +0,12,99,0,0,1,0,0,12,114,0,0,0,1,8,58,109,97,116,52,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18, +99,0,59,121,0,18,114,0,59,120,0,48,0,18,99,0,59,122,0,18,114,0,59,120,0,48,0,18,99,0,59,119,0,18, +114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0,48,0,18,99,0,59,121,0,18,114,0,59,121,0,48, +0,18,99,0,59,122,0,18,114,0,59,121,0,48,0,18,99,0,59,119,0,18,114,0,59,121,0,48,0,18,99,0,59,120,0, +18,114,0,59,122,0,48,0,18,99,0,59,121,0,18,114,0,59,122,0,48,0,18,99,0,59,122,0,18,114,0,59,122,0, +48,0,18,99,0,59,119,0,18,114,0,59,122,0,48,0,18,99,0,59,120,0,18,114,0,59,119,0,48,0,18,99,0,59, +121,0,18,114,0,59,119,0,48,0,18,99,0,59,122,0,18,114,0,59,119,0,48,0,18,99,0,59,119,0,18,114,0,59, +119,0,48,0,0,0,0,1,0,26,0,111,117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,11,99,0,0,1,0,0,10, +114,0,0,0,1,8,58,109,97,116,50,120,51,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0, +18,114,0,59,120,0,48,0,18,99,0,59,122,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0, +48,0,18,99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,59,122,0,18,114,0,59,121,0,48,0,0,0,0,1,0,27, +0,111,117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,10,99,0,0,1,0,0,11,114,0,0,0,1,8,58,109,97, +116,51,120,50,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,59,120,0,48,0,18, +99,0,59,120,0,18,114,0,59,121,0,48,0,18,99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,59,120,0,18, +114,0,59,122,0,48,0,18,99,0,59,121,0,18,114,0,59,122,0,48,0,0,0,0,1,0,28,0,111,117,116,101,114,80, +114,111,100,117,99,116,0,1,0,0,12,99,0,0,1,0,0,10,114,0,0,0,1,8,58,109,97,116,50,120,52,0,18,99,0, +59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,59,120,0,48,0,18,99,0,59,122,0,18,114,0, +59,120,0,48,0,18,99,0,59,119,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0,48,0,18, +99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,59,122,0,18,114,0,59,121,0,48,0,18,99,0,59,119,0,18, +114,0,59,121,0,48,0,0,0,0,1,0,29,0,111,117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,10,99,0,0, +1,0,0,12,114,0,0,0,1,8,58,109,97,116,52,120,50,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0, +59,121,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0,48,0,18,99,0,59,121,0,18,114,0, +59,121,0,48,0,18,99,0,59,120,0,18,114,0,59,122,0,48,0,18,99,0,59,121,0,18,114,0,59,122,0,48,0,18, +99,0,59,120,0,18,114,0,59,119,0,48,0,18,99,0,59,121,0,18,114,0,59,119,0,48,0,0,0,0,1,0,30,0,111, +117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,12,99,0,0,1,0,0,11,114,0,0,0,1,8,58,109,97,116, +51,120,52,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0,59,120,0,48,0,18,99, +0,59,122,0,18,114,0,59,120,0,48,0,18,99,0,59,119,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,18,114, +0,59,121,0,48,0,18,99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,59,122,0,18,114,0,59,121,0,48,0,18, +99,0,59,119,0,18,114,0,59,121,0,48,0,18,99,0,59,120,0,18,114,0,59,122,0,48,0,18,99,0,59,121,0,18, +114,0,59,122,0,48,0,18,99,0,59,122,0,18,114,0,59,122,0,48,0,18,99,0,59,119,0,18,114,0,59,122,0,48, +0,0,0,0,1,0,31,0,111,117,116,101,114,80,114,111,100,117,99,116,0,1,0,0,11,99,0,0,1,0,0,12,114,0,0, +0,1,8,58,109,97,116,52,120,51,0,18,99,0,59,120,0,18,114,0,59,120,0,48,0,18,99,0,59,121,0,18,114,0, +59,120,0,48,0,18,99,0,59,122,0,18,114,0,59,120,0,48,0,18,99,0,59,120,0,18,114,0,59,121,0,48,0,18, +99,0,59,121,0,18,114,0,59,121,0,48,0,18,99,0,59,122,0,18,114,0,59,121,0,48,0,18,99,0,59,120,0,18, +114,0,59,122,0,48,0,18,99,0,59,121,0,18,114,0,59,122,0,48,0,18,99,0,59,122,0,18,114,0,59,122,0,48, +0,18,99,0,59,120,0,18,114,0,59,119,0,48,0,18,99,0,59,121,0,18,114,0,59,119,0,48,0,18,99,0,59,122,0, +18,114,0,59,119,0,48,0,0,0,0,1,0,13,0,116,114,97,110,115,112,111,115,101,0,1,0,0,13,109,0,0,0,1,8, +58,109,97,116,50,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16, +8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,0,0,0,1,0,14,0,116,114,97,110,115,112,111, +115,101,0,1,0,0,14,109,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16, +10,49,0,57,59,120,0,0,18,109,0,16,10,50,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0, +16,10,49,0,57,59,121,0,0,18,109,0,16,10,50,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,18,109, +0,16,10,49,0,57,59,122,0,0,18,109,0,16,10,50,0,57,59,122,0,0,0,0,0,1,0,15,0,116,114,97,110,115,112, +111,115,101,0,1,0,0,15,109,0,0,0,1,8,58,109,97,116,52,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0, +16,10,49,0,57,59,120,0,0,18,109,0,16,10,50,0,57,59,120,0,0,18,109,0,16,10,51,0,57,59,120,0,0,18, +109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,10,50,0,57,59,121,0,0, +18,109,0,16,10,51,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,18,109,0,16,10,49,0,57,59,122,0, +0,18,109,0,16,10,50,0,57,59,122,0,0,18,109,0,16,10,51,0,57,59,122,0,0,18,109,0,16,8,48,0,57,59,119, +0,0,18,109,0,16,10,49,0,57,59,119,0,0,18,109,0,16,10,50,0,57,59,119,0,0,18,109,0,16,10,51,0,57,59, +119,0,0,0,0,0,1,0,26,0,116,114,97,110,115,112,111,115,101,0,1,0,0,27,109,0,0,0,1,8,58,109,97,116, +50,120,51,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,50,0, +57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,10,50, +0,57,59,121,0,0,0,0,0,1,0,27,0,116,114,97,110,115,112,111,115,101,0,1,0,0,26,109,0,0,0,1,8,58,109, +97,116,51,120,50,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16, +8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,18,109,0, +16,10,49,0,57,59,122,0,0,0,0,0,1,0,28,0,116,114,97,110,115,112,111,115,101,0,1,0,0,29,109,0,0,0,1, +8,58,109,97,116,50,120,52,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18, +109,0,16,10,50,0,57,59,120,0,0,18,109,0,16,10,51,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0, +18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,10,50,0,57,59,121,0,0,18,109,0,16,10,51,0,57,59,121, +0,0,0,0,0,1,0,29,0,116,114,97,110,115,112,111,115,101,0,1,0,0,28,109,0,0,0,1,8,58,109,97,116,52, +120,50,0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,8,48,0,57, +59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,18,109,0,16,10,49,0, +57,59,122,0,0,18,109,0,16,8,48,0,57,59,119,0,0,18,109,0,16,10,49,0,57,59,119,0,0,0,0,0,1,0,30,0, +116,114,97,110,115,112,111,115,101,0,1,0,0,31,109,0,0,0,1,8,58,109,97,116,51,120,52,0,18,109,0,16, +8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,50,0,57,59,120,0,0,18,109,0, +16,10,51,0,57,59,120,0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,18,109, +0,16,10,50,0,57,59,121,0,0,18,109,0,16,10,51,0,57,59,121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,18, +109,0,16,10,49,0,57,59,122,0,0,18,109,0,16,10,50,0,57,59,122,0,0,18,109,0,16,10,51,0,57,59,122,0,0, +0,0,0,1,0,31,0,116,114,97,110,115,112,111,115,101,0,1,0,0,30,109,0,0,0,1,8,58,109,97,116,52,120,51, +0,18,109,0,16,8,48,0,57,59,120,0,0,18,109,0,16,10,49,0,57,59,120,0,0,18,109,0,16,10,50,0,57,59,120, +0,0,18,109,0,16,8,48,0,57,59,121,0,0,18,109,0,16,10,49,0,57,59,121,0,0,18,109,0,16,10,50,0,57,59, +121,0,0,18,109,0,16,8,48,0,57,59,122,0,0,18,109,0,16,10,49,0,57,59,122,0,0,18,109,0,16,10,50,0,57, +59,122,0,0,18,109,0,16,8,48,0,57,59,119,0,0,18,109,0,16,10,49,0,57,59,119,0,0,18,109,0,16,10,50,0, +57,59,119,0,0,0,0,0,0 diff --git a/src/mesa/shader/slang/library/slang_builtin_120_fragment_gc.h b/src/mesa/shader/slang/library/slang_builtin_120_fragment_gc.h new file mode 100644 index 00000000000..2400b273d82 --- /dev/null +++ b/src/mesa/shader/slang/library/slang_builtin_120_fragment_gc.h @@ -0,0 +1,5 @@ + +/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE FOLLOWING FILE: */ +/* slang_builtin_120_fragment.gc */ + +3,2,2,3,10,1,103,108,95,80,111,105,110,116,67,111,111,114,100,0,0,0,0 diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index d368009ca50..5191e0c222f 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -282,6 +282,8 @@ sampler_to_texture_index(const slang_type_specifier_type type) } +#define SWIZZLE_ZWWW MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W) + /** * Return the VERT_ATTRIB_* or FRAG_ATTRIB_* value that corresponds to * a vertex or fragment program input variable. Return -1 if the input @@ -316,9 +318,11 @@ _slang_input_index(const char *name, GLenum target, GLuint *swizzleOut) { "gl_FragCoord", FRAG_ATTRIB_WPOS, SWIZZLE_NOOP }, { "gl_Color", FRAG_ATTRIB_COL0, SWIZZLE_NOOP }, { "gl_SecondaryColor", FRAG_ATTRIB_COL1, SWIZZLE_NOOP }, - { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, SWIZZLE_XXXX }, { "gl_TexCoord", FRAG_ATTRIB_TEX0, SWIZZLE_NOOP }, + /* note: we're packing several quantities into the fogcoord vector */ + { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, SWIZZLE_XXXX }, { "gl_FrontFacing", FRAG_ATTRIB_FOGC, SWIZZLE_YYYY }, /*XXX*/ + { "gl_PointCoord", FRAG_ATTRIB_FOGC, SWIZZLE_ZWWW }, { NULL, 0, SWIZZLE_NOOP } }; GLuint i; @@ -1843,6 +1847,7 @@ _slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var) n->Store->File = PROGRAM_TEMPORARY; n->Store->Size = _slang_sizeof_type_specifier(&n->Var->type.specifier); + A->program->NumTemporaries++; assert(n->Store->Size > 0); } return n; diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index 4e29e8dcc90..2be89a5ce05 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -1983,6 +1983,10 @@ static const byte slang_120_core_gc[] = { #include "library/slang_120_core_gc.h" }; +static const byte slang_120_fragment_gc[] = { +#include "library/slang_builtin_120_fragment_gc.h" +}; + static const byte slang_common_builtin_gc[] = { #include "library/slang_common_builtin_gc.h" }; @@ -2059,6 +2063,13 @@ compile_object(grammar * id, const char *source, slang_code_object * object, SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL, &object->builtin[SLANG_BUILTIN_COMMON], NULL)) return GL_FALSE; +#if FEATURE_ARB_shading_language_120 + if (!compile_binary(slang_120_fragment_gc, + &object->builtin[SLANG_BUILTIN_TARGET], + SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL, + &object->builtin[SLANG_BUILTIN_COMMON], NULL)) + return GL_FALSE; +#endif } else if (type == SLANG_UNIT_VERTEX_SHADER) { if (!compile_binary(slang_vertex_builtin_gc, diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c index ed47964a66a..7b143f6e5bb 100644 --- a/src/mesa/swrast/s_fog.c +++ b/src/mesa/swrast/s_fog.c @@ -168,7 +168,6 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) GLfloat rFog, gFog, bFog; ASSERT(swrast->_FogEnabled); - ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_FOGC); ASSERT(span->arrayMask & SPAN_RGBA); /* compute (scaled) fog color */ diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 14c9868c180..6656ebc0d0c 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -113,6 +113,7 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine, machine->DerivY = (GLfloat (*)[4]) span->attrStepY; machine->NumDeriv = FRAG_ATTRIB_MAX; + /* if running a GLSL program (not ARB_fragment_program) */ if (ctx->Shader.CurrentProgram) { /* Store front/back facing value in register FOGC.Y */ machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = (GLfloat) ctx->_Facing; diff --git a/src/mesa/swrast/s_points.c b/src/mesa/swrast/s_points.c index d54adc8fd18..ce73365a4ea 100644 --- a/src/mesa/swrast/s_points.c +++ b/src/mesa/swrast/s_points.c @@ -55,7 +55,7 @@ sprite_point(GLcontext *ctx, const SWvertex *vert) SWcontext *swrast = SWRAST_CONTEXT(ctx); SWspan span; GLfloat size; - GLuint tCoords[MAX_TEXTURE_COORD_UNITS]; + GLuint tCoords[MAX_TEXTURE_COORD_UNITS + 1]; GLuint numTcoords = 0; GLfloat t0, dtdy; @@ -99,57 +99,71 @@ sprite_point(GLcontext *ctx, const SWvertex *vert) span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F; span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F; - ATTRIB_LOOP_BEGIN - if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) { - const GLuint u = attr - FRAG_ATTRIB_TEX0; - /* a texcoord */ - if (ctx->Point.CoordReplace[u]) { - GLfloat s, r, dsdx; - - s = 0.0; - dsdx = 1.0 / size; - - if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT) { - t0 = 0.0; - dtdy = 1.0 / size; - } - else { - /* GL_UPPER_LEFT */ - t0 = 1.0; - dtdy = -1.0 / size; - } - tCoords[numTcoords++] = attr; - - if (ctx->Point.SpriteRMode == GL_ZERO) - r = 0.0F; - else if (ctx->Point.SpriteRMode == GL_S) - r = vert->attrib[attr][0]; - else /* GL_R */ - r = vert->attrib[attr][2]; - - span.attrStart[attr][0] = s; - span.attrStart[attr][1] = 0.0; /* overwritten below */ - span.attrStart[attr][2] = r; - span.attrStart[attr][3] = 1.0; - - span.attrStepX[attr][0] = dsdx; - span.attrStepX[attr][1] = 0.0; - span.attrStepX[attr][2] = 0.0; - span.attrStepX[attr][3] = 0.0; - - span.attrStepY[attr][0] = 0.0; - span.attrStepY[attr][1] = dtdy; - span.attrStepY[attr][2] = 0.0; - span.attrStepY[attr][3] = 0.0; + { + GLfloat s, r, dsdx; + + /* texcoord / pointcoord interpolants */ + s = 0.0; + dsdx = 1.0 / size; + if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT) { + t0 = 0.0; + dtdy = 1.0 / size; + } + else { + /* GL_UPPER_LEFT */ + t0 = 1.0; + dtdy = -1.0 / size; + } + ATTRIB_LOOP_BEGIN + if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) { + const GLuint u = attr - FRAG_ATTRIB_TEX0; + /* a texcoord */ + if (ctx->Point.CoordReplace[u]) { + tCoords[numTcoords++] = attr; + + if (ctx->Point.SpriteRMode == GL_ZERO) + r = 0.0F; + else if (ctx->Point.SpriteRMode == GL_S) + r = vert->attrib[attr][0]; + else /* GL_R */ + r = vert->attrib[attr][2]; + + span.attrStart[attr][0] = s; + span.attrStart[attr][1] = 0.0; /* overwritten below */ + span.attrStart[attr][2] = r; + span.attrStart[attr][3] = 1.0; + + span.attrStepX[attr][0] = dsdx; + span.attrStepX[attr][1] = 0.0; + span.attrStepX[attr][2] = 0.0; + span.attrStepX[attr][3] = 0.0; + + span.attrStepY[attr][0] = 0.0; + span.attrStepY[attr][1] = dtdy; + span.attrStepY[attr][2] = 0.0; + span.attrStepY[attr][3] = 0.0; + + continue; + } + } + else if (attr == FRAG_ATTRIB_FOGC) { + /* GLSL gl_PointCoord is stored in fog.zw */ + span.attrStart[FRAG_ATTRIB_FOGC][2] = 0.0; + span.attrStart[FRAG_ATTRIB_FOGC][3] = 0.0; /* t0 set below */ + span.attrStepX[FRAG_ATTRIB_FOGC][2] = dsdx; + span.attrStepX[FRAG_ATTRIB_FOGC][3] = 0.0; + span.attrStepY[FRAG_ATTRIB_FOGC][2] = 0.0; + span.attrStepY[FRAG_ATTRIB_FOGC][3] = dtdy; + tCoords[numTcoords++] = FRAG_ATTRIB_FOGC; continue; } - } - /* use vertex's texcoord/attrib */ - COPY_4V(span.attrStart[attr], vert->attrib[attr]); - ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0); - ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0); - ATTRIB_LOOP_END + /* use vertex's texcoord/attrib */ + COPY_4V(span.attrStart[attr], vert->attrib[attr]); + ASSIGN_4V(span.attrStepX[attr], 0, 0, 0, 0); + ASSIGN_4V(span.attrStepY[attr], 0, 0, 0, 0); + ATTRIB_LOOP_END; + } /* compute pos, bounds and render */ { @@ -184,7 +198,10 @@ sprite_point(GLcontext *ctx, const SWvertex *vert) GLuint i; /* setup texcoord T for this row */ for (i = 0; i < numTcoords; i++) { - span.attrStart[tCoords[i]][1] = tcoord; + if (tCoords[i] == FRAG_ATTRIB_FOGC) + span.attrStart[FRAG_ATTRIB_FOGC][3] = tcoord; + else + span.attrStart[tCoords[i]][1] = tcoord; } /* these might get changed by span clipping */ diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index f1e58bd3d81..000e192a4a5 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1183,7 +1183,7 @@ shade_texture_span(GLcontext *ctx, SWspan *span) if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) { convert_color_type(span, GL_FLOAT, 0); } - if (span->primitive != GL_POINT) { + if (span->primitive != GL_POINT || ctx->Point.PointSprite) { /* for points, we populated the arrays already */ interpolate_active_attribs(ctx, span, ~0); } diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c index c2a7512388e..bb4e38623c9 100644 --- a/src/mesa/swrast/s_texfilter.c +++ b/src/mesa/swrast/s_texfilter.c @@ -213,17 +213,10 @@ lerp_rgba_3d(GLchan result[4], GLfloat a, GLfloat b, GLfloat c, /** - * Compute the remainder of a divided by b, but be careful with - * negative values so that GL_REPEAT mode works right. + * If A is a signed integer, A % B doesn't give the right value for A < 0 + * (in terms of texture repeat). Just casting to unsigned fixes that. */ -static INLINE GLint -repeat_remainder(GLint a, GLint b) -{ - if (a >= 0) - return a % b; - else - return (a + 1) % b + b - 1; -} +#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B)) /** @@ -246,8 +239,8 @@ repeat_remainder(GLint a, GLint b) I1 = (I0 + 1) & (SIZE - 1); \ } \ else { \ - I0 = repeat_remainder(IFLOOR(U), SIZE); \ - I1 = repeat_remainder(I0 + 1, SIZE); \ + I0 = REMAINDER(IFLOOR(U), SIZE); \ + I1 = REMAINDER(I0 + 1, SIZE); \ } \ break; \ case GL_CLAMP_TO_EDGE: \ @@ -366,7 +359,7 @@ repeat_remainder(GLint a, GLint b) if (img->_IsPowerOfTwo) \ I &= (SIZE - 1); \ else \ - I = repeat_remainder(I, SIZE); \ + I = REMAINDER(I, SIZE); \ break; \ case GL_CLAMP_TO_EDGE: \ { \ diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c index 6a6db06285e..b7bc1977237 100644 --- a/src/mesa/tnl/t_vp_build.c +++ b/src/mesa/tnl/t_vp_build.c @@ -489,8 +489,8 @@ static void emit_dst( struct prog_dst_register *dst, dst->Index = reg.idx; /* allow zero as a shorthand for xyzw */ dst->WriteMask = mask ? mask : WRITEMASK_XYZW; - dst->CondMask = COND_TR; - dst->CondSwizzle = 0; + dst->CondMask = COND_TR; /* always pass cond test */ + dst->CondSwizzle = SWIZZLE_NOOP; dst->CondSrc = 0; dst->pad = 0; } @@ -513,7 +513,7 @@ static void debug_insn( struct prog_instruction *inst, const char *fn, static void emit_op3fn(struct tnl_program *p, - GLuint op, + enum prog_opcode op, struct ureg dest, GLuint mask, struct ureg src0, |