diff options
author | Brian Paul <brian.paul@tungstengraphics.com> | 2005-05-04 20:11:35 +0000 |
---|---|---|
committer | Brian Paul <brian.paul@tungstengraphics.com> | 2005-05-04 20:11:35 +0000 |
commit | e4b2356c07d31fbeeabb13b2fb47db703b473080 (patch) | |
tree | d8b7f1c7c9e7c84d84349485f942dd205dd4c16d /src/mesa/swrast | |
parent | ebef61f5c0950572f9c6a81b08f447957461675c (diff) |
Major check-in of changes for GL_EXT_framebuffer_object extension.
Main driver impacts:
- new code for creating the Mesa GLframebuffer
- new span/pixel read/write code
Some drivers not yet updated/tested.
Diffstat (limited to 'src/mesa/swrast')
33 files changed, 1966 insertions, 3021 deletions
diff --git a/src/mesa/swrast/s_accum.c b/src/mesa/swrast/s_accum.c index 55ba8310590..b0af0f95d4f 100644 --- a/src/mesa/swrast/s_accum.c +++ b/src/mesa/swrast/s_accum.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.0.1 + * Version: 6.3 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -27,20 +27,23 @@ #include "context.h" #include "macros.h" #include "imports.h" +#include "fbobject.h" #include "s_accum.h" -#include "s_alphabuf.h" #include "s_context.h" #include "s_masking.h" #include "s_span.h" +#define ACCUM_SCALE16 32767.0 + + /* * Accumulation buffer notes * * Normally, accumulation buffer values are GLshorts with values in * [-32767, 32767] which represent floating point colors in [-1, 1], - * as suggested by the OpenGL specification. + * as defined by the OpenGL specification. * * We optimize for the common case used for full-scene antialiasing: * // start with accum buffer cleared to zero @@ -54,68 +57,61 @@ * In this scenario, we can simply store unscaled integer values in * the accum buffer instead of scaled integers. We'll also keep track * of the w value so when we do GL_RETURN we simply divide the accumulated - * values by n (=1/w). + * values by n (n=1/w). * This lets us avoid _many_ int->float->int conversions. */ -#if CHAN_BITS == 8 && ACCUM_BITS < 32 -#define USE_OPTIMIZED_ACCUM /* enable the optimization */ -#endif - - -void -_swrast_alloc_accum_buffer( GLframebuffer *buffer ) -{ - GET_CURRENT_CONTEXT(ctx); - GLint n; - - ASSERT(buffer->UseSoftwareAccumBuffer); - - if (buffer->Accum) { - MESA_PBUFFER_FREE( buffer->Accum ); - buffer->Accum = NULL; - } - - /* allocate accumulation buffer if not already present */ - n = buffer->Width * buffer->Height * 4 * sizeof(GLaccum); - buffer->Accum = (GLaccum *) MESA_PBUFFER_ALLOC( n ); - if (!buffer->Accum) { - /* unable to setup accumulation buffer */ - _mesa_error( NULL, GL_OUT_OF_MEMORY, "glAccum" ); - } - - if (ctx) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); - /* XXX these fields should probably be in the GLframebuffer */ -#ifdef USE_OPTIMIZED_ACCUM - swrast->_IntegerAccumMode = GL_TRUE; +#if CHAN_BITS == 8 && ACCUM_BITS <= 32 +/* enable the optimization */ +#define USE_OPTIMIZED_ACCUM 1 #else - swrast->_IntegerAccumMode = GL_FALSE; +#define USE_OPTIMIZED_ACCUM 0 #endif - swrast->_IntegerAccumScaler = 0.0; - } -} -/* +/** * This is called when we fall out of optimized/unscaled accum buffer mode. * That is, we convert each unscaled accum buffer value into a scaled value * representing the range[-1, 1]. */ -static void rescale_accum( GLcontext *ctx ) +static void +rescale_accum( GLcontext *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height * 4; + struct gl_renderbuffer *rb + = ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer; const GLfloat s = swrast->_IntegerAccumScaler * (32767.0F / CHAN_MAXF); - GLaccum *accum = ctx->DrawBuffer->Accum; - GLuint i; + assert(rb); + assert(rb->_BaseFormat == GL_RGBA); + /* add other types in future? */ + assert(rb->DataType == GL_SHORT || rb->DataType == GL_UNSIGNED_SHORT); assert(swrast->_IntegerAccumMode); - assert(accum); - for (i = 0; i < n; i++) { - accum[i] = (GLaccum) (accum[i] * s); + if (rb->GetPointer(ctx, rb, 0, 0)) { + /* directly-addressable memory */ + GLuint y; + for (y = 0; y < rb->Height; y++) { + GLuint i; + GLshort *acc = (GLshort *) rb->GetPointer(ctx, rb, 0, y); + for (i = 0; i < 4 * rb->Width; i++) { + acc[i] = (GLshort) (acc[i] * s); + } + } + } + else { + /* use get/put row funcs */ + GLuint y; + for (y = 0; y < rb->Height; y++) { + GLshort accRow[MAX_WIDTH * 4]; + GLuint i; + rb->GetRow(ctx, rb, rb->Width, 0, y, accRow); + for (i = 0; i < 4 * rb->Width; i++) { + accRow[i] = (GLshort) (accRow[i] * s); + } + rb->PutRow(ctx, rb, rb->Width, 0, y, accRow, NULL); + } } swrast->_IntegerAccumMode = GL_FALSE; @@ -123,406 +119,472 @@ static void rescale_accum( GLcontext *ctx ) - - - -/* +/** * Clear the accumulation Buffer. */ void -_swrast_clear_accum_buffer( GLcontext *ctx ) +_swrast_clear_accum_buffer( GLcontext *ctx, struct gl_renderbuffer *rb ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLuint buffersize; - GLfloat acc_scale; + GLuint x, y, width, height; - if (ctx->Visual.accumRedBits==0) { - /* No accumulation buffer! */ + if (ctx->Visual.accumRedBits == 0) { + /* No accumulation buffer! Not an error. */ return; } - if (sizeof(GLaccum)==1) { - acc_scale = 127.0; - } - else if (sizeof(GLaccum)==2) { - acc_scale = 32767.0; + assert(rb); + assert(rb->_BaseFormat == GL_RGBA); + /* add other types in future? */ + assert(rb->DataType == GL_SHORT || rb->DataType == GL_UNSIGNED_SHORT); + + /* bounds, with scissor */ + x = ctx->DrawBuffer->_Xmin; + y = ctx->DrawBuffer->_Ymin; + width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + + if (rb->DataType == GL_SHORT || rb->DataType == GL_UNSIGNED_SHORT) { + const GLfloat accScale = 32767.0; + GLshort clearVal[4]; + GLuint i; + + clearVal[0] = (GLshort) (ctx->Accum.ClearColor[0] * accScale); + clearVal[1] = (GLshort) (ctx->Accum.ClearColor[1] * accScale); + clearVal[2] = (GLshort) (ctx->Accum.ClearColor[2] * accScale); + clearVal[3] = (GLshort) (ctx->Accum.ClearColor[3] * accScale); + + for (i = 0; i < height; i++) { + rb->PutMonoRow(ctx, rb, width, x, y + i, clearVal, NULL); + } } else { - acc_scale = 1.0F; + /* someday support other sizes */ } - /* number of pixels */ - buffersize = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; - - if (!ctx->DrawBuffer->Accum) { - /* try to alloc accumulation buffer */ - ctx->DrawBuffer->Accum = (GLaccum *) - MALLOC( buffersize * 4 * sizeof(GLaccum) ); + /* update optimized accum state vars */ + if (ctx->Accum.ClearColor[0] == 0.0 && ctx->Accum.ClearColor[1] == 0.0 && + ctx->Accum.ClearColor[2] == 0.0 && ctx->Accum.ClearColor[3] == 0.0) { +#if USE_OPTIMIZED_ACCUM + swrast->_IntegerAccumMode = GL_TRUE; +#else + swrast->_IntegerAccumMode = GL_FALSE; +#endif + swrast->_IntegerAccumScaler = 0.0; /* denotes empty accum buffer */ } + else { + swrast->_IntegerAccumMode = GL_FALSE; + } +} - if (ctx->DrawBuffer->Accum) { - if (ctx->Scissor.Enabled) { - /* Limit clear to scissor box */ - const GLaccum r = (GLaccum) (ctx->Accum.ClearColor[0] * acc_scale); - const GLaccum g = (GLaccum) (ctx->Accum.ClearColor[1] * acc_scale); - const GLaccum b = (GLaccum) (ctx->Accum.ClearColor[2] * acc_scale); - const GLaccum a = (GLaccum) (ctx->Accum.ClearColor[3] * acc_scale); - GLint i, j; - GLint width, height; - GLaccum *row; - /* size of region to clear */ - width = 4 * (ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin); - height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - /* ptr to first element to clear */ - row = ctx->DrawBuffer->Accum - + 4 * (ctx->DrawBuffer->_Ymin * ctx->DrawBuffer->Width - + ctx->DrawBuffer->_Xmin); - for (j=0;j<height;j++) { - for (i=0;i<width;i+=4) { - row[i+0] = r; - row[i+1] = g; - row[i+2] = b; - row[i+3] = a; - } - row += 4 * ctx->DrawBuffer->Width; - } + +static void +accum_add(GLcontext *ctx, GLfloat value, + GLint xpos, GLint ypos, GLint width, GLint height ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + struct gl_renderbuffer *rb + = ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer; + + assert(rb); + + /* Leave optimized accum buffer mode */ + if (swrast->_IntegerAccumMode) + rescale_accum(ctx); + + if (rb->DataType == GL_SHORT || rb->DataType == GL_UNSIGNED_SHORT) { + const GLshort incr = (GLshort) (value * ACCUM_SCALE16); + if (rb->GetPointer(ctx, rb, 0, 0)) { + GLint i, j; + for (i = 0; i < height; i++) { + GLshort *acc = (GLshort *) rb->GetPointer(ctx, rb, xpos, ypos + i); + for (j = 0; j < 4 * width; j++) { + acc[j] += incr; + } + } } else { - /* clear whole buffer */ - if (ctx->Accum.ClearColor[0]==0.0 && - ctx->Accum.ClearColor[1]==0.0 && - ctx->Accum.ClearColor[2]==0.0 && - ctx->Accum.ClearColor[3]==0.0) { - /* Black */ - _mesa_bzero( ctx->DrawBuffer->Accum, - buffersize * 4 * sizeof(GLaccum) ); - } - else { - /* Not black */ - const GLaccum r = (GLaccum) (ctx->Accum.ClearColor[0] * acc_scale); - const GLaccum g = (GLaccum) (ctx->Accum.ClearColor[1] * acc_scale); - const GLaccum b = (GLaccum) (ctx->Accum.ClearColor[2] * acc_scale); - const GLaccum a = (GLaccum) (ctx->Accum.ClearColor[3] * acc_scale); - GLaccum *acc = ctx->DrawBuffer->Accum; - GLuint i; - for (i=0;i<buffersize;i++) { - *acc++ = r; - *acc++ = g; - *acc++ = b; - *acc++ = a; - } - } + GLint i, j; + for (i = 0; i < height; i++) { + GLshort accRow[4 * MAX_WIDTH]; + rb->GetRow(ctx, rb, width, xpos, ypos + i, accRow); + for (j = 0; j < 4 * width; j++) { + accRow[j] += incr; + } + rb->PutRow(ctx, rb, width, xpos, ypos + i, accRow, NULL); + } } + } + else { + /* other types someday */ + } +} - /* update optimized accum state vars */ - if (ctx->Accum.ClearColor[0] == 0.0 && ctx->Accum.ClearColor[1] == 0.0 && - ctx->Accum.ClearColor[2] == 0.0 && ctx->Accum.ClearColor[3] == 0.0) { -#ifdef USE_OPTIMIZED_ACCUM - swrast->_IntegerAccumMode = GL_TRUE; -#else - swrast->_IntegerAccumMode = GL_FALSE; -#endif - swrast->_IntegerAccumScaler = 0.0; /* denotes empty accum buffer */ + +static void +accum_mult(GLcontext *ctx, GLfloat mult, + GLint xpos, GLint ypos, GLint width, GLint height ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + struct gl_renderbuffer *rb + = ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer; + + assert(rb); + + /* Leave optimized accum buffer mode */ + if (swrast->_IntegerAccumMode) + rescale_accum(ctx); + + if (rb->DataType == GL_SHORT || rb->DataType == GL_UNSIGNED_SHORT) { + if (rb->GetPointer(ctx, rb, 0, 0)) { + GLint i, j; + for (i = 0; i < height; i++) { + GLshort *acc = (GLshort *) rb->GetPointer(ctx, rb, xpos, ypos + i); + for (j = 0; j < 4 * width; j++) { + acc[j] = (GLshort) (acc[j] * mult); + } + } } else { - swrast->_IntegerAccumMode = GL_FALSE; + GLint i, j; + for (i = 0; i < height; i++) { + GLshort accRow[4 * MAX_WIDTH]; + rb->GetRow(ctx, rb, width, xpos, ypos + i, accRow); + for (j = 0; j < 4 * width; j++) { + accRow[j] = (GLshort) (accRow[j] * mult); + } + rb->PutRow(ctx, rb, width, xpos, ypos + i, accRow, NULL); + } } } + else { + /* other types someday */ + } } -void -_swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value, - GLint xpos, GLint ypos, - GLint width, GLint height ) +static void +accum_accum(GLcontext *ctx, GLfloat value, + GLint xpos, GLint ypos, GLint width, GLint height ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLuint width4; - GLfloat acc_scale; - GLchan rgba[MAX_WIDTH][4]; - const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); + struct gl_renderbuffer *rb + = ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer; + const GLboolean directAccess = (rb->GetPointer(ctx, rb, 0, 0) != NULL); + assert(rb); - if (SWRAST_CONTEXT(ctx)->NewState) - _swrast_validate_derived( ctx ); - - if (!ctx->DrawBuffer->Accum) { - _mesa_warning(ctx, - "Calling glAccum() without an accumulation " - "buffer (low memory?)"); + if (!ctx->ReadBuffer->_ColorReadBuffer) { + /* no read buffer - OK */ return; } - if (sizeof(GLaccum)==1) { - acc_scale = 127.0; - } - else if (sizeof(GLaccum)==2) { - acc_scale = 32767.0; - } - else { - acc_scale = 1.0F; - } - - width4 = 4 * width; + /* May have to leave optimized accum buffer mode */ + if (swrast->_IntegerAccumScaler == 0.0 && value > 0.0 && value <= 1.0) + swrast->_IntegerAccumScaler = value; + if (swrast->_IntegerAccumMode && value != swrast->_IntegerAccumScaler) + rescale_accum(ctx); - switch (op) { - case GL_ADD: - if (value != 0.0F) { - const GLaccum val = (GLaccum) (value * acc_scale); - GLint j; - /* Leave optimized accum buffer mode */ - if (swrast->_IntegerAccumMode) - rescale_accum(ctx); - for (j = 0; j < height; j++) { - GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + 4*xpos; - GLuint i; - for (i = 0; i < width4; i++) { - acc[i] += val; - } - ypos++; - } - } - break; + _swrast_use_read_buffer(ctx); - case GL_MULT: - if (value != 1.0F) { - GLint j; - /* Leave optimized accum buffer mode */ - if (swrast->_IntegerAccumMode) - rescale_accum(ctx); - for (j = 0; j < height; j++) { - GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + 4 * xpos; - GLuint i; - for (i = 0; i < width4; i++) { - acc[i] = (GLaccum) ( (GLfloat) acc[i] * value ); - } - ypos++; - } - } - break; - - case GL_ACCUM: - if (value == 0.0F) - return; + if (rb->DataType == GL_SHORT || rb->DataType == GL_UNSIGNED_SHORT) { + const GLfloat scale = value * ACCUM_SCALE16 / CHAN_MAXF; + GLshort accumRow[4 * MAX_WIDTH]; + GLchan rgba[MAX_WIDTH][4]; + GLint i; - _swrast_use_read_buffer(ctx); - - /* May have to leave optimized accum buffer mode */ - if (swrast->_IntegerAccumScaler == 0.0 && value > 0.0 && value <= 1.0) - swrast->_IntegerAccumScaler = value; - if (swrast->_IntegerAccumMode && value != swrast->_IntegerAccumScaler) - rescale_accum(ctx); + for (i = 0; i < height; i++) { + GLshort *acc; + if (directAccess) { + acc = (GLshort *) rb->GetPointer(ctx, rb, xpos, ypos + i); + } + else { + rb->GetRow(ctx, rb, width, xpos, ypos + i, accumRow); + acc = accumRow; + } - RENDER_START(swrast,ctx); + /* read colors from color buffer */ + _swrast_read_rgba_span(ctx, ctx->ReadBuffer->_ColorReadBuffer, width, + xpos, ypos + i, rgba); + /* do accumulation */ if (swrast->_IntegerAccumMode) { /* simply add integer color values into accum buffer */ GLint j; - GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4; - assert(swrast->_IntegerAccumScaler > 0.0); - assert(swrast->_IntegerAccumScaler <= 1.0); - for (j = 0; j < height; j++) { - - GLint i, i4; - _swrast_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba); - for (i = i4 = 0; i < width; i++, i4+=4) { - acc[i4+0] += rgba[i][RCOMP]; - acc[i4+1] += rgba[i][GCOMP]; - acc[i4+2] += rgba[i][BCOMP]; - acc[i4+3] += rgba[i][ACOMP]; - } - acc += width4; - ypos++; + for (j = 0; j < width; j++) { + acc[j * 4 + 0] += rgba[j][RCOMP]; + acc[j * 4 + 1] += rgba[j][GCOMP]; + acc[j * 4 + 2] += rgba[j][BCOMP]; + acc[j * 4 + 3] += rgba[j][ACOMP]; } } else { /* scaled integer (or float) accum buffer */ - const GLfloat rscale = value * acc_scale / CHAN_MAXF; - const GLfloat gscale = value * acc_scale / CHAN_MAXF; - const GLfloat bscale = value * acc_scale / CHAN_MAXF; - const GLfloat ascale = value * acc_scale / CHAN_MAXF; GLint j; - for (j=0;j<height;j++) { - GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4; - GLint i; - _swrast_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba); - for (i=0;i<width;i++) { - acc[0] += (GLaccum) ( (GLfloat) rgba[i][RCOMP] * rscale ); - acc[1] += (GLaccum) ( (GLfloat) rgba[i][GCOMP] * gscale ); - acc[2] += (GLaccum) ( (GLfloat) rgba[i][BCOMP] * bscale ); - acc[3] += (GLaccum) ( (GLfloat) rgba[i][ACOMP] * ascale ); - acc += 4; - } - ypos++; + for (j = 0; j < width; j++) { + acc[j * 4 + 0] += (GLshort) ((GLfloat) rgba[j][RCOMP] * scale); + acc[j * 4 + 1] += (GLshort) ((GLfloat) rgba[j][GCOMP] * scale); + acc[j * 4 + 2] += (GLshort) ((GLfloat) rgba[j][BCOMP] * scale); + acc[j * 4 + 3] += (GLshort) ((GLfloat) rgba[j][ACOMP] * scale); } } - /* restore read buffer = draw buffer (the default) */ - _swrast_use_draw_buffer(ctx); - RENDER_FINISH(swrast,ctx); - break; + if (!directAccess) { + rb->PutRow(ctx, rb, width, xpos, ypos + i, accumRow, NULL); + } + } + } + else { + /* other types someday */ + } - case GL_LOAD: - _swrast_use_read_buffer(ctx); + _swrast_use_draw_buffer(ctx); +} + + + +static void +accum_load(GLcontext *ctx, GLfloat value, + GLint xpos, GLint ypos, GLint width, GLint height ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + struct gl_renderbuffer *rb + = ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer; + const GLboolean directAccess = (rb->GetPointer(ctx, rb, 0, 0) != NULL); - /* This is a change to go into optimized accum buffer mode */ - if (value > 0.0 && value <= 1.0) { -#ifdef USE_OPTIMIZED_ACCUM - swrast->_IntegerAccumMode = GL_TRUE; + assert(rb); + + if (!ctx->ReadBuffer->_ColorReadBuffer) { + /* no read buffer - OK */ + return; + } + + /* This is a change to go into optimized accum buffer mode */ + if (value > 0.0 && value <= 1.0) { +#if USE_OPTIMIZED_ACCUM + swrast->_IntegerAccumMode = GL_TRUE; #else - swrast->_IntegerAccumMode = GL_FALSE; + swrast->_IntegerAccumMode = GL_FALSE; #endif - swrast->_IntegerAccumScaler = value; + swrast->_IntegerAccumScaler = value; + } + else { + swrast->_IntegerAccumMode = GL_FALSE; + swrast->_IntegerAccumScaler = 0.0; + } + + _swrast_use_read_buffer(ctx); + + if (rb->DataType == GL_SHORT || rb->DataType == GL_UNSIGNED_SHORT) { + const GLfloat scale = value * ACCUM_SCALE16 / CHAN_MAXF; + GLshort accumRow[4 * MAX_WIDTH]; + GLchan rgba[MAX_WIDTH][4]; + GLint i; + + for (i = 0; i < height; i++) { + GLshort *acc; + if (directAccess) { + acc = (GLshort *) rb->GetPointer(ctx, rb, xpos, ypos + i); } else { - swrast->_IntegerAccumMode = GL_FALSE; - swrast->_IntegerAccumScaler = 0.0; + rb->GetRow(ctx, rb, width, xpos, ypos + i, accumRow); + acc = accumRow; } - RENDER_START(swrast,ctx); + /* read colors from color buffer */ + _swrast_read_rgba_span(ctx, ctx->ReadBuffer->_ColorReadBuffer, width, + xpos, ypos + i, rgba); + + /* do load */ if (swrast->_IntegerAccumMode) { - /* just copy values into accum buffer */ + /* just copy values in */ GLint j; - GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4; assert(swrast->_IntegerAccumScaler > 0.0); assert(swrast->_IntegerAccumScaler <= 1.0); - for (j = 0; j < height; j++) { - GLint i, i4; - _swrast_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba); - for (i = i4 = 0; i < width; i++, i4 += 4) { - acc[i4+0] = rgba[i][RCOMP]; - acc[i4+1] = rgba[i][GCOMP]; - acc[i4+2] = rgba[i][BCOMP]; - acc[i4+3] = rgba[i][ACOMP]; - } - acc += width4; - ypos++; + for (j = 0; j < width; j++) { + acc[j * 4 + 0] = rgba[j][RCOMP]; + acc[j * 4 + 1] = rgba[j][GCOMP]; + acc[j * 4 + 2] = rgba[j][BCOMP]; + acc[j * 4 + 3] = rgba[j][ACOMP]; } } else { /* scaled integer (or float) accum buffer */ - const GLfloat rscale = value * acc_scale / CHAN_MAXF; - const GLfloat gscale = value * acc_scale / CHAN_MAXF; - const GLfloat bscale = value * acc_scale / CHAN_MAXF; - const GLfloat ascale = value * acc_scale / CHAN_MAXF; -#if 0 - const GLfloat d = 3.0 / acc_scale; /* XXX what's this? */ -#endif - GLint i, j; - for (j = 0; j < height; j++) { - GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4; - _swrast_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba); - for (i=0;i<width;i++) { -#if 0 - *acc++ = (GLaccum) ((GLfloat) rgba[i][RCOMP] * rscale + d); - *acc++ = (GLaccum) ((GLfloat) rgba[i][GCOMP] * gscale + d); - *acc++ = (GLaccum) ((GLfloat) rgba[i][BCOMP] * bscale + d); - *acc++ = (GLaccum) ((GLfloat) rgba[i][ACOMP] * ascale + d); -#else - *acc++ = (GLaccum) ((GLfloat) rgba[i][RCOMP] * rscale); - *acc++ = (GLaccum) ((GLfloat) rgba[i][GCOMP] * gscale); - *acc++ = (GLaccum) ((GLfloat) rgba[i][BCOMP] * bscale); - *acc++ = (GLaccum) ((GLfloat) rgba[i][ACOMP] * ascale); -#endif - } - ypos++; + GLint j; + for (j = 0; j < width; j++) { + acc[j * 4 + 0] = (GLshort) ((GLfloat) rgba[j][RCOMP] * scale); + acc[j * 4 + 1] = (GLshort) ((GLfloat) rgba[j][GCOMP] * scale); + acc[j * 4 + 2] = (GLshort) ((GLfloat) rgba[j][BCOMP] * scale); + acc[j * 4 + 3] = (GLshort) ((GLfloat) rgba[j][ACOMP] * scale); } } - /* restore read buffer = draw buffer (the default) */ - _swrast_use_draw_buffer(ctx); + if (!directAccess) { + rb->PutRow(ctx, rb, width, xpos, ypos + i, accumRow, NULL); + } + } + } + else { + /* other types someday */ + } - RENDER_FINISH(swrast,ctx); - break; + _swrast_use_draw_buffer(ctx); +} - case GL_RETURN: - /* May have to leave optimized accum buffer mode */ - if (swrast->_IntegerAccumMode && value != 1.0) - rescale_accum(ctx); - - RENDER_START(swrast,ctx); -#ifdef USE_OPTIMIZED_ACCUM - if (swrast->_IntegerAccumMode && swrast->_IntegerAccumScaler > 0) { - /* build lookup table to avoid many floating point multiplies */ - static GLchan multTable[32768]; - static GLfloat prevMult = 0.0; - const GLfloat mult = swrast->_IntegerAccumScaler; - const GLint max = MIN2((GLint) (256 / mult), 32767); - GLint j; - if (mult != prevMult) { - for (j = 0; j < max; j++) - multTable[j] = IROUND((GLfloat) j * mult); - prevMult = mult; - } - assert(swrast->_IntegerAccumScaler > 0.0); - assert(swrast->_IntegerAccumScaler <= 1.0); - for (j = 0; j < height; j++) { - const GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos*4; - GLint i, i4; - for (i = i4 = 0; i < width; i++, i4 += 4) { - ASSERT(acc[i4+0] < max); - ASSERT(acc[i4+1] < max); - ASSERT(acc[i4+2] < max); - ASSERT(acc[i4+3] < max); - rgba[i][RCOMP] = multTable[acc[i4+0]]; - rgba[i][GCOMP] = multTable[acc[i4+1]]; - rgba[i][BCOMP] = multTable[acc[i4+2]]; - rgba[i][ACOMP] = multTable[acc[i4+3]]; - } - if (colorMask != 0xffffffff) { - _swrast_mask_rgba_array( ctx, width, xpos, ypos, rgba ); - } - (*swrast->Driver.WriteRGBASpan)( ctx, width, xpos, ypos, - (const GLchan (*)[4])rgba, NULL ); - if (ctx->DrawBuffer->UseSoftwareAlphaBuffers - && ctx->Color.ColorMask[ACOMP]) { - _swrast_write_alpha_span(ctx, width, xpos, ypos, - (CONST GLchan (*)[4]) rgba, NULL); - } - ypos++; +static void +accum_return(GLcontext *ctx, GLfloat value, + GLint xpos, GLint ypos, GLint width, GLint height ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct gl_renderbuffer *accumRb = fb->Attachment[BUFFER_ACCUM].Renderbuffer; + const GLboolean directAccess + = (accumRb->GetPointer(ctx, accumRb, 0, 0) != NULL); + const GLboolean masking = (!ctx->Color.ColorMask[RCOMP] || + !ctx->Color.ColorMask[GCOMP] || + !ctx->Color.ColorMask[BCOMP] || + !ctx->Color.ColorMask[ACOMP]); + + static GLchan multTable[32768]; + static GLfloat prevMult = 0.0; + const GLfloat mult = swrast->_IntegerAccumScaler; + const GLint max = MIN2((GLint) (256 / mult), 32767); + + /* May have to leave optimized accum buffer mode */ + if (swrast->_IntegerAccumMode && value != 1.0) + rescale_accum(ctx); + + if (swrast->_IntegerAccumMode && swrast->_IntegerAccumScaler > 0) { + /* build lookup table to avoid many floating point multiplies */ + GLint j; + assert(swrast->_IntegerAccumScaler <= 1.0); + if (mult != prevMult) { + for (j = 0; j < max; j++) + multTable[j] = IROUND((GLfloat) j * mult); + prevMult = mult; + } + } + + if (accumRb->DataType == GL_SHORT || + accumRb->DataType == GL_UNSIGNED_SHORT) { + const GLfloat scale = value * CHAN_MAXF / ACCUM_SCALE16; + GLuint buffer, i; + + /* XXX maybe transpose the 'i' and 'buffer' loops??? */ + for (i = 0; i < height; i++) { + GLchan rgba[MAX_WIDTH][4]; + GLshort accumRow[4 * MAX_WIDTH]; + GLshort *acc; + + if (directAccess) { + acc = (GLshort *) accumRb->GetPointer(ctx, accumRb, xpos, ypos +i); + } + else { + accumRb->GetRow(ctx, accumRb, width, xpos, ypos + i, accumRow); + acc = accumRow; + } + + /* get the colors to return */ + if (swrast->_IntegerAccumMode) { + GLint j; + for (j = 0; j < width; j++) { + ASSERT(acc[j * 4 + 0] < max); + ASSERT(acc[j * 4 + 1] < max); + ASSERT(acc[j * 4 + 2] < max); + ASSERT(acc[j * 4 + 3] < max); + rgba[j][RCOMP] = multTable[acc[j * 4 + 0]]; + rgba[j][GCOMP] = multTable[acc[j * 4 + 1]]; + rgba[j][BCOMP] = multTable[acc[j * 4 + 2]]; + rgba[j][ACOMP] = multTable[acc[j * 4 + 3]]; } } - else -#endif /* USE_OPTIMIZED_ACCUM */ - { + else { /* scaled integer (or float) accum buffer */ - const GLfloat rscale = value / acc_scale * CHAN_MAXF; - const GLfloat gscale = value / acc_scale * CHAN_MAXF; - const GLfloat bscale = value / acc_scale * CHAN_MAXF; - const GLfloat ascale = value / acc_scale * CHAN_MAXF; - GLint i, j; - for (j=0;j<height;j++) { - const GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos*4; - for (i=0;i<width;i++) { - GLint r = IROUND( (GLfloat) (acc[0]) * rscale ); - GLint g = IROUND( (GLfloat) (acc[1]) * gscale ); - GLint b = IROUND( (GLfloat) (acc[2]) * bscale ); - GLint a = IROUND( (GLfloat) (acc[3]) * ascale ); - acc += 4; - rgba[i][RCOMP] = CLAMP( r, 0, CHAN_MAX ); - rgba[i][GCOMP] = CLAMP( g, 0, CHAN_MAX ); - rgba[i][BCOMP] = CLAMP( b, 0, CHAN_MAX ); - rgba[i][ACOMP] = CLAMP( a, 0, CHAN_MAX ); - } - if (colorMask != 0xffffffff) { - _swrast_mask_rgba_array( ctx, width, xpos, ypos, rgba ); - } - (*swrast->Driver.WriteRGBASpan)( ctx, width, xpos, ypos, - (const GLchan (*)[4])rgba, NULL ); - if (ctx->DrawBuffer->UseSoftwareAlphaBuffers - && ctx->Color.ColorMask[ACOMP]) { - _swrast_write_alpha_span(ctx, width, xpos, ypos, - (CONST GLchan (*)[4]) rgba, NULL); - } - ypos++; + GLint j; + for (j = 0; j < width; j++) { + GLint r = IROUND( (GLfloat) (acc[j * 4 + 0]) * scale ); + GLint g = IROUND( (GLfloat) (acc[j * 4 + 1]) * scale ); + GLint b = IROUND( (GLfloat) (acc[j * 4 + 2]) * scale ); + GLint a = IROUND( (GLfloat) (acc[j * 4 + 3]) * scale ); + rgba[j][RCOMP] = CLAMP( r, 0, CHAN_MAX ); + rgba[j][GCOMP] = CLAMP( g, 0, CHAN_MAX ); + rgba[j][BCOMP] = CLAMP( b, 0, CHAN_MAX ); + rgba[j][ACOMP] = CLAMP( a, 0, CHAN_MAX ); } + } + + /* store colors */ + for (buffer = 0; buffer < fb->_NumColorDrawBuffers[0]; buffer++) { + struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[0][buffer]; + if (masking) { + _swrast_mask_rgba_array(ctx, rb, width, xpos, ypos + i, rgba); + } +#if OLD_RENDERBUFFER + if (swrast->Driver.WriteRGBASpan) + swrast->Driver.WriteRGBASpan(ctx, rb, width, xpos, ypos + i, + (const GLchan (*)[4]) rgba, NULL); + else +#endif + rb->PutRow(ctx, rb, width, xpos, ypos + i, rgba, NULL); + } + } + } + else { + /* other types someday */ + } +} + + + +/** + * Software fallback for glAccum. + */ +void +_swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value, + GLint xpos, GLint ypos, + GLint width, GLint height ) + +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (SWRAST_CONTEXT(ctx)->NewState) + _swrast_validate_derived( ctx ); + + if (!ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer) { + _mesa_warning(ctx, "Calling glAccum() without an accumulation buffer"); + return; + } + + RENDER_START(swrast, ctx); + + switch (op) { + case GL_ADD: + if (value != 0.0F) { + accum_add(ctx, value, xpos, ypos, width, height); } - RENDER_FINISH(swrast,ctx); break; - + case GL_MULT: + if (value != 1.0F) { + accum_mult(ctx, value, xpos, ypos, width, height); + } + break; + case GL_ACCUM: + if (value != 0.0F) { + accum_accum(ctx, value, xpos, ypos, width, height); + } + break; + case GL_LOAD: + accum_load(ctx, value, xpos, ypos, width, height); + break; + case GL_RETURN: + accum_return(ctx, value, xpos, ypos, width, height); + break; default: - _mesa_error( ctx, GL_INVALID_ENUM, "glAccum" ); + _mesa_problem(ctx, "invalid mode in _swrast_Accum()"); + break; } + + RENDER_FINISH(swrast, ctx); } diff --git a/src/mesa/swrast/s_accum.h b/src/mesa/swrast/s_accum.h index ac84fdec95b..97d2bef4c31 100644 --- a/src/mesa/swrast/s_accum.h +++ b/src/mesa/swrast/s_accum.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.0.1 + * Version: 6.3 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -28,15 +28,10 @@ #include "mtypes.h" -#include "swrast.h" extern void -_swrast_alloc_accum_buffer( GLframebuffer *buffer ); - - -extern void -_swrast_clear_accum_buffer( GLcontext *ctx ); +_swrast_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb); #endif diff --git a/src/mesa/swrast/s_alphabuf.c b/src/mesa/swrast/s_alphabuf.c deleted file mode 100644 index 5d8107c2d6b..00000000000 --- a/src/mesa/swrast/s_alphabuf.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * 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. - */ - - -/* - * Software alpha planes. Many frame buffers don't have alpha bits so - * we simulate them in software. - */ - - -#include "glheader.h" -#include "colormac.h" -#include "context.h" -#include "imports.h" - -#include "s_context.h" -#include "s_alphabuf.h" - - -/* - * Allocate a new front and back alpha buffer. - */ -void -_swrast_alloc_alpha_buffers( GLframebuffer *buffer ) -{ - const GLint bytes = buffer->Width * buffer->Height * sizeof(GLchan); - - ASSERT(buffer->UseSoftwareAlphaBuffers); - - if (buffer->FrontLeftAlpha) { - MESA_PBUFFER_FREE( buffer->FrontLeftAlpha ); - } - buffer->FrontLeftAlpha = (GLchan *) MESA_PBUFFER_ALLOC( bytes ); - if (!buffer->FrontLeftAlpha) { - /* out of memory */ - _mesa_error( NULL, GL_OUT_OF_MEMORY, - "Couldn't allocate front-left alpha buffer" ); - } - - if (buffer->Visual.doubleBufferMode) { - if (buffer->BackLeftAlpha) { - MESA_PBUFFER_FREE( buffer->BackLeftAlpha ); - } - buffer->BackLeftAlpha = (GLchan *) MESA_PBUFFER_ALLOC( bytes ); - if (!buffer->BackLeftAlpha) { - /* out of memory */ - _mesa_error( NULL, GL_OUT_OF_MEMORY, - "Couldn't allocate back-left alpha buffer" ); - } - } - - if (buffer->Visual.stereoMode) { - if (buffer->FrontRightAlpha) { - MESA_PBUFFER_FREE( buffer->FrontRightAlpha ); - } - buffer->FrontRightAlpha = (GLchan *) MESA_PBUFFER_ALLOC( bytes ); - if (!buffer->FrontRightAlpha) { - /* out of memory */ - _mesa_error( NULL, GL_OUT_OF_MEMORY, - "Couldn't allocate front-right alpha buffer" ); - } - - if (buffer->Visual.doubleBufferMode) { - if (buffer->BackRightAlpha) { - MESA_PBUFFER_FREE( buffer->BackRightAlpha ); - } - buffer->BackRightAlpha = (GLchan *) MESA_PBUFFER_ALLOC( bytes ); - if (!buffer->BackRightAlpha) { - /* out of memory */ - _mesa_error( NULL, GL_OUT_OF_MEMORY, - "Couldn't allocate back-right alpha buffer" ); - } - } - } -} - - -/* - * Clear all the alpha buffers - */ -void -_swrast_clear_alpha_buffers( GLcontext *ctx ) -{ - GLchan aclear; - GLuint bufferBit; - - CLAMPED_FLOAT_TO_CHAN(aclear, ctx->Color.ClearColor[3]); - - ASSERT(ctx->DrawBuffer->UseSoftwareAlphaBuffers); - ASSERT(ctx->Color.ColorMask[ACOMP]); - - /* loop over four possible alpha buffers */ - for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) { - if (bufferBit & ctx->Color._DrawDestMask[0]) { - GLchan *buffer; - if (bufferBit == DD_FRONT_LEFT_BIT) { - buffer = ctx->DrawBuffer->FrontLeftAlpha; - } - else if (bufferBit == DD_FRONT_RIGHT_BIT) { - buffer = ctx->DrawBuffer->FrontRightAlpha; - } - else if (bufferBit == DD_BACK_LEFT_BIT) { - buffer = ctx->DrawBuffer->BackLeftAlpha; - } - else { - buffer = ctx->DrawBuffer->BackRightAlpha; - } - - if (ctx->Scissor.Enabled) { - /* clear scissor region */ - GLint j; - GLint rowLen = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - GLint width = ctx->DrawBuffer->Width; - GLchan *aptr = buffer - + ctx->DrawBuffer->_Ymin * ctx->DrawBuffer->Width - + ctx->DrawBuffer->_Xmin; - for (j = 0; j < rows; j++) { -#if CHAN_BITS == 8 - MEMSET( aptr, aclear, rowLen ); -#elif CHAN_BITS == 16 - MEMSET16( aptr, aclear, rowLen ); -#else - GLint i; - for (i = 0; i < rowLen; i++) { - aptr[i] = aclear; - } -#endif - aptr += width; - } - } - else { - /* clear whole buffer */ - GLuint pixels = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; -#if CHAN_BITS == 8 - MEMSET(buffer, aclear, pixels); -#elif CHAN_BITS == 16 - MEMSET16(buffer, aclear, pixels); -#else - GLuint i; - for (i = 0; i < pixels; i++) { - buffer[i] = aclear; - } -#endif - } - } - } -} - - - -static INLINE -GLchan *get_alpha_buffer( GLcontext *ctx ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - switch (swrast->CurrentBufferBit) { - case DD_FRONT_LEFT_BIT: - return ctx->DrawBuffer->FrontLeftAlpha; - case DD_BACK_LEFT_BIT: - return ctx->DrawBuffer->BackLeftAlpha; - case DD_FRONT_RIGHT_BIT: - return ctx->DrawBuffer->FrontRightAlpha; - case DD_BACK_RIGHT_BIT: - return ctx->DrawBuffer->BackRightAlpha; - default: - _mesa_problem(ctx, "Bad CurrentBuffer in get_alpha_buffer()"); - return (GLchan *) ctx->DrawBuffer->FrontLeftAlpha; - } -} - - -void -_swrast_write_alpha_span( GLcontext *ctx, GLuint n, GLint x, GLint y, - CONST GLchan rgba[][4], const GLubyte mask[] ) -{ - GLchan *buffer, *aptr; - GLuint i; - - buffer = get_alpha_buffer(ctx); - aptr = buffer + y * ctx->DrawBuffer->Width + x; - - if (mask) { - for (i=0;i<n;i++) { - if (mask[i]) { - *aptr = rgba[i][ACOMP]; - } - aptr++; - } - } - else { - for (i=0;i<n;i++) { - *aptr++ = rgba[i][ACOMP]; - } - } -} - - -void -_swrast_write_mono_alpha_span( GLcontext *ctx, GLuint n, GLint x, GLint y, - GLchan alpha, const GLubyte mask[] ) -{ - GLchan *buffer, *aptr; - GLuint i; - - buffer = get_alpha_buffer(ctx); - aptr = buffer + y * ctx->DrawBuffer->Width + x; - - if (mask) { - for (i=0;i<n;i++) { - if (mask[i]) { - *aptr = alpha; - } - aptr++; - } - } - else { - for (i=0;i<n;i++) { - *aptr++ = alpha; - } - } -} - - -void -_swrast_write_alpha_pixels( GLcontext *ctx, - GLuint n, const GLint x[], const GLint y[], - CONST GLchan rgba[][4], const GLubyte mask[] ) -{ - GLchan *buffer; - GLuint i; - - buffer = get_alpha_buffer(ctx); - - if (mask) { - for (i=0;i<n;i++) { - if (mask[i]) { - GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i]; - *aptr = rgba[i][ACOMP]; - } - } - } - else { - for (i=0;i<n;i++) { - GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i]; - *aptr = rgba[i][ACOMP]; - } - } -} - - -void -_swrast_write_mono_alpha_pixels( GLcontext *ctx, - GLuint n, const GLint x[], const GLint y[], - GLchan alpha, const GLubyte mask[] ) -{ - GLchan *buffer; - GLuint i; - - buffer = get_alpha_buffer(ctx); - - if (mask) { - for (i=0;i<n;i++) { - if (mask[i]) { - GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i]; - *aptr = alpha; - } - } - } - else { - for (i=0;i<n;i++) { - GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i]; - *aptr = alpha; - } - } -} - - - -void -_swrast_read_alpha_span( GLcontext *ctx, - GLuint n, GLint x, GLint y, GLchan rgba[][4] ) -{ - const GLchan *buffer, *aptr; - GLuint i; - - buffer = get_alpha_buffer(ctx); - aptr = buffer + y * ctx->DrawBuffer->Width + x; - - for (i = 0; i < n; i++) - rgba[i][ACOMP] = *aptr++; -} - - -void -_swrast_read_alpha_pixels( GLcontext *ctx, - GLuint n, const GLint x[], const GLint y[], - GLchan rgba[][4], const GLubyte mask[] ) -{ - const GLchan *buffer; - GLuint i; - - buffer = get_alpha_buffer(ctx); - - for (i = 0; i < n; i++) { - if (mask[i]) { - const GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i]; - rgba[i][ACOMP] = *aptr; - } - } -} diff --git a/src/mesa/swrast/s_alphabuf.h b/src/mesa/swrast/s_alphabuf.h deleted file mode 100644 index f09bb91adbe..00000000000 --- a/src/mesa/swrast/s_alphabuf.h +++ /dev/null @@ -1,80 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 4.0.2 - * - * 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 - * 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_ALPHABUF_H -#define S_ALPHABUF_H - - -#include "mtypes.h" -#include "swrast.h" - - -extern void -_swrast_alloc_alpha_buffers( GLframebuffer *buffer ); - - -extern void -_swrast_clear_alpha_buffers( GLcontext *ctx ); - - -extern void -_swrast_write_alpha_span( GLcontext *ctx, GLuint n, GLint x, GLint y, - CONST GLchan rgba[][4], const GLubyte mask[] ); - - -extern void -_swrast_write_mono_alpha_span( GLcontext *ctx, - GLuint n, GLint x, GLint y, - GLchan alpha, const GLubyte mask[] ); - - - -extern void -_swrast_write_alpha_pixels( GLcontext* ctx, - GLuint n, const GLint x[], const GLint y[], - CONST GLchan rgba[][4], - const GLubyte mask[] ); - - -extern void -_swrast_write_mono_alpha_pixels( GLcontext* ctx, - GLuint n, const GLint x[], - const GLint y[], GLchan alpha, - const GLubyte mask[] ); - - -extern void -_swrast_read_alpha_span( GLcontext* ctx, - GLuint n, GLint x, GLint y, GLchan rgba[][4] ); - - -extern void -_swrast_read_alpha_pixels( GLcontext* ctx, - GLuint n, const GLint x[], const GLint y[], - GLchan rgba[][4], const GLubyte mask[] ); - - -#endif diff --git a/src/mesa/swrast/s_auxbuffer.c b/src/mesa/swrast/s_auxbuffer.c deleted file mode 100644 index b2224c8884b..00000000000 --- a/src/mesa/swrast/s_auxbuffer.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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" - - - -/** - * Allocate memory for the software auxillary buffers associated with - * the given GLframebuffer. Free any currently allocated aux buffers - * first. - */ -void -_swrast_alloc_aux_buffers( GLframebuffer *buffer ) -{ - GLint i; - - ASSERT(buffer->UseSoftwareAuxBuffers); - - for (i = 0; i < buffer->Visual.numAuxBuffers; i++) { - if (buffer->AuxBuffers[i]) { - _mesa_free(buffer->AuxBuffers[i]); - buffer->AuxBuffers[i] = NULL; - } - - buffer->AuxBuffers[i] = (GLchan *) _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); - (void) buffer; - - 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 deleted file mode 100644 index 48fb6951a18..00000000000 --- a/src/mesa/swrast/s_auxbuffer.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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_blend.c b/src/mesa/swrast/s_blend.c index 1001d6f2124..f15c95710dc 100644 --- a/src/mesa/swrast/s_blend.c +++ b/src/mesa/swrast/s_blend.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.0 + * Version: 6.3 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -37,7 +37,6 @@ #include "colormac.h" #include "macros.h" -#include "s_alphabuf.h" #include "s_blend.h" #include "s_context.h" #include "s_span.h" @@ -847,8 +846,8 @@ void _swrast_choose_blend_func( GLcontext *ctx ) * pixel coordinates. */ void -_swrast_blend_span( GLcontext *ctx, const struct sw_span *span, - GLchan rgba[][4] ) +_swrast_blend_span(GLcontext *ctx, struct gl_renderbuffer *rb, + const struct sw_span *span, GLchan rgba[][4]) { SWcontext *swrast = SWRAST_CONTEXT(ctx); GLchan framebuffer[MAX_WIDTH][4]; @@ -860,19 +859,20 @@ _swrast_blend_span( GLcontext *ctx, const struct sw_span *span, /* Read span of current frame buffer pixels */ if (span->arrayMask & SPAN_XY) { /* array of x/y pixel coords */ - (*swrast->Driver.ReadRGBAPixels)( ctx, span->end, +#if OLD_RENDERBUFFER + if (swrast->Driver.ReadRGBAPixels) + (*swrast->Driver.ReadRGBAPixels)( ctx, rb, span->end, span->array->x, span->array->y, framebuffer, span->array->mask ); - if (swrast->_RasterMask & ALPHABUF_BIT) { - _swrast_read_alpha_pixels( ctx, span->end, - span->array->x, span->array->y, - framebuffer, span->array->mask ); - } + else +#endif + rb->GetValues(ctx, rb, span->end, span->array->x, span->array->y, + framebuffer); } else { /* horizontal run of pixels */ - _swrast_read_rgba_span( ctx, ctx->DrawBuffer, span->end, - span->x, span->y, framebuffer ); + _swrast_read_rgba_span(ctx, rb, span->end, span->x, span->y, + framebuffer); } SWRAST_CONTEXT(ctx)->BlendFunc( ctx, span->end, span->array->mask, rgba, diff --git a/src/mesa/swrast/s_blend.h b/src/mesa/swrast/s_blend.h index 11bf378e319..c9519321521 100644 --- a/src/mesa/swrast/s_blend.h +++ b/src/mesa/swrast/s_blend.h @@ -1,9 +1,8 @@ - /* * Mesa 3-D graphics library - * Version: 4.1 + * Version: 6.3 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -32,14 +31,13 @@ #include "s_context.h" - extern void -_swrast_blend_span( GLcontext *ctx, const struct sw_span *span, - GLchan rgba[][4] ); +_swrast_blend_span(GLcontext *ctx, struct gl_renderbuffer *rb, + const struct sw_span *span, GLchan rgba[][4]); extern void -_swrast_choose_blend_func( GLcontext *ctx ); +_swrast_choose_blend_func(GLcontext *ctx); #endif diff --git a/src/mesa/swrast/s_buffers.c b/src/mesa/swrast/s_buffers.c index d05c8dfbf9b..cf469f8c626 100644 --- a/src/mesa/swrast/s_buffers.c +++ b/src/mesa/swrast/s_buffers.c @@ -2,7 +2,7 @@ * Mesa 3-D graphics library * Version: 6.3 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -27,10 +27,10 @@ #include "colormac.h" #include "macros.h" #include "imports.h" +#include "mtypes.h" +#include "fbobject.h" #include "s_accum.h" -#include "s_alphabuf.h" -#include "s_auxbuffer.h" #include "s_context.h" #include "s_depth.h" #include "s_masking.h" @@ -38,98 +38,190 @@ /** - * 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(). + * Clear the color buffer when glColorMask is in effect. */ static void -clear_color_buffer_with_masking( GLcontext *ctx ) +clear_rgba_buffer_with_masking(GLcontext *ctx, struct gl_renderbuffer *rb) { 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; const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + GLchan clearColor[4]; + GLint i; - if (ctx->Visual.rgbMode) { - /* RGBA mode */ - 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++) { - COPY_CHAN4(rgba[j], clearColor); - } - _swrast_mask_rgba_array( ctx, width, x, y + i, rgba ); - (*swrast->Driver.WriteRGBASpan)( ctx, width, x, y + i, - (CONST GLchan (*)[4]) rgba, NULL ); + ASSERT(ctx->Visual.rgbMode); + + 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++) { + COPY_CHAN4(rgba[j], clearColor); } + _swrast_mask_rgba_array( ctx, rb, width, x, y + i, rgba ); +#if NEW_RENDERBUFFER + if (rb->PutRow) { + rb->PutRow(ctx, rb, width, x, y + i, rgba, NULL); + } +#endif +#if OLD_RENDERBUFFER + else { + swrast->Driver.WriteRGBASpan(ctx, rb, width, x, y + i, + (CONST GLchan (*)[4]) rgba, NULL); + } +#endif } - 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; - } - _swrast_mask_index_array( ctx, width, x, y + i, span ); - (*swrast->Driver.WriteCI32Span)( ctx, width, x, y + i, span, mask ); +} + + +/** + * Clear color index buffer with masking. + */ +static void +clear_ci_buffer_with_masking(GLcontext *ctx, struct gl_renderbuffer *rb) +{ + 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; + GLuint span[MAX_WIDTH]; + GLubyte mask[MAX_WIDTH]; + GLint i, j; + + ASSERT(!ctx->Visual.rgbMode); + + MEMSET( mask, 1, width ); + for (i = 0; i < height;i++) { + for (j = 0; j < width;j++) { + span[j] = ctx->Color.ClearIndex; } + _swrast_mask_ci_array(ctx, rb, width, x, y + i, span); + ASSERT(rb->PutRow); + ASSERT(rb->DataType == GL_UNSIGNED_INT); + rb->PutRow(ctx, rb, width, x, y + i, span, mask); } } /** - * Clear a color buffer without index/channel masking. - * We'll have specified which color buffer to clear by previously - * calling Driver.SetBuffer(). + * Clear an rgba color buffer without channel masking. */ static void -clear_color_buffer(GLcontext *ctx) +clear_rgba_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { 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; const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - - if (ctx->Visual.rgbMode) { - /* RGBA mode */ + GLint i; + + ASSERT(ctx->Visual.rgbMode); + + ASSERT(ctx->Color.ColorMask[0] && + ctx->Color.ColorMask[1] && + ctx->Color.ColorMask[2] && + ctx->Color.ColorMask[3]); + +#if NEW_RENDERBUFFER + if (rb->PutMonoRow) { /* XXX assert this */ + GLubyte clear8[4]; + GLushort clear16[4]; + GLvoid *clearVal; + switch (rb->DataType) { + case GL_UNSIGNED_BYTE: + clear8[0] = FLOAT_TO_UBYTE(ctx->Color.ClearColor[0]); + clear8[1] = FLOAT_TO_UBYTE(ctx->Color.ClearColor[1]); + clear8[2] = FLOAT_TO_UBYTE(ctx->Color.ClearColor[2]); + clear8[3] = FLOAT_TO_UBYTE(ctx->Color.ClearColor[3]); + clearVal = clear8; + break; + case GL_UNSIGNED_SHORT: + clear16[0] = FLOAT_TO_USHORT(ctx->Color.ClearColor[0]); + clear16[1] = FLOAT_TO_USHORT(ctx->Color.ClearColor[1]); + clear16[2] = FLOAT_TO_USHORT(ctx->Color.ClearColor[2]); + clear16[3] = FLOAT_TO_USHORT(ctx->Color.ClearColor[3]); + clearVal = clear16; + break; + case GL_FLOAT: + clearVal = ctx->Color.ClearColor; + break; + default: + _mesa_problem(ctx, "Bad rb DataType in clear_color_buffer"); + return; + } + for (i = 0; i < height; i++) { + rb->PutMonoRow(ctx, rb, width, x, y + i, clearVal, NULL); + } + } +#endif +#if OLD_RENDERBUFFER + else { 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 < height; i++) { - (*swrast->Driver.WriteMonoRGBASpan)( ctx, width, x, y + i, - clearColor, NULL ); + swrast->Driver.WriteMonoRGBASpan(ctx, rb, width, x, y + i, + clearColor, NULL ); } } - else { - /* Color index mode */ +#endif +} + + +/** + * Clear color index buffer without masking. + */ +static void +clear_ci_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) +{ + 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; + + ASSERT(!ctx->Visual.rgbMode); + + ASSERT((ctx->Color.IndexMask & ((1 << ctx->Visual.indexBits) - 1)) + == (GLuint) ((1 << ctx->Visual.indexBits) - 1)); + +#if NEW_RENDERBUFFER + if (rb->PutMonoRow) { /* XXX assert this */ + GLubyte clear8; + GLushort clear16; + GLuint clear32; + GLvoid *clearVal; 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); + switch (rb->DataType) { + case GL_UNSIGNED_BYTE: + clear8 = (GLubyte) ctx->Color.ClearIndex; + clearVal = &clear8; + break; + case GL_UNSIGNED_SHORT: + clear16 = (GLushort) ctx->Color.ClearIndex; + clearVal = &clear16; + break; + case GL_UNSIGNED_INT: + clear32 = ctx->Color.ClearIndex; + clearVal = &clear32; + break; + default: + _mesa_problem(ctx, "Bad rb DataType in clear_color_buffer"); + return; } + for (i = 0; i < height; i++) + rb->PutMonoRow(ctx, rb, width, x, y + i, clearVal, NULL); } +#endif } @@ -141,20 +233,46 @@ clear_color_buffer(GLcontext *ctx) static void clear_color_buffers(GLcontext *ctx) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); - GLuint bufferBit; + GLboolean masking; + GLuint i; - /* loop over four possible dest color buffers */ - for (bufferBit = 1; bufferBit <= DD_AUX3_BIT; bufferBit <<= 1) { - if (bufferBit & ctx->Color._DrawDestMask[0]) { - (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit); + if (ctx->Visual.rgbMode) { + if (ctx->Color.ColorMask[0] && + ctx->Color.ColorMask[1] && + ctx->Color.ColorMask[2] && + ctx->Color.ColorMask[3]) { + masking = GL_FALSE; + } + else { + masking = GL_TRUE; + } + } + else { + const GLuint indexBits = (1 << ctx->Visual.indexBits) - 1; + if ((ctx->Color.IndexMask & indexBits) == indexBits) { + masking = GL_FALSE; + } + else { + masking = GL_TRUE; + } + } - if (colorMask != 0xffffffff) { - clear_color_buffer_with_masking(ctx); + for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers[0]; i++) { + struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][i]; + if (ctx->Visual.rgbMode) { + if (masking) { + clear_rgba_buffer_with_masking(ctx, rb); } else { - clear_color_buffer(ctx); + clear_rgba_buffer(ctx, rb); + } + } + else { + if (masking) { + clear_ci_buffer_with_masking(ctx, rb); + } + else { + clear_ci_buffer(ctx, rb); } } } @@ -171,26 +289,27 @@ clear_color_buffers(GLcontext *ctx) * \param all if GL_TRUE, clear whole buffer, else clear specified region. */ void -_swrast_Clear( GLcontext *ctx, GLbitfield mask, - GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +_swrast_Clear(GLcontext *ctx, GLbitfield mask, + GLboolean all, GLint x, GLint y, GLint width, GLint height) { SWcontext *swrast = SWRAST_CONTEXT(ctx); + (void) all; (void) x; (void) y; (void) width; (void) height; -#ifdef DEBUG + +#ifdef DEBUG_FOO { 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_AUX0_BIT | - DD_AUX1_BIT | - DD_AUX2_BIT | - DD_AUX3_BIT; + BUFFER_BIT_FRONT_LEFT | + BUFFER_BIT_FRONT_RIGHT | + BUFFER_BIT_BACK_LEFT | + BUFFER_BIT_BACK_RIGHT | + BUFFER_BIT_DEPTH | + BUFFER_BIT_STENCIL | + BUFFER_BIT_ACCUM | + BUFFER_BIT_AUX0 | + BUFFER_BIT_AUX1 | + BUFFER_BIT_AUX2 | + BUFFER_BIT_AUX3; assert((mask & (~legalBits)) == 0); } #endif @@ -199,22 +318,30 @@ _swrast_Clear( GLcontext *ctx, GLbitfield mask, /* do software clearing here */ if (mask) { - if (mask & ctx->Color._DrawDestMask[0]) { + if (mask & ctx->DrawBuffer->_ColorDrawBufferMask[0]) { clear_color_buffers(ctx); /* clear software-based alpha buffer(s) */ +#if OLD_RENDERBUFFER && 0 if (ctx->DrawBuffer->UseSoftwareAlphaBuffers && ctx->Color.ColorMask[ACOMP]) { _swrast_clear_alpha_buffers( ctx ); } +#endif } - if (mask & DD_DEPTH_BIT) { - _swrast_clear_depth_buffer(ctx); + if (mask & BUFFER_BIT_DEPTH) { + struct gl_renderbuffer *rb + = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; + _swrast_clear_depth_buffer(ctx, rb); } - if (mask & DD_ACCUM_BIT) { - _swrast_clear_accum_buffer(ctx); + if (mask & BUFFER_BIT_ACCUM) { + struct gl_renderbuffer *rb + = ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer; + _swrast_clear_accum_buffer(ctx, rb); } - if (mask & DD_STENCIL_BIT) { - _swrast_clear_stencil_buffer(ctx); + if (mask & BUFFER_BIT_STENCIL) { + struct gl_renderbuffer *rb + = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; + _swrast_clear_stencil_buffer(ctx, rb); } } @@ -222,33 +349,6 @@ _swrast_Clear( GLcontext *ctx, GLbitfield mask, } -/** - * 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 ) -{ - /* Reallocate other buffers if needed. */ - if (buffer->UseSoftwareDepthBuffer) { - _swrast_alloc_depth_buffer( buffer ); - } - if (buffer->UseSoftwareStencilBuffer) { - _swrast_alloc_stencil_buffer( buffer ); - } - if (buffer->UseSoftwareAccumBuffer) { - _swrast_alloc_accum_buffer( buffer ); - } - if (buffer->UseSoftwareAlphaBuffers) { - _swrast_alloc_alpha_buffers( buffer ); - } - if (buffer->UseSoftwareAuxBuffers) { - _swrast_alloc_aux_buffers( buffer ); - } -} - - /* * Fallback for ctx->Driver.DrawBuffer() */ @@ -281,7 +381,7 @@ _swrast_use_read_buffer( GLcontext *ctx ) SWcontext *swrast = SWRAST_CONTEXT(ctx); /* Do this so the software-emulated alpha plane span functions work! */ - swrast->CurrentBufferBit = ctx->Pixel._ReadSrcMask; + swrast->CurrentBufferBit = ctx->ReadBuffer->_ColorReadBufferMask; /* Tell the device driver where to read/write spans */ swrast->Driver.SetBuffer(ctx, ctx->ReadBuffer, swrast->CurrentBufferBit); } @@ -307,25 +407,25 @@ _swrast_use_draw_buffer( GLcontext *ctx ) * we loop over multiple color buffers when needed. */ - if (ctx->Color._DrawDestMask[0] & DD_FRONT_LEFT_BIT) - swrast->CurrentBufferBit = DD_FRONT_LEFT_BIT; - else if (ctx->Color._DrawDestMask[0] & DD_BACK_LEFT_BIT) - swrast->CurrentBufferBit = DD_BACK_LEFT_BIT; - else if (ctx->Color._DrawDestMask[0] & DD_FRONT_RIGHT_BIT) - swrast->CurrentBufferBit = DD_FRONT_RIGHT_BIT; - else if (ctx->Color._DrawDestMask[0] & DD_BACK_RIGHT_BIT) - swrast->CurrentBufferBit = DD_BACK_RIGHT_BIT; - else if (ctx->Color._DrawDestMask[0] & DD_AUX0_BIT) - swrast->CurrentBufferBit = DD_AUX0_BIT; - else if (ctx->Color._DrawDestMask[0] & DD_AUX1_BIT) - swrast->CurrentBufferBit = DD_AUX1_BIT; - else if (ctx->Color._DrawDestMask[0] & DD_AUX2_BIT) - swrast->CurrentBufferBit = DD_AUX2_BIT; - else if (ctx->Color._DrawDestMask[0] & DD_AUX3_BIT) - swrast->CurrentBufferBit = DD_AUX3_BIT; + if (ctx->DrawBuffer->_ColorDrawBufferMask[0] & BUFFER_BIT_FRONT_LEFT) + swrast->CurrentBufferBit = BUFFER_BIT_FRONT_LEFT; + else if (ctx->DrawBuffer->_ColorDrawBufferMask[0] & BUFFER_BIT_BACK_LEFT) + swrast->CurrentBufferBit = BUFFER_BIT_BACK_LEFT; + else if (ctx->DrawBuffer->_ColorDrawBufferMask[0] & BUFFER_BIT_FRONT_RIGHT) + swrast->CurrentBufferBit = BUFFER_BIT_FRONT_RIGHT; + else if (ctx->DrawBuffer->_ColorDrawBufferMask[0] & BUFFER_BIT_BACK_RIGHT) + swrast->CurrentBufferBit = BUFFER_BIT_BACK_RIGHT; + else if (ctx->DrawBuffer->_ColorDrawBufferMask[0] & BUFFER_BIT_AUX0) + swrast->CurrentBufferBit = BUFFER_BIT_AUX0; + else if (ctx->DrawBuffer->_ColorDrawBufferMask[0] & BUFFER_BIT_AUX1) + swrast->CurrentBufferBit = BUFFER_BIT_AUX1; + else if (ctx->DrawBuffer->_ColorDrawBufferMask[0] & BUFFER_BIT_AUX2) + swrast->CurrentBufferBit = BUFFER_BIT_AUX2; + else if (ctx->DrawBuffer->_ColorDrawBufferMask[0] & BUFFER_BIT_AUX3) + swrast->CurrentBufferBit = BUFFER_BIT_AUX3; else /* glDrawBuffer(GL_NONE) */ - swrast->CurrentBufferBit = DD_FRONT_LEFT_BIT; /* we always have this buffer */ + swrast->CurrentBufferBit = BUFFER_BIT_FRONT_LEFT; /* we always have this buffer */ 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 f6dcdbb9644..00c4ae4bc9c 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -73,11 +73,6 @@ _swrast_update_rasterflags( GLcontext *ctx ) if (ctx->Color.IndexLogicOpEnabled) rasterMask |= LOGIC_OP_BIT; } - if (ctx->DrawBuffer->UseSoftwareAlphaBuffers - && ctx->Color.ColorMask[ACOMP] - && ctx->Color.DrawBuffer != GL_NONE) - rasterMask |= ALPHABUF_BIT; - if ( ctx->Viewport.X < 0 || ctx->Viewport.X + ctx->Viewport.Width > (GLint) ctx->DrawBuffer->Width || ctx->Viewport.Y < 0 @@ -93,7 +88,9 @@ _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 (_mesa_bitcount(ctx->Color._DrawDestMask[0]) != 1) { +#if NEW_RENDERBUFFER + if (ctx->DrawBuffer->_NumColorDrawBuffers[0] != 1) { +#endif /* more than one color buffer designated for writing (or zero buffers) */ rasterMask |= MULTI_DRAW_BIT; } @@ -446,26 +443,6 @@ _swrast_invalidate_state( GLcontext *ctx, GLuint new_state ) if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC) for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) swrast->TextureSample[i] = _swrast_validate_texture_sample; - - /* Debug checks */ - if (ctx->Visual.rgbMode) { - ASSERT(swrast->Driver.WriteRGBASpan); - ASSERT(swrast->Driver.WriteRGBSpan); - ASSERT(swrast->Driver.WriteMonoRGBASpan); - ASSERT(swrast->Driver.WriteRGBAPixels); - ASSERT(swrast->Driver.WriteMonoRGBAPixels); - ASSERT(swrast->Driver.ReadRGBASpan); - ASSERT(swrast->Driver.ReadRGBAPixels); - } - else { - ASSERT(swrast->Driver.WriteCI32Span); - ASSERT(swrast->Driver.WriteCI8Span); - ASSERT(swrast->Driver.WriteMonoCISpan); - ASSERT(swrast->Driver.WriteCI32Pixels); - ASSERT(swrast->Driver.WriteMonoCIPixels); - ASSERT(swrast->Driver.ReadCI32Span); - ASSERT(swrast->Driver.ReadCI32Pixels); - } } @@ -625,12 +602,12 @@ _swrast_CreateContext( GLcontext *ctx ) swrast->AllowPixelFog = GL_TRUE; if (ctx->Visual.doubleBufferMode) - swrast->CurrentBufferBit = DD_BACK_LEFT_BIT; + swrast->CurrentBufferBit = BUFFER_BIT_BACK_LEFT; else - swrast->CurrentBufferBit = DD_FRONT_LEFT_BIT; + swrast->CurrentBufferBit = BUFFER_FRONT_LEFT; /* Optimized Accum buffer */ - swrast->_IntegerAccumMode = GL_TRUE; + swrast->_IntegerAccumMode = GL_FALSE; swrast->_IntegerAccumScaler = 0.0; for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h index 6eac3232b05..5f5efdc22ae 100644 --- a/src/mesa/swrast/s_context.h +++ b/src/mesa/swrast/s_context.h @@ -240,7 +240,6 @@ typedef void (*swrast_tri_func)( GLcontext *ctx, const SWvertex *, #define CLIP_BIT 0x020 /**< Scissor or window clip pixels */ #define STENCIL_BIT 0x040 /**< Stencil pixels */ #define MASKING_BIT 0x080 /**< Do glColorMask or glIndexMask */ -#define ALPHABUF_BIT 0x100 /**< Using software alpha buffer */ #define MULTI_DRAW_BIT 0x400 /**< Write to more than one color- */ /**< buffer or no buffers. */ #define OCCLUSION_BIT 0x800 /**< GL_HP_occlusion_test enabled */ @@ -294,8 +293,6 @@ typedef struct GLboolean _IntegerAccumMode; /**< Storing unscaled integers? */ GLfloat _IntegerAccumScaler; /**< Implicit scale factor */ - GLchan *CurAuxBuffer; - /* Working values: */ GLuint StippleCounter; /**< Line stipple counter */ diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c index 7454cfd2d2b..3d6d91de51d 100644 --- a/src/mesa/swrast/s_copypix.c +++ b/src/mesa/swrast/s_copypix.c @@ -131,6 +131,7 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GLint width, GLint height, GLint destx, GLint desty) { SWcontext *swrast = SWRAST_CONTEXT(ctx); + struct gl_renderbuffer *drawRb = NULL; GLboolean quick_draw; GLint row; GLboolean changeBuffer; @@ -152,6 +153,7 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, && destx >= 0 && destx + width <= (GLint) ctx->DrawBuffer->Width) { quick_draw = GL_TRUE; + drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0][0]; } else { quick_draw = GL_FALSE; @@ -185,8 +187,8 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, for (row = 0; row < height; row++) { GLchan rgba[MAX_WIDTH][4]; /* Read GLchan and convert to GLfloat */ - _swrast_read_rgba_span(ctx, ctx->ReadBuffer, width, srcx, - srcy + row, rgba); + _swrast_read_rgba_span(ctx, ctx->ReadBuffer->_ColorReadBuffer, + width, srcx, srcy + row, rgba); chan_span_to_float(width, (CONST GLchan (*)[4]) rgba, (GLfloat (*)[4]) dest); dest += 4 * width; @@ -240,8 +242,14 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, dy = desty + row; if (quick_draw && dy >= 0 && dy < (GLint) ctx->DrawBuffer->Height) { - (*swrast->Driver.WriteRGBASpan)( ctx, width, destx, dy, - (const GLchan (*)[4])span.array->rgba, NULL ); +#if OLD_RENDERBUFFER + if (swrast->Driver.WriteRGBASpan) + swrast->Driver.WriteRGBASpan(ctx, drawRb, width, destx, dy, + (const GLchan (*)[4]) span.array->rgba, NULL); + else +#endif + drawRb->PutRow(ctx, drawRb, width, destx, dy, + span.array->rgba, NULL); } else if (zoom) { span.x = destx; @@ -271,6 +279,7 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GLint width, GLint height, GLint destx, GLint desty) { SWcontext *swrast = SWRAST_CONTEXT(ctx); + struct gl_renderbuffer *drawRb; GLchan *tmpImage,*p; GLboolean quick_draw; GLint sy, dy, stepy, j; @@ -280,6 +289,11 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, const GLuint transferOps = ctx->_ImageTransferState; struct sw_span span; + if (!ctx->ReadBuffer->_ColorReadBuffer) { + /* no readbuffer - OK */ + return; + } + INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA); if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) { @@ -319,9 +333,11 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, && destx >= 0 && destx + width <= (GLint) ctx->DrawBuffer->Width) { quick_draw = GL_TRUE; + drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0][0]; } else { quick_draw = GL_FALSE; + drawRb = NULL; } /* If read and draw buffer are different we must do buffer switching */ @@ -341,8 +357,8 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, /* read the source image */ p = tmpImage; for (j = 0; j < height; j++, ssy += stepy) { - _swrast_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, ssy, - (GLchan (*)[4]) p ); + _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, + width, srcx, ssy, (GLchan (*)[4]) p ); p += width * 4; } p = tmpImage; @@ -370,8 +386,8 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, if (changeBuffer) _swrast_use_read_buffer(ctx); ASSERT(width < MAX_WIDTH); - _swrast_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, sy, - span.array->rgba ); + _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, + width, srcx, sy, span.array->rgba ); if (changeBuffer) _swrast_use_draw_buffer(ctx); } @@ -397,8 +413,14 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, /* Write color span */ if (quick_draw && dy >= 0 && dy < (GLint) ctx->DrawBuffer->Height) { - (*swrast->Driver.WriteRGBASpan)( ctx, width, destx, dy, - (const GLchan (*)[4])span.array->rgba, NULL ); +#if OLD_RENDERBUFFER + if (swrast->Driver.WriteRGBASpan) + swrast->Driver.WriteRGBASpan(ctx, drawRb, width, destx, dy, + (const GLchan (*)[4])span.array->rgba, NULL); + else +#endif + drawRb->PutRow(ctx, drawRb, width, destx, dy, span.array->rgba, NULL); + } else if (zoom) { span.x = destx; @@ -435,6 +457,11 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy, GLint overlapping; struct sw_span span; + if (!ctx->ReadBuffer->_ColorReadBuffer) { + /* no readbuffer - OK */ + return; + } + INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX); /* Determine if copy should be bottom-to-top or top-to-bottom */ @@ -481,7 +508,8 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy, /* read the image */ p = tmpImage; for (j = 0; j < height; j++, ssy += stepy) { - _swrast_read_index_span( ctx, ctx->ReadBuffer, width, srcx, ssy, p ); + _swrast_read_index_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, + width, srcx, ssy, p ); p += width; } p = tmpImage; @@ -505,8 +533,8 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy, else { if (changeBuffer) _swrast_use_read_buffer(ctx); - _swrast_read_index_span( ctx, ctx->ReadBuffer, width, srcx, sy, - span.array->index ); + _swrast_read_index_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, + width, srcx, sy, span.array->index ); if (changeBuffer) _swrast_use_draw_buffer(ctx); } @@ -543,6 +571,9 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy, GLint width, GLint height, GLint destx, GLint desty ) { + const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; + struct gl_renderbuffer *readRb + = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; GLfloat *p, *tmpImage; GLint sy, dy, stepy; GLint i, j; @@ -550,6 +581,11 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy, GLint overlapping; struct sw_span span; + if (!readRb) { + /* no readbuffer - OK */ + return; + } + INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z); if (!ctx->Visual.depthBits) { @@ -592,7 +628,7 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy, } p = tmpImage; for (j = 0; j < height; j++, ssy += stepy) { - _swrast_read_depth_span_float(ctx, width, srcx, ssy, p); + _swrast_read_depth_span_float(ctx, readRb, width, srcx, ssy, p); p += width; } p = tmpImage; @@ -604,20 +640,21 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy, for (j = 0; j < height; j++, sy += stepy, dy += stepy) { GLfloat depth[MAX_WIDTH]; - + float sum = 0; /* get depth values */ if (overlapping) { MEMCPY(depth, p, width * sizeof(GLfloat)); p += width; } else { - _swrast_read_depth_span_float(ctx, width, srcx, sy, depth); + _swrast_read_depth_span_float(ctx, readRb, width, srcx, sy, depth); } /* apply scale and bias */ for (i = 0; i < width; i++) { GLfloat d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias; - span.array->z[i] = (GLdepth) (CLAMP(d, 0.0F, 1.0F) * ctx->DepthMax); + sum += d; + span.array->z[i] = (GLdepth) (CLAMP(d, 0.0F, 1.0F) * depthMax); } /* write depth values */ @@ -650,6 +687,8 @@ copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy, GLint width, GLint height, GLint destx, GLint desty ) { + struct gl_renderbuffer *rb + = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; GLint sy, dy, stepy; GLint j; GLstencil *p, *tmpImage; @@ -662,6 +701,11 @@ copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy, return; } + if (!rb) { + /* no readbuffer - OK */ + return; + } + /* Determine if copy should be bottom-to-top or top-to-bottom */ if (srcy < desty) { /* top-down max-to-min */ @@ -693,7 +737,7 @@ copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy, } p = tmpImage; for (j = 0; j < height; j++, ssy += stepy) { - _swrast_read_stencil_span( ctx, width, srcx, ssy, p ); + _swrast_read_stencil_span( ctx, rb, width, srcx, ssy, p ); p += width; } p = tmpImage; @@ -712,7 +756,7 @@ copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy, p += width; } else { - _swrast_read_stencil_span( ctx, width, srcx, sy, stencil ); + _swrast_read_stencil_span( ctx, rb, width, srcx, sy, stencil ); } /* Apply shift, offset, look-up table */ diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c index 0142fe15520..e36878e6fc8 100644 --- a/src/mesa/swrast/s_depth.c +++ b/src/mesa/swrast/s_depth.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 5.1 + * Version: 6.3 * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -27,51 +27,21 @@ #include "context.h" #include "macros.h" #include "imports.h" +#include "fbobject.h" #include "s_depth.h" #include "s_context.h" /** - * Return address of depth buffer value for given window coord. - */ -GLvoid * -_swrast_zbuffer_address(GLcontext *ctx, GLint x, GLint y) -{ - if (ctx->Visual.depthBits <= 16) - return (GLushort *) ctx->DrawBuffer->DepthBuffer - + ctx->DrawBuffer->Width * y + x; - else - return (GLuint *) ctx->DrawBuffer->DepthBuffer - + ctx->DrawBuffer->Width * y + x; -} - - -#define Z_ADDRESS16( CTX, X, Y ) \ - ( ((GLushort *) (CTX)->DrawBuffer->DepthBuffer) \ - + (CTX)->DrawBuffer->Width * (Y) + (X) ) - -#define Z_ADDRESS32( CTX, X, Y ) \ - ( ((GLuint *) (CTX)->DrawBuffer->DepthBuffer) \ - + (CTX)->DrawBuffer->Width * (Y) + (X) ) - - - -/**********************************************************************/ -/***** Depth Testing Functions *****/ -/**********************************************************************/ - - -/* - * Do depth test for an array of fragments. This is used both for - * software and hardware Z buffers. + * Do depth test for a horizontal span of fragments. * Input: zbuffer - array of z values in the zbuffer * z - array of fragment z values * Return: number of fragments which pass the test. */ static GLuint depth_test_span16( GLcontext *ctx, GLuint n, - GLushort zbuffer[], const GLdepth z[], GLubyte mask[] ) + GLushort zbuffer[], const GLuint z[], GLubyte mask[] ) { GLuint passed = 0; @@ -300,7 +270,7 @@ depth_test_span16( GLcontext *ctx, GLuint n, static GLuint depth_test_span32( GLcontext *ctx, GLuint n, - GLuint zbuffer[], const GLdepth z[], GLubyte mask[] ) + GLuint zbuffer[], const GLuint z[], GLubyte mask[] ) { GLuint passed = 0; @@ -529,74 +499,69 @@ depth_test_span32( GLcontext *ctx, GLuint n, /* - * Apply depth test to span of fragments. Hardware or software z buffer. + * Apply depth test to span of fragments. */ static GLuint depth_test_span( GLcontext *ctx, struct sw_span *span) { + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; const GLint x = span->x; const GLint y = span->y; - const GLuint n = span->end; - SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLuint count = span->end; + const GLuint *zValues = span->array->z; + GLubyte *mask = span->array->mask; + GLuint passed; ASSERT((span->arrayMask & SPAN_XY) == 0); ASSERT(span->arrayMask & SPAN_Z); - if (swrast->Driver.ReadDepthSpan) { - /* hardware-based depth buffer */ - GLdepth zbuffer[MAX_WIDTH]; - GLuint passed; - (*swrast->Driver.ReadDepthSpan)(ctx, n, x, y, zbuffer); - passed = depth_test_span32(ctx, n, zbuffer, span->array->z, - span->array->mask); - ASSERT(swrast->Driver.WriteDepthSpan); - (*swrast->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer, - span->array->mask); - if (passed < n) - span->writeAll = GL_FALSE; - return passed; - } - else { - GLuint passed; - /* software depth buffer */ - if (ctx->Visual.depthBits <= 16) { - GLushort *zptr = (GLushort *) Z_ADDRESS16(ctx, x, y); - passed = depth_test_span16(ctx, n, zptr, span->array->z, span->array->mask); + if (rb->GetPointer(ctx, rb, 0, 0)) { + /* Directly access buffer */ + if (ctx->DrawBuffer->Visual.depthBits <= 16) { + GLushort *zbuffer = (GLushort *) rb->GetPointer(ctx, rb, x, y); + passed = depth_test_span16(ctx, count, zbuffer, zValues, mask); } else { - GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, x, y); - passed = depth_test_span32(ctx, n, zptr, span->array->z, span->array->mask); + GLuint *zbuffer = (GLuint *) rb->GetPointer(ctx, rb, x, y); + passed = depth_test_span32(ctx, count, zbuffer, zValues, mask); } -#if 1 - if (passed < span->end) { - span->writeAll = GL_FALSE; + } + else { + /* read depth values from buffer, test, write back */ + if (rb->DataType == GL_UNSIGNED_SHORT) { + GLushort zbuffer[MAX_WIDTH]; + rb->GetRow(ctx, rb, count, x, y, zbuffer); + passed = depth_test_span16(ctx, count, zbuffer, zValues, mask ); + rb->PutRow(ctx, rb, count, x, y, zbuffer, NULL); } -#else - /* this causes a glDrawPixels(GL_DEPTH_COMPONENT) conformance failure */ - if (passed < span->end) { - span->writeAll = GL_FALSE; - if (passed == 0) { - span->end = 0; - return 0; - } - while (span->end > 0 && span->mask[span->end - 1] == 0) - span->end --; + else { + GLuint zbuffer[MAX_WIDTH]; + ASSERT(rb->DataType == GL_UNSIGNED_INT); + rb->GetRow(ctx, rb, count, x, y, zbuffer); + passed = depth_test_span32(ctx, count, zbuffer, zValues, mask ); + rb->PutRow(ctx, rb, count, x, y, zbuffer, NULL); } -#endif - return passed; } + + if (passed < count) { + span->writeAll = GL_FALSE; + } + return passed; } +#define Z_ADDRESS(X, Y) (zStart + (Y) * stride + (X)) + /* - * Do depth testing for an array of fragments using software Z buffer. + * Do depth testing for an array of fragments at assorted locations. */ static void -software_depth_test_pixels16( GLcontext *ctx, GLuint n, - const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ) +direct_depth_test_pixels16(GLcontext *ctx, GLushort *zStart, GLuint stride, + GLuint n, const GLint x[], const GLint y[], + const GLuint z[], GLubyte mask[] ) { /* switch cases ordered from most frequent to less frequent */ switch (ctx->Depth.Func) { @@ -606,7 +571,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]); + GLushort *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] < *zptr) { /* pass */ *zptr = z[i]; @@ -623,7 +588,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]); + GLushort *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] < *zptr) { /* pass */ } @@ -641,7 +606,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]); + GLushort *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] <= *zptr) { /* pass */ *zptr = z[i]; @@ -658,7 +623,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]); + GLushort *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] <= *zptr) { /* pass */ } @@ -676,7 +641,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]); + GLushort *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] >= *zptr) { /* pass */ *zptr = z[i]; @@ -693,7 +658,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]); + GLushort *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] >= *zptr) { /* pass */ } @@ -711,7 +676,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]); + GLushort *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] > *zptr) { /* pass */ *zptr = z[i]; @@ -728,7 +693,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]); + GLushort *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] > *zptr) { /* pass */ } @@ -746,7 +711,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]); + GLushort *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] != *zptr) { /* pass */ *zptr = z[i]; @@ -763,7 +728,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]); + GLushort *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] != *zptr) { /* pass */ } @@ -781,7 +746,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]); + GLushort *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] == *zptr) { /* pass */ *zptr = z[i]; @@ -798,7 +763,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]); + GLushort *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] == *zptr) { /* pass */ } @@ -816,7 +781,7 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]); + GLushort *zptr = Z_ADDRESS(x[i], y[i]); *zptr = z[i]; } } @@ -830,19 +795,19 @@ software_depth_test_pixels16( GLcontext *ctx, GLuint n, _mesa_bzero(mask, n * sizeof(GLubyte)); break; default: - _mesa_problem(ctx, "Bad depth func in software_depth_test_pixels"); + _mesa_problem(ctx, "Bad depth func in direct_depth_test_pixels"); } } /* - * Do depth testing for an array of fragments using software Z buffer. + * Do depth testing for an array of fragments with direct access to zbuffer. */ static void -software_depth_test_pixels32( GLcontext *ctx, GLuint n, - const GLint x[], const GLint y[], - const GLdepth z[], GLubyte mask[] ) +direct_depth_test_pixels32(GLcontext *ctx, GLuint *zStart, GLuint stride, + GLuint n, const GLint x[], const GLint y[], + const GLuint z[], GLubyte mask[] ) { /* switch cases ordered from most frequent to less frequent */ switch (ctx->Depth.Func) { @@ -852,7 +817,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]); + GLuint *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] < *zptr) { /* pass */ *zptr = z[i]; @@ -869,7 +834,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]); + GLuint *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] < *zptr) { /* pass */ } @@ -887,7 +852,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]); + GLuint *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] <= *zptr) { /* pass */ *zptr = z[i]; @@ -904,7 +869,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]); + GLuint *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] <= *zptr) { /* pass */ } @@ -922,7 +887,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]); + GLuint *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] >= *zptr) { /* pass */ *zptr = z[i]; @@ -939,7 +904,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]); + GLuint *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] >= *zptr) { /* pass */ } @@ -957,7 +922,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]); + GLuint *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] > *zptr) { /* pass */ *zptr = z[i]; @@ -974,7 +939,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]); + GLuint *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] > *zptr) { /* pass */ } @@ -992,7 +957,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]); + GLuint *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] != *zptr) { /* pass */ *zptr = z[i]; @@ -1009,7 +974,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]); + GLuint *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] != *zptr) { /* pass */ } @@ -1027,7 +992,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]); + GLuint *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] == *zptr) { /* pass */ *zptr = z[i]; @@ -1044,7 +1009,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]); + GLuint *zptr = Z_ADDRESS(x[i], y[i]); if (z[i] == *zptr) { /* pass */ } @@ -1062,7 +1027,7 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, GLuint i; for (i=0; i<n; i++) { if (mask[i]) { - GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]); + GLuint *zptr = Z_ADDRESS(x[i], y[i]); *zptr = z[i]; } } @@ -1076,275 +1041,55 @@ software_depth_test_pixels32( GLcontext *ctx, GLuint n, _mesa_bzero(mask, n * sizeof(GLubyte)); break; default: - _mesa_problem(ctx, "Bad depth func in software_depth_test_pixels"); + _mesa_problem(ctx, "Bad depth func in direct_depth_test_pixels"); } } -/* - * Do depth testing for an array of pixels using hardware Z buffer. - * Input/output: zbuffer - array of depth values from Z buffer - * Input: z - array of fragment z values. - */ -static void -hardware_depth_test_pixels( GLcontext *ctx, GLuint n, GLdepth zbuffer[], - const GLdepth z[], GLubyte mask[] ) -{ - /* switch cases ordered from most frequent to less frequent */ - switch (ctx->Depth.Func) { - case GL_LESS: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - GLuint i; - for (i=0; i<n; i++) { - if (mask[i]) { - if (z[i] < zbuffer[i]) { - /* pass */ - zbuffer[i] = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - GLuint i; - for (i=0; i<n; i++) { - if (mask[i]) { - if (z[i] < zbuffer[i]) { - /* pass */ - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - break; - case GL_LEQUAL: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - GLuint i; - for (i=0; i<n; i++) { - if (mask[i]) { - if (z[i] <= zbuffer[i]) { - /* pass */ - zbuffer[i] = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - GLuint i; - for (i=0; i<n; i++) { - if (mask[i]) { - if (z[i] <= zbuffer[i]) { - /* pass */ - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - break; - case GL_GEQUAL: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - GLuint i; - for (i=0; i<n; i++) { - if (mask[i]) { - if (z[i] >= zbuffer[i]) { - /* pass */ - zbuffer[i] = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - GLuint i; - for (i=0; i<n; i++) { - if (mask[i]) { - if (z[i] >= zbuffer[i]) { - /* pass */ - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - break; - case GL_GREATER: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - GLuint i; - for (i=0; i<n; i++) { - if (mask[i]) { - if (z[i] > zbuffer[i]) { - /* pass */ - zbuffer[i] = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - GLuint i; - for (i=0; i<n; i++) { - if (mask[i]) { - if (z[i] > zbuffer[i]) { - /* pass */ - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - break; - case GL_NOTEQUAL: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - GLuint i; - for (i=0; i<n; i++) { - if (mask[i]) { - if (z[i] != zbuffer[i]) { - /* pass */ - zbuffer[i] = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - GLuint i; - for (i=0; i<n; i++) { - if (mask[i]) { - if (z[i] != zbuffer[i]) { - /* pass */ - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - break; - case GL_EQUAL: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - GLuint i; - for (i=0; i<n; i++) { - if (mask[i]) { - if (z[i] == zbuffer[i]) { - /* pass */ - zbuffer[i] = z[i]; - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - else { - /* Don't update Z buffer */ - GLuint i; - for (i=0; i<n; i++) { - if (mask[i]) { - if (z[i] == zbuffer[i]) { - /* pass */ - } - else { - /* fail */ - mask[i] = 0; - } - } - } - } - break; - case GL_ALWAYS: - if (ctx->Depth.Mask) { - /* Update Z buffer */ - GLuint i; - for (i=0; i<n; i++) { - if (mask[i]) { - zbuffer[i] = z[i]; - } - } - } - else { - /* Don't update Z buffer or mask */ - } - break; - case GL_NEVER: - /* depth test never passes */ - _mesa_bzero(mask, n * sizeof(GLubyte)); - break; - default: - _mesa_problem(ctx, "Bad depth func in hardware_depth_test_pixels"); - } -} - - static GLuint depth_test_pixels( GLcontext *ctx, struct sw_span *span ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLuint n = span->end; + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; + const GLuint count = span->end; const GLint *x = span->array->x; const GLint *y = span->array->y; - const GLdepth *z = span->array->z; + const GLuint *z = span->array->z; GLubyte *mask = span->array->mask; - if (swrast->Driver.ReadDepthPixels) { - /* read depth values from hardware Z buffer */ - GLdepth zbuffer[MAX_WIDTH]; - (*swrast->Driver.ReadDepthPixels)(ctx, n, x, y, zbuffer); - - hardware_depth_test_pixels( ctx, n, zbuffer, z, mask ); - - /* update hardware Z buffer with new values */ - assert(swrast->Driver.WriteDepthPixels); - (*swrast->Driver.WriteDepthPixels)(ctx, n, x, y, zbuffer, mask ); + if (rb->GetPointer(ctx, rb, 0, 0)) { + /* Directly access values */ + if (rb->DataType == GL_UNSIGNED_SHORT) { + GLushort *zStart = (GLushort *) rb->Data; + GLuint stride = rb->Width; + direct_depth_test_pixels16(ctx, zStart, stride, count, x, y, z, mask); + } + else { + GLuint *zStart = (GLuint *) rb->Data; + GLuint stride = rb->Width; + direct_depth_test_pixels32(ctx, zStart, stride, count, x, y, z, mask); + } } else { - /* software depth testing */ - if (ctx->Visual.depthBits <= 16) - software_depth_test_pixels16(ctx, n, x, y, z, mask); - else - software_depth_test_pixels32(ctx, n, x, y, z, mask); + /* read depth values from buffer, test, write back */ + if (rb->DataType == GL_UNSIGNED_SHORT) { + GLushort zbuffer[MAX_WIDTH]; + rb->GetValues(ctx, rb, count, x, y, zbuffer); + depth_test_span16(ctx, count, zbuffer, z, mask ); + rb->PutValues(ctx, rb, count, x, y, zbuffer, NULL); + } + else { + GLuint zbuffer[MAX_WIDTH]; + ASSERT(rb->DataType == GL_UNSIGNED_INT); + rb->GetValues(ctx, rb, count, x, y, zbuffer); + depth_test_span32(ctx, count, zbuffer, z, mask ); + rb->PutValues(ctx, rb, count, x, y, zbuffer, NULL); + } } - return n; /* not really correct, but OK */ + + return count; /* not really correct, but OK */ } @@ -1372,24 +1117,33 @@ _swrast_depth_test_span( GLcontext *ctx, struct sw_span *span) GLboolean _swrast_depth_bounds_test( GLcontext *ctx, struct sw_span *span ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLdepth zMin = (GLdepth) (ctx->Depth.BoundsMin * ctx->DepthMaxF + 0.5F); - GLdepth zMax = (GLdepth) (ctx->Depth.BoundsMax * ctx->DepthMaxF + 0.5F); + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; + GLuint zMin = (GLuint) (ctx->Depth.BoundsMin * fb->_DepthMaxF + 0.5F); + GLuint zMax = (GLuint) (ctx->Depth.BoundsMax * fb->_DepthMaxF + 0.5F); GLubyte *mask = span->array->mask; + const GLuint count = span->end; GLuint i; GLboolean anyPass = GL_FALSE; - if (swrast->Driver.ReadDepthPixels) { - /* read depth values from hardware Z buffer */ - GLdepth zbuffer[MAX_WIDTH]; - ASSERT(span->end <= MAX_WIDTH); - if (span->arrayMask & SPAN_XY) - (*swrast->Driver.ReadDepthPixels)(ctx, span->end, span->array->x, - span->array->y, zbuffer); - else - (*swrast->Driver.ReadDepthSpan)(ctx, span->end, span->x, span->y, - zbuffer); - for (i = 0; i < span->end; i++) { + if (rb->DataType == GL_UNSIGNED_SHORT) { + /* get 16-bit values */ + GLushort zbuffer16[MAX_WIDTH], *zbuffer; + if (span->arrayMask & SPAN_XY) { + rb->GetValues(ctx, rb, count, span->array->x, span->array->y, zbuffer16); + zbuffer = zbuffer16; + } + else { + zbuffer = rb->GetPointer(ctx, rb, span->x, span->y); + if (!zbuffer) { + rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer16); + zbuffer = zbuffer16; + } + } + assert(zbuffer); + + /* Now do the tests */ + for (i = 0; i < count; i++) { if (mask[i]) { if (zbuffer[i] < zMin || zbuffer[i] > zMax) mask[i] = GL_FALSE; @@ -1399,62 +1153,32 @@ _swrast_depth_bounds_test( GLcontext *ctx, struct sw_span *span ) } } else { - /* software Z buffer */ + /* get 32-bit values */ + GLuint zbuffer32[MAX_WIDTH], *zbuffer; if (span->arrayMask & SPAN_XY) { - if (ctx->Visual.depthBits <= 16) { - /* 16 bits / Z */ - for (i = 0; i < span->end; i++) { - if (mask[i]) { - const GLushort *zPtr = Z_ADDRESS16(ctx, span->array->x[i], - span->array->y[i]); - if (*zPtr < zMin || *zPtr > zMax) - mask[i] = GL_FALSE; - else - anyPass = GL_TRUE; - } - } - } - else { - /* 32 bits / Z */ - for (i = 0; i < span->end; i++) { - if (mask[i]) { - const GLuint *zPtr = Z_ADDRESS32(ctx, span->array->x[i], - span->array->y[i]); - if (*zPtr < zMin || *zPtr > zMax) - mask[i] = GL_FALSE; - else - anyPass = GL_TRUE; - } - } - } + rb->GetValues(ctx, rb, count, span->array->x, span->array->y, zbuffer32); + zbuffer = zbuffer32; } else { - if (ctx->Visual.depthBits <= 16) { - /* 16 bits / Z */ - const GLushort *zPtr = Z_ADDRESS16(ctx, span->x, span->y); - for (i = 0; i < span->end; i++) { - if (mask[i]) { - if (zPtr[i] < zMin || zPtr[i] > zMax) - mask[i] = GL_FALSE; - else - anyPass = GL_TRUE; - } - } + zbuffer = rb->GetPointer(ctx, rb, span->x, span->y); + if (!zbuffer) { + rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer32); + zbuffer = zbuffer32; } - else { - /* 32 bits / Z */ - const GLuint *zPtr = Z_ADDRESS32(ctx, span->x, span->y); - for (i = 0; i < span->end; i++) { - if (mask[i]) { - if (zPtr[i] < zMin || zPtr[i] > zMax) - mask[i] = GL_FALSE; - else - anyPass = GL_TRUE; - } - } + } + assert(zbuffer); + + /* Now do the tests */ + for (i = 0; i < count; i++) { + if (mask[i]) { + if (zbuffer[i] < zMin || zbuffer[i] > zMax) + mask[i] = GL_FALSE; + else + anyPass = GL_TRUE; } } } + return anyPass; } @@ -1468,15 +1192,16 @@ _swrast_depth_bounds_test( GLcontext *ctx, struct sw_span *span ) /** * Read a span of depth values from the depth buffer. * This function does clipping before calling the device driver function. + * + * XXXX this is no longer a swrast function!!! + * */ void -_swrast_read_depth_span( GLcontext *ctx, - GLint n, GLint x, GLint y, GLdepth depth[] ) +_swrast_read_depth_span( GLcontext *ctx, struct gl_renderbuffer *rb, + GLint n, GLint x, GLint y, GLuint depth[] ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - if (y < 0 || y >= (GLint) ctx->DrawBuffer->Height || - x + (GLint) n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) { + if (y < 0 || y >= (GLint) rb->Height || + x + (GLint) n <= 0 || x >= (GLint) rb->Width) { /* span is completely outside framebuffer */ GLint i; for (i = 0; i < n; i++) @@ -1493,8 +1218,8 @@ _swrast_read_depth_span( GLcontext *ctx, n -= dx; depth += dx; } - if (x + n > (GLint) ctx->DrawBuffer->Width) { - GLint dx = x + n - (GLint) ctx->DrawBuffer->Width; + if (x + n > (GLint) rb->Width) { + GLint dx = x + n - (GLint) rb->Width; GLint i; for (i = 0; i < dx; i++) depth[n - i - 1] = 0; @@ -1504,292 +1229,127 @@ _swrast_read_depth_span( GLcontext *ctx, return; } - if (ctx->DrawBuffer->DepthBuffer) { - /* read from software depth buffer */ - if (ctx->Visual.depthBits <= 16) { - const GLushort *zptr = Z_ADDRESS16( ctx, x, y ); - GLint i; - for (i = 0; i < n; i++) { - depth[i] = zptr[i]; - } - } - else { - const GLuint *zptr = Z_ADDRESS32( ctx, x, y ); - GLint i; - for (i = 0; i < n; i++) { - depth[i] = zptr[i]; - } - } + /* we'll always return 32-bit values to our caller */ + if (!rb) { + _mesa_bzero(depth, n * sizeof(GLuint)); } - else if (swrast->Driver.ReadDepthSpan) { - /* read from hardware depth buffer */ - (*swrast->Driver.ReadDepthSpan)( ctx, n, x, y, depth ); + else if (rb->DataType == GL_UNSIGNED_INT) { + rb->GetRow(ctx, rb, x, y, n, depth); } else { - /* no depth buffer */ - _mesa_bzero(depth, n * sizeof(GLfloat)); + GLushort temp[MAX_WIDTH]; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT); + rb->GetRow(ctx, rb, n, x, y, temp); + for (i = 0; i < n; i++) { + depth[i] = temp[i]; + } } - } - - /** * Return a span of depth values from the depth buffer as floats in [0,1]. - * This is used for both hardware and software depth buffers. * Input: n - how many pixels * x,y - location of first pixel * Output: depth - the array of depth values */ void -_swrast_read_depth_span_float( GLcontext *ctx, - GLint n, GLint x, GLint y, GLfloat depth[] ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLfloat scale = 1.0F / ctx->DepthMaxF; - - if (y < 0 || y >= (GLint) ctx->DrawBuffer->Height || - x + (GLint) n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) { - /* span is completely outside framebuffer */ - GLint i; - for (i = 0; i < n; i++) - depth[i] = 0.0F; - return; - } - - if (x < 0) { - GLint dx = -x; - GLint i; - for (i = 0; i < dx; i++) - depth[i] = 0.0F; - n -= dx; - x = 0; - } - if (x + n > (GLint) ctx->DrawBuffer->Width) { - GLint dx = x + n - (GLint) ctx->DrawBuffer->Width; - GLint i; - for (i = 0; i < dx; i++) - depth[n - i - 1] = 0.0F; - n -= dx; - } - if (n <= 0) { - return; - } - - if (ctx->DrawBuffer->DepthBuffer) { - /* read from software depth buffer */ - if (ctx->Visual.depthBits <= 16) { - const GLushort *zptr = Z_ADDRESS16( ctx, x, y ); - GLint i; - for (i = 0; i < n; i++) { - depth[i] = (GLfloat) zptr[i] * scale; - } - } - else { - const GLuint *zptr = Z_ADDRESS32( ctx, x, y ); - GLint i; - for (i = 0; i < n; i++) { - depth[i] = (GLfloat) zptr[i] * scale; - } - } - } - else if (swrast->Driver.ReadDepthSpan) { - /* read from hardware depth buffer */ - GLdepth d[MAX_WIDTH]; - GLint i; - assert(n <= MAX_WIDTH); - (*swrast->Driver.ReadDepthSpan)( ctx, n, x, y, d ); - for (i = 0; i < n; i++) { - depth[i] = d[i] * scale; - } - } - else { - /* no depth buffer */ - _mesa_bzero(depth, n * sizeof(GLfloat)); - } -} - - - -/**********************************************************************/ -/***** Allocate and Clear Depth Buffer *****/ -/**********************************************************************/ - - - -/** - * Allocate a new depth buffer. If there's already a depth buffer allocated - * it will be free()'d. The new depth buffer will be uninitialized. - */ -void -_swrast_alloc_depth_buffer( GLframebuffer *buffer ) +_swrast_read_depth_span_float( GLcontext *ctx, struct gl_renderbuffer *rb, + GLint n, GLint x, GLint y, GLfloat depth[] ) { - GLint bytesPerValue; - - ASSERT(buffer->UseSoftwareDepthBuffer); + const GLfloat scale = 1.0F / ctx->DrawBuffer->_DepthMaxF; + GLuint temp[MAX_WIDTH]; + GLint i; - /* deallocate current depth buffer if present */ - if (buffer->DepthBuffer) { - MESA_PBUFFER_FREE(buffer->DepthBuffer); - buffer->DepthBuffer = NULL; - } - - /* allocate new depth buffer, but don't initialize it */ - if (buffer->Visual.depthBits <= 16) - bytesPerValue = sizeof(GLushort); - else - bytesPerValue = sizeof(GLuint); + assert(n <= MAX_WIDTH); - buffer->DepthBuffer = MESA_PBUFFER_ALLOC(buffer->Width * buffer->Height - * bytesPerValue); - - if (!buffer->DepthBuffer) { - /* out of memory */ - GET_CURRENT_CONTEXT(ctx); - if (ctx) { - ctx->Depth.Test = GL_FALSE; - ctx->NewState |= _NEW_DEPTH; - _mesa_error(ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer"); - } + _swrast_read_depth_span(ctx, rb, n, x, y, temp); + for (i = 0; i < n; i++) { + depth[i] = temp[i] * scale; } } /** - * Clear the depth buffer. If the depth buffer doesn't exist yet we'll - * allocate it now. - * This function is only called through Driver.clear_depth_buffer. + * Clear the depth buffer. + * XXX this is no longer a swrast function!!! */ void -_swrast_clear_depth_buffer( GLcontext *ctx ) +_swrast_clear_depth_buffer( GLcontext *ctx, struct gl_renderbuffer *rb ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLuint clearValue + = (GLuint) (ctx->Depth.Clear * ctx->DrawBuffer->_DepthMaxF); + GLint x, y, width, height; - if (ctx->Visual.depthBits == 0 - || !ctx->Depth.Mask) { + if (!rb || !ctx->Depth.Mask) { /* no depth buffer, or writing to it is disabled */ return; } - if (swrast->Driver.WriteMonoDepthSpan) { - const GLdepth clearValue = (GLdepth)(ctx->Depth.Clear * ctx->DepthMax); - 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; - GLint i; - - for (i = 0; i < height; i++) { - (*swrast->Driver.WriteMonoDepthSpan)( ctx, width, x, y + i, - clearValue, NULL ); - } - - return; - } - - if (!ctx->DrawBuffer->DepthBuffer) - return; - - /* The loops in this function have been written so the IRIX 5.3 - * C compiler can unroll them. Hopefully other compilers can too! - */ - - if (ctx->Scissor.Enabled) { - /* only clear scissor region */ - if (ctx->Visual.depthBits <= 16) { - const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->DepthMax); - const GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - const GLint cols = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - const GLint rowStride = ctx->DrawBuffer->Width; - GLushort *dRow = (GLushort *) ctx->DrawBuffer->DepthBuffer - + ctx->DrawBuffer->_Ymin * rowStride + ctx->DrawBuffer->_Xmin; - GLint i, j; - for (i = 0; i < rows; i++) { - for (j = 0; j < cols; j++) { - dRow[j] = clearValue; + assert(rb->_BaseFormat == GL_DEPTH_COMPONENT); + + /* compute region to clear */ + x = ctx->DrawBuffer->_Xmin; + y = ctx->DrawBuffer->_Ymin; + width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + + if (rb->GetPointer(ctx, rb, 0, 0)) { + /* Direct buffer access is possible. Either this is just malloc'd + * memory, or perhaps the driver mmap'd the zbuffer memory. + */ + if (rb->DataType == GL_UNSIGNED_SHORT) { + if (width == rb->Width && + (clearValue & 0xff) == ((clearValue >> 8) & 0xff)) { + /* optimized case */ + GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y); + GLuint len = width * height * sizeof(GLushort); + _mesa_memset(dst, (clearValue & 0xff), len); + } + else { + /* general case */ + GLint i, j; + for (i = 0; i < height; i++) { + GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y + i); + for (j = 0; j < width; j++) { + dst[j] = clearValue; + } } - dRow += rowStride; } } else { - const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->DepthMax); - const GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - const GLint cols = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - const GLint rowStride = ctx->DrawBuffer->Width; - GLuint *dRow = (GLuint *) ctx->DrawBuffer->DepthBuffer - + ctx->DrawBuffer->_Ymin * rowStride + ctx->DrawBuffer->_Xmin; GLint i, j; - for (i = 0; i < rows; i++) { - for (j = 0; j < cols; j++) { - dRow[j] = clearValue; + ASSERT(rb->DataType == GL_UNSIGNED_INT); + for (i = 0; i < height; i++) { + GLuint *dst = (GLuint *) rb->GetPointer(ctx, rb, x, y + i); + for (j = 0; j < width; j++) { + dst[j] = clearValue; } - dRow += rowStride; } } } else { - /* clear whole buffer */ - if (ctx->Visual.depthBits <= 16) { - const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->DepthMax); - if ((clearValue & 0xff) == (clearValue >> 8)) { - if (clearValue == 0) { - _mesa_bzero(ctx->DrawBuffer->DepthBuffer, - 2*ctx->DrawBuffer->Width*ctx->DrawBuffer->Height); - } - else { - /* lower and upper bytes of clear_value are same, use MEMSET */ - MEMSET( ctx->DrawBuffer->DepthBuffer, clearValue & 0xff, - 2 * ctx->DrawBuffer->Width * ctx->DrawBuffer->Height); - } + /* Direct access not possible. Use PutRow to write new values. */ + if (rb->DataType == GL_UNSIGNED_SHORT) { + GLushort clearRow[MAX_WIDTH]; + GLint i, j; + for (j = 0; j < width; j++) { + clearRow[j] = clearValue; } - else { - GLushort *d = (GLushort *) ctx->DrawBuffer->DepthBuffer; - GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; - while (n >= 16) { - d[0] = clearValue; d[1] = clearValue; - d[2] = clearValue; d[3] = clearValue; - d[4] = clearValue; d[5] = clearValue; - d[6] = clearValue; d[7] = clearValue; - d[8] = clearValue; d[9] = clearValue; - d[10] = clearValue; d[11] = clearValue; - d[12] = clearValue; d[13] = clearValue; - d[14] = clearValue; d[15] = clearValue; - d += 16; - n -= 16; - } - while (n > 0) { - *d++ = clearValue; - n--; - } + for (i = 0; i < height; i++) { + rb->PutRow(ctx, rb, width, x, y + i, clearRow, NULL); } } else { - /* >16 bit depth buffer */ - const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->DepthMax); - if (clearValue == 0) { - _mesa_bzero(ctx->DrawBuffer->DepthBuffer, - ctx->DrawBuffer->Width*ctx->DrawBuffer->Height*sizeof(GLuint)); + GLuint clearRow[MAX_WIDTH]; + GLint i, j; + assert(rb->DataType == GL_UNSIGNED_INT); + for (j = 0; j < width; j++) { + clearRow[j] = clearValue; } - else { - GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; - GLuint *d = (GLuint *) ctx->DrawBuffer->DepthBuffer; - while (n >= 16) { - d[0] = clearValue; d[1] = clearValue; - d[2] = clearValue; d[3] = clearValue; - d[4] = clearValue; d[5] = clearValue; - d[6] = clearValue; d[7] = clearValue; - d[8] = clearValue; d[9] = clearValue; - d[10] = clearValue; d[11] = clearValue; - d[12] = clearValue; d[13] = clearValue; - d[14] = clearValue; d[15] = clearValue; - d += 16; - n -= 16; - } - while (n > 0) { - *d++ = clearValue; - n--; - } + for (i = 0; i < height; i++) { + rb->PutRow(ctx, rb, width, x, y + i, clearRow, NULL); } } } diff --git a/src/mesa/swrast/s_depth.h b/src/mesa/swrast/s_depth.h index b972a84c56f..2229e8a22df 100644 --- a/src/mesa/swrast/s_depth.h +++ b/src/mesa/swrast/s_depth.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 5.1 + * Version: 6.3 * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -31,10 +31,6 @@ #include "s_context.h" -extern GLvoid * -_swrast_zbuffer_address(GLcontext *ctx, GLint x, GLint y); - - extern GLuint _swrast_depth_test_span( GLcontext *ctx, struct sw_span *span); @@ -44,21 +40,17 @@ _swrast_depth_bounds_test( GLcontext *ctx, struct sw_span *span ); extern void -_swrast_read_depth_span( GLcontext *ctx, - GLint n, GLint x, GLint y, GLdepth depth[] ); - - -extern void -_swrast_read_depth_span_float( GLcontext *ctx, GLint n, GLint x, GLint y, - GLfloat depth[] ); +_swrast_read_depth_span( GLcontext *ctx, struct gl_renderbuffer *rb, + GLint n, GLint x, GLint y, GLuint depth[] ); extern void -_swrast_alloc_depth_buffer( GLframebuffer *buffer ); +_swrast_read_depth_span_float( GLcontext *ctx, struct gl_renderbuffer *rb, + GLint n, GLint x, GLint y, GLfloat depth[] ); extern void -_swrast_clear_depth_buffer( GLcontext *ctx ); +_swrast_clear_depth_buffer( GLcontext *ctx, struct gl_renderbuffer *rb ); #endif diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c index 5b0a24bfb29..bd9a14b1197 100644 --- a/src/mesa/swrast/s_drawpix.c +++ b/src/mesa/swrast/s_drawpix.c @@ -51,6 +51,9 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels) { +#if NEW_RENDERBUFFER + struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0]; +#endif SWcontext *swrast = SWRAST_CONTEXT(ctx); struct sw_span span; @@ -59,6 +62,9 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, if (!ctx->Current.RasterPosValid) { return GL_TRUE; /* no-op */ } + + if (swrast->_RasterMask & MULTI_DRAW_BIT) + return GL_FALSE; if (ctx->Depth.Test) _swrast_span_default_z(ctx, &span); @@ -164,8 +170,15 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, /* no zooming */ GLint row; for (row=0; row<drawHeight; row++) { - (*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, - (CONST GLchan (*)[4]) src, NULL); +#if OLD_RENDERBUFFER + if (swrast->Driver.WriteRGBASpan) + swrast->Driver.WriteRGBASpan(ctx, rb, drawWidth, + destX, destY, + (CONST GLchan (*)[4]) src, + NULL); + else +#endif + rb->PutRow(ctx, rb, drawWidth, destX, destY, src, NULL); src += rowLength * 4; destY++; } @@ -175,8 +188,15 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, GLint row; for (row=0; row<drawHeight; row++) { destY--; - (*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, - (CONST GLchan (*)[4]) src, NULL); +#if OLD_RENDERBUFFER + if (swrast->Driver.WriteRGBASpan) + swrast->Driver.WriteRGBASpan(ctx, rb, drawWidth, + destX, destY, + (CONST GLchan (*)[4]) src, + NULL); + else +#endif + rb->PutRow(ctx, rb, drawWidth, destX, destY, src, NULL); src += rowLength * 4; } } @@ -204,8 +224,15 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { GLint row; for (row=0; row<drawHeight; row++) { - (*swrast->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY, - (CONST GLchan (*)[3]) src, NULL); +#if OLD_RENDERBUFFER + if (swrast->Driver.WriteRGBSpan) + (*swrast->Driver.WriteRGBSpan)(ctx, rb, drawWidth, + destX, destY, + (CONST GLchan (*)[3]) src, + NULL); + else +#endif + rb->PutRowRGB(ctx, rb, drawWidth, destX, destY, src, NULL); src += rowLength * 3; destY++; } @@ -215,8 +242,15 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, GLint row; for (row=0; row<drawHeight; row++) { destY--; - (*swrast->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY, - (CONST GLchan (*)[3]) src, NULL); +#if OLD_RENDERBUFFER + if (swrast->Driver.WriteRGBASpan) + (*swrast->Driver.WriteRGBSpan)(ctx, rb, drawWidth, + destX, destY, + (CONST GLchan (*)[3]) src, + NULL); + else +#endif + rb->PutRowRGB(ctx, rb, drawWidth, destX, destY, src, NULL); src += rowLength * 3; } } @@ -252,8 +286,15 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, span.array->rgb[i][1] = src[i]; span.array->rgb[i][2] = src[i]; } - (*swrast->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY, +#if OLD_RENDERBUFFER + if (swrast->Driver.WriteRGBSpan) + (*swrast->Driver.WriteRGBSpan)(ctx, rb, drawWidth, + destX, destY, (CONST GLchan (*)[3]) span.array->rgb, NULL); + else +#endif + rb->PutRowRGB(ctx, rb, drawWidth, destX, destY, + span.array->rgb, NULL); src += rowLength; destY++; } @@ -270,8 +311,15 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, span.array->rgb[i][2] = src[i]; } destY--; - (*swrast->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY, +#if OLD_RENDERBUFFER + if (swrast->Driver.WriteRGBSpan) + (*swrast->Driver.WriteRGBSpan)(ctx, rb, drawWidth, + destX, destY, (CONST GLchan (*)[3]) span.array->rgb, NULL); + else +#endif + rb->PutRow(ctx, rb, drawWidth, destX, destY, + span.array->rgb, NULL); src += rowLength; } } @@ -316,8 +364,14 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, span.array->rgba[i][2] = *ptr++; span.array->rgba[i][3] = *ptr++; } - (*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, +#if OLD_RENDERBUFFER + if (swrast->Driver.WriteRGBASpan) + swrast->Driver.WriteRGBASpan(ctx, rb, drawWidth, destX,destY, (CONST GLchan (*)[4]) span.array->rgba, NULL); + else +#endif + rb->PutRow(ctx, rb, drawWidth, destX, destY, + span.array->rgba, NULL); src += rowLength*2; destY++; } @@ -336,8 +390,14 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, span.array->rgba[i][3] = *ptr++; } destY--; - (*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, +#if OLD_RENDERBUFFER + if (swrast->Driver.WriteRGBASpan) + swrast->Driver.WriteRGBASpan(ctx, rb, drawWidth, destX,destY, (CONST GLchan (*)[4]) span.array->rgba, NULL); + else +#endif + rb->PutRow(ctx, rb, drawWidth, destX, destY, + span.array->rgba, NULL); src += rowLength*2; } } @@ -376,8 +436,15 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, for (row=0; row<drawHeight; row++) { ASSERT(drawWidth <= MAX_WIDTH); _mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.array->rgba); - (*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, +#if OLD_RENDERBUFFER + if (swrast->Driver.WriteRGBASpan) + swrast->Driver.WriteRGBASpan(ctx, rb, drawWidth, destX,destY, (const GLchan (*)[4]) span.array->rgba, NULL); + else +#endif + rb->PutRow(ctx, rb, drawWidth, destX, destY, + span.array->rgba, NULL); + src += rowLength; destY++; } @@ -390,8 +457,14 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, ASSERT(drawWidth <= MAX_WIDTH); _mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.array->rgba); destY--; - (*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, +#if OLD_RENDERBUFFER + if (swrast->Driver.WriteRGBASpan) + swrast->Driver.WriteRGBASpan(ctx, rb, drawWidth, destX,destY, (CONST GLchan (*)[4]) span.array->rgba, NULL); + else +#endif + rb->PutRow(ctx, rb, drawWidth, destX, destY, + span.array->rgba, NULL); src += rowLength; } return GL_TRUE; @@ -419,8 +492,11 @@ fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { /* no zooming */ for (row=0; row<drawHeight; row++) { - (*swrast->Driver.WriteCI8Span)(ctx, drawWidth, destX, destY, - src, NULL); + GLuint index32[MAX_WIDTH]; + GLint col; + for (col = 0; col < drawWidth; col++) + index32[col] = src[col]; + rb->PutRow(ctx, rb, drawWidth, destX, destY, index32, NULL); src += rowLength; destY++; } @@ -656,6 +732,7 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, } else { /* General case */ + const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; GLint row, skipPixels = 0; /* in case width > MAX_WIDTH do the copy in chunks */ @@ -683,10 +760,9 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, zSrc, unpack); /* clamp depth values to [0,1] and convert from floats to ints */ { - const GLfloat zScale = ctx->DepthMaxF; GLuint i; for (i = 0; i < span.end; i++) { - span.array->z[i] = (GLdepth) (floatSpan[i] * zScale); + span.array->z[i] = (GLdepth) (floatSpan[i] * depthMax); } } if (zoom) { @@ -717,6 +793,7 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, const GLvoid *pixels ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); + struct gl_renderbuffer *rb = NULL; /* only used for quickDraw path */ const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; const GLint desty = y; GLboolean quickDraw; @@ -744,11 +821,14 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, if (SWRAST_CONTEXT(ctx)->_RasterMask == 0 && !zoom && x >= 0 && y >= 0 && x + width <= (GLint) ctx->DrawBuffer->Width - && y + height <= (GLint) ctx->DrawBuffer->Height) { + && y + height <= (GLint) ctx->DrawBuffer->Height + && ctx->DrawBuffer->_NumColorDrawBuffers[0] == 1) { quickDraw = GL_TRUE; + rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0]; } else { quickDraw = GL_FALSE; + rb = NULL; } if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) { @@ -846,8 +926,14 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, /* draw the span */ if (quickDraw) { - (*swrast->Driver.WriteRGBASpan)(ctx, span.end, span.x, span.y, - (CONST GLchan (*)[4]) span.array->rgba, NULL); +#if OLD_RENDERBUFFER + if (swrast->Driver.WriteRGBASpan) + swrast->Driver.WriteRGBASpan(ctx, rb, span.end, span.x, span.y, + (CONST GLchan (*)[4]) span.array->rgba, NULL); + else +#endif + rb->PutRow(ctx, rb, span.end, span.x, span.y, + span.array->rgba, NULL); } else if (zoom) { _swrast_write_zoomed_rgba_span(ctx, &span, diff --git a/src/mesa/swrast/s_feedback.c b/src/mesa/swrast/s_feedback.c index 892c40db6a2..26cb05cd560 100644 --- a/src/mesa/swrast/s_feedback.c +++ b/src/mesa/swrast/s_feedback.c @@ -1,9 +1,8 @@ - /* * Mesa 3-D graphics library - * Version: 5.1 + * Version: 6.3 * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -54,7 +53,7 @@ static void feedback_vertex( GLcontext *ctx, win[0] = v->win[0]; win[1] = v->win[1]; - win[2] = v->win[2] / ctx->DepthMaxF; + win[2] = v->win[2] / ctx->DrawBuffer->_DepthMaxF; win[3] = 1.0F / v->win[3]; color[0] = CHAN_TO_FLOAT(pv->color[0]); @@ -138,7 +137,7 @@ void _swrast_select_triangle( GLcontext *ctx, const SWvertex *v2) { if (_swrast_culltriangle( ctx, v0, v1, v2 )) { - const GLfloat zs = 1.0F / ctx->DepthMaxF; + const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF; _mesa_update_hitflag( ctx, v0->win[2] * zs ); _mesa_update_hitflag( ctx, v1->win[2] * zs ); @@ -149,7 +148,7 @@ void _swrast_select_triangle( GLcontext *ctx, void _swrast_select_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) { - const GLfloat zs = 1.0F / ctx->DepthMaxF; + const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF; _mesa_update_hitflag( ctx, v0->win[2] * zs ); _mesa_update_hitflag( ctx, v1->win[2] * zs ); } @@ -157,6 +156,6 @@ void _swrast_select_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 void _swrast_select_point( GLcontext *ctx, const SWvertex *v ) { - const GLfloat zs = 1.0F / ctx->DepthMaxF; + const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF; _mesa_update_hitflag( ctx, v->win[2] * zs ); } diff --git a/src/mesa/swrast/s_imaging.c b/src/mesa/swrast/s_imaging.c index 088215d5350..5c79a7ba95e 100644 --- a/src/mesa/swrast/s_imaging.c +++ b/src/mesa/swrast/s_imaging.c @@ -41,6 +41,11 @@ _swrast_CopyColorTable( GLcontext *ctx, GLchan data[MAX_WIDTH][4]; struct gl_buffer_object *bufferSave; + if (!ctx->ReadBuffer->_ColorReadBuffer) { + /* no readbuffer - OK */ + return; + } + /* Select buffer to read from */ _swrast_use_read_buffer(ctx); @@ -48,7 +53,8 @@ _swrast_CopyColorTable( GLcontext *ctx, width = MAX_WIDTH; /* read the data from framebuffer */ - _swrast_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y, data ); + _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, + width, x, y, data ); /* Restore reading from draw buffer (the default) */ _swrast_use_draw_buffer(ctx); @@ -71,6 +77,11 @@ _swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start, GLchan data[MAX_WIDTH][4]; struct gl_buffer_object *bufferSave; + if (!ctx->ReadBuffer->_ColorReadBuffer) { + /* no readbuffer - OK */ + return; + } + /* Select buffer to read from */ _swrast_use_read_buffer(ctx); @@ -78,7 +89,8 @@ _swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start, width = MAX_WIDTH; /* read the data from framebuffer */ - _swrast_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y, data ); + _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, + width, x, y, data ); /* Restore reading from draw buffer (the default) */ _swrast_use_draw_buffer(ctx); @@ -103,14 +115,19 @@ _swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target, GLchan rgba[MAX_CONVOLUTION_WIDTH][4]; struct gl_buffer_object *bufferSave; + if (!ctx->ReadBuffer->_ColorReadBuffer) { + /* no readbuffer - OK */ + return; + } + /* Select buffer to read from */ _swrast_use_read_buffer(ctx); RENDER_START( swrast, ctx ); /* read the data from framebuffer */ - _swrast_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y, - (GLchan (*)[4]) rgba ); + _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, + width, x, y, (GLchan (*)[4]) rgba ); RENDER_FINISH( swrast, ctx ); @@ -141,6 +158,11 @@ _swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target, GLint i; struct gl_buffer_object *bufferSave; + if (!ctx->ReadBuffer->_ColorReadBuffer) { + /* no readbuffer - OK */ + return; + } + /* Select buffer to read from */ _swrast_use_read_buffer(ctx); @@ -148,8 +170,8 @@ _swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target, /* read pixels from framebuffer */ for (i = 0; i < height; i++) { - _swrast_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y + i, - (GLchan (*)[4]) rgba[i] ); + _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, + width, x, y + i, (GLchan (*)[4]) rgba[i] ); } RENDER_FINISH(swrast,ctx); diff --git a/src/mesa/swrast/s_linetemp.h b/src/mesa/swrast/s_linetemp.h index efdf1490691..af7aeabf629 100644 --- a/src/mesa/swrast/s_linetemp.h +++ b/src/mesa/swrast/s_linetemp.h @@ -82,6 +82,7 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) #if defined(DEPTH_TYPE) const GLint depthBits = ctx->Visual.depthBits; const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0; + struct gl_renderbuffer *zrb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; #define FixedToDepth(F) ((F) >> fixedToDepthShift) GLint zPtrXstep, zPtrYstep; DEPTH_TYPE *zPtr; @@ -151,7 +152,7 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) return; #ifdef DEPTH_TYPE - zPtr = (DEPTH_TYPE *) _swrast_zbuffer_address(ctx, x0, y0); + zPtr = (DEPTH_TYPE *) zrb->GetPointer(ctx, zrb, x0, y0); #endif #ifdef PIXEL_ADDRESS pixelPtr = (PIXEL_TYPE *) PIXEL_ADDRESS(x0,y0); diff --git a/src/mesa/swrast/s_logic.c b/src/mesa/swrast/s_logic.c index ad27cb7b625..aabe18d9c9a 100644 --- a/src/mesa/swrast/s_logic.c +++ b/src/mesa/swrast/s_logic.c @@ -1,9 +1,8 @@ - /* * Mesa 3-D graphics library - * Version: 4.1 + * Version: 6.3 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -29,133 +28,151 @@ #include "imports.h" #include "macros.h" -#include "s_alphabuf.h" #include "s_context.h" #include "s_logic.h" #include "s_span.h" +#define LOGIC_OP_LOOP(MODE) \ +do { \ + GLuint i; \ + switch (MODE) { \ + case GL_CLEAR: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = 0; \ + } \ + } \ + break; \ + case GL_SET: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = ~0; \ + } \ + } \ + break; \ + case GL_COPY: \ + /* do nothing */ \ + break; \ + case GL_COPY_INVERTED: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = ~src[i]; \ + } \ + } \ + break; \ + case GL_NOOP: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = dest[i]; \ + } \ + } \ + break; \ + case GL_INVERT: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = ~dest[i]; \ + } \ + } \ + break; \ + case GL_AND: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] &= dest[i]; \ + } \ + } \ + break; \ + case GL_NAND: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = ~(src[i] & dest[i]); \ + } \ + } \ + break; \ + case GL_OR: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] |= dest[i]; \ + } \ + } \ + break; \ + case GL_NOR: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = ~(src[i] | dest[i]); \ + } \ + } \ + break; \ + case GL_XOR: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] ^= dest[i]; \ + } \ + } \ + break; \ + case GL_EQUIV: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = ~(src[i] ^ dest[i]); \ + } \ + } \ + break; \ + case GL_AND_REVERSE: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = src[i] & ~dest[i]; \ + } \ + } \ + break; \ + case GL_AND_INVERTED: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = ~src[i] & dest[i]; \ + } \ + } \ + break; \ + case GL_OR_REVERSE: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = src[i] | ~dest[i]; \ + } \ + } \ + break; \ + case GL_OR_INVERTED: \ + for (i = 0; i < n; i++) { \ + if (mask[i]) { \ + src[i] = ~src[i] | dest[i]; \ + } \ + } \ + break; \ + default: \ + _mesa_problem(ctx, "bad logicop mode");\ + } \ +} while (0) + + -/* - * Apply logic op to array of CI pixels. - */ static void -index_logicop( GLcontext *ctx, GLuint n, GLuint index[], const GLuint dest[], - const GLubyte mask[] ) +logicop_ubyte(GLcontext *ctx, GLuint n, GLubyte src[], const GLubyte dest[], + const GLubyte mask[]) { - GLuint i; - switch (ctx->Color.LogicOp) { - case GL_CLEAR: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = 0; - } - } - break; - case GL_SET: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = ~0; - } - } - break; - case GL_COPY: - /* do nothing */ - break; - case GL_COPY_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = ~index[i]; - } - } - break; - case GL_NOOP: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = dest[i]; - } - } - break; - case GL_INVERT: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = ~dest[i]; - } - } - break; - case GL_AND: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] &= dest[i]; - } - } - break; - case GL_NAND: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = ~(index[i] & dest[i]); - } - } - break; - case GL_OR: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] |= dest[i]; - } - } - break; - case GL_NOR: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = ~(index[i] | dest[i]); - } - } - break; - case GL_XOR: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] ^= dest[i]; - } - } - break; - case GL_EQUIV: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = ~(index[i] ^ dest[i]); - } - } - break; - case GL_AND_REVERSE: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = index[i] & ~dest[i]; - } - } - break; - case GL_AND_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = ~index[i] & dest[i]; - } - } - break; - case GL_OR_REVERSE: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = index[i] | ~dest[i]; - } - } - break; - case GL_OR_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - index[i] = ~index[i] | dest[i]; - } - } - break; - default: - _mesa_problem(ctx, "bad mode in index_logic()"); - } + LOGIC_OP_LOOP(ctx->Color.LogicOp); +} + + +static void +logicop_ushort(GLcontext *ctx, GLuint n, GLushort src[], const GLushort dest[], + const GLubyte mask[]) +{ + LOGIC_OP_LOOP(ctx->Color.LogicOp); +} + + +static void +logicop_uint(GLcontext *ctx, GLuint n, GLuint src[], const GLuint dest[], + const GLubyte mask[]) +{ + LOGIC_OP_LOOP(ctx->Color.LogicOp); } @@ -165,305 +182,35 @@ index_logicop( GLcontext *ctx, GLuint n, GLuint index[], const GLuint dest[], * used if the device driver can't do logic ops. */ void -_swrast_logicop_ci_span( GLcontext *ctx, const struct sw_span *span, - GLuint index[] ) +_swrast_logicop_ci_span(GLcontext *ctx, struct gl_renderbuffer *rb, + const struct sw_span *span, GLuint index[]) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); GLuint dest[MAX_WIDTH]; ASSERT(span->end < MAX_WIDTH); /* Read dest values from frame buffer */ if (span->arrayMask & SPAN_XY) { - (*swrast->Driver.ReadCI32Pixels)( ctx, span->end, - span->array->x, span->array->y, - dest, span->array->mask ); + ASSERT(rb->DataType == GL_UNSIGNED_INT); + rb->GetValues(ctx, rb, span->end, span->array->x, span->array->y, dest); } else { - (*swrast->Driver.ReadCI32Span)( ctx, span->end, span->x, span->y, dest ); + ASSERT(rb->DataType == GL_UNSIGNED_INT); + rb->GetRow(ctx, rb, span->end, span->x, span->y, dest); } - index_logicop( ctx, span->end, index, dest, span->array->mask ); + logicop_uint(ctx, span->end, index, dest, span->array->mask); } - -/* - * Apply logic operator to rgba pixels. - * Input: ctx - the context - * n - number of pixels - * mask - pixel mask array - * In/Out: src - incoming pixels which will be modified - * Input: dest - frame buffer values - * - * Note: Since the R, G, B, and A channels are all treated the same we - * process them as 4-byte GLuints instead of four GLubytes. - */ -static void -rgba_logicop_ui( const GLcontext *ctx, GLuint n, const GLubyte mask[], - GLuint src[], const GLuint dest[] ) -{ - GLuint i; - switch (ctx->Color.LogicOp) { - case GL_CLEAR: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = 0; - } - } - break; - case GL_SET: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~0; - } - } - break; - case GL_COPY: - /* do nothing */ - break; - case GL_COPY_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~src[i]; - } - } - break; - case GL_NOOP: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = dest[i]; - } - } - break; - case GL_INVERT: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~dest[i]; - } - } - break; - case GL_AND: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] &= dest[i]; - } - } - break; - case GL_NAND: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~(src[i] & dest[i]); - } - } - break; - case GL_OR: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i]|= dest[i]; - } - } - break; - case GL_NOR: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~(src[i] | dest[i]); - } - } - break; - case GL_XOR: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] ^= dest[i]; - } - } - break; - case GL_EQUIV: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~(src[i] ^ dest[i]); - } - } - break; - case GL_AND_REVERSE: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = src[i] & ~dest[i]; - } - } - break; - case GL_AND_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~src[i] & dest[i]; - } - } - break; - case GL_OR_REVERSE: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = src[i] | ~dest[i]; - } - } - break; - case GL_OR_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~src[i] | dest[i]; - } - } - break; - default: - /* should never happen */ - _mesa_problem(ctx, "Bad function in rgba_logicop"); - } -} - - -/* - * As above, but operate on GLchan values - * Note: need to pass n = numPixels * 4. - */ -static void -rgba_logicop_chan( const GLcontext *ctx, GLuint n, const GLubyte mask[], - GLchan srcPtr[], const GLchan destPtr[] ) -{ -#if CHAN_TYPE == GL_FLOAT - GLuint *src = (GLuint *) srcPtr; - const GLuint *dest = (const GLuint *) destPtr; - GLuint i; - ASSERT(sizeof(GLfloat) == sizeof(GLuint)); -#else - GLchan *src = srcPtr; - const GLchan *dest = destPtr; - GLuint i; -#endif - - switch (ctx->Color.LogicOp) { - case GL_CLEAR: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = 0; - } - } - break; - case GL_SET: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~0; - } - } - break; - case GL_COPY: - /* do nothing */ - break; - case GL_COPY_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~src[i]; - } - } - break; - case GL_NOOP: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = dest[i]; - } - } - break; - case GL_INVERT: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~dest[i]; - } - } - break; - case GL_AND: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] &= dest[i]; - } - } - break; - case GL_NAND: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~(src[i] & dest[i]); - } - } - break; - case GL_OR: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i]|= dest[i]; - } - } - break; - case GL_NOR: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~(src[i] | dest[i]); - } - } - break; - case GL_XOR: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] ^= dest[i]; - } - } - break; - case GL_EQUIV: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~(src[i] ^ dest[i]); - } - } - break; - case GL_AND_REVERSE: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = src[i] & ~dest[i]; - } - } - break; - case GL_AND_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~src[i] & dest[i]; - } - } - break; - case GL_OR_REVERSE: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = src[i] | ~dest[i]; - } - } - break; - case GL_OR_INVERTED: - for (i=0;i<n;i++) { - if (mask[i]) { - src[i] = ~src[i] | dest[i]; - } - } - break; - default: - /* should never happen */ - _mesa_problem(ctx, "Bad function in rgba_logicop"); - } -} - - - -/* +/** * Apply the current logic operator to a span of RGBA pixels. * We can handle horizontal runs of pixels (spans) or arrays of x/y * pixel coordinates. */ void -_swrast_logicop_rgba_span( GLcontext *ctx, const struct sw_span *span, - GLchan rgba[][4] ) +_swrast_logicop_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb, + const struct sw_span *span, GLchan rgba[][4]) { SWcontext *swrast = SWRAST_CONTEXT(ctx); GLchan dest[MAX_WIDTH][4]; @@ -472,26 +219,27 @@ _swrast_logicop_rgba_span( GLcontext *ctx, const struct sw_span *span, ASSERT(span->arrayMask & SPAN_RGBA); if (span->arrayMask & SPAN_XY) { - (*swrast->Driver.ReadRGBAPixels)(ctx, span->end, - span->array->x, span->array->y, - dest, span->array->mask); - if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { - _swrast_read_alpha_pixels(ctx, span->end, - span->array->x, span->array->y, - dest, span->array->mask); - } + swrast->Driver.ReadRGBAPixels(ctx, rb, span->end, + span->array->x, span->array->y, + dest, span->array->mask); } else { - _swrast_read_rgba_span(ctx, ctx->DrawBuffer, span->end, - span->x, span->y, dest); + _swrast_read_rgba_span(ctx, rb, span->end, span->x, span->y, dest); } - if (sizeof(GLchan) * 4 == sizeof(GLuint)) { - rgba_logicop_ui(ctx, span->end, span->array->mask, - (GLuint *) rgba, (const GLuint *) dest); - } - else { - rgba_logicop_chan(ctx, 4 * span->end, span->array->mask, - (GLchan *) rgba, (const GLchan *) dest); - } + /* NEW_RENDERBUFFER: XXX make this a runtime test */ +#if CHAN_TYPE == GL_UNSIGNED_BYTE + /* treat 4*GLubyte as GLuint */ + logicop_uint(ctx, span->end, (GLuint *) rgba, + (const GLuint *) dest, span->array->mask); +#elif CHAN_TYPE == GL_UNSIGNED_SHORT + logicop_ushort(ctx, 4 * span->end, (GLushort *) rgba, + (const GLushort *) dest, span->array->mask); +#elif CHAN_TYPE == GL_FLOAT + logicop_uint(ctx, 4 * span->end, (GLuint *) rgba, + (const GLuint *) dest, span->array->mask); +#endif + (void) logicop_ubyte; + (void) logicop_ushort; + (void) logicop_uint; } diff --git a/src/mesa/swrast/s_logic.h b/src/mesa/swrast/s_logic.h index 19ec9c3246f..ce5f183ff65 100644 --- a/src/mesa/swrast/s_logic.h +++ b/src/mesa/swrast/s_logic.h @@ -1,9 +1,8 @@ - /* * Mesa 3-D graphics library - * Version: 4.1 + * Version: 6.3 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -33,13 +32,13 @@ extern void -_swrast_logicop_ci_span( GLcontext *ctx, const struct sw_span *span, - GLuint index[] ); +_swrast_logicop_ci_span(GLcontext *ctx, struct gl_renderbuffer *rb, + const struct sw_span *span, GLuint index[]); extern void -_swrast_logicop_rgba_span( GLcontext *ctx, const struct sw_span *span, - GLchan rgba[][4] ); +_swrast_logicop_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb, + const struct sw_span *span, GLchan rgba[][4]); #endif diff --git a/src/mesa/swrast/s_masking.c b/src/mesa/swrast/s_masking.c index 3badb86007e..d5f60a69587 100644 --- a/src/mesa/swrast/s_masking.c +++ b/src/mesa/swrast/s_masking.c @@ -1,9 +1,8 @@ - /* * Mesa 3-D graphics library - * Version: 4.1 + * Version: 6.3 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -33,7 +32,6 @@ #include "enums.h" #include "macros.h" -#include "s_alphabuf.h" #include "s_context.h" #include "s_masking.h" #include "s_span.h" @@ -41,8 +39,8 @@ void -_swrast_mask_rgba_span( GLcontext *ctx, const struct sw_span *span, - GLchan rgba[][4] ) +_swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb, + const struct sw_span *span, GLchan rgba[][4]) { SWcontext *swrast = SWRAST_CONTEXT(ctx); GLchan dest[MAX_WIDTH][4]; @@ -64,15 +62,16 @@ _swrast_mask_rgba_span( GLcontext *ctx, const struct sw_span *span, ASSERT(span->arrayMask & SPAN_RGBA); if (span->arrayMask & SPAN_XY) { - (*swrast->Driver.ReadRGBAPixels)(ctx, n, span->array->x, span->array->y, +#if OLD_RENDERBUFFER + if (swrast->Driver.ReadRGBAPixels) + swrast->Driver.ReadRGBAPixels(ctx, rb, n, span->array->x, span->array->y, dest, span->array->mask); - if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { - _swrast_read_alpha_pixels(ctx, n, span->array->x, span->array->y, - dest, span->array->mask); - } + else +#endif + rb->GetValues(ctx, rb, n, span->array->x, span->array->y, dest); } else { - _swrast_read_rgba_span(ctx, ctx->DrawBuffer, n, span->x, span->y, dest); + _swrast_read_rgba_span(ctx, rb, n, span->x, span->y, dest); } #if CHAN_BITS == 8 @@ -90,14 +89,12 @@ _swrast_mask_rgba_span( GLcontext *ctx, const struct sw_span *span, } - - /* * Apply glColorMask to a span of RGBA pixels. */ void -_swrast_mask_rgba_array( GLcontext *ctx, - GLuint n, GLint x, GLint y, GLchan rgba[][4] ) +_swrast_mask_rgba_array(GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, GLchan rgba[][4]) { GLchan dest[MAX_WIDTH][4]; GLuint i; @@ -109,7 +106,7 @@ _swrast_mask_rgba_array( GLcontext *ctx, GLuint *rgba32 = (GLuint *) rgba; GLuint *dest32 = (GLuint *) dest; - _swrast_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest ); + _swrast_read_rgba_span( ctx, rb, n, x, y, dest ); for (i = 0; i < n; i++) { rgba32[i] = (rgba32[i] & srcMask) | (dest32[i] & dstMask); } @@ -135,57 +132,46 @@ _swrast_mask_rgba_array( GLcontext *ctx, void -_swrast_mask_index_span( GLcontext *ctx, const struct sw_span *span, - GLuint index[] ) +_swrast_mask_ci_span(GLcontext *ctx, struct gl_renderbuffer *rb, + const struct sw_span *span, GLuint index[]) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLuint msrc = ctx->Color.IndexMask; - const GLuint mdest = ~msrc; - GLuint fbindexes[MAX_WIDTH]; + const GLuint srcMask = ctx->Color.IndexMask; + const GLuint dstMask = ~srcMask; + GLuint dest[MAX_WIDTH]; GLuint i; ASSERT(span->arrayMask & SPAN_INDEX); ASSERT(span->end < MAX_WIDTH); + ASSERT(rb->DataType == GL_UNSIGNED_INT); if (span->arrayMask & SPAN_XY) { - - (*swrast->Driver.ReadCI32Pixels)(ctx, span->end, span->array->x, - span->array->y, fbindexes, - span->array->mask); - - for (i = 0; i < span->end; i++) { - index[i] = (index[i] & msrc) | (fbindexes[i] & mdest); - } + rb->GetValues(ctx, rb, span->end, span->array->x, span->array->y, dest); } else { - _swrast_read_index_span(ctx, ctx->DrawBuffer, span->end, span->x, span->y, - fbindexes ); + _swrast_read_index_span(ctx, rb, span->end, span->x, span->y, dest); + } - for (i = 0; i < span->end; i++) { - index[i] = (index[i] & msrc) | (fbindexes[i] & mdest); - } + for (i = 0; i < span->end; i++) { + index[i] = (index[i] & srcMask) | (dest[i] & dstMask); } } - /* - * Apply glIndexMask to a span of CI pixels. + * Apply glIndexMask to an array of CI pixels. */ void -_swrast_mask_index_array( GLcontext *ctx, - GLuint n, GLint x, GLint y, GLuint index[] ) +_swrast_mask_ci_array(GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, GLuint index[]) { + const GLuint srcMask = ctx->Color.IndexMask; + const GLuint dstMask = ~srcMask; + GLuint dest[MAX_WIDTH]; GLuint i; - GLuint fbindexes[MAX_WIDTH]; - GLuint msrc, mdest; - - _swrast_read_index_span( ctx, ctx->DrawBuffer, n, x, y, fbindexes ); - msrc = ctx->Color.IndexMask; - mdest = ~msrc; + _swrast_read_index_span(ctx, rb, n, x, y, dest); for (i=0;i<n;i++) { - index[i] = (index[i] & msrc) | (fbindexes[i] & mdest); + index[i] = (index[i] & srcMask) | (dest[i] & dstMask); } } diff --git a/src/mesa/swrast/s_masking.h b/src/mesa/swrast/s_masking.h index 965e9f21809..e2265448f88 100644 --- a/src/mesa/swrast/s_masking.h +++ b/src/mesa/swrast/s_masking.h @@ -1,9 +1,8 @@ - /* * Mesa 3-D graphics library - * Version: 4.1 + * Version: 6.3 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -36,26 +35,24 @@ * Implement glColorMask for a span of RGBA pixels. */ extern void -_swrast_mask_rgba_span( GLcontext *ctx, const struct sw_span *span, - GLchan rgba[][4] ); +_swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb, + const struct sw_span *span, GLchan rgba[][4]); extern void -_swrast_mask_rgba_array( GLcontext *ctx, GLuint n, GLint x, GLint y, - GLchan rgba[][4] ); +_swrast_mask_rgba_array(GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, GLchan rgba[][4]); /* * Implement glIndexMask for a span of CI pixels. */ extern void -_swrast_mask_index_span( GLcontext *ctx, const struct sw_span *span, - GLuint index[] ); - +_swrast_mask_ci_span(GLcontext *ctx, struct gl_renderbuffer *rb, + const struct sw_span *span, GLuint index[]); extern void -_swrast_mask_index_array( GLcontext *ctx, - GLuint n, GLint x, GLint y, GLuint index[] ); - +_swrast_mask_ci_array(GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, GLuint index[]); #endif diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c index 51d36c0a2b5..1cd1bdaf493 100644 --- a/src/mesa/swrast/s_nvfragprog.c +++ b/src/mesa/swrast/s_nvfragprog.c @@ -207,13 +207,13 @@ fetch_vector4_deriv( GLcontext *ctx, if (xOrY == 'X') { src[0] = 1.0; src[1] = 0.0; - src[2] = span->dzdx / ctx->DepthMaxF; + src[2] = span->dzdx / ctx->DrawBuffer->_DepthMaxF; src[3] = span->dwdx; } else { src[0] = 0.0; src[1] = 1.0; - src[2] = span->dzdy / ctx->DepthMaxF; + src[2] = span->dzdy / ctx->DrawBuffer->_DepthMaxF; src[3] = span->dwdy; } break; @@ -1180,6 +1180,8 @@ execute_program( GLcontext *ctx, * while the NV extension says it's implementation dependant. */ fetch_texel( ctx, texcoord, 0.0F, inst->TexSrcUnit, color ); + if (color[3]) + printf("color[3] = %f\n", color[3]); store_vector4( inst, machine, color ); } break; @@ -1362,7 +1364,7 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, GLfloat *wpos = machine->Inputs[FRAG_ATTRIB_WPOS]; wpos[0] = (GLfloat) span->x + col; wpos[1] = (GLfloat) span->y; - wpos[2] = (GLfloat) span->array->z[col] / ctx->DepthMaxF; + wpos[2] = (GLfloat) span->array->z[col] / ctx->DrawBuffer->_DepthMaxF; wpos[3] = span->w + col * span->dwdx; } if (inputsRead & (1 << FRAG_ATTRIB_COL0)) { @@ -1444,7 +1446,7 @@ _swrast_exec_fragment_program( GLcontext *ctx, struct sw_span *span ) } /* depth value */ if (program->OutputsWritten & (1 << FRAG_OUTPUT_DEPR)) - span->array->z[i] = IROUND(ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_DEPR][0] * ctx->DepthMaxF); + span->array->z[i] = IROUND(ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_DEPR][0] * ctx->DrawBuffer->_DepthMaxF); } } diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c index 7d8112fb9b3..559fed5da6d 100644 --- a/src/mesa/swrast/s_readpix.c +++ b/src/mesa/swrast/s_readpix.c @@ -34,7 +34,6 @@ #include "imports.h" #include "pixel.h" -#include "s_alphabuf.h" #include "s_context.h" #include "s_depth.h" #include "s_span.h" @@ -52,7 +51,10 @@ read_index_pixels( GLcontext *ctx, GLenum type, GLvoid *pixels, const struct gl_pixelstore_attrib *packing ) { + struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; + /* SWcontext *swrast = SWRAST_CONTEXT(ctx); + */ GLint i, readWidth; /* error checking */ @@ -81,8 +83,8 @@ read_index_pixels( GLcontext *ctx, for (i = 0; i < height; i++) { GLuint index[MAX_WIDTH]; GLvoid *dest; - - (*swrast->Driver.ReadCI32Span)(ctx, readWidth, x, y + i, index); + ASSERT(rb->DataType == GL_UNSIGNED_INT); + rb->GetRow(ctx, rb, readWidth, x, y + i, index); dest = _mesa_image_address2d(packing, pixels, width, height, GL_COLOR_INDEX, type, i, 0); @@ -106,9 +108,16 @@ read_depth_pixels( GLcontext *ctx, GLenum type, GLvoid *pixels, const struct gl_pixelstore_attrib *packing ) { + struct gl_renderbuffer *rb + = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; GLint readWidth; GLboolean bias_or_scale; + if (!rb) { + /* no readbuffer - OK */ + return; + } + /* Error checking */ if (ctx->Visual.depthBits <= 0) { /* No depth buffer */ @@ -116,9 +125,6 @@ read_depth_pixels( GLcontext *ctx, return; } - /* XXX: width should never be > MAX_WIDTH since we did clipping earlier */ - readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; - if (type != GL_BYTE && type != GL_UNSIGNED_BYTE && type != GL_SHORT && @@ -130,6 +136,9 @@ read_depth_pixels( GLcontext *ctx, return; } + /* XXX: width should never be > MAX_WIDTH since we did clipping earlier */ + readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; + bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0; if (type==GL_UNSIGNED_SHORT && ctx->Visual.depthBits == 16 @@ -141,7 +150,7 @@ read_depth_pixels( GLcontext *ctx, GLushort *dst = (GLushort*) _mesa_image_address2d(packing, pixels, width, height, GL_DEPTH_COMPONENT, type, j, 0); GLint i; - _swrast_read_depth_span(ctx, width, x, y, depth); + _swrast_read_depth_span(ctx, rb, width, x, y, depth); for (i = 0; i < width; i++) dst[i] = depth[i]; } @@ -153,7 +162,7 @@ read_depth_pixels( GLcontext *ctx, for (j=0;j<height;j++,y++) { GLdepth *dst = (GLdepth *) _mesa_image_address2d(packing, pixels, width, height, GL_DEPTH_COMPONENT, type, j, 0); - _swrast_read_depth_span(ctx, width, x, y, dst); + _swrast_read_depth_span(ctx, rb, width, x, y, dst); } } else { @@ -163,7 +172,7 @@ read_depth_pixels( GLcontext *ctx, GLfloat depth[MAX_WIDTH]; GLvoid *dest; - _swrast_read_depth_span_float(ctx, readWidth, x, y, depth); + _swrast_read_depth_span_float(ctx, rb, readWidth, x, y, depth); dest = _mesa_image_address2d(packing, pixels, width, height, GL_DEPTH_COMPONENT, type, j, 0); @@ -185,8 +194,15 @@ read_stencil_pixels( GLcontext *ctx, GLenum type, GLvoid *pixels, const struct gl_pixelstore_attrib *packing ) { + struct gl_renderbuffer *rb + = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; GLint j, readWidth; + if (!rb) { + /* no readbuffer - OK */ + return; + } + if (type != GL_BYTE && type != GL_UNSIGNED_BYTE && type != GL_SHORT && @@ -199,21 +215,21 @@ read_stencil_pixels( GLcontext *ctx, return; } - /* XXX: width should never be > MAX_WIDTH since we did clipping earlier */ - readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; - if (ctx->Visual.stencilBits <= 0) { /* No stencil buffer */ _mesa_error( ctx, GL_INVALID_OPERATION, "glReadPixels" ); return; } + /* XXX: width should never be > MAX_WIDTH since we did clipping earlier */ + readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; + /* process image row by row */ for (j=0;j<height;j++,y++) { GLvoid *dest; GLstencil stencil[MAX_WIDTH]; - _swrast_read_stencil_span(ctx, readWidth, x, y, stencil); + _swrast_read_stencil_span(ctx, rb, readWidth, x, y, stencil); dest = _mesa_image_address2d(packing, pixels, width, height, GL_STENCIL_INDEX, type, j, 0); @@ -237,7 +253,7 @@ read_fast_rgba_pixels( GLcontext *ctx, GLvoid *pixels, const struct gl_pixelstore_attrib *packing ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); + struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; /* can't do scale, bias, mapping, etc */ if (ctx->_ImageTransferState) return GL_FALSE; @@ -285,12 +301,16 @@ read_fast_rgba_pixels( GLcontext *ctx, } for (row=0; row<readHeight; row++) { - (*swrast->Driver.ReadRGBASpan)(ctx, readWidth, srcX, srcY, +#if OLD_RENDERBUFFER && 0 + (*swrast->Driver.ReadRGBASpan)(ctx, rb, readWidth, srcX, srcY, (GLchan (*)[4]) dest); if (ctx->DrawBuffer->UseSoftwareAlphaBuffers) { _swrast_read_alpha_span(ctx, readWidth, srcX, srcY, (GLchan (*)[4]) dest); } +#else + rb->GetRow(ctx, rb, readWidth, srcX, srcY, dest); +#endif dest += rowLength * 4; srcY++; } @@ -315,22 +335,17 @@ read_rgba_pixels( GLcontext *ctx, GLenum format, GLenum type, GLvoid *pixels, const struct gl_pixelstore_attrib *packing ) { + struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; + /* SWcontext *swrast = SWRAST_CONTEXT(ctx); + */ GLint readWidth; - _swrast_use_read_buffer(ctx); - - /* Try optimized path first */ - if (read_fast_rgba_pixels( ctx, x, y, width, height, - format, type, pixels, packing )) { - - _swrast_use_draw_buffer(ctx); - return; /* done! */ + if (!rb) { + /* No readbuffer is OK with GL_EXT_framebuffer_object */ + return; } - /* XXX: width should never be > MAX_WIDTH since we did clipping earlier */ - readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; - /* do error checking on pixel type, format was already checked by caller */ switch (type) { case GL_UNSIGNED_BYTE: @@ -371,6 +386,20 @@ read_rgba_pixels( GLcontext *ctx, return; } + _swrast_use_read_buffer(ctx); + + /* Try optimized path first */ + if (read_fast_rgba_pixels( ctx, x, y, width, height, + format, type, pixels, packing )) { + + _swrast_use_draw_buffer(ctx); + return; /* done! */ + } + + /* XXX: width should never be > MAX_WIDTH since we did clipping earlier */ + readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; + + if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) { const GLuint transferOps = ctx->_ImageTransferState; GLfloat *dest, *src, *tmpImage, *convImage; @@ -393,11 +422,12 @@ read_rgba_pixels( GLcontext *ctx, for (row = 0; row < height; row++, y++) { GLchan rgba[MAX_WIDTH][4]; if (ctx->Visual.rgbMode) { - _swrast_read_rgba_span(ctx, ctx->ReadBuffer, readWidth, x, y, rgba); + _swrast_read_rgba_span(ctx, rb, readWidth, x, y, rgba); } else { GLuint index[MAX_WIDTH]; - (*swrast->Driver.ReadCI32Span)(ctx, readWidth, x, y, index); + ASSERT(rb->DataType == GL_UNSIGNED_INT); + rb->GetRow(ctx, rb, readWidth, x, y, index); if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset !=0 ) { _mesa_map_ci(ctx, readWidth, index); } @@ -439,11 +469,12 @@ read_rgba_pixels( GLcontext *ctx, GLchan rgba[MAX_WIDTH][4]; GLvoid *dst; if (ctx->Visual.rgbMode) { - _swrast_read_rgba_span(ctx, ctx->ReadBuffer, readWidth, x, y, rgba); + _swrast_read_rgba_span(ctx, rb, readWidth, x, y, rgba); } else { GLuint index[MAX_WIDTH]; - (*swrast->Driver.ReadCI32Span)(ctx, readWidth, x, y, index); + ASSERT(rb->DataType == GL_UNSIGNED_INT); + rb->GetRow(ctx, rb, readWidth, x, y, index); if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset != 0) { _mesa_map_ci(ctx, readWidth, index); } diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index e6afee1eaa0..6019eff9902 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -2,7 +2,7 @@ * Mesa 3-D graphics library * Version: 6.3 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -38,7 +38,6 @@ #include "s_atifragshader.h" #include "s_alpha.h" -#include "s_alphabuf.h" #include "s_blend.h" #include "s_context.h" #include "s_depth.h" @@ -58,10 +57,11 @@ void _swrast_span_default_z( GLcontext *ctx, struct sw_span *span ) { + const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; if (ctx->Visual.depthBits <= 16) - span->z = FloatToFixed(ctx->Current.RasterPos[2] * ctx->DepthMax + 0.5F); + span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F); else - span->z = (GLint) (ctx->Current.RasterPos[2] * ctx->DepthMax + 0.5F); + span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F); span->zStep = 0; span->interpMask |= SPAN_Z; } @@ -235,6 +235,7 @@ interpolate_indexes(GLcontext *ctx, struct sw_span *span) } } span->arrayMask |= SPAN_INDEX; + span->interpMask &= ~SPAN_INDEX; } @@ -761,141 +762,22 @@ clip_span( GLcontext *ctx, struct sw_span *span ) } - /** - * Draw to more than one color buffer (or none). - */ -static void -multi_write_index_span( GLcontext *ctx, struct sw_span *span ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLuint bufferBit; - - /* loop over four possible dest color buffers */ - for (bufferBit = 1; bufferBit <= 8; bufferBit <<= 1) { - if (bufferBit & ctx->Color._DrawDestMask[0]) { - GLuint indexTmp[MAX_WIDTH]; - ASSERT(span->end < MAX_WIDTH); - - /* Set the current read/draw buffer */ - swrast->CurrentBufferBit = bufferBit; - (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit); - - /* make copy of incoming indexes */ - MEMCPY( indexTmp, span->array->index, span->end * sizeof(GLuint) ); - - if (ctx->Color.IndexLogicOpEnabled) { - _swrast_logicop_ci_span(ctx, span, indexTmp); - } - - if (ctx->Color.IndexMask != 0xffffffff) { - _swrast_mask_index_span(ctx, span, indexTmp); - } - - if (span->arrayMask & SPAN_XY) { - /* array of pixel coords */ - (*swrast->Driver.WriteCI32Pixels)(ctx, span->end, - span->array->x, span->array->y, - indexTmp, span->array->mask); - } - else { - /* horizontal run of pixels */ - (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y, - indexTmp, span->array->mask); - } - } - } - - /* restore default dest buffer */ - _swrast_use_draw_buffer(ctx); -} - - -/** - * Draw to more than one RGBA color buffer (or none). - * All fragment operations, up to (but not) blending/logicop should - * have been done first. - */ -static void -multi_write_rgba_span( GLcontext *ctx, struct sw_span *span ) -{ - const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); - GLuint bufferBit; - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - ASSERT(colorMask != 0x0); - - if (ctx->Color.DrawBuffer == GL_NONE) - return; - - /* loop over four possible dest color buffers */ - for (bufferBit = 1; bufferBit <= 8; bufferBit <<= 1) { - if (bufferBit & ctx->Color._DrawDestMask[0]) { - GLchan rgbaTmp[MAX_WIDTH][4]; - ASSERT(span->end < MAX_WIDTH); - - /* Set the current read/draw buffer */ - swrast->CurrentBufferBit = bufferBit; - (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit); - - /* make copy of incoming colors */ - MEMCPY( rgbaTmp, span->array->rgba, 4 * span->end * sizeof(GLchan) ); - - if (ctx->Color._LogicOpEnabled) { - _swrast_logicop_rgba_span(ctx, span, rgbaTmp); - } - else if (ctx->Color.BlendEnabled) { - _swrast_blend_span(ctx, span, rgbaTmp); - } - - if (colorMask != 0xffffffff) { - _swrast_mask_rgba_span(ctx, span, rgbaTmp); - } - - if (span->arrayMask & SPAN_XY) { - /* array of pixel coords */ - (*swrast->Driver.WriteRGBAPixels)(ctx, span->end, - span->array->x, span->array->y, - (const GLchan (*)[4]) rgbaTmp, - span->array->mask); - if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { - _swrast_write_alpha_pixels(ctx, span->end, - span->array->x, span->array->y, - (const GLchan (*)[4]) rgbaTmp, - span->array->mask); - } - } - else { - /* horizontal run of pixels */ - (*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y, - (const GLchan (*)[4]) rgbaTmp, - span->array->mask); - if (swrast->_RasterMask & ALPHABUF_BIT) { - _swrast_write_alpha_span(ctx, span->end, span->x, span->y, - (const GLchan (*)[4]) rgbaTmp, - span->array->mask); - } - } - } - } - - /* restore default dest buffer */ - _swrast_use_draw_buffer(ctx); -} - - - -/** - * This function may modify any of the array values in the span. + * Apply all the per-fragment opertions to a span of color index fragments + * and write them to the enabled color drawbuffers. + * The 'span' parameter can be considered to be const. Note that * span->interpMask and span->arrayMask may be changed but will be restored * to their original values before returning. */ void _swrast_write_index_span( GLcontext *ctx, struct sw_span *span) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); + const SWcontext *swrast = SWRAST_CONTEXT(ctx); + const struct gl_framebuffer *fb = ctx->DrawBuffer; + const GLuint output = 0; const GLuint origInterpMask = span->interpMask; const GLuint origArrayMask = span->arrayMask; + GLuint buf; ASSERT(span->end <= MAX_WIDTH); ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || @@ -946,7 +828,7 @@ _swrast_write_index_span( GLcontext *ctx, struct sw_span *span) stipple_polygon_span(ctx, span); } - /* Depth test and stencil */ + /* Stencil and Z testing */ if (ctx->Depth.Test || ctx->Stencil.Enabled) { if (span->interpMask & SPAN_Z) _swrast_span_interpolate_z(ctx, span); @@ -960,6 +842,7 @@ _swrast_write_index_span( GLcontext *ctx, struct sw_span *span) else { ASSERT(ctx->Depth.Test); if (!_swrast_depth_test_span(ctx, span)) { + span->interpMask = origInterpMask; span->arrayMask = origArrayMask; return; } @@ -988,10 +871,13 @@ _swrast_write_index_span( GLcontext *ctx, struct sw_span *span) } /* Interpolate the color indexes if needed */ - if (span->interpMask & SPAN_INDEX) { - interpolate_indexes(ctx, span); - /* clear the bit - this allows the WriteMonoCISpan optimization below */ - span->interpMask &= ~SPAN_INDEX; + if (ctx->Fog.Enabled || + ctx->Color.IndexLogicOpEnabled || + ctx->Color.IndexMask != 0xffffffff || + (span->arrayMask & SPAN_COVERAGE)) { + if (span->interpMask & SPAN_INDEX) { + interpolate_indexes(ctx, span); + } } /* Fog */ @@ -1001,61 +887,111 @@ _swrast_write_index_span( GLcontext *ctx, struct sw_span *span) /* Antialias coverage application */ if (span->arrayMask & SPAN_COVERAGE) { - GLuint i; + const GLfloat *coverage = span->array->coverage; GLuint *index = span->array->index; - GLfloat *coverage = span->array->coverage; + GLuint i; for (i = 0; i < span->end; i++) { ASSERT(coverage[i] < 16); index[i] = (index[i] & ~0xf) | ((GLuint) coverage[i]); } } - if (swrast->_RasterMask & MULTI_DRAW_BIT) { - /* draw to zero or two or more buffers */ - multi_write_index_span(ctx, span); - } - else { - /* normal situation: draw to exactly one buffer */ - if (ctx->Color.IndexLogicOpEnabled) { - _swrast_logicop_ci_span(ctx, span, span->array->index); - } + /* Loop over drawing buffers */ + for (buf = 0; buf < fb->_NumColorDrawBuffers[output]; buf++) { + struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf]; + GLuint indexTemp[MAX_WIDTH], *index32; + + ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); + + if (ctx->Color.IndexLogicOpEnabled || + ctx->Color.IndexMask != 0xffffffff) { + /* make copy of incoming indexes */ + MEMCPY(indexTemp, span->array->index, span->end * sizeof(GLuint)); - if (ctx->Color.IndexMask != 0xffffffff) { - _swrast_mask_index_span(ctx, span, span->array->index); + if (ctx->Color.IndexLogicOpEnabled) { + _swrast_logicop_ci_span(ctx, rb, span, indexTemp); + } + + if (ctx->Color.IndexMask != 0xffffffff) { + _swrast_mask_ci_span(ctx, rb, span, indexTemp); + } + index32 = indexTemp; + } + else { + index32 = span->array->index; } - /* write pixels */ - if (span->arrayMask & SPAN_XY) { - /* array of pixel coords */ - if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) { - /* all pixels have same color index */ - (*swrast->Driver.WriteMonoCIPixels)(ctx, span->end, - span->array->x, span->array->y, - FixedToInt(span->index), - span->array->mask); + if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) { + /* all fragments have same color index */ + GLubyte index8; + GLushort index16; + GLuint index32; + void *value; + + if (rb->DataType == GL_UNSIGNED_BYTE) { + index8 = FixedToInt(span->index); + value = &index8; + } + else if (rb->DataType == GL_UNSIGNED_SHORT) { + index16 = FixedToInt(span->index); + value = &index16; } else { - (*swrast->Driver.WriteCI32Pixels)(ctx, span->end, span->array->x, - span->array->y, span->array->index, - span->array->mask ); + ASSERT(rb->DataType == GL_UNSIGNED_INT); + index32 = FixedToInt(span->index); + value = &index32; + } + + if (span->arrayMask & SPAN_XY) { + rb->PutMonoValues(ctx, rb, span->end, span->array->x, + span->array->y, value, span->array->mask); + } + else { + rb->PutMonoRow(ctx, rb, span->end, span->x, span->y, + value, span->array->mask); } } else { - /* horizontal run of pixels */ - if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) { - /* all pixels have same color index */ - (*swrast->Driver.WriteMonoCISpan)(ctx, span->end, span->x, span->y, - FixedToInt(span->index), - span->array->mask); + /* each fragment is a different color */ + GLubyte index8[MAX_WIDTH]; + GLushort index16[MAX_WIDTH]; + void *values; + + if (rb->DataType == GL_UNSIGNED_BYTE) { + GLuint k; + for (k = 0; k < span->end; k++) { + index8[k] = (GLubyte) index32[k]; + } + values = index8; + } + else if (rb->DataType == GL_UNSIGNED_SHORT) { + GLuint k; + for (k = 0; k < span->end; k++) { + index16[k] = (GLushort) index32[k]; + } + values = index16; } else { - (*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y, - span->array->index, - span->array->mask); + ASSERT(rb->DataType == GL_UNSIGNED_INT); + values = index32; + } + + if (span->arrayMask & SPAN_XY) { + rb->PutValues(ctx, rb, span->end, span->array->x, span->array->y, + values, span->array->mask); + } + else { + rb->PutRow(ctx, rb, span->end, span->x, span->y, + values, span->array->mask); } } } +#if OLD_RENDERBUFFER + /* restore default dest buffer */ + _swrast_use_draw_buffer(ctx); +#endif + span->interpMask = origInterpMask; span->arrayMask = origArrayMask; } @@ -1088,6 +1024,88 @@ add_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] ) /** + * XXX merge this code into the _swrast_write_rgba_span() routine! + * + * Draw to more than one RGBA color buffer (or none). + * All fragment operations, up to (but not) blending/logicop should + * have been done first. + */ +static void +multi_write_rgba_span( GLcontext *ctx, struct sw_span *span ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); + struct gl_framebuffer *fb = ctx->DrawBuffer; + const GLuint output = 0; + GLuint i; + + ASSERT(span->end < MAX_WIDTH); + ASSERT(colorMask != 0x0); + + for (i = 0; i < fb->_NumColorDrawBuffers[output]; i++) { + struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][i]; + GLchan rgbaTmp[MAX_WIDTH][4]; + +#if OLD_RENDERBUFFER /* obsolete code */ + GLuint bufferBit = fb->_ColorDrawBit[output][i]; + /* Set the current read/draw buffer */ + swrast->CurrentBufferBit = bufferBit; + (*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit); +#endif + + /* make copy of incoming colors */ + MEMCPY( rgbaTmp, span->array->rgba, 4 * span->end * sizeof(GLchan) ); + + if (ctx->Color._LogicOpEnabled) { + _swrast_logicop_rgba_span(ctx, rb, span, rgbaTmp); + } + else if (ctx->Color.BlendEnabled) { + _swrast_blend_span(ctx, rb, span, rgbaTmp); + } + + if (colorMask != 0xffffffff) { + _swrast_mask_rgba_span(ctx, rb, span, rgbaTmp); + } + + if (span->arrayMask & SPAN_XY) { + /* array of pixel coords */ + if (rb->PutValues) { + rb->PutValues(ctx, rb, span->end, span->array->x, + span->array->y, rgbaTmp, span->array->mask); + } +#if OLD_RENDERBUFFER + else { + swrast->Driver.WriteRGBAPixels(ctx, rb, span->end, + span->array->x, span->array->y, + (const GLchan (*)[4]) rgbaTmp, + span->array->mask); + } +#endif + } + else { + /* horizontal run of pixels */ + if (rb->PutRow) { + rb->PutRow(ctx, rb, span->end, span->x, span->y, rgbaTmp, + span->array->mask); + } +#if OLD_RENDERBUFFER + else { + swrast->Driver.WriteRGBASpan(ctx, rb, span->end, span->x, span->y, + (const GLchan (*)[4]) rgbaTmp, + span->array->mask); + } +#endif + } + } + +#if OLD_RENDERBUFFER + /* restore default dest buffer */ + _swrast_use_draw_buffer(ctx); +#endif +} + + +/** * Apply all the per-fragment operations to a span. * This now includes texturing (_swrast_write_texture_span() is history). * This function may modify any of the array values in the span. @@ -1194,7 +1212,7 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span) if (span->interpMask & SPAN_Z) _swrast_span_interpolate_z(ctx, span); - if (ctx->Stencil.Enabled) { + if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) { /* Combined Z/stencil tests */ if (!_swrast_stencil_and_ztest_span(ctx, span)) { span->interpMask = origInterpMask; @@ -1202,7 +1220,7 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span) return; } } - else { + else if (ctx->DrawBuffer->Visual.depthBits > 0) { /* Just regular depth testing */ ASSERT(ctx->Depth.Test); ASSERT(span->arrayMask & SPAN_Z); @@ -1302,41 +1320,54 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span) } else { /* normal: write to exactly one buffer */ + struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0]; + if (ctx->Color._LogicOpEnabled) { - _swrast_logicop_rgba_span(ctx, span, span->array->rgba); + _swrast_logicop_rgba_span(ctx, rb, span, span->array->rgba); } else if (ctx->Color.BlendEnabled) { - _swrast_blend_span(ctx, span, span->array->rgba); + _swrast_blend_span(ctx, rb, span, span->array->rgba); } /* Color component masking */ if (colorMask != 0xffffffff) { - _swrast_mask_rgba_span(ctx, span, span->array->rgba); + _swrast_mask_rgba_span(ctx, rb, span, span->array->rgba); } /* Finally, write the pixels to a color buffer */ if (span->arrayMask & SPAN_XY) { /* array of pixel coords */ - swrast->Driver.WriteRGBAPixels(ctx, span->end, span->array->x, + if (rb->PutValues) { + ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA); + /* XXX check datatype */ + rb->PutValues(ctx, rb, span->end, span->array->x, span->array->y, + span->array->rgba, span->array->mask); + } +#ifdef OLD_RENDERBUFFER + else + { + swrast->Driver.WriteRGBAPixels(ctx, rb, span->end, span->array->x, span->array->y, (const GLchan (*)[4]) span->array->rgba, span->array->mask); - if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { - _swrast_write_alpha_pixels(ctx, span->end, - span->array->x, span->array->y, - (const GLchan (*)[4]) span->array->rgba, - span->array->mask); } +#endif } else { /* horizontal run of pixels */ - swrast->Driver.WriteRGBASpan(ctx, span->end, span->x, span->y, + if (rb->PutRow) { + ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA); + /* XXX check datatype */ + rb->PutRow(ctx, rb, span->end, span->x, span->y, span->array->rgba, + span->writeAll ? NULL : span->array->mask); + } +#ifdef OLD_RENDERBUFFER + else + { + swrast->Driver.WriteRGBASpan(ctx, rb, span->end, span->x, span->y, (const GLchan (*)[4]) span->array->rgba, span->writeAll ? NULL : span->array->mask); - if (swrast->_RasterMask & ALPHABUF_BIT) { - _swrast_write_alpha_span(ctx, span->end, span->x, span->y, - (const GLchan (*)[4]) span->array->rgba, - span->writeAll ? NULL : span->array->mask); } +#endif } } @@ -1351,16 +1382,16 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span) * reading ouside the buffer's boundaries. */ void -_swrast_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer, +_swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, GLchan rgba[][4] ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLint bufWidth = (GLint) buffer->Width; - const GLint bufHeight = (GLint) buffer->Height; + const GLint bufWidth = (GLint) rb->Width; + const GLint bufHeight = (GLint) rb->Height; if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { /* completely above, below, or right */ - /* XXX maybe leave undefined? */ + /* XXX maybe leave rgba values undefined? */ _mesa_bzero(rgba, 4 * n * sizeof(GLchan)); } else { @@ -1392,10 +1423,22 @@ _swrast_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer, length = (GLint) n; } - (*swrast->Driver.ReadRGBASpan)( ctx, length, x + skip, y, rgba + skip ); - if (buffer->UseSoftwareAlphaBuffers) { - _swrast_read_alpha_span(ctx, length, x + skip, y, rgba + skip); + if (rb && rb->GetRow) { + assert(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA); + assert(rb->DataType == GL_UNSIGNED_BYTE); + rb->GetRow(ctx, rb, length, x + skip, y, rgba + skip); + } +#if OLD_RENDERBUFFER + else { + swrast->Driver.ReadRGBASpan(ctx, rb, length, x + skip, y, + rgba + skip); + /* + if (buffer->UseSoftwareAlphaBuffers) { + _swrast_read_alpha_span(ctx, length, x + skip, y, rgba + skip); + } + */ } +#endif } } @@ -1405,16 +1448,15 @@ _swrast_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer, * reading ouside the buffer's boundaries. */ void -_swrast_read_index_span( GLcontext *ctx, GLframebuffer *buffer, - GLuint n, GLint x, GLint y, GLuint indx[] ) +_swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, GLuint index[] ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLint bufWidth = (GLint) buffer->Width; - const GLint bufHeight = (GLint) buffer->Height; + const GLint bufWidth = (GLint) rb->Width; + const GLint bufHeight = (GLint) rb->Height; if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { /* completely above, below, or right */ - _mesa_bzero(indx, n * sizeof(GLuint)); + _mesa_bzero(index, n * sizeof(GLuint)); } else { GLint skip, length; @@ -1445,6 +1487,25 @@ _swrast_read_index_span( GLcontext *ctx, GLframebuffer *buffer, length = (GLint) n; } - (*swrast->Driver.ReadCI32Span)( ctx, length, skip + x, y, indx + skip ); + ASSERT(rb->GetRow); + ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); + + if (rb->DataType == GL_UNSIGNED_BYTE) { + GLubyte index8[MAX_WIDTH]; + GLint i; + rb->GetRow(ctx, rb, length, x + skip, y, index8); + for (i = 0; i < length; i++) + index[skip + i] = index8[i]; + } + else if (rb->DataType == GL_UNSIGNED_SHORT) { + GLushort index16[MAX_WIDTH]; + GLint i; + rb->GetRow(ctx, rb, length, x + skip, y, index16); + for (i = 0; i < length; i++) + index[skip + i] = index16[i]; + } + else if (rb->DataType == GL_UNSIGNED_INT) { + rb->GetRow(ctx, rb, length, x + skip, y, index + skip); + } } } diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h index 29c485c4d0c..789010bd7fc 100644 --- a/src/mesa/swrast/s_span.h +++ b/src/mesa/swrast/s_span.h @@ -2,7 +2,7 @@ * Mesa 3-D graphics library * Version: 6.3 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -60,11 +60,11 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span); extern void -_swrast_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer, +_swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, GLchan rgba[][4] ); extern void -_swrast_read_index_span( GLcontext *ctx, GLframebuffer *buffer, +_swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, GLuint indx[] ); #endif diff --git a/src/mesa/swrast/s_spantemp.h b/src/mesa/swrast/s_spantemp.h index 1ce0b00bef9..5c67758035f 100644 --- a/src/mesa/swrast/s_spantemp.h +++ b/src/mesa/swrast/s_spantemp.h @@ -1,9 +1,8 @@ - /* * Mesa 3-D graphics library - * Version: 5.1 + * Version: 6.3 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -52,12 +51,14 @@ #ifdef STORE_RGBA_PIXEL static void -NAME(write_rgba_span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, - CONST GLchan rgba[][4], const GLubyte mask[] ) +NAME(write_rgba_span)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *values, const GLubyte mask[] ) { #ifdef SPAN_VARS SPAN_VARS #endif + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; GLuint i; INIT_PIXEL_PTR(pixel, x, y); if (mask) { @@ -79,12 +80,14 @@ NAME(write_rgba_span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, } static void -NAME(write_rgb_span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, - CONST GLchan rgb[][3], const GLubyte mask[] ) +NAME(write_rgb_span)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *values, const GLubyte mask[] ) { #ifdef SPAN_VARS SPAN_VARS #endif + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; GLuint i; INIT_PIXEL_PTR(pixel, x, y); if (mask) { @@ -106,12 +109,14 @@ NAME(write_rgb_span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, } static void -NAME(write_monorgba_span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, - const GLchan color[4], const GLubyte mask[] ) +NAME(write_monorgba_span)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *value, const GLubyte mask[] ) { #ifdef SPAN_VARS SPAN_VARS #endif + const GLubyte *color = (const GLubyte *) value; GLuint i; INIT_PIXEL_PTR(pixel, x, y); if (mask) { @@ -133,13 +138,14 @@ NAME(write_monorgba_span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, } static void -NAME(write_rgba_pixels)( const GLcontext *ctx, GLuint n, - const GLint x[], const GLint y[], - CONST GLchan rgba[][4], const GLubyte mask[] ) +NAME(write_rgba_pixels)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], + const void *values, const GLubyte mask[] ) { #ifdef SPAN_VARS SPAN_VARS #endif + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; GLuint i; ASSERT(mask); for (i = 0; i < n; i++) { @@ -152,13 +158,14 @@ NAME(write_rgba_pixels)( const GLcontext *ctx, GLuint n, } static void -NAME(write_monorgba_pixels)( const GLcontext *ctx, +NAME(write_monorgba_pixels)( GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], - const GLchan color[4], const GLubyte mask[] ) + const void *value, const GLubyte mask[] ) { #ifdef SPAN_VARS SPAN_VARS #endif + const GLubyte *color = (const GLubyte *) value; GLuint i; ASSERT(mask); for (i = 0; i < n; i++) { @@ -171,12 +178,13 @@ NAME(write_monorgba_pixels)( const GLcontext *ctx, } static void -NAME(read_rgba_span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, - GLchan rgba[][4] ) +NAME(read_rgba_span)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, void *values ) { #ifdef SPAN_VARS SPAN_VARS #endif + GLubyte (*rgba)[4] = (GLubyte (*)[4]) values; GLuint i; INIT_PIXEL_PTR(pixel, x, y); for (i = 0; i < n; i++) { @@ -187,21 +195,20 @@ NAME(read_rgba_span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, } static void -NAME(read_rgba_pixels)( const GLcontext *ctx, +NAME(read_rgba_pixels)( GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], - GLchan rgba[][4], const GLubyte mask[] ) + void *values) { #ifdef SPAN_VARS SPAN_VARS #endif + GLubyte (*rgba)[4] = (GLubyte (*)[4]) values; GLuint i; ASSERT(mask); for (i = 0; i < n; i++) { - if (mask[i]) { - INIT_PIXEL_PTR(pixel, x[i], y[i]); - FETCH_RGBA_PIXEL(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], - rgba[i][ACOMP], pixel); - } + INIT_PIXEL_PTR(pixel, x[i], y[i]); + FETCH_RGBA_PIXEL(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP], + rgba[i][ACOMP], pixel); } } @@ -213,38 +220,14 @@ NAME(read_rgba_pixels)( const GLcontext *ctx, #ifdef STORE_CI_PIXEL static void -NAME(write_index32_span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, - const GLuint index[], const GLubyte mask[] ) -{ -#ifdef SPAN_VARS - SPAN_VARS -#endif - GLuint i; - INIT_PIXEL_PTR(pixel, x, y); - if (mask) { - for (i = 0; i < n; i++) { - if (mask[i]) { - STORE_CI_PIXEL(pixel, index[i]); - } - INC_PIXEL_PTR(pixel); - } - } - else { - for (i = 0; i < n; i++) { - STORE_CI_PIXEL(pixel, index[i]); - INC_PIXEL_PTR(pixel); - } - } -} - - -static void -NAME(write_index8_span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, - const GLubyte index[], const GLubyte mask[] ) +NAME(write_index_span)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *values, const GLubyte mask[] ) { #ifdef SPAN_VARS SPAN_VARS #endif + const GLuint *index = (const GLuint *) values; GLuint i; INIT_PIXEL_PTR(pixel, x, y); if (mask) { @@ -265,12 +248,14 @@ NAME(write_index8_span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, static void -NAME(write_monoindex_span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, - GLuint colorIndex, const GLubyte mask[] ) +NAME(write_monoindex_span)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *value, const GLubyte mask[] ) { #ifdef SPAN_VARS SPAN_VARS #endif + GLuint colorIndex = *((GLuint *) value); GLuint i; INIT_PIXEL_PTR(pixel, x, y); if (mask) { @@ -291,13 +276,14 @@ NAME(write_monoindex_span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, static void -NAME(write_index_pixels)( const GLcontext *ctx, +NAME(write_index_pixels)( GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], - const GLuint index[], const GLubyte mask[] ) + const void *values, const GLubyte mask[] ) { #ifdef SPAN_VARS SPAN_VARS #endif + const GLuint *index = (const GLuint *) values; GLuint i; ASSERT(mask); for (i = 0; i < n; i++) { @@ -310,13 +296,14 @@ NAME(write_index_pixels)( const GLcontext *ctx, static void -NAME(write_monoindex_pixels)( const GLcontext *ctx, +NAME(write_monoindex_pixels)( GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], - GLuint colorIndex, const GLubyte mask[] ) + const void *value, const GLubyte mask[] ) { #ifdef SPAN_VARS SPAN_VARS #endif + GLuint colorIndex = *((GLuint *) value); GLuint i; ASSERT(mask); for (i = 0; i < n; i++) { @@ -329,12 +316,13 @@ NAME(write_monoindex_pixels)( const GLcontext *ctx, static void -NAME(read_index_span)( const GLcontext *ctx, - GLuint n, GLint x, GLint y, GLuint index[] ) +NAME(read_index_span)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, void *values ) { #ifdef SPAN_VARS SPAN_VARS #endif + GLuint *index = (GLuint *) values; GLuint i; INIT_PIXEL_PTR(pixel, x, y); for (i = 0; i < n; i++) { @@ -345,20 +333,19 @@ NAME(read_index_span)( const GLcontext *ctx, static void -NAME(read_index_pixels)( const GLcontext *ctx, +NAME(read_index_pixels)( GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], - GLuint index[], const GLubyte mask[] ) + void *values ) { #ifdef SPAN_VARS SPAN_VARS #endif + GLuint *index = (GLuint *) values; GLuint i; ASSERT(mask); for (i = 0; i < n; i++) { - if (mask[i] ) { - INIT_PIXEL_PTR(pixel, x[i], y[i]); - FETCH_CI_PIXEL(index[i], pixel); - } + INIT_PIXEL_PTR(pixel, x[i], y[i]); + FETCH_CI_PIXEL(index[i], pixel); } } diff --git a/src/mesa/swrast/s_stencil.c b/src/mesa/swrast/s_stencil.c index 38182ad613b..84818771718 100644 --- a/src/mesa/swrast/s_stencil.c +++ b/src/mesa/swrast/s_stencil.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 6.3 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -27,6 +27,7 @@ #include "context.h" #include "macros.h" #include "imports.h" +#include "fbobject.h" #include "s_context.h" #include "s_depth.h" @@ -50,14 +51,6 @@ ENDIF */ -/* - * Return the address of a stencil buffer value given the window coords: - */ -#define STENCIL_ADDRESS(X,Y) \ - (ctx->DrawBuffer->Stencil + ctx->DrawBuffer->Width * (Y) + (X)) - - - /** * Apply the given stencil operator to the array of stencil values. * Don't touch stencil[i] if mask[i] is zero. @@ -415,7 +408,8 @@ do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[], static GLboolean stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span, GLuint face) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; GLstencil stencilRow[MAX_WIDTH]; GLstencil *stencil; const GLuint n = span->end; @@ -431,19 +425,13 @@ stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span, GLuint face) ASSERT(span->arrayMask & SPAN_Z); } #endif - - /* Get initial stencil values */ - if (swrast->Driver.WriteStencilSpan) { - /* Get stencil values from the hardware stencil buffer */ - ASSERT(swrast->Driver.ReadStencilSpan); - (*swrast->Driver.ReadStencilSpan)(ctx, n, x, y, stencilRow); + + stencil = rb->GetPointer(ctx, rb, x, y); + if (!stencil) { + rb->GetRow(ctx, rb, n, x, y, stencilRow); stencil = stencilRow; } - else { - /* Get pointer into software stencil buffer */ - stencil = STENCIL_ADDRESS(x, y); - } - + /* * Apply the stencil test to the fragments. * failMask[i] is 1 if the stencil test failed. @@ -507,9 +495,8 @@ stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span, GLuint face) /* * Write updated stencil values back into hardware stencil buffer. */ - if (swrast->Driver.WriteStencilSpan) { - ASSERT(stencil == stencilRow); - (swrast->Driver.WriteStencilSpan)(ctx, n, x, y, stencil, mask ); + if (!rb->GetPointer(ctx, rb, 0, 0)) { + rb->PutRow(ctx, rb, n, x, y, stencil, mask); } span->writeAll = GL_FALSE; @@ -519,6 +506,12 @@ stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span, GLuint face) +/* + * Return the address of a stencil buffer value given the window coords: + */ +#define STENCIL_ADDRESS(X, Y) (stencilStart + (Y) * stride + (X)) + + /** * Apply the given stencil operator for each pixel in the array whose @@ -530,16 +523,21 @@ stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span, GLuint face) * mask - array [n] of flag: 1=apply operator, 0=don't apply operator */ static void -apply_stencil_op_to_pixels( const GLcontext *ctx, +apply_stencil_op_to_pixels( GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], GLenum oper, GLuint face, const GLubyte mask[] ) { + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; const GLstencil ref = ctx->Stencil.Ref[face]; const GLstencil wrtmask = ctx->Stencil.WriteMask[face]; const GLstencil invmask = (GLstencil) (~wrtmask); GLuint i; + GLstencil *stencilStart = (GLubyte *) rb->Data; + const GLuint stride = rb->Width; - ASSERT(!SWRAST_CONTEXT(ctx)->Driver.WriteStencilSpan); /* software stencil buffer only! */ + ASSERT(rb->GetPointer(ctx, rb, 0, 0)); + ASSERT(sizeof(GLstencil) == 1); switch (oper) { case GL_KEEP: @@ -701,16 +699,18 @@ static GLboolean stencil_test_pixels( GLcontext *ctx, GLuint face, GLuint n, const GLint x[], const GLint y[], GLubyte mask[] ) { + const struct gl_framebuffer *fb = ctx->DrawBuffer; + struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; GLubyte fail[MAX_WIDTH]; GLstencil r, s; GLuint i; GLboolean allfail = GL_FALSE; const GLuint valueMask = ctx->Stencil.ValueMask[face]; + const GLstencil *stencilStart = (GLstencil *) rb->Data; + const GLuint stride = rb->Width; - /* software stencil buffer only! */ - ASSERT(ctx->DrawBuffer->UseSoftwareStencilBuffer); - ASSERT(!SWRAST_CONTEXT(ctx)->Driver.ReadStencilSpan); - ASSERT(!SWRAST_CONTEXT(ctx)->Driver.WriteStencilSpan); + ASSERT(rb->GetPointer(ctx, rb, 0, 0)); + ASSERT(sizeof(GLstencil) == 1); /* * Perform stencil test. The results of this operation are stored @@ -740,7 +740,7 @@ stencil_test_pixels( GLcontext *ctx, GLuint face, GLuint n, r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;i<n;i++) { if (mask[i]) { - GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); + const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); s = (GLstencil) (*sptr & valueMask); if (r < s) { /* passed */ @@ -760,7 +760,7 @@ stencil_test_pixels( GLcontext *ctx, GLuint face, GLuint n, r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;i<n;i++) { if (mask[i]) { - GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); + const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); s = (GLstencil) (*sptr & valueMask); if (r <= s) { /* pass */ @@ -780,7 +780,7 @@ stencil_test_pixels( GLcontext *ctx, GLuint face, GLuint n, r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;i<n;i++) { if (mask[i]) { - GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); + const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); s = (GLstencil) (*sptr & valueMask); if (r > s) { /* passed */ @@ -800,7 +800,7 @@ stencil_test_pixels( GLcontext *ctx, GLuint face, GLuint n, r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;i<n;i++) { if (mask[i]) { - GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); + const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); s = (GLstencil) (*sptr & valueMask); if (r >= s) { /* passed */ @@ -820,7 +820,7 @@ stencil_test_pixels( GLcontext *ctx, GLuint face, GLuint n, r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;i<n;i++) { if (mask[i]) { - GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); + const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); s = (GLstencil) (*sptr & valueMask); if (r == s) { /* passed */ @@ -840,7 +840,7 @@ stencil_test_pixels( GLcontext *ctx, GLuint face, GLuint n, r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;i<n;i++) { if (mask[i]) { - GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); + const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); s = (GLstencil) (*sptr & valueMask); if (r != s) { /* passed */ @@ -897,24 +897,23 @@ stencil_test_pixels( GLcontext *ctx, GLuint face, GLuint n, static GLboolean stencil_and_ztest_pixels( GLcontext *ctx, struct sw_span *span, GLuint face ) { + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; const GLuint n = span->end; const GLint *x = span->array->x; const GLint *y = span->array->y; GLubyte *mask = span->array->mask; - SWcontext *swrast = SWRAST_CONTEXT(ctx); ASSERT(span->arrayMask & SPAN_XY); ASSERT(ctx->Stencil.Enabled); ASSERT(n <= MAX_WIDTH); - if (swrast->Driver.WriteStencilPixels) { - /*** Hardware stencil buffer ***/ + if (!rb->GetPointer(ctx, rb, 0, 0)) { + /* No direct access */ GLstencil stencil[MAX_WIDTH]; GLubyte origMask[MAX_WIDTH]; - ASSERT(!ctx->DrawBuffer->UseSoftwareStencilBuffer); - ASSERT(swrast->Driver.ReadStencilPixels); - (*swrast->Driver.ReadStencilPixels)(ctx, n, x, y, stencil); + rb->GetValues(ctx, rb, n, x, y, stencil); MEMCPY(origMask, mask, n * sizeof(GLubyte)); @@ -950,14 +949,12 @@ stencil_and_ztest_pixels( GLcontext *ctx, struct sw_span *span, GLuint face ) } /* Write updated stencil values into hardware stencil buffer */ - (swrast->Driver.WriteStencilPixels)(ctx, n, x, y, stencil, origMask); + rb->PutValues(ctx, rb, n, x, y, stencil, origMask); return GL_TRUE; } else { - /*** Software stencil buffer ***/ - - ASSERT(ctx->DrawBuffer->UseSoftwareStencilBuffer); + /* Direct access to stencil buffer */ if (stencil_test_pixels(ctx, face, n, x, y, mask) == GL_FALSE) { /* all fragments failed the stencil test, we're done. */ @@ -1015,6 +1012,39 @@ _swrast_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span) } +#if 0 +GLuint +clip_span(GLuint bufferWidth, GLuint bufferHeight, + GLint x, GLint y, GLuint *count) +{ + GLuint n = *count; + GLuint skipPixels = 0; + + if (y < 0 || y >= bufferHeight || x + n <= 0 || x >= bufferWidth) { + /* totally out of bounds */ + n = 0; + } + else { + /* left clip */ + if (x < 0) { + skipPixels = -x; + x = 0; + n -= skipPixels; + } + /* right clip */ + if (x + n > bufferWidth) { + GLint dx = x + n - bufferWidth; + n -= dx; + } + } + + *count = n; + + return skipPixels; +} +#endif + + /** * Return a span of stencil values from the stencil buffer. * Used for glRead/CopyPixels @@ -1023,14 +1053,10 @@ _swrast_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span) * Output: stencil - the array of stencil values */ void -_swrast_read_stencil_span( GLcontext *ctx, - GLint n, GLint x, GLint y, GLstencil stencil[] ) +_swrast_read_stencil_span(GLcontext *ctx, struct gl_renderbuffer *rb, + GLint n, GLint x, GLint y, GLstencil stencil[]) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLint bufWidth = (GLint) ctx->DrawBuffer->Width; - const GLint bufHeight = (GLint) ctx->DrawBuffer->Height; - - if (y < 0 || y >= bufHeight || x + n <= 0 || x >= bufWidth) { + if (y < 0 || y >= rb->Height || x + n <= 0 || x >= rb->Width) { /* span is completely outside framebuffer */ return; /* undefined values OK */ } @@ -1041,29 +1067,15 @@ _swrast_read_stencil_span( GLcontext *ctx, n -= dx; stencil += dx; } - if (x + n > bufWidth) { - GLint dx = x + n - bufWidth; + if (x + n > rb->Width) { + GLint dx = x + n - rb->Width; n -= dx; } if (n <= 0) { return; } - - ASSERT(n >= 0); - if (swrast->Driver.ReadStencilSpan) { - (*swrast->Driver.ReadStencilSpan)( ctx, (GLuint) n, x, y, stencil ); - } - else if (ctx->DrawBuffer->Stencil) { - const GLstencil *s = STENCIL_ADDRESS( x, y ); -#if STENCIL_BITS == 8 - MEMCPY( stencil, s, n * sizeof(GLstencil) ); -#else - GLuint i; - for (i=0;i<n;i++) - stencil[i] = s[i]; -#endif - } + rb->GetRow(ctx, rb, n, x, y, stencil); } @@ -1076,252 +1088,113 @@ _swrast_read_stencil_span( GLcontext *ctx, * stencil - the array of stencil values */ void -_swrast_write_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y, - const GLstencil stencil[] ) +_swrast_write_stencil_span(GLcontext *ctx, GLint n, GLint x, GLint y, + const GLstencil stencil[] ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLstencil *ssrc = stencil; - const GLint bufWidth = (GLint) ctx->DrawBuffer->Width; - const GLint bufHeight = (GLint) ctx->DrawBuffer->Height; + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; - if (y < 0 || y >= bufHeight || x + n <= 0 || x >= bufWidth) { + if (y < 0 || y >= rb->Height || x + n <= 0 || x >= rb->Width) { /* span is completely outside framebuffer */ return; /* undefined values OK */ } - if (x < 0) { GLint dx = -x; x = 0; n -= dx; - ssrc += dx; + stencil += dx; } - if (x + n > bufWidth) { - GLint dx = x + n - bufWidth; + if (x + n > rb->Width) { + GLint dx = x + n - rb->Width; n -= dx; } if (n <= 0) { return; } - if (swrast->Driver.WriteStencilSpan) { - (*swrast->Driver.WriteStencilSpan)( ctx, n, x, y, ssrc, NULL ); - } - else if (ctx->DrawBuffer->Stencil) { - GLstencil *s = STENCIL_ADDRESS( x, y ); -#if STENCIL_BITS == 8 - MEMCPY( s, ssrc, n * sizeof(GLstencil) ); -#else - GLuint i; - for (i=0;i<n;i++) - s[i] = ssrc[i]; -#endif - } + rb->PutRow(ctx, rb, n, x, y, stencil, NULL); } /** - * Allocate a new stencil buffer. If there's an old one it will be - * deallocated first. The new stencil buffer will be uninitialized. + * Clear the stencil buffer. */ void -_swrast_alloc_stencil_buffer( GLframebuffer *buffer ) +_swrast_clear_stencil_buffer( GLcontext *ctx, struct gl_renderbuffer *rb ) { - ASSERT(buffer->UseSoftwareStencilBuffer); - - /* deallocate current stencil buffer if present */ - if (buffer->Stencil) { - MESA_PBUFFER_FREE(buffer->Stencil); - buffer->Stencil = NULL; - } - - /* allocate new stencil buffer */ - buffer->Stencil = (GLstencil *) - MESA_PBUFFER_ALLOC(buffer->Width * buffer->Height * sizeof(GLstencil)); - if (!buffer->Stencil) { - /* out of memory */ - _mesa_error( NULL, GL_OUT_OF_MEMORY, "_swrast_alloc_stencil_buffer" ); - } -} + const GLstencil mask = ctx->Stencil.WriteMask[0]; + const GLstencil invMask = ~mask; + const GLstencil clearVal = (ctx->Stencil.Clear & mask); + GLint x, y, width, height; - - -/** - * Clear the software (malloc'd) stencil buffer. - */ -static void -clear_software_stencil_buffer( GLcontext *ctx ) -{ - if (ctx->Visual.stencilBits==0 || !ctx->DrawBuffer->Stencil) { - /* no stencil buffer */ + if (!rb || mask == 0) return; - } - - if (ctx->Scissor.Enabled) { - /* clear scissor region only */ - const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) { - /* must apply mask to the clear */ - GLint y; - for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { - const GLstencil mask = ctx->Stencil.WriteMask[0]; - const GLstencil invMask = ~mask; - const GLstencil clearVal = (ctx->Stencil.Clear & mask); - GLstencil *stencil = STENCIL_ADDRESS( ctx->DrawBuffer->_Xmin, y ); - GLint i; - for (i = 0; i < width; i++) { - stencil[i] = (stencil[i] & invMask) | clearVal; - } - } - } - else { - /* no masking */ - GLint y; - for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { - GLstencil *stencil = STENCIL_ADDRESS( ctx->DrawBuffer->_Xmin, y ); -#if STENCIL_BITS==8 - MEMSET( stencil, ctx->Stencil.Clear, width * sizeof(GLstencil) ); -#else - GLint i; - for (i = 0; i < width; i++) - stencil[i] = ctx->Stencil.Clear; -#endif - } - } - } - else { - /* clear whole stencil buffer */ - if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) { - /* must apply mask to the clear */ - const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; - GLstencil *stencil = ctx->DrawBuffer->Stencil; - const GLstencil mask = ctx->Stencil.WriteMask[0]; - const GLstencil invMask = ~mask; - const GLstencil clearVal = (ctx->Stencil.Clear & mask); - GLuint i; - for (i = 0; i < n; i++) { - stencil[i] = (stencil[i] & invMask) | clearVal; - } - } - else { - /* clear whole buffer without masking */ - const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; - GLstencil *stencil = ctx->DrawBuffer->Stencil; - -#if STENCIL_BITS==8 - MEMSET(stencil, ctx->Stencil.Clear, n * sizeof(GLstencil) ); -#else - GLuint i; - for (i = 0; i < n; i++) { - stencil[i] = ctx->Stencil.Clear; - } -#endif - } - } -} + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + ASSERT(rb->_BaseFormat == GL_STENCIL_INDEX); + /* compute region to clear */ + x = ctx->DrawBuffer->_Xmin; + y = ctx->DrawBuffer->_Ymin; + width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; -/** - * Clear the hardware (in graphics card) stencil buffer. - * This is done with the Driver.WriteStencilSpan() and Driver.ReadStencilSpan() - * functions. - * Actually, if there is a hardware stencil buffer it really should have - * been cleared in Driver.Clear()! However, if the hardware does not - * support scissored clears or masked clears (i.e. glStencilMask) then - * we have to use the span-based functions. - */ -static void -clear_hardware_stencil_buffer( GLcontext *ctx ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - ASSERT(swrast->Driver.WriteStencilSpan); - ASSERT(swrast->Driver.ReadStencilSpan); - - if (ctx->Scissor.Enabled) { - /* clear scissor region only */ - const GLint x = ctx->DrawBuffer->_Xmin; - const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + if (rb->GetPointer(ctx, rb, 0, 0)) { + /* Direct buffer access */ if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) { - /* must apply mask to the clear */ - GLint y; - for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { - const GLstencil mask = ctx->Stencil.WriteMask[0]; - const GLstencil invMask = ~mask; - const GLstencil clearVal = (ctx->Stencil.Clear & mask); - GLstencil stencil[MAX_WIDTH]; - GLint i; - (*swrast->Driver.ReadStencilSpan)(ctx, width, x, y, stencil); - for (i = 0; i < width; i++) { - stencil[i] = (stencil[i] & invMask) | clearVal; + /* need to mask the clear */ + GLint i, j; + for (i = 0; i < height; i++) { + GLubyte *stencil = rb->GetPointer(ctx, rb, x, y + i); + for (j = 0; j < width; j++) { + stencil[j] = (stencil[j] & invMask) | clearVal; } - (*swrast->Driver.WriteStencilSpan)(ctx, width, x, y, stencil, NULL); } } else { - /* no masking */ - GLstencil stencil[MAX_WIDTH]; - GLint y, i; - for (i = 0; i < width; i++) { - stencil[i] = ctx->Stencil.Clear; + /* no bit masking */ + if (width == rb->Width && + rb->InternalFormat == GL_STENCIL_INDEX8_EXT) { + /* optimized case */ + GLubyte *stencil = rb->GetPointer(ctx, rb, x, y); + GLuint len = width * height * sizeof(GLubyte); + _mesa_memset(stencil, clearVal, len); } - for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { - (*swrast->Driver.WriteStencilSpan)(ctx, width, x, y, stencil, NULL); + else { + /* general case */ + GLint i, j; + for (i = 0; i < height; i++) { + GLubyte *stencil = rb->GetPointer(ctx, rb, x, y + i); + for (j = 0; j < width; j++) { + stencil[j] = clearVal; + } + } } } } else { - /* clear whole stencil buffer */ + /* no direct access */ if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) { - /* must apply mask to the clear */ - const GLstencil mask = ctx->Stencil.WriteMask[0]; - const GLstencil invMask = ~mask; - const GLstencil clearVal = (ctx->Stencil.Clear & mask); - const GLint width = ctx->DrawBuffer->Width; - const GLint height = ctx->DrawBuffer->Height; - const GLint x = ctx->DrawBuffer->_Xmin; - GLint y; - for (y = 0; y < height; y++) { - GLstencil stencil[MAX_WIDTH]; - GLint i; - (*swrast->Driver.ReadStencilSpan)(ctx, width, x, y, stencil); - for (i = 0; i < width; i++) { - stencil[i] = (stencil[i] & invMask) | clearVal; + /* need to mask the clear */ + GLint i, j; + for (i = 0; i < height; i++) { + GLubyte stencil[MAX_WIDTH]; + rb->GetRow(ctx, rb, width, x, y + i, stencil); + for (j = 0; j < width; j++) { + stencil[j] = (stencil[j] & invMask) | clearVal; } - (*swrast->Driver.WriteStencilSpan)(ctx, width, x, y, stencil, NULL); + rb->PutRow(ctx, rb, width, x, y + i, stencil, NULL); } } else { - /* clear whole buffer without masking */ - const GLint width = ctx->DrawBuffer->Width; - const GLint height = ctx->DrawBuffer->Height; - const GLint x = ctx->DrawBuffer->_Xmin; - GLstencil stencil[MAX_WIDTH]; - GLint y, i; - for (i = 0; i < width; i++) { - stencil[i] = ctx->Stencil.Clear; - } - for (y = 0; y < height; y++) { - (*swrast->Driver.WriteStencilSpan)(ctx, width, x, y, stencil, NULL); - } + /* no bit masking */ + const GLubyte clear8 = clearVal; + GLint i; + for (i = 0; i < height; i++) { + rb->PutMonoRow(ctx, rb, width, x, y + i, &clear8, NULL); + } } } } - - -/** - * Clear the stencil buffer (hardware or software). - */ -void -_swrast_clear_stencil_buffer( GLcontext *ctx ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - if (swrast->Driver.WriteStencilSpan) { - ASSERT(swrast->Driver.ReadStencilSpan); - clear_hardware_stencil_buffer(ctx); - } - else { - clear_software_stencil_buffer(ctx); - } -} diff --git a/src/mesa/swrast/s_stencil.h b/src/mesa/swrast/s_stencil.h index 655f1dc3cf8..fabc25250da 100644 --- a/src/mesa/swrast/s_stencil.h +++ b/src/mesa/swrast/s_stencil.h @@ -1,9 +1,8 @@ - /* * Mesa 3-D graphics library - * Version: 4.1 + * Version: 6.3 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -37,10 +36,9 @@ extern GLboolean _swrast_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span); - extern void -_swrast_read_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y, - GLstencil stencil[] ); +_swrast_read_stencil_span(GLcontext *ctx, struct gl_renderbuffer *rb, + GLint n, GLint x, GLint y, GLstencil stencil[]); extern void @@ -49,11 +47,7 @@ _swrast_write_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y, extern void -_swrast_alloc_stencil_buffer( GLframebuffer *buffer ); - - -extern void -_swrast_clear_stencil_buffer( GLcontext *ctx ); +_swrast_clear_stencil_buffer( GLcontext *ctx, struct gl_renderbuffer *rb ); #endif diff --git a/src/mesa/swrast/s_texstore.c b/src/mesa/swrast/s_texstore.c index fa6b74b7451..24470a73580 100644 --- a/src/mesa/swrast/s_texstore.c +++ b/src/mesa/swrast/s_texstore.c @@ -79,8 +79,8 @@ read_color_image( GLcontext *ctx, GLint x, GLint y, dst = image; stride = width * 4; for (i = 0; i < height; i++) { - _swrast_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y + i, - (GLchan (*)[4]) dst ); + _swrast_read_rgba_span(ctx, ctx->ReadBuffer->_ColorReadBuffer, + width, x, y + i, (GLchan (*)[4]) dst); dst += stride; } @@ -100,6 +100,8 @@ static GLfloat * read_depth_image( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height ) { + struct gl_renderbuffer *rb + = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; SWcontext *swrast = SWRAST_CONTEXT(ctx); GLfloat *image, *dst; GLint i; @@ -112,7 +114,7 @@ read_depth_image( GLcontext *ctx, GLint x, GLint y, dst = image; for (i = 0; i < height; i++) { - _swrast_read_depth_span_float(ctx, width, x, y + i, dst); + _swrast_read_depth_span_float(ctx, rb, width, x, y + i, dst); dst += width; } diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c index 4533980455e..48ec2836e8b 100644 --- a/src/mesa/swrast/s_triangle.c +++ b/src/mesa/swrast/s_triangle.c @@ -2,7 +2,7 @@ * Mesa 3-D graphics library * Version: 6.3 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -35,8 +35,6 @@ #include "imports.h" #include "macros.h" #include "texformat.h" -#include "teximage.h" -#include "texstate.h" #include "s_aatriangle.h" #include "s_context.h" @@ -151,6 +149,7 @@ _swrast_culltriangle( GLcontext *ctx, #define SETUP_CODE \ SWcontext *swrast = SWRAST_CONTEXT(ctx); \ + struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];\ struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \ const GLint b = obj->BaseLevel; \ const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width; \ @@ -179,9 +178,13 @@ _swrast_culltriangle( GLcontext *ctx, span.intTex[0] += span.intTexStep[0]; \ span.intTex[1] += span.intTexStep[1]; \ } \ - (*swrast->Driver.WriteRGBSpan)(ctx, span.end, span.x, span.y, \ + if (swrast->Driver.WriteRGBSpan) \ + swrast->Driver.WriteRGBSpan(ctx, rb, span.end, span.x, span.y, \ (CONST GLchan (*)[3]) span.array->rgb,\ - NULL ); + NULL ); \ + else \ + rb->PutRowRGB(ctx, rb, span.end, span.x, span.y, span.array->rgb, NULL); + #include "s_tritemp.h" @@ -203,6 +206,7 @@ _swrast_culltriangle( GLcontext *ctx, #define SETUP_CODE \ SWcontext *swrast = SWRAST_CONTEXT(ctx); \ + struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];\ struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \ const GLint b = obj->BaseLevel; \ const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width; \ @@ -240,9 +244,13 @@ _swrast_culltriangle( GLcontext *ctx, span.intTex[1] += span.intTexStep[1]; \ span.z += span.zStep; \ } \ - (*swrast->Driver.WriteRGBSpan)(ctx, span.end, span.x, span.y, \ + if (swrast->Driver.WriteRGBSpan) \ + swrast->Driver.WriteRGBSpan(ctx, rb, span.end, span.x, span.y, \ (CONST GLchan (*)[3]) span.array->rgb,\ - span.array->mask ); + span.array->mask ); \ + else \ + rb->PutRowRGB(ctx, rb, span.end, span.x, span.y, span.array->rgb, NULL); + #include "s_tritemp.h" @@ -908,6 +916,8 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span, #define NAME occlusion_zless_triangle #define INTERP_Z 1 #define SETUP_CODE \ + struct gl_renderbuffer *rb \ + = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; \ ASSERT(ctx->Depth.Test); \ ASSERT(!ctx->Depth.Mask); \ ASSERT(ctx->Depth.Func == GL_LESS); \ @@ -918,7 +928,7 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span, if (ctx->Visual.depthBits <= 16) { \ GLuint i; \ const GLushort *zRow = (const GLushort *) \ - _swrast_zbuffer_address(ctx, span.x, span.y); \ + rb->GetPointer(ctx, rb, span.x, span.y); \ for (i = 0; i < span.end; i++) { \ GLdepth z = FixedToDepth(span.z); \ if (z < zRow[i]) { \ @@ -931,7 +941,7 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span, else { \ GLuint i; \ const GLuint *zRow = (const GLuint *) \ - _swrast_zbuffer_address(ctx, span.x, span.y); \ + rb->GetPointer(ctx, rb, span.x, span.y); \ for (i = 0; i < span.end; i++) { \ if ((GLuint)span.z < zRow[i]) { \ ctx->OcclusionResult = GL_TRUE; \ diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index 0be17ed0b38..fe19a3363f9 100644 --- a/src/mesa/swrast/s_tritemp.h +++ b/src/mesa/swrast/s_tritemp.h @@ -169,9 +169,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, } EdgeT; #ifdef INTERP_Z - const GLint depthBits = ctx->Visual.depthBits; + const GLint depthBits = ctx->DrawBuffer->Visual.depthBits; const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0; - const GLfloat maxDepth = ctx->DepthMaxF; + const GLfloat maxDepth = ctx->DrawBuffer->_DepthMaxF; #define FixedToDepth(F) ((F) >> fixedToDepthShift) #endif EdgeT eMaj, eTop, eBot; @@ -688,6 +688,8 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #endif #ifdef INTERP_Z # ifdef DEPTH_TYPE + struct gl_renderbuffer *zrb + = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; DEPTH_TYPE *zRow = NULL; GLint dZRowOuter = 0, dZRowInner; /* offset in bytes */ # endif @@ -853,7 +855,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, } # ifdef DEPTH_TYPE zRow = (DEPTH_TYPE *) - _swrast_zbuffer_address(ctx, InterpToInt(fxLeftEdge), span.y); + zrb->GetPointer(ctx, zrb, InterpToInt(fxLeftEdge), span.y); dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE); # endif } @@ -1065,7 +1067,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, /* ff = fixed-pt fragment */ const GLint right = InterpToInt(fxRightEdge); span.x = InterpToInt(fxLeftEdge); - if (right <= span.x) span.end = 0; else diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h index 8f249d94280..e1dbe0f512a 100644 --- a/src/mesa/swrast/swrast.h +++ b/src/mesa/swrast/swrast.h @@ -2,7 +2,7 @@ * Mesa 3-D graphics library * Version: 6.3 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 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"), @@ -79,9 +79,6 @@ struct swrast_device_driver; /* These are the public-access functions exported from swrast. */ extern void -_swrast_alloc_buffers( GLframebuffer *buffer ); - -extern void _swrast_use_read_buffer( GLcontext *ctx ); extern void @@ -260,7 +257,7 @@ _swrast_copy_texsubimage3d(GLcontext *ctx, * Unless otherwise noted, all functions are mandatory. */ struct swrast_device_driver { - +#if OLD_RENDERBUFFER void (*SetBuffer)(GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit); /* * Specifies the current color buffer for span/pixel writing/reading. @@ -274,7 +271,7 @@ struct swrast_device_driver { * DD_BACK_RIGHT_BIT - when using stereo and double buffering * DD_AUXn_BIT - if aux buffers are implemented */ - +#endif /*** *** Functions for synchronizing access to the framebuffer: @@ -297,10 +294,10 @@ struct swrast_device_driver { *** Functions for writing pixels to the frame buffer: ***/ - void (*WriteRGBASpan)( const GLcontext *ctx, + void (*WriteRGBASpan)( const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, CONST GLchan rgba[][4], const GLubyte mask[] ); - void (*WriteRGBSpan)( const GLcontext *ctx, + void (*WriteRGBSpan)( const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, CONST GLchan rgb[][3], const GLubyte mask[] ); /* Write a horizontal run of RGBA or RGB pixels. @@ -308,28 +305,33 @@ struct swrast_device_driver { * If mask is not null, only draw pixel [i] when mask [i] is true. */ - void (*WriteMonoRGBASpan)( const GLcontext *ctx, GLuint n, GLint x, GLint y, + void (*WriteMonoRGBASpan)( const GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, const GLchan color[4], const GLubyte mask[] ); /* Write a horizontal run of RGBA pixels all with the same color. * If mask is NULL, draw all pixels. * If mask is not null, only draw pixel [i] when mask [i] is true. */ - void (*WriteRGBAPixels)( const GLcontext *ctx, + void (*WriteRGBAPixels)( const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], CONST GLchan rgba[][4], const GLubyte mask[] ); /* Write array of RGBA pixels at random locations. */ void (*WriteMonoRGBAPixels)( const GLcontext *ctx, + struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], const GLchan color[4], const GLubyte mask[] ); /* Write an array of mono-RGBA pixels at random locations. */ - void (*WriteCI32Span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, +#if OLD_RENDERBUFFER /* these are obsolete */ + void (*WriteCI32Span)( const GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, const GLuint index[], const GLubyte mask[] ); - void (*WriteCI8Span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, + void (*WriteCI8Span)( const GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, const GLubyte index[], const GLubyte mask[] ); /* Write a horizontal run of CI pixels. One function is for 32bpp * indexes and the other for 8bpp pixels (the common case). You mus @@ -337,8 +339,8 @@ struct swrast_device_driver { * If mask is NULL, draw all pixels. * If mask is not null, only draw pixel [i] when mask [i] is true. */ - - void (*WriteMonoCISpan)( const GLcontext *ctx, GLuint n, GLint x, GLint y, + void (*WriteMonoCISpan)( const GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, GLuint colorIndex, const GLubyte mask[] ); /* Write a horizontal run of color index pixels using the color index * last specified by the Index() function. @@ -346,42 +348,40 @@ struct swrast_device_driver { * If mask is not null, only draw pixel [i] when mask [i] is true. */ - void (*WriteCI32Pixels)( const GLcontext *ctx, + void (*WriteCI32Pixels)( const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], const GLuint index[], const GLubyte mask[] ); /* * Write a random array of CI pixels. */ - - void (*WriteMonoCIPixels)( const GLcontext *ctx, - GLuint n, const GLint x[], const GLint y[], + void (*WriteMonoCIPixels)( const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], GLuint colorIndex, const GLubyte mask[] ); /* Write a random array of color index pixels using the color index * last specified by the Index() function. */ - /*** *** Functions to read pixels from frame buffer: ***/ - void (*ReadCI32Span)( const GLcontext *ctx, + void (*ReadCI32Span)( const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, GLuint index[] ); /* Read a horizontal run of color index pixels. */ - void (*ReadRGBASpan)( const GLcontext *ctx, GLuint n, GLint x, GLint y, - GLchan rgba[][4] ); - /* Read a horizontal run of RGBA pixels. - */ - - void (*ReadCI32Pixels)( const GLcontext *ctx, + void (*ReadCI32Pixels)( const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], GLuint indx[], const GLubyte mask[] ); /* Read a random array of CI pixels. */ +#endif + + void (*ReadRGBASpan)( const GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, GLchan rgba[][4] ); + /* Read a horizontal run of RGBA pixels. + */ - void (*ReadRGBAPixels)( const GLcontext *ctx, + void (*ReadRGBAPixels)( const GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, const GLint x[], const GLint y[], GLchan rgba[][4], const GLubyte mask[] ); /* Read a random array of RGBA pixels. @@ -396,34 +396,36 @@ struct swrast_device_driver { *** buffer is less than 32 bits deep then the extra upperbits are zero. ***/ - void (*WriteDepthSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y, + void (*WriteDepthSpan)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, const GLdepth depth[], const GLubyte mask[] ); /* Write a horizontal span of values into the depth buffer. Only write * depth[i] value if mask[i] is nonzero. */ - void (*WriteMonoDepthSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y, + void (*WriteMonoDepthSpan)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, const GLdepth depth, const GLubyte mask[] ); /* Write a horizontal run of depth values. * If mask is NULL, draw all pixels. * If mask is not null, only draw pixel [i] when mask [i] is true. */ - void (*ReadDepthSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y, - GLdepth depth[] ); + void (*ReadDepthSpan)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, GLdepth depth[] ); /* Read a horizontal span of values from the depth buffer. */ - void (*WriteDepthPixels)( GLcontext *ctx, GLuint n, - const GLint x[], const GLint y[], + void (*WriteDepthPixels)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], const GLdepth depth[], const GLubyte mask[] ); /* Write an array of randomly positioned depth values into the * depth buffer. Only write depth[i] value if mask[i] is nonzero. */ - void (*ReadDepthPixels)( GLcontext *ctx, GLuint n, - const GLint x[], const GLint y[], + void (*ReadDepthPixels)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], GLdepth depth[] ); /* Read an array of randomly positioned depth values from the depth buffer. */ @@ -435,20 +437,21 @@ struct swrast_device_driver { *** Either ALL or NONE of these functions must be implemented! ***/ - void (*WriteStencilSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y, + void (*WriteStencilSpan)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, const GLstencil stencil[], const GLubyte mask[] ); /* Write a horizontal span of stencil values into the stencil buffer. * If mask is NULL, write all stencil values. * Else, only write stencil[i] if mask[i] is non-zero. */ - void (*ReadStencilSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y, - GLstencil stencil[] ); + void (*ReadStencilSpan)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, GLstencil stencil[] ); /* Read a horizontal span of stencil values from the stencil buffer. */ - void (*WriteStencilPixels)( GLcontext *ctx, GLuint n, - const GLint x[], const GLint y[], + void (*WriteStencilPixels)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], const GLstencil stencil[], const GLubyte mask[] ); /* Write an array of stencil values into the stencil buffer. @@ -456,8 +459,8 @@ struct swrast_device_driver { * Else, only write stencil[i] if mask[i] is non-zero. */ - void (*ReadStencilPixels)( GLcontext *ctx, GLuint n, - const GLint x[], const GLint y[], + void (*ReadStencilPixels)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], GLstencil stencil[] ); /* Read an array of stencil values from the stencil buffer. */ |