📄 tdfx_render.c
字号:
/* -*- mode: c; c-basic-offset: 3 -*- * * Copyright 2000 VA Linux Systems Inc., Fremont, California. * * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL * VA LINUX SYSTEMS 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/tdfx/tdfx_render.c,v 1.4 2002/02/22 21:45:03 dawes Exp $ *//* * New fixes: * Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004 * * Original rewrite: * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 * * Authors: * Gareth Hughes <gareth@valinux.com> * Brian Paul <brianp@valinux.com> * */#include "tdfx_context.h"#include "tdfx_render.h"#include "tdfx_state.h"#include "tdfx_texman.h"#include "swrast/swrast.h"/* Clear the color and/or depth buffers. */static void tdfxClear( GLcontext *ctx, GLbitfield mask ){ tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx; GLbitfield softwareMask = mask & (BUFFER_BIT_ACCUM); const GLuint stencil_size = fxMesa->haveHwStencil ? fxMesa->glCtx->Visual.stencilBits : 0; if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "tdfxClear(0x%x)\n", mask); } /* Need this check to respond to glScissor and clipping updates */ if ((fxMesa->new_state & (TDFX_NEW_CLIP | TDFX_NEW_DEPTH)) || (fxMesa->dirty & TDFX_UPLOAD_COLOR_MASK)) { tdfxDDUpdateHwState(ctx); } /* we can't clear accum buffers */ mask &= ~(BUFFER_BIT_ACCUM); if (mask & BUFFER_BIT_STENCIL) { if (!fxMesa->haveHwStencil || (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { /* Napalm seems to have trouble with stencil write masks != 0xff */ /* do stencil clear in software */ mask &= ~(BUFFER_BIT_STENCIL); softwareMask |= BUFFER_BIT_STENCIL; } } if (fxMesa->glCtx->Visual.redBits != 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. */ LOCK_HARDWARE(fxMesa); if (mask & BUFFER_BIT_STENCIL) { fxMesa->Glide.grStencilMask(/*ctx->Stencil.WriteMask*/ 0xff); /* set stencil ref value = desired clear value */ fxMesa->Glide.grStencilFunc(GR_CMP_ALWAYS, (fxMesa->Stencil.Clear & 0xff), 0xff); fxMesa->Glide.grStencilOp(GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE); fxMesa->Glide.grEnable(GR_STENCIL_MODE_EXT); } else { fxMesa->Glide.grDisable(GR_STENCIL_MODE_EXT); } UNLOCK_HARDWARE(fxMesa); } /* * This may be ugly, but it's needed in order to work around a number * of Glide bugs. */ BEGIN_CLIP_LOOP(fxMesa); { /* * 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 */ FX_grColorMaskv_NoLock(ctx, true4); /* work around Voodoo3 bug */ fxMesa->Glide.grDepthMask(FXTRUE); fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER); if (stencil_size > 0) { fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear, (FxU32) (ctx->Stencil.Clear & 0xff)); } else fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear); if (!ctx->Depth.Mask || !ctx->Depth.Test) { fxMesa->Glide.grDepthMask(FXFALSE); } 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 */ fxMesa->Glide.grDepthMask(FXTRUE); fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER); FX_grColorMaskv_NoLock(ctx, false4); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear, (FxU32) (ctx->Stencil.Clear & 0xff)); else fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear & 0xff); /* clear front */ FX_grColorMaskv_NoLock(ctx, true4); fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear, (FxU32) (ctx->Stencil.Clear & 0xff)); else fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear); if (!ctx->Depth.Mask || !ctx->Depth.Test) { fxMesa->Glide.grDepthMask(FXFALSE); } break; case BUFFER_BIT_BACK_LEFT: /* back buffer only */ fxMesa->Glide.grDepthMask(FXFALSE); fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear, (FxU32) (ctx->Stencil.Clear & 0xff)); else fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear); if (ctx->Depth.Mask && ctx->Depth.Test) { fxMesa->Glide.grDepthMask(FXTRUE); } break; case BUFFER_BIT_FRONT_LEFT: /* front buffer only */ fxMesa->Glide.grDepthMask(FXFALSE); fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear, (FxU32) (ctx->Stencil.Clear & 0xff)); else fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear); if (ctx->Depth.Mask && ctx->Depth.Test) { fxMesa->Glide.grDepthMask(FXTRUE); } break; case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT: /* front and back */ fxMesa->Glide.grDepthMask(FXFALSE); fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear, (FxU32) (ctx->Stencil.Clear & 0xff)); else fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear); fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear, (FxU32) (ctx->Stencil.Clear & 0xff)); else fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear); if (ctx->Depth.Mask && ctx->Depth.Test) { fxMesa->Glide.grDepthMask(FXTRUE); } break; case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT | BUFFER_BIT_DEPTH: /* clear front */ fxMesa->Glide.grDepthMask(FXFALSE); fxMesa->Glide.grRenderBuffer(GR_BUFFER_FRONTBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear, (FxU32) (ctx->Stencil.Clear & 0xff)); else fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear); /* clear back and depth */ fxMesa->Glide.grDepthMask(FXTRUE); fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear, (FxU32) (ctx->Stencil.Clear & 0xff)); else fxMesa->Glide.grBufferClear(fxMesa->Color.ClearColor, fxMesa->Color.ClearAlpha, fxMesa->Depth.Clear); if (!ctx->Depth.Mask || !ctx->Depth.Mask) { fxMesa->Glide.grDepthMask(FXFALSE); } break; case BUFFER_BIT_DEPTH: /* just the depth buffer */ fxMesa->Glide.grRenderBuffer(GR_BUFFER_BACKBUFFER); FX_grColorMaskv_NoLock(ctx, false4); fxMesa->Glide.grDepthMask(FXTRUE); if (stencil_size > 0) fxMesa->Glide.grBufferClearExt(fxMesa->Color.ClearColor,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -