📄 fxdd.c
字号:
/* * Mesa 3-D graphics library * Version: 5.1 * * Copyright (C) 1999-2003 Brian Paul 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 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL * BRIAN PAUL 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. *//* Authors: * David Bucciarelli * Brian Paul * Daryll Strauss * Keith Whitwell * Daniel Borca * Hiroshi Morii *//* fxdd.c - 3Dfx VooDoo Mesa device driver functions */#ifdef HAVE_CONFIG_H#include "conf.h"#endif#if defined(FX)#include "image.h"#include "mtypes.h"#include "fxdrv.h"#include "buffers.h"#include "enums.h"#include "extensions.h"#include "macros.h"#include "texstore.h"#include "teximage.h"#include "swrast/swrast.h"#include "swrast/s_context.h"#include "swrast_setup/swrast_setup.h"#include "tnl/tnl.h"#include "tnl/t_context.h"#include "tnl/t_pipeline.h"#include "vbo/vbo.h"/* lookup table for scaling 4 bit colors up to 8 bits */GLuint FX_rgb_scale_4[16] = { 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};/* lookup table for scaling 5 bit colors up to 8 bits */GLuint FX_rgb_scale_5[32] = { 0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140, 148, 156, 165, 173, 181, 189, 197, 206, 214, 222, 230, 239, 247, 255};/* lookup table for scaling 6 bit colors up to 8 bits */GLuint FX_rgb_scale_6[64] = { 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138, 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255};/* * Disable color by masking out R, G, B, A */static void fxDisableColor (fxMesaContext fxMesa){ if (fxMesa->colDepth == 32) { /* 32bpp mode */ fxMesa->Glide.grColorMaskExt(FXFALSE, FXFALSE, FXFALSE, FXFALSE); } else { /* 15/16 bpp mode */ grColorMask(FXFALSE, FXFALSE); }}/**********************************************************************//***** Miscellaneous functions *****//**********************************************************************//* Return buffer size information */static voidfxDDGetBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height){ GET_CURRENT_CONTEXT(ctx); if (ctx && FX_CONTEXT(ctx)) { fxMesaContext fxMesa = FX_CONTEXT(ctx); if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxDDGetBufferSize(...)\n"); } *width = fxMesa->width; *height = fxMesa->height; }}/** * We only implement this function as a mechanism to check if the * framebuffer size has changed (and update corresponding state). */static voidfxDDViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h){ GLuint newWidth, newHeight; GLframebuffer *buffer = ctx->WinSysDrawBuffer; fxDDGetBufferSize( buffer, &newWidth, &newHeight ); if (buffer->Width != newWidth || buffer->Height != newHeight) { _mesa_resize_framebuffer(ctx, buffer, newWidth, newHeight ); }}/* Implements glClearColor() */static voidfxDDClearColor(GLcontext * ctx, const GLfloat color[4]){ fxMesaContext fxMesa = FX_CONTEXT(ctx); GLubyte col[4]; if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxDDClearColor(%f, %f, %f, %f)\n", color[0], color[1], color[2], color[3]); } CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]); CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]); CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]); CLAMPED_FLOAT_TO_UBYTE(col[3], color[3]); fxMesa->clearC = FXCOLOR4(col); fxMesa->clearA = col[3];}/* Clear the color and/or depth buffers */static void fxDDClear( GLcontext *ctx, GLbitfield mask ){ fxMesaContext fxMesa = FX_CONTEXT(ctx); GLbitfield softwareMask = mask & (BUFFER_BIT_ACCUM); const GLuint stencil_size = fxMesa->haveHwStencil ? ctx->Visual.stencilBits : 0; const FxU32 clearD = (FxU32) (ctx->DrawBuffer->_DepthMaxF * ctx->Depth.Clear); const FxU8 clearS = (FxU8) (ctx->Stencil.Clear & 0xff); if ( TDFX_DEBUG & MESA_VERBOSE ) { fprintf( stderr, "fxDDClear\n"); } /* we can't clear accum buffers nor stereo */ mask &= ~(BUFFER_BIT_ACCUM | BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT); /* Need this check to respond to certain HW updates */ if (fxMesa->new_state & (FX_NEW_SCISSOR | FX_NEW_COLOR_MASK)) { fxSetupScissor(ctx); fxSetupColorMask(ctx); fxMesa->new_state &= ~(FX_NEW_SCISSOR | FX_NEW_COLOR_MASK); } /* * As per GL spec, color masking should be obeyed when clearing */ if (ctx->Visual.greenBits != 8) { /* can only do color masking if running in 24/32bpp on Napalm */ if (ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP] || ctx->Color.ColorMask[GCOMP] != ctx->Color.ColorMask[BCOMP]) { softwareMask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)); mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT); } } if (fxMesa->haveHwStencil) { /* * If we want to clear stencil, it must be enabled * in the HW, even if the stencil test is not enabled * in the OGL state. */ BEGIN_BOARD_LOCK(); if (mask & BUFFER_BIT_STENCIL) { fxMesa->Glide.grStencilMaskExt(fxMesa->unitsState.stencilWriteMask); /* set stencil ref value = desired clear value */ fxMesa->Glide.grStencilFuncExt(GR_CMP_ALWAYS, clearS, 0xff); fxMesa->Glide.grStencilOpExt(GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE); grEnable(GR_STENCIL_MODE_EXT); } else { grDisable(GR_STENCIL_MODE_EXT); } END_BOARD_LOCK(); } else if (mask & BUFFER_BIT_STENCIL) { softwareMask |= (mask & (BUFFER_BIT_STENCIL)); mask &= ~(BUFFER_BIT_STENCIL); } /* * This may be ugly, but it's needed in order to work around a number * of Glide bugs. */ BEGIN_CLIP_LOOP(); { /* * This could probably be done fancier but doing each possible case * explicitly is less error prone. */ switch (mask & ~BUFFER_BIT_STENCIL) { case BUFFER_BIT_BACK_LEFT | BUFFER_BIT_DEPTH: /* back buffer & depth */ grDepthMask(FXTRUE); grRenderBuffer(GR_BUFFER_BACKBUFFER); if (stencil_size > 0) { fxMesa->Glide.grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); } else grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); break; case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_DEPTH: /* XXX it appears that the depth buffer isn't cleared when * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set. * This is a work-around/ */ /* clear depth */ grDepthMask(FXTRUE); fxDisableColor(fxMesa); grRenderBuffer(GR_BUFFER_BACKBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); else grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); fxSetupColorMask(ctx); grDepthMask(FXFALSE); /* clear front */ grRenderBuffer(GR_BUFFER_FRONTBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); else grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); break; case BUFFER_BIT_BACK_LEFT: /* back buffer only */ grDepthMask(FXFALSE); grRenderBuffer(GR_BUFFER_BACKBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); else grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); break; case BUFFER_BIT_FRONT_LEFT: /* front buffer only */ grDepthMask(FXFALSE); grRenderBuffer(GR_BUFFER_FRONTBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); else grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); break; case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT: /* front and back */ grDepthMask(FXFALSE); grRenderBuffer(GR_BUFFER_BACKBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); else grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); grRenderBuffer(GR_BUFFER_FRONTBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); else grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); break; case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT | BUFFER_BIT_DEPTH: /* clear back and depth */ grDepthMask(FXTRUE); grRenderBuffer(GR_BUFFER_BACKBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); else grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); /* clear front */ grDepthMask(FXFALSE); grRenderBuffer(GR_BUFFER_FRONTBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); else grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); break; case BUFFER_BIT_DEPTH: /* just the depth buffer */ grDepthMask(FXTRUE); fxDisableColor(fxMesa); grRenderBuffer(GR_BUFFER_BACKBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); else grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); fxSetupColorMask(ctx); break; default: /* clear no color buffers or depth buffer but might clear stencil */ if ((stencil_size > 0) && (mask & BUFFER_BIT_STENCIL)) { /* XXX need this RenderBuffer call to work around Glide bug */ grDepthMask(FXFALSE); grRenderBuffer(GR_BUFFER_BACKBUFFER); fxDisableColor(fxMesa); fxMesa->Glide.grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); fxSetupColorMask(ctx); } } } END_CLIP_LOOP(); if (fxMesa->haveHwStencil) { /* We changed the stencil state above. Restore it! */ fxSetupStencil(ctx); } fxSetupDepthTest(ctx); grRenderBuffer(fxMesa->currentFB); if (softwareMask) _swrast_Clear( ctx, softwareMask );}/* Set the buffer used for drawing *//* XXX support for separate read/draw buffers hasn't been tested *//* XXX GL_NONE disables color, but fails to correctly maintain state */static voidfxDDSetDrawBuffer(GLcontext * ctx, GLenum mode){ fxMesaContext fxMesa = FX_CONTEXT(ctx); if (TDFX_DEBUG & VERBOSE_DRIVER) { fprintf(stderr, "fxDDSetDrawBuffer(%x)\n", (int)mode); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -