diff options
author | Keith Whitwell <[email protected]> | 2000-10-31 18:00:04 +0000 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2000-10-31 18:00:04 +0000 |
commit | e3a051e0538a605551f4d58294c94f5eb00ed07f (patch) | |
tree | ea5ccfd6d578fee1f8adb5a5c7f34f12d601c1c9 /src/mesa/swrast/s_buffers.c | |
parent | 6e0f0f51e0371688a434ed65c4ae0da1b061a4b5 (diff) |
Moved software rasterizer functionality to new directory.
Diffstat (limited to 'src/mesa/swrast/s_buffers.c')
-rw-r--r-- | src/mesa/swrast/s_buffers.c | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/src/mesa/swrast/s_buffers.c b/src/mesa/swrast/s_buffers.c new file mode 100644 index 00000000000..b62198f091e --- /dev/null +++ b/src/mesa/swrast/s_buffers.c @@ -0,0 +1,257 @@ +/* $Id: s_buffers.c,v 1.1 2000/10/31 18:00:04 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2000 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. + */ + + +#include "glheader.h" +#include "macros.h" +#include "mem.h" + +#include "s_accum.h" +#include "s_alphabuf.h" +#include "s_depth.h" +#include "s_masking.h" +#include "s_stencil.h" + + + + +/* + * Clear the color buffer when glColorMask or glIndexMask is in effect. + */ +static void +clear_color_buffer_with_masking( GLcontext *ctx ) +{ + const GLint x = ctx->DrawBuffer->Xmin; + const GLint y = ctx->DrawBuffer->Ymin; + const GLint height = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin; + const GLint width = ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin; + + if (ctx->Visual.RGBAflag) { + /* RGBA mode */ + const GLchan r = (GLint) (ctx->Color.ClearColor[0] * CHAN_MAXF); + const GLchan g = (GLint) (ctx->Color.ClearColor[1] * CHAN_MAXF); + const GLchan b = (GLint) (ctx->Color.ClearColor[2] * CHAN_MAXF); + const GLchan a = (GLint) (ctx->Color.ClearColor[3] * CHAN_MAXF); + GLint i; + for (i = 0; i < height; i++) { + GLchan rgba[MAX_WIDTH][4]; + GLint j; + for (j=0; j<width; j++) { + rgba[j][RCOMP] = r; + rgba[j][GCOMP] = g; + rgba[j][BCOMP] = b; + rgba[j][ACOMP] = a; + } + _mesa_mask_rgba_span( ctx, width, x, y + i, rgba ); + (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y + i, + (CONST GLchan (*)[4]) rgba, NULL ); + } + } + else { + /* Color index mode */ + GLuint span[MAX_WIDTH]; + GLubyte mask[MAX_WIDTH]; + GLint i, j; + MEMSET( mask, 1, width ); + for (i=0;i<height;i++) { + for (j=0;j<width;j++) { + span[j] = ctx->Color.ClearIndex; + } + _mesa_mask_index_span( ctx, width, x, y + i, span ); + (*ctx->Driver.WriteCI32Span)( ctx, width, x, y + i, span, mask ); + } + } +} + + + +/* + * Clear a color buffer without index/channel masking. + */ +static void +clear_color_buffer(GLcontext *ctx) +{ + const GLint x = ctx->DrawBuffer->Xmin; + const GLint y = ctx->DrawBuffer->Ymin; + const GLint height = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin; + const GLint width = ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin; + + if (ctx->Visual.RGBAflag) { + /* RGBA mode */ + const GLchan r = (GLint) (ctx->Color.ClearColor[0] * CHAN_MAXF); + const GLchan g = (GLint) (ctx->Color.ClearColor[1] * CHAN_MAXF); + const GLchan b = (GLint) (ctx->Color.ClearColor[2] * CHAN_MAXF); + const GLchan a = (GLint) (ctx->Color.ClearColor[3] * CHAN_MAXF); + GLchan span[MAX_WIDTH][4]; + GLint i; + + ASSERT(*((GLuint *) &ctx->Color.ColorMask) == 0xffffffff); + + for (i = 0; i < width; i++) { + span[i][RCOMP] = r; + span[i][GCOMP] = g; + span[i][BCOMP] = b; + span[i][ACOMP] = a; + } + for (i = 0; i < height; i++) { + (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y + i, + (CONST GLchan (*)[4]) span, NULL ); + } + } + else { + /* Color index mode */ + ASSERT(ctx->Color.IndexMask == ~0); + if (ctx->Visual.IndexBits == 8) { + /* 8-bit clear */ + GLubyte span[MAX_WIDTH]; + GLint i; + MEMSET(span, ctx->Color.ClearIndex, width); + for (i = 0; i < height; i++) { + (*ctx->Driver.WriteCI8Span)( ctx, width, x, y + i, span, NULL ); + } + } + else { + /* non 8-bit clear */ + GLuint span[MAX_WIDTH]; + GLint i; + for (i = 0; i < width; i++) { + span[i] = ctx->Color.ClearIndex; + } + for (i = 0; i < height; i++) { + (*ctx->Driver.WriteCI32Span)( ctx, width, x, y + i, span, NULL ); + } + } + } +} + + + +/* + * Clear the front/back/left/right color buffers. + * This function is usually only called if we need to clear the + * buffers with masking. + */ +static void +clear_color_buffers(GLcontext *ctx) +{ + const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); + GLuint bufferBit; + + /* loop over four possible dest color buffers */ + for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) { + if (bufferBit & ctx->Color.DrawDestMask) { + if (bufferBit == FRONT_LEFT_BIT) { + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT); + (void) (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_FRONT_LEFT); + } + else if (bufferBit == FRONT_RIGHT_BIT) { + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT); + (void) (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_FRONT_RIGHT); + } + else if (bufferBit == BACK_LEFT_BIT) { + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT); + (void) (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_BACK_LEFT); + } + else { + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT); + (void) (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_BACK_RIGHT); + } + + if (colorMask != 0xffffffff) { + clear_color_buffer_with_masking(ctx); + } + else { + clear_color_buffer(ctx); + } + } + } + + /* restore default read/draw buffers */ + (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer ); + (void) (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer ); +} + + + +void +_swrast_Clear( GLcontext *ctx, GLbitfield mask, + GLboolean all, + GLint x, GLint y, GLint width, GLint height ) +{ + +#ifdef DEBUG + { + GLbitfield legalBits = DD_FRONT_LEFT_BIT | + DD_FRONT_RIGHT_BIT | + DD_BACK_LEFT_BIT | + DD_BACK_RIGHT_BIT | + DD_DEPTH_BIT | + DD_STENCIL_BIT | + DD_ACCUM_BIT; + assert((mask & (~legalBits)) == 0); + } +#endif + + RENDER_START(ctx); + + /* do software clearing here */ + if (mask) { + if (mask & ctx->Color.DrawDestMask) clear_color_buffers(ctx); + if (mask & GL_DEPTH_BUFFER_BIT) _mesa_clear_depth_buffer(ctx); + if (mask & GL_ACCUM_BUFFER_BIT) _mesa_clear_accum_buffer(ctx); + if (mask & GL_STENCIL_BUFFER_BIT) _mesa_clear_stencil_buffer(ctx); + } + + /* clear software-based alpha buffer(s) */ + if ( (mask & GL_COLOR_BUFFER_BIT) + && ctx->DrawBuffer->UseSoftwareAlphaBuffers + && ctx->Color.ColorMask[ACOMP]) { + _mesa_clear_alpha_buffers( ctx ); + } + + RENDER_FINISH(ctx); +} + + +void +_swrast_alloc_buffers( GLcontext *ctx ) +{ + /* Reallocate other buffers if needed. */ + if (ctx->DrawBuffer->UseSoftwareDepthBuffer) { + _mesa_alloc_depth_buffer( ctx ); + } + if (ctx->DrawBuffer->UseSoftwareStencilBuffer) { + _mesa_alloc_stencil_buffer( ctx ); + } + if (ctx->DrawBuffer->UseSoftwareAccumBuffer) { + _mesa_alloc_accum_buffer( ctx ); + } + if (ctx->DrawBuffer->UseSoftwareAlphaBuffers) { + _mesa_alloc_alpha_buffers( ctx ); + } +} + + |