| /* |
| * Author: Max Lingua <sunmax@libero.it> |
| */ |
| |
| #include "s3v_context.h" |
| #include "s3v_lock.h" |
| |
| #include "swrast/swrast.h" |
| |
| #define _SPANLOCK 1 |
| #define DBG 0 |
| |
| #define LOCAL_VARS \ |
| s3vContextPtr vmesa = S3V_CONTEXT(ctx); \ |
| s3vScreenPtr s3vscrn = vmesa->s3vScreen; \ |
| __DRIscreenPrivate *sPriv = vmesa->driScreen; \ |
| __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \ |
| GLuint pitch = ( (vmesa->Flags & S3V_BACK_BUFFER) ? \ |
| ((dPriv->w+31)&~31) * s3vscrn->cpp \ |
| : sPriv->fbWidth * s3vscrn->cpp); \ |
| GLuint height = dPriv->h; \ |
| char *buf = ( (vmesa->Flags & S3V_BACK_BUFFER) ? \ |
| (char *)(sPriv->pFB + vmesa->drawOffset) \ |
| : (char *)(sPriv->pFB + vmesa->drawOffset \ |
| + dPriv->x * s3vscrn->cpp + dPriv->y * pitch) ); \ |
| char *read_buf = ( (vmesa->Flags & S3V_BACK_BUFFER) ? \ |
| (char *)(sPriv->pFB + vmesa->drawOffset) \ |
| : (char *)(sPriv->pFB + vmesa->drawOffset \ |
| + dPriv->x * s3vscrn->cpp + dPriv->y * pitch) ); \ |
| GLuint p; \ |
| (void) read_buf; (void) buf; (void) p; (void) pitch |
| |
| /* FIXME! Depth/Stencil read/writes don't work ! */ |
| #define LOCAL_DEPTH_VARS \ |
| s3vScreenPtr s3vscrn = vmesa->s3vScreen; \ |
| __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \ |
| __DRIscreenPrivate *sPriv = vmesa->driScreen; \ |
| GLuint pitch = s3vscrn->depthPitch; \ |
| GLuint height = dPriv->h; \ |
| char *buf = (char *)(sPriv->pFB + \ |
| s3vscrn->depthOffset); /* + \ |
| dPriv->x * s3vscrn->cpp + \ |
| dPriv->y * pitch)*/ \ |
| (void) pitch |
| |
| #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS |
| |
| |
| #define CLIPPIXEL( _x, _y ) \ |
| ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy)) |
| |
| |
| #define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \ |
| if ( _y < miny || _y >= maxy ) { \ |
| _n1 = 0, _x1 = x; \ |
| } else { \ |
| _n1 = _n; \ |
| _x1 = _x; \ |
| if ( _x1 < minx ) \ |
| _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \ |
| if ( _x1 + _n1 >= maxx ) \ |
| n1 -= (_x1 + n1 - maxx); \ |
| } |
| |
| #define Y_FLIP( _y ) (height - _y - 1) |
| |
| #if _SPANLOCK /* OK, we lock */ |
| |
| #define HW_LOCK() \ |
| s3vContextPtr vmesa = S3V_CONTEXT(ctx); \ |
| (void) vmesa; \ |
| DMAFLUSH(); \ |
| S3V_SIMPLE_FLUSH_LOCK(vmesa); |
| #define HW_UNLOCK() S3V_SIMPLE_UNLOCK(vmesa); |
| |
| #else /* plz, don't lock */ |
| |
| #define HW_LOCK() \ |
| s3vContextPtr vmesa = S3V_CONTEXT(ctx); \ |
| (void) vmesa; \ |
| DMAFLUSH(); |
| #define HW_UNLOCK() |
| |
| #endif |
| |
| #define HW_CLIPLOOP() \ |
| do { \ |
| __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \ |
| int _nc = dPriv->numClipRects; \ |
| \ |
| while ( _nc-- ) { \ |
| int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \ |
| int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \ |
| int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \ |
| int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y; |
| |
| #define HW_ENDCLIPLOOP() \ |
| } \ |
| } while (0) |
| |
| |
| /* ================================================================ |
| * Color buffer |
| */ |
| |
| /* 16 bit, RGB565 color spanline and pixel functions |
| */ |
| #define INIT_MONO_PIXEL(p, color) \ |
| p = S3VIRGEPACKCOLOR555( color[0], color[1], color[2], color[3] ) |
| |
| #define WRITE_RGBA( _x, _y, r, g, b, a ) \ |
| do { \ |
| *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 7) | \ |
| (((int)g & 0xf8) << 2) | \ |
| (((int)b & 0xf8) >> 3)); \ |
| DEBUG(("buf=0x%x drawOffset=0x%x dPriv->x=%i s3vscrn->cpp=%i dPriv->y=%i pitch=%i\n", \ |
| sPriv->pFB, vmesa->drawOffset, dPriv->x, s3vscrn->cpp, dPriv->y, pitch)); \ |
| DEBUG(("dPriv->w = %i\n", dPriv->w)); \ |
| } while(0) |
| |
| #define WRITE_PIXEL( _x, _y, p ) \ |
| *(GLushort *)(buf + _x*2 + _y*pitch) = p |
| |
| #define READ_RGBA( rgba, _x, _y ) \ |
| do { \ |
| GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ |
| rgba[0] = (p >> 7) & 0xf8; \ |
| rgba[1] = (p >> 2) & 0xf8; \ |
| rgba[2] = (p << 3) & 0xf8; \ |
| rgba[3] = 0xff; /* |
| if ( rgba[0] & 0x08 ) rgba[0] |= 0x07; \ |
| if ( rgba[1] & 0x04 ) rgba[1] |= 0x03; \ |
| if ( rgba[2] & 0x08 ) rgba[2] |= 0x07; */ \ |
| } while (0) |
| |
| #define TAG(x) s3v##x##_RGB555 |
| #include "spantmp.h" |
| |
| |
| /* 32 bit, ARGB8888 color spanline and pixel functions |
| */ |
| |
| #undef INIT_MONO_PIXEL |
| #define INIT_MONO_PIXEL(p, color) \ |
| p = PACK_COLOR_8888( color[3], color[0], color[1], color[2] ) |
| |
| #define WRITE_RGBA( _x, _y, r, g, b, a ) \ |
| *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \ |
| (g << 8) | \ |
| (r << 16) | \ |
| (a << 24) ) |
| |
| #define WRITE_PIXEL( _x, _y, p ) \ |
| *(GLuint *)(buf + _x*4 + _y*pitch) = p |
| |
| #define READ_RGBA( rgba, _x, _y ) \ |
| do { \ |
| GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \ |
| rgba[0] = (p >> 16) & 0xff; \ |
| rgba[1] = (p >> 8) & 0xff; \ |
| rgba[2] = (p >> 0) & 0xff; \ |
| rgba[3] = (p >> 24) & 0xff; \ |
| } while (0) |
| |
| #define TAG(x) s3v##x##_ARGB8888 |
| #include "spantmp.h" |
| |
| |
| /* 16 bit depthbuffer functions. |
| */ |
| #define WRITE_DEPTH( _x, _y, d ) \ |
| *(GLushort *)(buf + _x*2 + _y*dPriv->w*2) = d |
| |
| #define READ_DEPTH( d, _x, _y ) \ |
| d = *(GLushort *)(buf + _x*2 + _y*dPriv->w*2); |
| |
| #define TAG(x) s3v##x##_16 |
| #include "depthtmp.h" |
| |
| |
| |
| |
| /* 32 bit depthbuffer functions. |
| */ |
| #if 0 |
| #define WRITE_DEPTH( _x, _y, d ) \ |
| *(GLuint *)(buf + _x*4 + _y*pitch) = d; |
| |
| #define READ_DEPTH( d, _x, _y ) \ |
| d = *(GLuint *)(buf + _x*4 + _y*pitch); |
| |
| #define TAG(x) s3v##x##_32 |
| #include "depthtmp.h" |
| #endif |
| |
| |
| /* 24/8 bit interleaved depth/stencil functions |
| */ |
| #if 0 |
| #define WRITE_DEPTH( _x, _y, d ) { \ |
| GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \ |
| tmp &= 0xff; \ |
| tmp |= (d) & 0xffffff00; \ |
| *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \ |
| } |
| |
| #define READ_DEPTH( d, _x, _y ) \ |
| d = *(GLuint *)(buf + _x*4 + _y*pitch) & ~0xff |
| |
| |
| #define TAG(x) s3v##x##_24_8 |
| #include "depthtmp.h" |
| |
| #define WRITE_STENCIL( _x, _y, d ) { \ |
| GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \ |
| tmp &= 0xffffff00; \ |
| tmp |= d & 0xff; \ |
| *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \ |
| } |
| |
| #define READ_STENCIL( d, _x, _y ) \ |
| d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xff |
| |
| #define TAG(x) s3v##x##_24_8 |
| #include "stenciltmp.h" |
| |
| #endif |
| |
| static void s3vSetBuffer( GLcontext *ctx, GLframebuffer *colorBuffer, |
| GLuint bufferBit ) |
| { |
| s3vContextPtr vmesa = S3V_CONTEXT(ctx); |
| |
| switch ( bufferBit ) { |
| case BUFFER_BIT_FRONT_LEFT: |
| vmesa->drawOffset = vmesa->readOffset = 0; |
| break; |
| case BUFFER_BIT_BACK_LEFT: |
| vmesa->drawOffset = vmesa->readOffset = vmesa->driScreen->fbHeight * |
| vmesa->driScreen->fbWidth * |
| vmesa->s3vScreen->cpp; |
| break; |
| } |
| } |
| |
| |
| void s3vInitSpanFuncs( GLcontext *ctx ) |
| { |
| s3vContextPtr vmesa = S3V_CONTEXT(ctx); |
| struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); |
| |
| swdd->SetBuffer = s3vSetBuffer; |
| |
| #if 0 |
| switch ( vmesa->s3vScreen->cpp ) { |
| case 2: |
| swdd->WriteRGBASpan = s3vWriteRGBASpan_RGB555; |
| swdd->WriteRGBSpan = s3vWriteRGBSpan_RGB555; |
| swdd->WriteMonoRGBASpan = s3vWriteMonoRGBASpan_RGB555; |
| swdd->WriteRGBAPixels = s3vWriteRGBAPixels_RGB555; |
| swdd->WriteMonoRGBAPixels = s3vWriteMonoRGBAPixels_RGB555; |
| swdd->ReadRGBASpan = s3vReadRGBASpan_RGB555; |
| swdd->ReadRGBAPixels = s3vReadRGBAPixels_RGB555; |
| break; |
| |
| case 4: |
| swdd->WriteRGBASpan = s3vWriteRGBASpan_ARGB8888; |
| swdd->WriteRGBSpan = s3vWriteRGBSpan_ARGB8888; |
| swdd->WriteMonoRGBASpan = s3vWriteMonoRGBASpan_ARGB8888; |
| swdd->WriteRGBAPixels = s3vWriteRGBAPixels_ARGB8888; |
| swdd->WriteMonoRGBAPixels = s3vWriteMonoRGBAPixels_ARGB8888; |
| #if 1 |
| swdd->ReadRGBASpan = s3vReadRGBASpan_ARGB8888; |
| #else |
| swdd->ReadRGBASpan = s3vReadRGBASpan8888; |
| #endif |
| swdd->ReadRGBAPixels = s3vReadRGBAPixels_ARGB8888; |
| break; |
| |
| default: |
| break; |
| } |
| #endif |
| |
| switch ( vmesa->glCtx->Visual.depthBits ) { |
| case 15: |
| case 16: |
| #if 0 |
| swdd->ReadDepthSpan = s3vReadDepthSpan_16; |
| swdd->WriteDepthSpan = s3vWriteDepthSpan_16; |
| swdd->ReadDepthPixels = s3vReadDepthPixels_16; |
| swdd->WriteDepthPixels = s3vWriteDepthPixels_16; |
| #endif |
| break; |
| |
| #if 0 |
| case 24: |
| swdd->ReadDepthSpan = s3vReadDepthSpan_24_8; |
| swdd->WriteDepthSpan = s3vWriteDepthSpan_24_8; |
| swdd->ReadDepthPixels = s3vReadDepthPixels_24_8; |
| swdd->WriteDepthPixels = s3vWriteDepthPixels_24_8; |
| |
| swdd->ReadStencilSpan = s3vReadStencilSpan_24_8; |
| swdd->WriteStencilSpan = s3vWriteStencilSpan_24_8; |
| swdd->ReadStencilPixels = s3vReadStencilPixels_24_8; |
| swdd->WriteStencilPixels = s3vWriteStencilPixels_24_8; |
| break; |
| #endif |
| |
| default: |
| break; |
| } |
| } |
| |
| |
| /** |
| * Plug in the Get/Put routines for the given driRenderbuffer. |
| */ |
| void |
| s3vSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis) |
| { |
| if (drb->Base.InternalFormat == GL_RGBA) { |
| if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) { |
| drb->Base.GetRow = s3vReadRGBASpan_RGB555; |
| drb->Base.GetValues = s3vReadRGBAPixels_RGB555; |
| drb->Base.PutRow = s3vWriteRGBASpan_RGB555; |
| drb->Base.PutRowRGB = s3vWriteRGBSpan_RGB555; |
| drb->Base.PutMonoRow = s3vWriteMonoRGBASpan_RGB555; |
| drb->Base.PutValues = s3vWriteRGBAPixels_RGB555; |
| drb->Base.PutMonoValues = s3vWriteMonoRGBAPixels_RGB555; |
| } |
| else { |
| drb->Base.GetRow = s3vReadRGBASpan_ARGB8888; |
| drb->Base.GetValues = s3vReadRGBAPixels_ARGB8888; |
| drb->Base.PutRow = s3vWriteRGBASpan_ARGB8888; |
| drb->Base.PutRowRGB = s3vWriteRGBSpan_ARGB8888; |
| drb->Base.PutMonoRow = s3vWriteMonoRGBASpan_ARGB8888; |
| drb->Base.PutValues = s3vWriteRGBAPixels_ARGB8888; |
| drb->Base.PutMonoValues = s3vWriteMonoRGBAPixels_ARGB8888; |
| } |
| } |
| else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT16) { |
| drb->Base.GetRow = s3vReadDepthSpan_16; |
| drb->Base.GetValues = s3vReadDepthPixels_16; |
| drb->Base.PutRow = s3vWriteDepthSpan_16; |
| drb->Base.PutMonoRow = s3vWriteMonoDepthSpan_16; |
| drb->Base.PutValues = s3vWriteDepthPixels_16; |
| drb->Base.PutMonoValues = NULL; |
| } |
| else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) { |
| drb->Base.GetRow = NULL; |
| drb->Base.GetValues = NULL; |
| drb->Base.PutRow = NULL; |
| drb->Base.PutMonoRow = NULL; |
| drb->Base.PutValues = NULL; |
| drb->Base.PutMonoValues = NULL; |
| } |
| else if (drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) { |
| drb->Base.GetRow = NULL; |
| drb->Base.GetValues = NULL; |
| drb->Base.PutRow = NULL; |
| drb->Base.PutMonoRow = NULL; |
| drb->Base.PutValues = NULL; |
| drb->Base.PutMonoValues = NULL; |
| } |
| } |