From 894844a8d956a0ee5f95836331dc318f49fdb845 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 21 Mar 2004 17:05:03 +0000 Subject: Implemented support for software-based AUX color buffers. Only available with Xlib driver for now. Assorted clean-ups related to Draw/ReadBuffer(). Renamed FRONT_LEFT_BIT -> DD_FRONT_LEFT_BIT, etc. --- src/mesa/swrast/s_alphabuf.c | 16 +++--- src/mesa/swrast/s_auxbuffer.c | 121 ++++++++++++++++++++++++++++++++++++++++++ src/mesa/swrast/s_auxbuffer.h | 41 ++++++++++++++ src/mesa/swrast/s_buffers.c | 109 ++++++++++++++++++++++++------------- src/mesa/swrast/s_context.c | 9 ++-- src/mesa/swrast/s_context.h | 3 +- src/mesa/swrast/s_span.c | 4 +- src/mesa/swrast/swrast.h | 16 +++--- 8 files changed, 256 insertions(+), 63 deletions(-) create mode 100644 src/mesa/swrast/s_auxbuffer.c create mode 100644 src/mesa/swrast/s_auxbuffer.h (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_alphabuf.c b/src/mesa/swrast/s_alphabuf.c index e0468a4c91..b563baf39a 100644 --- a/src/mesa/swrast/s_alphabuf.c +++ b/src/mesa/swrast/s_alphabuf.c @@ -114,13 +114,13 @@ _swrast_clear_alpha_buffers( GLcontext *ctx ) for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) { if (bufferBit & ctx->Color._DrawDestMask) { GLchan *buffer; - if (bufferBit == FRONT_LEFT_BIT) { + if (bufferBit == DD_FRONT_LEFT_BIT) { buffer = ctx->DrawBuffer->FrontLeftAlpha; } - else if (bufferBit == FRONT_RIGHT_BIT) { + else if (bufferBit == DD_FRONT_RIGHT_BIT) { buffer = ctx->DrawBuffer->FrontRightAlpha; } - else if (bufferBit == BACK_LEFT_BIT) { + else if (bufferBit == DD_BACK_LEFT_BIT) { buffer = ctx->DrawBuffer->BackLeftAlpha; } else { @@ -175,17 +175,17 @@ GLchan *get_alpha_buffer( GLcontext *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); - switch (swrast->CurrentBuffer) { - case FRONT_LEFT_BIT: + switch (swrast->CurrentBufferBit) { + case DD_FRONT_LEFT_BIT: return ctx->DrawBuffer->FrontLeftAlpha; break; - case BACK_LEFT_BIT: + case DD_BACK_LEFT_BIT: return ctx->DrawBuffer->BackLeftAlpha; break; - case FRONT_RIGHT_BIT: + case DD_FRONT_RIGHT_BIT: return ctx->DrawBuffer->FrontRightAlpha; break; - case BACK_RIGHT_BIT: + case DD_BACK_RIGHT_BIT: return ctx->DrawBuffer->BackRightAlpha; break; default: diff --git a/src/mesa/swrast/s_auxbuffer.c b/src/mesa/swrast/s_auxbuffer.c new file mode 100644 index 0000000000..ca36d90ded --- /dev/null +++ b/src/mesa/swrast/s_auxbuffer.c @@ -0,0 +1,121 @@ +/* + * Mesa 3-D graphics library + * Version: 6.1 + * + * Copyright (C) 1999-2004 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 "imports.h" + +#include "s_auxbuffer.h" +#include "s_context.h" + + + +void +_swrast_alloc_aux_buffers( GLframebuffer *buffer ) +{ + GLuint i; + + for (i = 0; i < buffer->Visual.numAuxBuffers; i++) { + if (buffer->AuxBuffers[i]) { + _mesa_free(buffer->AuxBuffers[i]); + buffer->AuxBuffers[i] = NULL; + } + + buffer->AuxBuffers[i] = _mesa_malloc(buffer->Width * buffer->Height + * 4 * sizeof(GLchan)); + } +} + + + +/* RGBA */ +#define NAME(PREFIX) PREFIX##_aux +#define SPAN_VARS \ + const SWcontext *swrast = SWRAST_CONTEXT(ctx); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLchan *P = swrast->CurAuxBuffer + ((Y) * ctx->DrawBuffer->Width + (X)) * 4; \ + assert(swrast->CurAuxBuffer); + +#define INC_PIXEL_PTR(P) P += 4 +#if CHAN_TYPE == GL_FLOAT +#define STORE_RGB_PIXEL(P, X, Y, R, G, B) \ + P[0] = MAX2((R), 0.0F); \ + P[1] = MAX2((G), 0.0F); \ + P[2] = MAX2((B), 0.0F); \ + P[3] = CHAN_MAXF +#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \ + P[0] = MAX2((R), 0.0F); \ + P[1] = MAX2((G), 0.0F); \ + P[2] = MAX2((B), 0.0F); \ + P[3] = CLAMP((A), 0.0F, CHAN_MAXF) +#else +#define STORE_RGB_PIXEL(P, X, Y, R, G, B) \ + P[0] = R; P[1] = G; P[2] = B; P[3] = CHAN_MAX +#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \ + P[0] = R; P[1] = G; P[2] = B; P[3] = A +#endif +#define FETCH_RGBA_PIXEL(R, G, B, A, P) \ + R = P[0]; G = P[1]; B = P[2]; A = P[3] +#include "swrast/s_spantemp.h" + + + +/** + * Called from driver's SetBuffer() function to choose an aux buffer. + */ +void +_swrast_use_aux_buffer(GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + switch (bufferBit) { + case DD_AUX0_BIT: + ASSERT(buffer->Visual.numAuxBuffers >= 1); + swrast->CurAuxBuffer = ctx->DrawBuffer->AuxBuffers[0]; + break; + case DD_AUX1_BIT: + ASSERT(buffer->Visual.numAuxBuffers >= 2); + swrast->CurAuxBuffer = ctx->DrawBuffer->AuxBuffers[1]; + break; + case DD_AUX2_BIT: + ASSERT(buffer->Visual.numAuxBuffers >= 3); + swrast->CurAuxBuffer = ctx->DrawBuffer->AuxBuffers[2]; + break; + case DD_AUX3_BIT: + ASSERT(buffer->Visual.numAuxBuffers >= 4); + swrast->CurAuxBuffer = ctx->DrawBuffer->AuxBuffers[3]; + break; + default: + swrast->CurAuxBuffer = NULL; + } + + swrast->Driver.WriteRGBASpan = write_rgba_span_aux; + swrast->Driver.WriteRGBSpan = write_rgb_span_aux; + swrast->Driver.WriteMonoRGBASpan = write_monorgba_span_aux; + swrast->Driver.WriteRGBAPixels = write_rgba_pixels_aux; + swrast->Driver.WriteMonoRGBAPixels = write_monorgba_pixels_aux; + swrast->Driver.ReadRGBASpan = read_rgba_span_aux; + swrast->Driver.ReadRGBAPixels = read_rgba_pixels_aux; +} + diff --git a/src/mesa/swrast/s_auxbuffer.h b/src/mesa/swrast/s_auxbuffer.h new file mode 100644 index 0000000000..48fb6951a1 --- /dev/null +++ b/src/mesa/swrast/s_auxbuffer.h @@ -0,0 +1,41 @@ +/* + * Mesa 3-D graphics library + * Version: 6.1 + * + * Copyright (C) 1999-2004 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. + */ + + +#ifndef S_AUXBUFFER_H +#define S_AUXBUFFER_H + + +#include "context.h" + + +extern void +_swrast_alloc_aux_buffers( GLframebuffer *buffer ); + + +extern void +_swrast_use_aux_buffer(GLcontext *ctx, GLframebuffer *buffr, GLuint bufferBit); + + +#endif /* S_AUXBUFFER_H */ diff --git a/src/mesa/swrast/s_buffers.c b/src/mesa/swrast/s_buffers.c index 894cc4060f..7888bb618f 100644 --- a/src/mesa/swrast/s_buffers.c +++ b/src/mesa/swrast/s_buffers.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.0.1 + * Version: 6.1 * * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. * @@ -30,16 +30,17 @@ #include "s_accum.h" #include "s_alphabuf.h" +#include "s_auxbuffer.h" #include "s_context.h" #include "s_depth.h" #include "s_masking.h" #include "s_stencil.h" - - -/* +/** * Clear the color buffer when glColorMask or glIndexMask is in effect. + * We'll have specified which color buffer to clear by previously + * calling Driver.SetBuffer(). */ static void clear_color_buffer_with_masking( GLcontext *ctx ) @@ -86,9 +87,10 @@ clear_color_buffer_with_masking( GLcontext *ctx ) } - -/* +/** * Clear a color buffer without index/channel masking. + * We'll have specified which color buffer to clear by previously + * calling Driver.SetBuffer(). */ static void clear_color_buffer(GLcontext *ctx) @@ -131,11 +133,10 @@ clear_color_buffer(GLcontext *ctx) } - -/* - * Clear the front/back/left/right color buffers. - * This function is usually only called if we need to clear the - * buffers with masking. +/** + * Clear the front/back/left/right/aux color buffers. + * This function is usually only called if the device driver can't + * clear its own color buffers for some reason (such as with masking). */ static void clear_color_buffers(GLcontext *ctx) @@ -145,7 +146,7 @@ clear_color_buffers(GLcontext *ctx) GLuint bufferBit; /* loop over four possible dest color buffers */ - for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) { + for (bufferBit = 1; bufferBit <= DD_AUX3_BIT; bufferBit <<= 1) { if (bufferBit & ctx->Color._DrawDestMask) { (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit); @@ -163,7 +164,12 @@ clear_color_buffers(GLcontext *ctx) } - +/** + * Called via the device driver's ctx->Driver.Clear() function if the + * device driver can't clear one or more of the buffers itself. + * \param mask bitwise-OR of DD_*_BIT flags. + * \param all if GL_TRUE, clear whole buffer, else clear specified region. + */ void _swrast_Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, @@ -172,13 +178,18 @@ _swrast_Clear( GLcontext *ctx, GLbitfield mask, SWcontext *swrast = SWRAST_CONTEXT(ctx); #ifdef DEBUG { - GLbitfield legalBits = DD_FRONT_LEFT_BIT | + const 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; + DD_ACCUM_BIT | + DD_AUX0_BIT | + DD_AUX1_BIT | + DD_AUX2_BIT | + DD_AUX3_BIT; assert((mask & (~legalBits)) == 0); } #endif @@ -187,23 +198,34 @@ _swrast_Clear( GLcontext *ctx, GLbitfield mask, /* do software clearing here */ if (mask) { - if (mask & ctx->Color._DrawDestMask) clear_color_buffers(ctx); - if (mask & GL_DEPTH_BUFFER_BIT) _swrast_clear_depth_buffer(ctx); - if (mask & GL_ACCUM_BUFFER_BIT) _swrast_clear_accum_buffer(ctx); - if (mask & GL_STENCIL_BUFFER_BIT) _swrast_clear_stencil_buffer(ctx); - } - - /* clear software-based alpha buffer(s) */ - if ( (mask & GL_COLOR_BUFFER_BIT) - && ctx->DrawBuffer->UseSoftwareAlphaBuffers - && ctx->Color.ColorMask[ACOMP]) { - _swrast_clear_alpha_buffers( ctx ); + if (mask & ctx->Color._DrawDestMask) { + clear_color_buffers(ctx); + /* clear software-based alpha buffer(s) */ + if (ctx->DrawBuffer->UseSoftwareAlphaBuffers + && ctx->Color.ColorMask[ACOMP]) { + _swrast_clear_alpha_buffers( ctx ); + } + } + if (mask & DD_DEPTH_BIT) { + _swrast_clear_depth_buffer(ctx); + } + if (mask & DD_ACCUM_BIT) { + _swrast_clear_accum_buffer(ctx); + } + if (mask & DD_STENCIL_BIT) { + _swrast_clear_stencil_buffer(ctx); + } } RENDER_FINISH(swrast,ctx); } +/** + * Typically called via ctx->Driver.ResizeBuffers(). + * Reallocate all software-based depth/stencil/accum/etc buffers + * to match current window dimensions. + */ void _swrast_alloc_buffers( GLframebuffer *buffer ) { @@ -220,6 +242,9 @@ _swrast_alloc_buffers( GLframebuffer *buffer ) if (buffer->UseSoftwareAlphaBuffers) { _swrast_alloc_alpha_buffers( buffer ); } + if (buffer->UseSoftwareAuxBuffers) { + _swrast_alloc_aux_buffers( buffer ); + } } @@ -244,9 +269,9 @@ _swrast_use_read_buffer( GLcontext *ctx ) SWcontext *swrast = SWRAST_CONTEXT(ctx); /* Do this so the software-emulated alpha plane span functions work! */ - swrast->CurrentBuffer = ctx->Pixel._ReadSrcMask; + swrast->CurrentBufferBit = ctx->Pixel._ReadSrcMask; /* Tell the device driver where to read/write spans */ - (*swrast->Driver.SetBuffer)( ctx, ctx->ReadBuffer, swrast->CurrentBuffer ); + swrast->Driver.SetBuffer(ctx, ctx->ReadBuffer, swrast->CurrentBufferBit); } @@ -270,17 +295,25 @@ _swrast_use_draw_buffer( GLcontext *ctx ) * we loop over multiple color buffers when needed. */ - if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT) - swrast->CurrentBuffer = FRONT_LEFT_BIT; - else if (ctx->Color._DrawDestMask & BACK_LEFT_BIT) - swrast->CurrentBuffer = BACK_LEFT_BIT; - else if (ctx->Color._DrawDestMask & FRONT_RIGHT_BIT) - swrast->CurrentBuffer = FRONT_RIGHT_BIT; - else if (ctx->Color._DrawDestMask & BACK_RIGHT_BIT) - swrast->CurrentBuffer = BACK_RIGHT_BIT; + if (ctx->Color._DrawDestMask & DD_FRONT_LEFT_BIT) + swrast->CurrentBufferBit = DD_FRONT_LEFT_BIT; + else if (ctx->Color._DrawDestMask & DD_BACK_LEFT_BIT) + swrast->CurrentBufferBit = DD_BACK_LEFT_BIT; + else if (ctx->Color._DrawDestMask & DD_FRONT_RIGHT_BIT) + swrast->CurrentBufferBit = DD_FRONT_RIGHT_BIT; + else if (ctx->Color._DrawDestMask & DD_BACK_RIGHT_BIT) + swrast->CurrentBufferBit = DD_BACK_RIGHT_BIT; + else if (ctx->Color._DrawDestMask & DD_AUX0_BIT) + swrast->CurrentBufferBit = DD_AUX0_BIT; + else if (ctx->Color._DrawDestMask & DD_AUX1_BIT) + swrast->CurrentBufferBit = DD_AUX1_BIT; + else if (ctx->Color._DrawDestMask & DD_AUX2_BIT) + swrast->CurrentBufferBit = DD_AUX2_BIT; + else if (ctx->Color._DrawDestMask & DD_AUX3_BIT) + swrast->CurrentBufferBit = DD_AUX3_BIT; else /* glDrawBuffer(GL_NONE) */ - swrast->CurrentBuffer = FRONT_LEFT_BIT; /* we always have this buffer */ + swrast->CurrentBufferBit = DD_FRONT_LEFT_BIT; /* we always have this buffer */ - (*swrast->Driver.SetBuffer)( ctx, ctx->DrawBuffer, swrast->CurrentBuffer ); + swrast->Driver.SetBuffer(ctx, ctx->DrawBuffer, swrast->CurrentBufferBit); } diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index be800d4d59..94b57e4bbf 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -91,10 +91,7 @@ _swrast_update_rasterflags( GLcontext *ctx ) * MULTI_DRAW_BIT flag. Also set it if we're drawing to no * buffers or the RGBA or CI mask disables all writes. */ - if (ctx->Color._DrawDestMask != FRONT_LEFT_BIT && - ctx->Color._DrawDestMask != BACK_LEFT_BIT && - ctx->Color._DrawDestMask != FRONT_RIGHT_BIT && - ctx->Color._DrawDestMask != BACK_RIGHT_BIT) { + if (_mesa_bitcount(ctx->Color._DrawDestMask) != 1) { /* more than one color buffer designated for writing (or zero buffers) */ RasterMask |= MULTI_DRAW_BIT; } @@ -582,9 +579,9 @@ _swrast_CreateContext( GLcontext *ctx ) swrast->AllowPixelFog = GL_TRUE; if (ctx->Visual.doubleBufferMode) - swrast->CurrentBuffer = BACK_LEFT_BIT; + swrast->CurrentBufferBit = DD_BACK_LEFT_BIT; else - swrast->CurrentBuffer = FRONT_LEFT_BIT; + swrast->CurrentBufferBit = DD_FRONT_LEFT_BIT; /* Optimized Accum buffer */ swrast->_IntegerAccumMode = GL_TRUE; diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h index 081d2557ad..d6a14e6b4a 100644 --- a/src/mesa/swrast/s_context.h +++ b/src/mesa/swrast/s_context.h @@ -281,6 +281,7 @@ typedef struct GLboolean _IntegerAccumMode; /**< Storing unscaled integers? */ GLfloat _IntegerAccumScaler; /**< Implicit scale factor */ + GLchan *CurAuxBuffer; /* Working values: */ @@ -288,7 +289,7 @@ typedef struct GLuint NewState; GLuint StateChanges; GLenum Primitive; /* current primitive being drawn (ala glBegin) */ - GLuint CurrentBuffer; /* exactly one of FRONT_LEFT_BIT, BACK_LEFT_BIT, etc*/ + GLbitfield CurrentBufferBit; /* exactly one the of DD_*_BIT buffer bits */ /** Mechanism to allow driver (like X11) to register further * software rasterization routines. diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 801595d970..13248fdc7c 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -653,7 +653,7 @@ multi_write_index_span( GLcontext *ctx, struct sw_span *span ) ASSERT(span->end < MAX_WIDTH); /* Set the current read/draw buffer */ - swrast->CurrentBuffer = bufferBit; + swrast->CurrentBufferBit = bufferBit; (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit); /* make copy of incoming indexes */ @@ -710,7 +710,7 @@ multi_write_rgba_span( GLcontext *ctx, struct sw_span *span ) ASSERT(span->end < MAX_WIDTH); /* Set the current read/draw buffer */ - swrast->CurrentBuffer = bufferBit; + swrast->CurrentBufferBit = bufferBit; (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit); /* make copy of incoming colors */ diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h index e1220cff4e..9447e99880 100644 --- a/src/mesa/swrast/swrast.h +++ b/src/mesa/swrast/swrast.h @@ -262,18 +262,18 @@ _swrast_copy_texsubimage3d(GLcontext *ctx, */ struct swrast_device_driver { - void (*SetBuffer)( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit); + void (*SetBuffer)(GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit); /* - * Specifies the current buffer for span/pixel writing/reading. + * Specifies the current color buffer for span/pixel writing/reading. * buffer indicates which window to write to / read from. Normally, * this'll be the buffer currently bound to the context, but it doesn't * have to be! - * bufferBit indicates which color buffer, one of: - * FRONT_LEFT_BIT - this buffer always exists - * BACK_LEFT_BIT - when double buffering - * FRONT_RIGHT_BIT - when using stereo - * BACK_RIGHT_BIT - when using stereo and double buffering - * AUXn_BIT - if aux buffers are implemented + * bufferBit indicates which color buffer, exactly one of: + * DD_FRONT_LEFT_BIT - this buffer always exists + * DD_BACK_LEFT_BIT - when double buffering + * DD_FRONT_RIGHT_BIT - when using stereo + * DD_BACK_RIGHT_BIT - when using stereo and double buffering + * DD_AUXn_BIT - if aux buffers are implemented */ -- cgit v1.2.3