""" Python 'base64_codec' Codec - base64 content transfer encoding Unlike most of the other codecs which target Unicode, this codec will return Python string objects for both encode and decode. Written by Marc-Andre Lemburg (mal@lemburg.com). """ import codecs, base64 ### Codec APIs def base64_encode(input,errors='strict'): """ Encodes the object input and returns a tuple (output object, length consumed). errors defines the error handling to apply. It defaults to 'strict' handling which is the only currently supported error handling for this codec. """ assert errors == 'strict' output = base64.encodestring(input) return (output, len(input)) def base64_decode(input,errors='strict'): """ Decodes the object input and returns a tuple (output object, length consumed). input must be an object which provides the bf_getreadbuf buffer slot. Python strings, buffer objects and memory mapped files are examples of objects providing this slot. errors defines the error handling to apply. It defaults to 'strict' handling which is the only currently supported error handling for this codec. """ assert errors == 'strict' output = base64.decodestring(input) return (output, len(input)) class Codec(codecs.Codec): def encode(self, input,errors='strict'): return base64_encode(input,errors) def decode(self, input,errors='strict'): return base64_decode(input,errors) class StreamWriter(Codec,codecs.StreamWriter): pass class StreamReader(Codec,codecs.StreamReader): pass ### encodings module API def getregentry(): return (base64_encode,base64_decode,StreamReader,StreamWriter) _G400_TC2_MAGIC; - + int flags = 0; + int texctl2 = MGA_G400_TC2_MAGIC | flags; + for (i = 0; i < sizeof(texformats) / sizeof(texformats[0]); i++) { if (texformats[i].fmt == pSrcPicture->format) { texctl |= texformats[i].card_fmt; break; } } + if (PICT_FORMAT_A(pSrcPicture->format) != 0) { texctl |= MGA_TAKEY; } else { texctl |= MGA_TAMASK | MGA_TAKEY; } - + + if (pSrcPicture->repeat) { + texctl &= ~MGA_CLAMPUV; + } + if (tmu == 1) - texctl2 |= MGA_TC2_DUALTEX | MGA_TC2_SELECT_TMU1; + texctl2 |= MGA_TC2_DUALTEX | MGA_TC2_SELECT_TMU1 | flags; mgaWaitAvail (6); MGA_OUT32 (mmio, MGA_REG_TEXCTL2, texctl2); @@ -162,17 +182,91 @@ MGA_OUT32 (mmio, MGA_REG_TEXORG, ((int)pSrc->devPrivate.ptr - mem_base)); MGA_OUT32 (mmio, MGA_REG_TEXWIDTH, (w-1)<<18 | ((8-w_log2)&63)<<9 | w_log2); MGA_OUT32 (mmio, MGA_REG_TEXHEIGHT, (h-1)<<18 | ((8-h_log2)&63)<<9 | h_log2); - /* Disable filtering since we aren't doing stretch blit */ - MGA_OUT32 (mmio, MGA_REG_TEXFILTER, (0x10<<21) | MGA_MAG_NRST | MGA_MIN_NRST); - + /* Set blit filtering flags */ + if (pSrcPicture->filter == PictFilterBilinear) { + MGA_OUT32 (mmio, MGA_REG_TEXFILTER, + (0x10<<21) | MGA_MAG_BILIN | MGA_MIN_BILIN); + } else { + MGA_OUT32 (mmio, MGA_REG_TEXFILTER, + (0x10<<21) | MGA_MAG_NRST | MGA_MIN_NRST); + } + if (tmu == 1) { mgaWaitAvail (1); - MGA_OUT32 (mmio, MGA_REG_TEXCTL2, MGA_G400_TC2_MAGIC | MGA_TC2_DUALTEX); + MGA_OUT32 (mmio, MGA_REG_TEXCTL2, MGA_G400_TC2_MAGIC | MGA_TC2_DUALTEX | flags); } return TRUE; } + +/* + * The formals params are the elements of the following matrix: + * + * Dest Transform Src + * coords coords + * / Xdst \ / X_incx X_incy X_init \ / Xsrc \ + * | Ydst | = | Y_incx Y_incy Y_init | x | Ysrc | + * \ 1 / \ H_incx H_incy H_init / \ 1 / + * + * matrix elements are 32bits fixed points (16.16) + * mga_fx_* is the size of the fixed point for the TMU + */ +static void +setTMIncrementsRegs(int X_incx, + int X_incy, + int X_init, + int Y_incx, + int Y_incy, + int Y_init, + int H_incx, + int H_incy, + int H_init, + int mga_fx_width_size, + int mga_fx_height_size) { + int decalw = mga_fx_width_size - 16; + int decalh = mga_fx_height_size - 16; + + /* Convert 16 bits fixpoint -> MGA variable size fixpoint */ + if (decalw >= 0) { + X_incx = X_incx << decalw; + X_incy = X_incy << decalw; + X_init = X_init << decalw; + } else { + decalw =- decalw; + X_incx = X_incx >> decalw; + X_incy = X_incy >> decalw; + X_init = X_init >> decalw; + } + + /* Convert 16 bits fixpoint -> MGA variable size fixpoint */ + if (decalh >= 0) { + Y_incx = Y_incx << decalh; + Y_incy = Y_incy << decalh; + Y_init = Y_init << decalh; + } else { + decalh =- decalh; + Y_incx = Y_incx >> decalh; + Y_incy = Y_incy >> decalh; + Y_init = Y_init >> decalh; + } + + /* Set TM registers */ + mgaWaitAvail (9); + MGA_OUT32 (mmio, MGA_REG_TMR0, X_incx); + MGA_OUT32 (mmio, MGA_REG_TMR1, Y_incx); + MGA_OUT32 (mmio, MGA_REG_TMR2, X_incy); + MGA_OUT32 (mmio, MGA_REG_TMR3, Y_incy); + MGA_OUT32 (mmio, MGA_REG_TMR4, H_incx); + MGA_OUT32 (mmio, MGA_REG_TMR5, H_incy); + MGA_OUT32 (mmio, MGA_REG_TMR6, X_init); + MGA_OUT32 (mmio, MGA_REG_TMR7, Y_init); + MGA_OUT32 (mmio, MGA_REG_TMR8, H_init); +} + + + + Bool mgaCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture) @@ -181,15 +275,12 @@ MGA_FALLBACK(("unsupported op %x", op)); if (!mgaCheckSourceTexture (0, pSrcPicture)) return FALSE; - if (pSrcPicture->transform != NULL) - MGA_FALLBACK(("Transformed src unsupported")); + if (pMaskPicture != NULL) { if (PICT_FORMAT_A(pMaskPicture->format) == 0) MGA_FALLBACK(("Mask without alpha unsupported")); if (!mgaCheckSourceTexture (1, pMaskPicture)) return FALSE; - if (pMaskPicture->transform != NULL) - MGA_FALLBACK(("Transformed mask unsupported")); } if (pMaskPicture->componentAlpha) @@ -203,20 +294,26 @@ return TRUE; } -#define C_ARG1_CUR 0x0 +#define C_ARG1_CUR 0x0 +#define C_ARG1_ALPHA MGA_TDS_COLOR_ARG1_REPLICATEALPHA #define C_ARG2_DIFFUSE MGA_TDS_COLOR_ARG2_DIFFUSE +#define C_ARG2_FCOL MGA_TDS_COLOR_ARG2_FCOL #define C_ARG2_PREV MGA_TDS_COLOR_ARG2_PREVSTAGE +#define C_ARG1_INV MGA_TDS_COLOR_ARG1_INV +#define C_ARG2_INV MGA_TDS_COLOR_ARG2_INV #define COLOR_MUL MGA_TDS_COLOR_SEL_MUL #define COLOR_ARG1 MGA_TDS_COLOR_SEL_ARG1 #define COLOR_ARG2 MGA_TDS_COLOR_SEL_ARG2 #define A_ARG1_CUR 0x0 #define A_ARG2_IGN A_ARG2_DIFFUSE +#define A_ARG2_FCOL MGA_TDS_ALPHA_ARG2_FCOL #define A_ARG2_DIFFUSE MGA_TDS_ALPHA_ARG2_DIFFUSE #define A_ARG2_PREV MGA_TDS_ALPHA_ARG2_PREVSTAGE #define ALPHA_MUL MGA_TDS_ALPHA_SEL_MUL #define ALPHA_ARG1 MGA_TDS_ALPHA_SEL_ARG1 #define ALPHA_ARG2 MGA_TDS_ALPHA_SEL_ARG2 + Bool mgaPrepareComposite (int op, PicturePtr pSrcPicture, @@ -229,71 +326,84 @@ KdScreenPriv (pSrc->drawable.pScreen); int mem_base=(int)pScreenPriv->screen->memory_base; int cmd, blendcntl; - - mgaWaitIdle(); + int ds0, ds1; + /* Init MGA (clipping) */ - mgaSetup (pSrc->drawable.pScreen, pDst->drawable.bitsPerPixel, 5); - MGA_OUT32 (mmio, MGA_REG_TMR1, 0); - MGA_OUT32 (mmio, MGA_REG_TMR2, 0); - MGA_OUT32 (mmio, MGA_REG_TMR3, 0); - MGA_OUT32 (mmio, MGA_REG_TMR4, 0); - MGA_OUT32 (mmio, MGA_REG_TMR5, 0); - MGA_OUT32 (mmio, MGA_REG_TMR6, 0); - MGA_OUT32 (mmio, MGA_REG_TMR7, 0); - MGA_OUT32 (mmio, MGA_REG_TMR8, 0x10000); - - /* Initialize colors to 0, used in the src = A8 case */ - mgaWaitAvail(9); - MGA_OUT32 (mmio, MGA_REG_DR4, 0); - MGA_OUT32 (mmio, MGA_REG_DR6, 0); - MGA_OUT32 (mmio, MGA_REG_DR7, 0); - MGA_OUT32 (mmio, MGA_REG_DR8, 0); - MGA_OUT32 (mmio, MGA_REG_DR10, 0); - MGA_OUT32 (mmio, MGA_REG_DR11, 0); - MGA_OUT32 (mmio, MGA_REG_DR12, 0); - MGA_OUT32 (mmio, MGA_REG_DR14, 0); - MGA_OUT32 (mmio, MGA_REG_DR15, 0); + mgaSetup (pSrc->drawable.pScreen, pDst->drawable.bitsPerPixel, 1); + /* Initialize fg color to 0, used in the src = A8 case */ + MGA_OUT32 (mmio, MGA_REG_FCOL, 0xff000000); + /* Destination flags */ mgaWaitAvail (2); MGA_OUT32 (mmio, MGA_REG_DSTORG, ((int)pDst->devPrivate.ptr - mem_base)); MGA_OUT32 (mmio, MGA_REG_PITCH, pDst->devKind / (pDst->drawable.bitsPerPixel >> 3)); - + + /* Source(s) flags */ if (!PrepareSourceTexture (0, pSrcPicture, pSrc)) return FALSE; - if (pMask != NULL) - if (!PrepareSourceTexture (1, pMaskPicture, pMask)) return FALSE; + if (pMask != NULL) { + if (!PrepareSourceTexture (1, pMaskPicture, pMask)) return FALSE; + } + + /* Prepare multi-texture registers */ + ds0=ds1=0; - /* MultiTexture modulation */ - mgaWaitAvail (2); if (pSrcPicture->format == PICT_a8) { /* C = 0 A = As */ - MGA_OUT32 (mmio, MGA_REG_TDUALSTAGE0, - C_ARG2_DIFFUSE | COLOR_ARG2 | - A_ARG1_CUR | ALPHA_ARG1); + /* MGA HW: A8 format makes RGB white. We use FCOL for the black + * If FCOL was not 0, it would have been be premultiplied (RENDER) + * color component would have been: + * C_ARG1_ALPHA | C_ARG2_FCOL | COLOR_MUL + */ + ds0=C_ARG2_FCOL | COLOR_ARG2 | + A_ARG1_CUR | ALPHA_ARG1; + /* MGA HW: TMU1 must be enabled when DUALSTAGE0 contains something */ + if (pMask == NULL) { + if (!PrepareSourceTexture (1, pSrcPicture, pSrc)) return FALSE; + ds1=C_ARG2_PREV | COLOR_ARG2 | + A_ARG2_PREV | ALPHA_ARG2; + } } else { /* C = Cs A = As */ - MGA_OUT32 (mmio, MGA_REG_TDUALSTAGE0, - C_ARG1_CUR | COLOR_ARG1 | - A_ARG1_CUR | ALPHA_ARG1); + ds0=C_ARG1_CUR | COLOR_ARG1 | + A_ARG1_CUR | ALPHA_ARG1; } + if (pMask != NULL) { - if (PICT_FORMAT_A (pSrcPicture->format) == 0) { - MGA_OUT32 (mmio, MGA_REG_TDUALSTAGE1, - C_ARG1_CUR | C_ARG2_PREV | COLOR_MUL | - A_ARG1_CUR | A_ARG2_IGN | ALPHA_ARG1 | - MGA_TDS_COLOR_ARG1_REPLICATEALPHA); + /* As or Am might be NULL. in this case we don't multiply because, + * the alpha component holds garbage. + */ + int color,alpha; + if (PICT_FORMAT_A (pMaskPicture->format) == 0) { + /* C = Cs */ + color = C_ARG2_PREV | COLOR_ARG2; } else { - MGA_OUT32 (mmio, MGA_REG_TDUALSTAGE1, - C_ARG1_CUR | C_ARG2_PREV | COLOR_MUL | - A_ARG1_CUR | A_ARG2_PREV | ALPHA_MUL | - MGA_TDS_COLOR_ARG1_REPLICATEALPHA); + /* C = Am * Cs */ + color = C_ARG1_ALPHA | C_ARG2_PREV | COLOR_MUL; } - } else { - MGA_OUT32 (mmio, MGA_REG_TDUALSTAGE1, 0); - } - + + if (PICT_FORMAT_A (pMaskPicture->format) == 0) { + /* A = As */ + alpha = A_ARG2_PREV | ALPHA_ARG2; + } else if (PICT_FORMAT_A (pSrcPicture->format) == 0) { + /* A = Am */ + alpha = A_ARG1_CUR | ALPHA_ARG1; + } else { + /* A = Am * As */ + alpha = A_ARG1_CUR | A_ARG2_PREV | ALPHA_MUL; + } + + ds1 = color | alpha; + } + + /* MultiTexture modulation */ + mgaWaitAvail (2); + MGA_OUT32 (mmio, MGA_REG_TDUALSTAGE0, ds0); + MGA_OUT32 (mmio, MGA_REG_TDUALSTAGE1, ds1); + + cmd = MGA_OPCOD_TEXTURE_TRAP | MGA_ATYPE_RSTR | 0x000c0000 | MGA_DWGCTL_SHIFTZERO | MGA_DWGCTL_SGNZERO | MGA_DWGCTL_ARZERO | MGA_ATYPE_I; @@ -309,13 +419,20 @@ mgaWaitAvail (2); MGA_OUT32 (mmio, MGA_REG_DWGCTL, cmd); MGA_OUT32 (mmio, MGA_REG_ALPHACTRL, MGA_ALPHACHANNEL | blendcntl); - - currentSrc=pSrc; - currentMask=pMask; + + currentSrcPicture = pSrcPicture; + currentMaskPicture = pMaskPicture; + currentSrc = pSrc; + currentMask = pMask; + src_w2 = MGA_LOG2 (currentSrc->drawable.width); + src_h2 = MGA_LOG2 (currentSrc->drawable.height); + mask_w2 = MGA_LOG2 (currentMask->drawable.width); + mask_h2 = MGA_LOG2 (currentMask->drawable.height); return TRUE; } + void mgaComposite (int srcX, int srcY, @@ -326,9 +443,6 @@ int width, int height) { - int src_w2 = MGA_LOG2 (currentSrc->drawable.width); - int src_h2 = MGA_LOG2 (currentSrc->drawable.height); - /* Source positions can be outside source textures' boundaries. * We clamp the values here to avoid rendering glitches. */ @@ -336,31 +450,55 @@ srcY=srcY % currentSrc->drawable.height; maskX=maskX % currentMask->drawable.width; maskY=maskY % currentMask->drawable.height; - - mgaWaitAvail (4); - /* Start position in the texture */ - MGA_OUT32 (mmio, MGA_REG_TMR6, srcX<<(20-src_w2)); - MGA_OUT32 (mmio, MGA_REG_TMR7, srcY<<(20-src_h2)); - /* Increments (1 since we aren't doing stretch blit) */ - MGA_OUT32 (mmio, MGA_REG_TMR0, 1<<(20-src_w2)); - MGA_OUT32 (mmio, MGA_REG_TMR3, 1<<(20-src_h2)); - + + if (currentSrcPicture->transform) { + setTMIncrementsRegs (currentSrcPicture->transform->matrix[0][0], + currentSrcPicture->transform->matrix[0][1], + currentSrcPicture->transform->matrix[0][2] + + (srcX << 16), + currentSrcPicture->transform->matrix[1][0], + currentSrcPicture->transform->matrix[1][1], + currentSrcPicture->transform->matrix[1][2] + + (srcY << 16), + currentSrcPicture->transform->matrix[2][0], + currentSrcPicture->transform->matrix[2][1], + currentSrcPicture->transform->matrix[2][2], + 20-src_w2, 20-src_h2); + } else { + setTMIncrementsRegs (1 << 16, 0, srcX << 16, + 0, 1 << 16, srcY << 16, + 0, 0, 0x10000, + 20-src_w2, 20-src_h2); + } + if (currentMask != NULL) { - int mask_w2 = MGA_LOG2 (currentMask->drawable.width); - int mask_h2 = MGA_LOG2 (currentMask->drawable.height); - - mgaWaitAvail (6); + mgaWaitAvail (1); MGA_OUT32 (mmio, MGA_REG_TEXCTL2, MGA_G400_TC2_MAGIC | MGA_TC2_DUALTEX | MGA_TC2_SELECT_TMU1); - - MGA_OUT32 (mmio, MGA_REG_TMR6, maskX<<(20-mask_w2)); - MGA_OUT32 (mmio, MGA_REG_TMR7, maskY<<(20-mask_h2)); - MGA_OUT32 (mmio, MGA_REG_TMR0, 1<<(20-mask_w2)); - MGA_OUT32 (mmio, MGA_REG_TMR3, 1<<(20-mask_h2)); - + if (currentMaskPicture->transform) { + setTMIncrementsRegs (currentMaskPicture->transform->matrix[0][0], + currentMaskPicture->transform->matrix[0][1], + currentMaskPicture->transform->matrix[0][2] + + (maskX << 16), + currentMaskPicture->transform->matrix[1][0], + currentMaskPicture->transform->matrix[1][1], + currentMaskPicture->transform->matrix[1][2] + + (maskY << 16), + currentMaskPicture->transform->matrix[2][0], + currentMaskPicture->transform->matrix[2][1], + currentMaskPicture->transform->matrix[2][2], + 20-mask_w2, 20-mask_h2); + } else { + setTMIncrementsRegs (1 << 16, 0, maskX << 16, + 0, 1 << 16, maskY << 16, + 0, 0, 0x10000, + 20-mask_w2, 20-mask_h2); + } + + mgaWaitAvail (1); MGA_OUT32 (mmio, MGA_REG_TEXCTL2, MGA_G400_TC2_MAGIC | MGA_TC2_DUALTEX); } - + /* Destination Bounding Box * (Boundary Right | Boundary Left, Y dest | Height) */ @@ -374,5 +512,4 @@ void mgaDoneComposite (void) { - } Index: mgadraw.c =================================================================== RCS file: /cvs/xserver/xserver/hw/kdrive/mga/mgadraw.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- mgadraw.c 9 Jun 2005 23:22:54 -0000 1.13 +++ mgadraw.c 6 Jul 2005 15:34:22 -0000 1.14 @@ -65,14 +65,18 @@ fifo_size -= n; } +#define MGA_OUT8(mmio, a, v) (*(VOL8 *) ((mmio) + (a)) = (v)) +#define MGA_REG_CRTC_INDEX (0x1fd4) + void mgaWaitIdle (void) { + + mgaWaitAvail (2); + MGA_OUT32(mmio, MGA_REG_CACHEFLUSH, 0); + /* MGA_OUT8 (mmio, MGA_REG_CRTC_INDEX, 0); */ while (MGA_IN32 (mmio, MGA_REG_STATUS) & 0x10000) ; - - mgaWaitAvail (1); - MGA_OUT32(mmio, MGA_REG_CACHEFLUSH, 0); } static void @@ -168,7 +172,6 @@ static void mgaDoneSolid (void) { - mgaWaitIdle(); } #define BLIT_LEFT 1 @@ -179,7 +182,6 @@ int dx, int dy, int alu, Pixel pm) { KdScreenPriv(pSrcPixmap->drawable.pScreen); - int cmd; cmd = MGA_OPCOD_BITBLT | MGA_DWGCTL_BFCOL | MGA_DWGCTL_SHIFTZERO | mgaRop[alu]; @@ -214,7 +216,6 @@ mgaCopy (int srcX, int srcY, int dstX, int dstY, int w, int h) { int start, end; - if (dir & BLIT_UP) { srcY += h - 1; @@ -239,13 +240,12 @@ static void mgaDoneCopy (void) { - mgaWaitIdle(); } #if 0 static Bool mgaUploadToScreen(PixmapPtr pDst, char *src, int src_pitch) { - /* fprintf(stderr,"Upload to Screen %p [%d]\n",src,src_pitch); */ + /*fprintf(stderr,"Upload to Screen %p [%d]\n",src,src_pitch);*/ return TRUE; } #endif @@ -272,14 +272,15 @@ */ mgas->kaa.pitchAlign = 128; mgas->kaa.flags = KAA_OFFSCREEN_PIXMAPS; - + if (card->attr.deviceID == MGA_G4XX_DEVICE_ID) { mgas->kaa.CheckComposite = mgaCheckComposite; mgas->kaa.PrepareComposite = mgaPrepareComposite; mgas->kaa.Composite = mgaComposite; mgas->kaa.DoneComposite = mgaDoneComposite; } - /*mgaKaa.UploadToScreen=mgaUploadToScreen;*/ + + /*mgas->kaa.UploadToScreen=mgaUploadToScreen;*/ if (!kaaDrawInit (pScreen, &mgas->kaa)) return FALSE;