diff options
Diffstat (limited to 'src/mesa/drivers/dri/sis/sis_clear.c')
-rw-r--r-- | src/mesa/drivers/dri/sis/sis_clear.c | 454 |
1 files changed, 454 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/sis/sis_clear.c b/src/mesa/drivers/dri/sis/sis_clear.c new file mode 100644 index 0000000000..2506cd5a37 --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_clear.c @@ -0,0 +1,454 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +Copyright 2003 Eric Anholt +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_clear.c,v 1.5 2000/09/26 15:56:48 tsi Exp $ */ + +/* + * Authors: + * Sung-Ching Lin <sclin@sis.com.tw> + * Eric Anholt <anholt@FreeBSD.org> + */ + +#include "sis_context.h" +#include "sis_state.h" +#include "sis_lock.h" +#include "macros.h" +#include "swrast/swrast.h" + +#if 0 +static GLbitfield sis_3D_Clear( GLcontext * ctx, GLbitfield mask, + GLint x, GLint y, GLint width, + GLint height ); +#endif +static void sis_clear_color_buffer( GLcontext *ctx, GLenum mask, GLint x, + GLint y, GLint width, GLint height ); +static void sis_clear_z_stencil_buffer( GLcontext * ctx, + GLbitfield mask, GLint x, + GLint y, GLint width, + GLint height ); + +static void +set_color_pattern( sisContextPtr smesa, GLubyte red, GLubyte green, + GLubyte blue, GLubyte alpha ) +{ + /* XXX only RGB565 and ARGB8888 */ + switch (GET_ColorFormat(smesa)) + { + case DST_FORMAT_ARGB_8888: + smesa->clearColorPattern = (alpha << 24) + + (red << 16) + (green << 8) + (blue); + break; + case DST_FORMAT_RGB_565: + smesa->clearColorPattern = ((red >> 3) << 11) + + ((green >> 2) << 5) + (blue >> 3); + smesa->clearColorPattern |= smesa->clearColorPattern << 16; + break; + default: + assert(0); + } +} + +void +sisUpdateZStencilPattern( sisContextPtr smesa, GLclampd z, GLint stencil ) +{ + GLuint zPattern; + + if (z <= 0.0f) + zPattern = 0x0; + else if (z >= 1.0f) + zPattern = 0xFFFFFFFF; + else + zPattern = doFPtoFixedNoRound( z, 32 ); + + switch (smesa->zFormat) + { + case SiS_ZFORMAT_Z16: + zPattern = zPattern >> 16; + zPattern |= zPattern << 16; + break; + case SiS_ZFORMAT_S8Z24: + zPattern = zPattern >> 8; + zPattern |= stencil << 24; + break; + case SiS_ZFORMAT_Z32: + break; + default: + assert(0); + } + smesa->clearZStencilPattern = zPattern; +} + +void +sisDDClear( GLcontext * ctx, GLbitfield mask, GLboolean all, + GLint x, GLint y, GLint width, GLint height ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + GLint x1, y1, width1, height1; + + if (all) { + GLframebuffer *buffer = ctx->DrawBuffer; + + x1 = 0; + y1 = 0; + width1 = buffer->Width; + height1 = buffer->Height; + } else { + x1 = x; + y1 = Y_FLIP(y+height-1); + width1 = width; + height1 = height; + } + + LOCK_HARDWARE(); + +#if 0 + /* The 3d clear code is disabled because it appears to be slower, even + * in the case of being requested to clear Z and color buffers at the + * same time. + */ + if (mask & (DD_BACK_LEFT_BIT | DD_DEPTH_BIT | DD_STENCIL_BIT)) + { + /* only Clear either depth or stencil buffer */ + mask = sis_3D_Clear( ctx, mask, x1, y1, width1, height1 ); + } +#endif + + if ( mask & DD_FRONT_LEFT_BIT || mask & DD_BACK_LEFT_BIT) { + sis_clear_color_buffer( ctx, mask, x1, y1, width1, height1 ); + mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT); + } + + if (mask & (DD_DEPTH_BIT | DD_STENCIL_BIT)) { + if (smesa->depthbuffer != NULL) + sis_clear_z_stencil_buffer( ctx, mask, x1, y1, width1, height1 ); + mask &= ~(DD_DEPTH_BIT | DD_STENCIL_BIT); + } + + UNLOCK_HARDWARE(); + + if (mask != 0) + _swrast_Clear( ctx, mask, all, x1, y1, width, height ); +} + + +void +sisDDClearColor( GLcontext * ctx, const GLfloat color[4] ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + GLubyte c[4]; + + CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]); + + set_color_pattern( smesa, c[0], c[1], c[2], c[3] ); +} + +void +sisDDClearDepth( GLcontext * ctx, GLclampd d ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + sisUpdateZStencilPattern( smesa, d, ctx->Stencil.Clear ); +} + +void +sisDDClearStencil( GLcontext * ctx, GLint s ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + sisUpdateZStencilPattern( smesa, ctx->Depth.Clear, s ); +} + +#if 0 +static GLbitfield +sis_3D_Clear( GLcontext * ctx, GLbitfield mask, + GLint x, GLint y, GLint width, GLint height ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *current = &smesa->current; + + float left, top, right, bottom, zClearVal; + GLboolean bClrColor, bClrDepth, bClrStencil; + GLint dwPrimitiveSet; + GLint dwEnable1 = 0, dwEnable2 = 0, dwDepthMask = 0, dwSten1 = 0, dwSten2 = 0; + GLint dirtyflags = GFLAG_ENABLESETTING | GFLAG_ENABLESETTING2 | + GFLAG_CLIPPING | GFLAG_DESTSETTING; + + int count; + XF86DRIClipRectPtr pExtents; + + bClrColor = ((mask & DD_BACK_LEFT_BIT) != 0); + bClrDepth = ((mask & DD_DEPTH_BIT) != 0) && (ctx->Visual.depthBits != 0); + bClrStencil = ((mask & DD_STENCIL_BIT) != 0) && (ctx->Visual.stencilBits != 0); + + if (smesa->GlobalFlag & GFLAG_RENDER_STATES) + sis_update_render_state( smesa ); + + if (!bClrColor) + dwEnable2 |= MASK_ColorMaskWriteEnable; + + if (bClrStencil) { + dwSten1 = STENCIL_FORMAT_8 | SiS_STENCIL_ALWAYS | + (ctx->Stencil.Clear << 8) | 0xff; + dwSten2 = SiS_SFAIL_REPLACE | SiS_SPASS_ZFAIL_REPLACE | + SiS_SPASS_ZPASS_REPLACE; + dwEnable1 = MASK_ZWriteEnable | MASK_StencilTestEnable; + dwEnable2 |= MASK_ZMaskWriteEnable; + dwDepthMask |= ctx->Stencil.WriteMask[0] << 24; + } else if (bClrDepth) { + dwEnable1 = MASK_ZWriteEnable; + dwEnable2 |= MASK_ZMaskWriteEnable; + } + + if (bClrDepth) { + zClearVal = ctx->Depth.Clear; + if (ctx->Visual.depthBits != 32) + dwDepthMask |= 0x00ffffff; + else + dwDepthMask = 0xffffffff; + } else + zClearVal = 0.0; + + mWait3DCmdQueue(9); + MMIO(REG_3D_TEnable, dwEnable1); + MMIO(REG_3D_TEnable2, dwEnable2); + if (bClrDepth || bClrStencil) { + MMIO(REG_3D_ZSet, (current->hwZ & ~MASK_ZTestMode) | SiS_Z_COMP_ALWAYS); + dirtyflags |= GFLAG_ZSETTING; + } + if (bClrColor) { + MMIO(REG_3D_DstSet, (current->hwDstSet & ~MASK_ROP2) | LOP_COPY); + } else { + MMIO(REG_3D_DstAlphaWriteMask, 0L); + } + if (bClrStencil) { + MMIO(REG_3D_StencilSet, dwSten1); + MMIO(REG_3D_StencilSet2, dwSten2); + dirtyflags |= GFLAG_STENCILSETTING; + } + + if (mask & DD_FRONT_LEFT_BIT) { + pExtents = smesa->driDrawable->pClipRects; + count = smesa->driDrawable->numClipRects; + } else { + pExtents = NULL; + count = 1; + } + + while(count--) { + left = x; + right = x + width; + top = y; + bottom = y + height; + + if (pExtents != NULL) { + GLuint x1, y1, x2, y2; + + x1 = pExtents->x1 - smesa->driDrawable->x; + y1 = pExtents->y1 - smesa->driDrawable->y; + x2 = pExtents->x2 - smesa->driDrawable->x - 1; + y2 = pExtents->y2 - smesa->driDrawable->y - 1; + + left = (left > x1) ? left : x1; + right = (right > x2) ? x2 : right; + top = (top > y1) ? top : y1; + bottom = (bottom > y2) ? y2 : bottom; + pExtents++; + if (left > right || top > bottom) + continue; + } + + mWait3DCmdQueue(20); + + MMIO(REG_3D_ClipTopBottom, ((GLint)top << 13) | (GLint)bottom); + MMIO(REG_3D_ClipLeftRight, ((GLint)left << 13) | (GLint)right); + + /* the first triangle */ + dwPrimitiveSet = OP_3D_TRIANGLE_DRAW | OP_3D_FIRE_TSARGBc | + SHADE_FLAT_VertexC; + MMIO(REG_3D_PrimitiveSet, dwPrimitiveSet); + + MMIO(REG_3D_TSZa, *(GLint *) &zClearVal); + MMIO(REG_3D_TSXa, *(GLint *) &right); + MMIO(REG_3D_TSYa, *(GLint *) &top); + MMIO(REG_3D_TSARGBa, smesa->clearColorPattern); + + MMIO(REG_3D_TSZb, *(GLint *) &zClearVal); + MMIO(REG_3D_TSXb, *(GLint *) &left); + MMIO(REG_3D_TSYb, *(GLint *) &top); + MMIO(REG_3D_TSARGBb, smesa->clearColorPattern); + + MMIO(REG_3D_TSZc, *(GLint *) &zClearVal); + MMIO(REG_3D_TSXc, *(GLint *) &left); + MMIO(REG_3D_TSYc, *(GLint *) &bottom); + MMIO(REG_3D_TSARGBc, smesa->clearColorPattern); + + /* second triangle */ + dwPrimitiveSet = OP_3D_TRIANGLE_DRAW | OP_3D_FIRE_TSARGBb | + SHADE_FLAT_VertexB; + MMIO(REG_3D_PrimitiveSet, dwPrimitiveSet); + + MMIO(REG_3D_TSZb, *(GLint *) &zClearVal); + MMIO(REG_3D_TSXb, *(GLint *) &right); + MMIO(REG_3D_TSYb, *(GLint *) &bottom); + MMIO(REG_3D_TSARGBb, smesa->clearColorPattern); + } + + mEndPrimitive(); + + smesa->GlobalFlag |= dirtyflags; + + return (mask & ~(DD_BACK_LEFT_BIT | DD_DEPTH_BIT | DD_STENCIL_BIT)); +} +#endif + +static void +sis_bitblt_clear_cmd( sisContextPtr smesa, ENGPACKET * pkt ) +{ + GLint *lpdwDest, *lpdwSrc; + int i; + + lpdwSrc = (GLint *) pkt + 1; + lpdwDest = (GLint *) (GET_IOBase (smesa) + REG_SRC_ADDR) + 1; + + mWait3DCmdQueue (10); + + *lpdwDest++ = *lpdwSrc++; + lpdwSrc++; + lpdwDest++; + for (i = 3; i < 8; i++) { + *lpdwDest++ = *lpdwSrc++; + } + + MMIO(REG_CMD0, *(GLint *) & pkt->stdwCmd); + MMIO(REG_QueueLen, -1); +} + +static void +sis_clear_color_buffer( GLcontext *ctx, GLenum mask, GLint x, GLint y, + GLint width, GLint height ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + int count; + GLuint depth = GET_DEPTH (smesa); + XF86DRIClipRectPtr pExtents = NULL; + GLint xx, yy; + GLint x0, y0, width0, height0; + + ENGPACKET stEngPacket; + + /* Clear back buffer */ + if (mask & DD_BACK_LEFT_BIT) { + smesa->cbClearPacket.stdwDestPos.wY = y; + smesa->cbClearPacket.stdwDestPos.wX = x; + smesa->cbClearPacket.stdwDim.wWidth = (GLshort) width; + smesa->cbClearPacket.stdwDim.wHeight = (GLshort) height; + smesa->cbClearPacket.dwFgRopColor = smesa->clearColorPattern; + + sis_bitblt_clear_cmd( smesa, &smesa->cbClearPacket ); + } + + if ((mask & DD_FRONT_LEFT_BIT) == 0) + return; + + /* Clear front buffer */ + x0 = x; + y0 = y; + width0 = width; + height0 = height; + + pExtents = smesa->driDrawable->pClipRects; + count = smesa->driDrawable->numClipRects; + + memset( &stEngPacket, 0, sizeof (ENGPACKET) ); + + stEngPacket.dwSrcPitch = (depth == 2) ? 0x80000000 : 0xc0000000; + stEngPacket.dwDestBaseAddr = smesa->frontOffset; + stEngPacket.wDestPitch = smesa->frontPitch; + /* TODO: set maximum value? */ + stEngPacket.wDestHeight = smesa->virtualY; + stEngPacket.stdwCmd.cRop = 0xf0; + stEngPacket.dwFgRopColor = smesa->clearColorPattern; + + /* for SGRAM Block Write Enable */ + if (smesa->blockWrite) + stEngPacket.stdwCmd.cCmd0 = CMD0_PAT_FG_COLOR; + else + stEngPacket.stdwCmd.cCmd0 = 0; + stEngPacket.stdwCmd.cCmd1 = CMD1_DIR_X_INC | CMD1_DIR_Y_INC; + + while (count--) { + GLint x2 = pExtents->x1 - smesa->driDrawable->x; + GLint y2 = pExtents->y1 - smesa->driDrawable->y; + GLint xx2 = pExtents->x2 - smesa->driDrawable->x; + GLint yy2 = pExtents->y2 - smesa->driDrawable->y; + + x = (x0 > x2) ? x0 : x2; + y = (y0 > y2) ? y0 : y2; + xx = ((x0 + width0) > (xx2)) ? xx2 : x0 + width0; + yy = ((y0 + height0) > (yy2)) ? yy2 : y0 + height0; + width = xx - x; + height = yy - y; + pExtents++; + + if (width <= 0 || height <= 0) + continue; + + stEngPacket.stdwDestPos.wY = y; + stEngPacket.stdwDestPos.wX = x; + stEngPacket.stdwDim.wWidth = (GLshort)width; + stEngPacket.stdwDim.wHeight = (GLshort)height; + + sis_bitblt_clear_cmd( smesa, &stEngPacket ); + } +} + +static void +sis_clear_z_stencil_buffer( GLcontext * ctx, GLbitfield mask, + GLint x, GLint y, GLint width, GLint height ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + /* TODO: check write mask */ + + if ( smesa->depthbuffer == NULL ) + return; + + /* TODO: consider alignment of width, height? */ + smesa->zClearPacket.stdwDestPos.wY = y; + smesa->zClearPacket.stdwDestPos.wX = x; + smesa->zClearPacket.stdwDim.wWidth = (GLshort) width; + smesa->zClearPacket.stdwDim.wHeight = (GLshort) height; + smesa->zClearPacket.dwFgRopColor = smesa->clearZStencilPattern; + + sis_bitblt_clear_cmd( smesa, &smesa->zClearPacket ); +} + |