summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/trident/trident_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/trident/trident_state.c')
-rw-r--r--src/mesa/drivers/dri/trident/trident_state.c552
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;
+}