diff options
Diffstat (limited to 'src/mesa/drivers/dri/trident/trident_state.c')
-rw-r--r-- | src/mesa/drivers/dri/trident/trident_state.c | 552 |
1 files changed, 552 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/trident/trident_state.c b/src/mesa/drivers/dri/trident/trident_state.c new file mode 100644 index 00000000000..49318824f5c --- /dev/null +++ b/src/mesa/drivers/dri/trident/trident_state.c @@ -0,0 +1,552 @@ +/* + * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Alan Hourihane, <[email protected]> + * + * Trident CyberBladeXP driver. + * + */ +#include "trident_context.h" +#include "trident_lock.h" +#include "swrast/swrast.h" + +#define TRIDENTPACKCOLOR332(r, g, b) \ + (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6)) + +#define TRIDENTPACKCOLOR1555(r, g, b, a) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#define TRIDENTPACKCOLOR565(r, g, b) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define TRIDENTPACKCOLOR888(r, g, b) \ + (((r) << 16) | ((g) << 8) | (b)) + +#define TRIDENTPACKCOLOR8888(r, g, b, a) \ + (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) + +#define TRIDENTPACKCOLOR4444(r, g, b, a) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) + +static __inline__ GLuint tridentPackColor( GLuint cpp, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a ) +{ + switch ( cpp ) { + case 2: + return TRIDENTPACKCOLOR565( r, g, b ); + case 4: + return TRIDENTPACKCOLOR8888( r, g, b, a ); + default: + return 0; + } +} + +void tridentUploadHwStateLocked( tridentContextPtr tmesa ) +{ + unsigned char *MMIO = tmesa->tridentScreen->mmio.map; +#if 0 + ATISAREAPrivPtr sarea = tmesa->sarea; + trident_context_regs_t *regs = &(sarea->ContextState); +#endif + + if ( tmesa->dirty & TRIDENT_UPLOAD_COMMAND_D ) { + MMIO_OUT32(MMIO, 0x00281C, tmesa->commandD ); + tmesa->dirty &= ~TRIDENT_UPLOAD_COMMAND_D; + } + + if ( tmesa->dirty & TRIDENT_UPLOAD_CLIPRECTS ) { + /* XXX FIX ME ! */ + MMIO_OUT32(MMIO, 0x002C80 , 0x20008000 | tmesa->tridentScreen->height ); + MMIO_OUT32(MMIO, 0x002C84 , 0x20000000 | tmesa->tridentScreen->width ); + tmesa->dirty &= ~TRIDENT_UPLOAD_CLIPRECTS; + } + + tmesa->dirty = 0; +} + +/* Copy the back color buffer to the front color buffer. + */ +void tridentCopyBuffer( const __DRIdrawablePrivate *dPriv ) +{ + unsigned char *MMIO; + tridentContextPtr tmesa; + GLint nbox, i, ret; + int busy; + XF86DRIClipRectPtr pbox; + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + tmesa = (tridentContextPtr) dPriv->driContextPriv->driverPrivate; + MMIO = tmesa->tridentScreen->mmio.map; + + LOCK_HARDWARE( tmesa ); + + /* use front buffer cliprects */ + nbox = dPriv->numClipRects; + pbox = dPriv->pClipRects; + + for ( i = 0 ; i < nbox ; i++ ) { +#if 0 + GLint nr = MIN2( i + MACH64_NR_SAREA_CLIPRECTS , nbox ); + XF86DRIClipRectPtr b = tmesa->sarea->boxes; + GLint n = 0; + + for ( ; i < nr ; i++ ) { + *b++ = pbox[i]; + n++; + } + tmesa->sarea->nbox = n; +#endif + + MMIO_OUT32(MMIO, 0x2150, tmesa->tridentScreen->frontPitch << 20 | tmesa->tridentScreen->frontOffset>>4); + MMIO_OUT32(MMIO, 0x2154, tmesa->tridentScreen->backPitch << 20 | tmesa->tridentScreen->backOffset>>4); + MMIO_OUT8(MMIO, 0x2127, 0xCC); /* Copy Rop */ + MMIO_OUT32(MMIO, 0x2128, 0x4); /* scr2scr */ + MMIO_OUT32(MMIO, 0x2138, (pbox->x1 << 16) | pbox->y1); + MMIO_OUT32(MMIO, 0x213C, (pbox->x1 << 16) | pbox->y1); + MMIO_OUT32(MMIO, 0x2140, (pbox->x2 - pbox->x1) << 16 | (pbox->y2 - pbox->y1) ); + MMIO_OUT8(MMIO, 0x2124, 0x01); /* BLT */ +#define GE_BUSY 0x80 + for (;;) { + busy = MMIO_IN8(MMIO, 0x2120); + if ( !(busy & GE_BUSY) ) + break; + } + } + + UNLOCK_HARDWARE( tmesa ); + +#if 0 + tmesa->dirty |= (MACH64_UPLOAD_CONTEXT | + MACH64_UPLOAD_MISC | + MACH64_UPLOAD_CLIPRECTS); +#endif +} + + +static void tridentDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch ) +{ + tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx); + unsigned char *MMIO = tmesa->tridentScreen->mmio.map; + __DRIdrawablePrivate *dPriv = tmesa->driDrawable; + int busy; + GLuint flags = 0; + GLint i; + GLint ret; + +#define DRM_TRIDENT_FRONT 0x01 +#define DRM_TRIDENT_BACK 0x02 +#define DRM_TRIDENT_DEPTH 0x04 + + if ( tmesa->new_state ) + tridentDDUpdateHWState( ctx ); + + if ( mask & DD_FRONT_LEFT_BIT ) { + flags |= DRM_TRIDENT_FRONT; + mask &= ~DD_FRONT_LEFT_BIT; + } + + if ( mask & DD_BACK_LEFT_BIT ) { + flags |= DRM_TRIDENT_BACK; + mask &= ~DD_BACK_LEFT_BIT; + } + + if ( ( mask & DD_DEPTH_BIT ) && ctx->Depth.Mask ) { + flags |= DRM_TRIDENT_DEPTH; + mask &= ~DD_DEPTH_BIT; + } + + LOCK_HARDWARE(tmesa); + + if ( flags ) { + + cx += tmesa->drawX; + cy += tmesa->drawY; + + /* HACK!!! + */ + if ( tmesa->dirty & ~TRIDENT_UPLOAD_CLIPRECTS ) { + tridentUploadHwStateLocked( tmesa ); + } + + for ( i = 0 ; i < tmesa->numClipRects ; i++ ) { +#if 0 + int nr = MIN2( i + TRIDENT_NR_SAREA_CLIPRECTS, tmesa->numClipRects ); + XF86DRIClipRectPtr box = tmesa->pClipRects; + XF86DRIClipRectPtr b = tmesa->sarea->boxes; + GLint n = 0; + + if ( !all ) { + for ( ; i < nr ; i++ ) { + GLint x = box[i].x1; + GLint y = box[i].y1; + GLint w = box[i].x2 - x; + GLint h = box[i].y2 - y; + + if ( x < cx ) w -= cx - x, x = cx; + if ( y < cy ) h -= cy - y, y = cy; + if ( x + w > cx + cw ) w = cx + cw - x; + if ( y + h > cy + ch ) h = cy + ch - y; + if ( w <= 0 ) continue; + if ( h <= 0 ) continue; + + b->x1 = x; + b->y1 = y; + b->x2 = x + w; + b->y2 = y + h; + b++; + n++; + } + } else { + for ( ; i < nr ; i++ ) { + *b++ = box[i]; + n++; + } + } + + tmesa->sarea->nbox = n; +#endif + +if (flags & DRM_TRIDENT_BACK) { + MMIO_OUT32(MMIO, 0x2150, tmesa->tridentScreen->backPitch << 20 | tmesa->tridentScreen->backOffset>>4); + MMIO_OUT8(MMIO, 0x2127, 0xF0); /* Pat Rop */ + MMIO_OUT32(MMIO, 0x2158, tmesa->ClearColor); + MMIO_OUT32(MMIO, 0x2128, 0x4000); /* solidfill */ + MMIO_OUT32(MMIO, 0x2138, cx << 16 | cy); + MMIO_OUT32(MMIO, 0x2140, cw << 16 | ch); + MMIO_OUT8(MMIO, 0x2124, 0x01); /* BLT */ +#define GE_BUSY 0x80 + for (;;) { + busy = MMIO_IN8(MMIO, 0x2120); + if ( !(busy & GE_BUSY) ) + break; + } +} +if (flags & DRM_TRIDENT_DEPTH) { + MMIO_OUT32(MMIO, 0x2150, tmesa->tridentScreen->depthPitch << 20 | tmesa->tridentScreen->depthOffset>>4); + MMIO_OUT8(MMIO, 0x2127, 0xF0); /* Pat Rop */ + MMIO_OUT32(MMIO, 0x2158, tmesa->ClearColor); + MMIO_OUT32(MMIO, 0x2128, 0x4000); /* solidfill */ + MMIO_OUT32(MMIO, 0x2138, cx << 16 | cy); + MMIO_OUT32(MMIO, 0x2140, cw << 16 | ch); + MMIO_OUT8(MMIO, 0x2124, 0x01); /* BLT */ +#define GE_BUSY 0x80 + for (;;) { + busy = MMIO_IN8(MMIO, 0x2120); + if ( !(busy & GE_BUSY) ) + break; + } +} + MMIO_OUT32(MMIO, 0x2150, tmesa->tridentScreen->frontPitch << 20 | tmesa->tridentScreen->frontOffset>>4); +if (flags & DRM_TRIDENT_FRONT) { + MMIO_OUT8(MMIO, 0x2127, 0xF0); /* Pat Rop */ + MMIO_OUT32(MMIO, 0x2158, tmesa->ClearColor); + MMIO_OUT32(MMIO, 0x2128, 0x4000); /* solidfill */ + MMIO_OUT32(MMIO, 0x2138, cx << 16 | cy); + MMIO_OUT32(MMIO, 0x2140, cw << 16 | ch); + MMIO_OUT8(MMIO, 0x2124, 0x01); /* BLT */ +#define GE_BUSY 0x80 + for (;;) { + busy = MMIO_IN8(MMIO, 0x2120); + if ( !(busy & GE_BUSY) ) + break; + } +} + + } + +#if 0 + tmesa->dirty |= (TRIDENT_UPLOAD_CONTEXT | + TRIDENT_UPLOAD_MISC | + TRIDENT_UPLOAD_CLIPRECTS); +#endif + } + + UNLOCK_HARDWARE(tmesa); + + if ( mask ) + _swrast_Clear( ctx, mask, all, cx, cy, cw, ch ); +} + +static void tridentDDShadeModel( GLcontext *ctx, GLenum mode ) +{ + tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx); + GLuint s = tmesa->commandD; + +#define TRIDENT_FLAT_SHADE 0x000000E0 +#define TRIDENT_FLAT_SHADE_VERTEX_C 0x00000060 +#define TRIDENT_FLAT_SHADE_GOURAUD 0x00000080 + + s &= ~TRIDENT_FLAT_SHADE; + + switch ( mode ) { + case GL_FLAT: + s |= TRIDENT_FLAT_SHADE_VERTEX_C; + break; + case GL_SMOOTH: + s |= TRIDENT_FLAT_SHADE_GOURAUD; + break; + default: + return; + } + + if ( tmesa->commandD != s ) { + tmesa->commandD = s; + + tmesa->dirty |= TRIDENT_UPLOAD_COMMAND_D; + } +} + +void tridentCalcViewport( GLcontext *ctx ) +{ + tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx); + const GLfloat *v = ctx->Viewport._WindowMap.m; + GLfloat *m = tmesa->hw_viewport; + + /* See also trident_translate_vertex. + */ + m[MAT_SX] = v[MAT_SX]; + m[MAT_TX] = v[MAT_TX] + tmesa->drawX + SUBPIXEL_X; + m[MAT_SY] = - v[MAT_SY]; + m[MAT_TY] = - v[MAT_TY] + tmesa->driDrawable->h + tmesa->drawY + SUBPIXEL_Y; +#if 0 + m[MAT_SZ] = v[MAT_SZ] * tmesa->depth_scale; + m[MAT_TZ] = v[MAT_TZ] * tmesa->depth_scale; +#else + m[MAT_SZ] = v[MAT_SZ]; + m[MAT_TZ] = v[MAT_TZ]; +#endif + + tmesa->SetupNewInputs = ~0; +} + +static void tridentDDViewport( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height ) +{ + tridentCalcViewport( ctx ); +} + +static void tridentDDDepthRange( GLcontext *ctx, + GLclampd nearval, GLclampd farval ) +{ + tridentCalcViewport( ctx ); +} + +void tridentSetCliprects( tridentContextPtr tmesa, GLenum mode ) +{ + __DRIdrawablePrivate *dPriv = tmesa->driDrawable; + + switch ( mode ) { + case GL_FRONT_LEFT: + if (dPriv->numClipRects == 0) { + static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0}; + tmesa->numClipRects = 1; + tmesa->pClipRects = &zeroareacliprect; + } else { + tmesa->numClipRects = dPriv->numClipRects; + tmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pClipRects; + } + tmesa->drawX = dPriv->x; + tmesa->drawY = dPriv->y; + break; + case GL_BACK_LEFT: + if ( dPriv->numBackClipRects == 0 ) { + if (dPriv->numClipRects == 0) { + static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0}; + tmesa->numClipRects = 1; + tmesa->pClipRects = &zeroareacliprect; + } else { + tmesa->numClipRects = dPriv->numClipRects; + tmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pClipRects; + tmesa->drawX = dPriv->x; + tmesa->drawY = dPriv->y; + } + } + else { + tmesa->numClipRects = dPriv->numBackClipRects; + tmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pBackClipRects; + tmesa->drawX = dPriv->backX; + tmesa->drawY = dPriv->backY; + } + break; + default: + return; + } + +#if 0 + tmesa->dirty |= TRIDENT_UPLOAD_CLIPRECTS; +#endif +} + +static GLboolean tridentDDSetDrawBuffer( GLcontext *ctx, GLenum mode ) +{ + tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx); + int found = GL_TRUE; + + if ( tmesa->DrawBuffer != mode ) { + tmesa->DrawBuffer = mode; + + switch ( mode ) { + case GL_FRONT_LEFT: + tridentFallback( tmesa, TRIDENT_FALLBACK_DRAW_BUFFER, GL_FALSE ); + tmesa->drawOffset = tmesa->tridentScreen->frontOffset; + tmesa->drawPitch = tmesa->tridentScreen->frontPitch; + tridentSetCliprects( tmesa, GL_FRONT_LEFT ); + break; + case GL_BACK_LEFT: + tridentFallback( tmesa, TRIDENT_FALLBACK_DRAW_BUFFER, GL_FALSE ); + tmesa->drawOffset = tmesa->tridentScreen->backOffset; + tmesa->drawPitch = tmesa->tridentScreen->backPitch; + tridentSetCliprects( tmesa, GL_BACK_LEFT ); + break; + default: + tridentFallback( tmesa, TRIDENT_FALLBACK_DRAW_BUFFER, GL_TRUE ); + found = GL_FALSE; + break; + } + +#if 0 + tmesa->setup.dst_off_pitch = (((tmesa->drawPitch/8) << 22) | + (tmesa->drawOffset >> 3)); + + tmesa->dirty |= MACH64_UPLOAD_DST_OFF_PITCH | MACH64_UPLOAD_CONTEXT; +#endif + + } + + return found; +} + +static void tridentDDClearColor( GLcontext *ctx, + const GLchan color[4] ) +{ + tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx); + + tmesa->ClearColor = tridentPackColor( tmesa->tridentScreen->cpp, + color[0], color[1], + color[2], color[3] ); +} + + +void tridentDDUpdateState( GLcontext *ctx, GLuint new_state ) +{ + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + TRIDENT_CONTEXT(ctx)->new_gl_state |= new_state; +} + + +/* Initialize the context's hardware state. + */ +void tridentDDInitState( tridentContextPtr tmesa ) +{ + tmesa->new_state = 0; + + switch ( tmesa->glCtx->Visual.depthBits ) { + case 16: + tmesa->depth_scale = 1.0 / (GLfloat)0xffff; + break; + case 24: + tmesa->depth_scale = 1.0 / (GLfloat)0xffffff; + break; + } +} + +void tridentDDUpdateHWState( GLcontext *ctx ) +{ + tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx); + int new_state = tmesa->new_state; + + if ( new_state ) + { + tmesa->new_state = 0; + +#if 0 + /* Update the various parts of the context's state. + */ + if ( new_state & GAMMA_NEW_ALPHA ) + tridentUpdateAlphaMode( ctx ); + + if ( new_state & GAMMA_NEW_DEPTH ) + tridentUpdateZMode( ctx ); + + if ( new_state & GAMMA_NEW_FOG ) + gammaUpdateFogAttrib( ctx ); + + if ( new_state & GAMMA_NEW_CLIP ) + gammaUpdateClipping( ctx ); + + if ( new_state & GAMMA_NEW_POLYGON ) + gammaUpdatePolygon( ctx ); + + if ( new_state & GAMMA_NEW_CULL ) + gammaUpdateCull( ctx ); + + if ( new_state & GAMMA_NEW_MASKS ) + gammaUpdateMasks( ctx ); + + if ( new_state & GAMMA_NEW_STIPPLE ) + gammaUpdateStipple( ctx ); +#endif + } + + /* HACK ! */ + +#if 0 + gammaEmitHwState( tmesa ); +#endif +} + +/* Initialize the driver's state functions. + */ +void tridentDDInitStateFuncs( GLcontext *ctx ) +{ + ctx->Driver.UpdateState = tridentDDUpdateState; + + ctx->Driver.Clear = tridentDDClear; + ctx->Driver.DepthRange = tridentDDDepthRange; + ctx->Driver.ShadeModel = tridentDDShadeModel; + ctx->Driver.Viewport = tridentDDViewport; + + /* Pixel path fallbacks. + */ + ctx->Driver.Accum = _swrast_Accum; + ctx->Driver.Bitmap = _swrast_Bitmap; + ctx->Driver.CopyPixels = _swrast_CopyPixels; + ctx->Driver.DrawPixels = _swrast_DrawPixels; + ctx->Driver.ReadPixels = _swrast_ReadPixels; + ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; + + /* Swrast hooks for imaging extensions: + */ + ctx->Driver.CopyColorTable = _swrast_CopyColorTable; + ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; + ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; + ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; +} |