-/* $Id: s_buffers.c,v 1.3 2001/01/23 23:39:37 brianp Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
- *
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
- *
+ * Version: 5.1
+ *
+ * Copyright (C) 1999-2002 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
#include "glheader.h"
+#include "colormac.h"
#include "macros.h"
-#include "mem.h"
+#include "imports.h"
#include "s_accum.h"
#include "s_alphabuf.h"
+#include "s_context.h"
#include "s_depth.h"
#include "s_masking.h"
#include "s_stencil.h"
static void
clear_color_buffer_with_masking( GLcontext *ctx )
{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLint x = ctx->DrawBuffer->_Xmin;
const GLint y = ctx->DrawBuffer->_Ymin;
const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
if (ctx->Visual.rgbMode) {
/* 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 clearColor[4];
GLint i;
+ CLAMPED_FLOAT_TO_CHAN(clearColor[RCOMP], ctx->Color.ClearColor[0]);
+ CLAMPED_FLOAT_TO_CHAN(clearColor[GCOMP], ctx->Color.ClearColor[1]);
+ CLAMPED_FLOAT_TO_CHAN(clearColor[BCOMP], ctx->Color.ClearColor[2]);
+ CLAMPED_FLOAT_TO_CHAN(clearColor[ACOMP], ctx->Color.ClearColor[3]);
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;
+ for (j = 0; j < width; j++) {
+ COPY_CHAN4(rgba[j], clearColor);
}
- _mesa_mask_rgba_span( ctx, width, x, y + i, rgba );
- (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y + i,
- (CONST GLchan (*)[4]) rgba, NULL );
+ _swrast_mask_rgba_array( ctx, width, x, y + i, rgba );
+ (*swrast->Driver.WriteRGBASpan)( ctx, width, x, y + i,
+ (CONST GLchan (*)[4]) rgba, NULL );
}
}
else {
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 );
+ _swrast_mask_index_array( ctx, width, x, y + i, span );
+ (*swrast->Driver.WriteCI32Span)( ctx, width, x, y + i, span, mask );
}
}
}
static void
clear_color_buffer(GLcontext *ctx)
{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLint x = ctx->DrawBuffer->_Xmin;
const GLint y = ctx->DrawBuffer->_Ymin;
const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
if (ctx->Visual.rgbMode) {
/* 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];
+ GLchan clearColor[4];
GLint i;
+ CLAMPED_FLOAT_TO_CHAN(clearColor[RCOMP], ctx->Color.ClearColor[0]);
+ CLAMPED_FLOAT_TO_CHAN(clearColor[GCOMP], ctx->Color.ClearColor[1]);
+ CLAMPED_FLOAT_TO_CHAN(clearColor[BCOMP], ctx->Color.ClearColor[2]);
+ CLAMPED_FLOAT_TO_CHAN(clearColor[ACOMP], ctx->Color.ClearColor[3]);
+
ASSERT(*((GLuint *) &ctx->Color.ColorMask) == 0xffffffff);
+ ASSERT(swrast->Driver.WriteRGBASpan);
- 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 );
+ (*swrast->Driver.WriteMonoRGBASpan)( ctx, width, x, y + i,
+ clearColor, 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 );
- }
+ GLint i;
+ ASSERT((ctx->Color.IndexMask & ((1 << ctx->Visual.indexBits) - 1))
+ == (GLuint) ((1 << ctx->Visual.indexBits) - 1));
+ ASSERT(swrast->Driver.WriteMonoCISpan);
+ for (i = 0; i < height; i++) {
+ (*swrast->Driver.WriteMonoCISpan)( ctx, width, x, y + i,
+ ctx->Color.ClearIndex, NULL);
}
}
}
static void
clear_color_buffers(GLcontext *ctx)
{
+ SWcontext *swrast = SWRAST_CONTEXT(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 (bufferBit & ctx->Color._DrawDestMask) {
+ (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit);
+
if (colorMask != 0xffffffff) {
clear_color_buffer_with_masking(ctx);
}
}
}
- /* restore default read/draw buffers */
- (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer );
- (void) (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer );
+ /* restore default read/draw buffer */
+ _swrast_use_draw_buffer(ctx);
}
-void
+void
_swrast_Clear( GLcontext *ctx, GLbitfield mask,
- GLboolean all,
+ GLboolean all,
GLint x, GLint y, GLint width, GLint height )
{
-
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
#ifdef DEBUG
{
GLbitfield legalBits = DD_FRONT_LEFT_BIT |
}
#endif
- RENDER_START(ctx);
+ RENDER_START(swrast,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);
+ 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) _swarst_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]) {
- _mesa_clear_alpha_buffers( ctx );
+ _swrast_clear_alpha_buffers( ctx );
}
- RENDER_FINISH(ctx);
+ RENDER_FINISH(swrast,ctx);
}
void
-_swrast_alloc_buffers( GLcontext *ctx )
+_swrast_alloc_buffers( GLframebuffer *buffer )
{
/* Reallocate other buffers if needed. */
- if (ctx->DrawBuffer->UseSoftwareDepthBuffer) {
- _mesa_alloc_depth_buffer( ctx );
+ if (buffer->UseSoftwareDepthBuffer) {
+ _swrast_alloc_depth_buffer( buffer );
}
- if (ctx->DrawBuffer->UseSoftwareStencilBuffer) {
- _mesa_alloc_stencil_buffer( ctx );
+ if (buffer->UseSoftwareStencilBuffer) {
+ _swrast_alloc_stencil_buffer( buffer );
}
- if (ctx->DrawBuffer->UseSoftwareAccumBuffer) {
- _mesa_alloc_accum_buffer( ctx );
+ if (buffer->UseSoftwareAccumBuffer) {
+ _swrast_alloc_accum_buffer( buffer );
}
- if (ctx->DrawBuffer->UseSoftwareAlphaBuffers) {
- _mesa_alloc_alpha_buffers( ctx );
+ if (buffer->UseSoftwareAlphaBuffers) {
+ _swrast_alloc_alpha_buffers( buffer );
}
}
+/*
+ * Fallback for ctx->Driver.DrawBuffer()
+ */
+void
+_swrast_DrawBuffer( GLcontext *ctx, GLenum mode )
+{
+ _swrast_use_draw_buffer(ctx);
+}
+
+
+/*
+ * Setup things so that we read/write spans from the user-designated
+ * read buffer (set via glReadPixels). We usually just have to call
+ * this for glReadPixels, glCopyPixels, etc.
+ */
+void
+_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;
+ /* Tell the device driver where to read/write spans */
+ (*swrast->Driver.SetBuffer)( ctx, ctx->ReadBuffer, swrast->CurrentBuffer );
+}
+
+
+/*
+ * Setup things so that we read/write spans from the default draw buffer.
+ * This is the usual mode that Mesa's software rasterizer operates in.
+ */
+void
+_swrast_use_draw_buffer( GLcontext *ctx )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ /* The user can specify rendering to zero, one, two, or four color
+ * buffers simultaneously with glDrawBuffer()!
+ * We don't expect the span/point/line/triangle functions to deal with
+ * that mess so we'll iterate over the multiple buffers as needed.
+ * But usually we only render to one color buffer at a time.
+ * We set ctx->Color._DriverDrawBuffer to that buffer and tell the
+ * device driver to use that buffer.
+ * Look in s_span.c's multi_write_rgba_span() function to see how
+ * 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;
+ else
+ /* glDrawBuffer(GL_NONE) */
+ swrast->CurrentBuffer = FRONT_LEFT_BIT; /* we always have this buffer */
+
+ (*swrast->Driver.SetBuffer)( ctx, ctx->DrawBuffer, swrast->CurrentBuffer );
+}