diff options
Diffstat (limited to 'mesalib/src/mesa/swrast')
-rw-r--r-- | mesalib/src/mesa/swrast/s_accum.c | 598 | ||||
-rw-r--r-- | mesalib/src/mesa/swrast/s_clear.c | 5 | ||||
-rw-r--r-- | mesalib/src/mesa/swrast/s_context.c | 6 | ||||
-rw-r--r-- | mesalib/src/mesa/swrast/s_context.h | 5 | ||||
-rw-r--r-- | mesalib/src/mesa/swrast/s_copypix.c | 10 | ||||
-rw-r--r-- | mesalib/src/mesa/swrast/s_renderbuffer.c | 2034 | ||||
-rw-r--r-- | mesalib/src/mesa/swrast/s_renderbuffer.h (renamed from mesalib/src/mesa/swrast/s_accum.h) | 104 | ||||
-rw-r--r-- | mesalib/src/mesa/swrast/s_texfetch_tmp.h | 4 | ||||
-rw-r--r-- | mesalib/src/mesa/swrast/s_zoom.c | 10 | ||||
-rw-r--r-- | mesalib/src/mesa/swrast/swrast.h | 3 |
10 files changed, 2123 insertions, 656 deletions
diff --git a/mesalib/src/mesa/swrast/s_accum.c b/mesalib/src/mesa/swrast/s_accum.c deleted file mode 100644 index 0ec907d79..000000000 --- a/mesalib/src/mesa/swrast/s_accum.c +++ /dev/null @@ -1,598 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 1999-2006 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 "main/glheader.h" -#include "main/condrender.h" -#include "main/context.h" -#include "main/macros.h" -#include "main/imports.h" - -#include "s_accum.h" -#include "s_context.h" -#include "s_masking.h" -#include "s_span.h" - - -/* XXX this would have to change for accum buffers with more or less - * than 16 bits per color channel. - */ -#define ACCUM_SCALE16 32767.0F - - -/* - * Accumulation buffer notes - * - * Normally, accumulation buffer values are GLshorts with values in - * [-32767, 32767] which represent floating point colors in [-1, 1], - * as defined by the OpenGL specification. - * - * We optimize for the common case used for full-scene antialiasing: - * // start with accum buffer cleared to zero - * glAccum(GL_LOAD, w); // or GL_ACCUM the first image - * glAccum(GL_ACCUM, w); - * ... - * glAccum(GL_ACCUM, w); - * glAccum(GL_RETURN, 1.0); - * That is, we start with an empty accumulation buffer and accumulate - * n images, each with weight w = 1/n. - * 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 (n=1/w). - * This lets us avoid _many_ int->float->int conversions. - */ - - -#if CHAN_BITS == 8 -/* enable the optimization */ -#define USE_OPTIMIZED_ACCUM 1 -#else -#define USE_OPTIMIZED_ACCUM 0 -#endif - - -/** - * 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( struct gl_context *ctx ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - struct gl_renderbuffer *rb - = ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer; - const GLfloat s = swrast->_IntegerAccumScaler * (32767.0F / CHAN_MAXF); - - 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); - - 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; -} - - - -/** - * Clear the accumulation Buffer. - */ -void -_swrast_clear_accum_buffer( struct gl_context *ctx, struct gl_renderbuffer *rb ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLuint x, y, width, height; - - /* No accumulation buffer! Not an error. */ - if (!rb || !rb->Data) - return; - - 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 { - /* someday support other sizes */ - } - - /* 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; - } -} - - -static void -accum_add(struct gl_context *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 { - 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 */ - } -} - - -static void -accum_mult(struct gl_context *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 { - 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 */ - } -} - - - -static void -accum_accum(struct gl_context *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); - - assert(rb); - - if (!ctx->ReadBuffer->_ColorReadBuffer) { - /* no read buffer - OK */ - return; - } - - /* 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); - - 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 { - rb->GetRow(ctx, rb, width, xpos, ypos + i, accumRow); - acc = accumRow; - } - - /* read colors from color buffer */ - _swrast_read_rgba_span(ctx, ctx->ReadBuffer->_ColorReadBuffer, width, - xpos, ypos + i, CHAN_TYPE, rgba); - - /* do accumulation */ - if (swrast->_IntegerAccumMode) { - /* simply add integer color values into accum buffer */ - GLint j; - 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 */ - 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); - } - } - - if (!directAccess) { - rb->PutRow(ctx, rb, width, xpos, ypos + i, accumRow, NULL); - } - } - } - else { - /* other types someday */ - } -} - - - -static void -accum_load(struct gl_context *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); - - 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; -#endif - swrast->_IntegerAccumScaler = value; - } - else { - swrast->_IntegerAccumMode = GL_FALSE; - swrast->_IntegerAccumScaler = 0.0; - } - - 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 { - rb->GetRow(ctx, rb, width, xpos, ypos + i, accumRow); - acc = accumRow; - } - - /* read colors from color buffer */ - _swrast_read_rgba_span(ctx, ctx->ReadBuffer->_ColorReadBuffer, width, - xpos, ypos + i, CHAN_TYPE, rgba); - - /* do load */ - if (swrast->_IntegerAccumMode) { - /* just copy values in */ - GLint j; - assert(swrast->_IntegerAccumScaler > 0.0); - assert(swrast->_IntegerAccumScaler <= 1.0); - 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 */ - 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); - } - } - - if (!directAccess) { - rb->PutRow(ctx, rb, width, xpos, ypos + i, accumRow, NULL); - } - } - } -} - - -static void -accum_return(struct gl_context *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); - - 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; - GLint i; - - /* XXX maybe transpose the 'i' and 'buffer' loops??? */ - for (i = 0; i < height; i++) { - GLshort accumRow[4 * MAX_WIDTH]; - GLshort *acc; - SWspan span; - - /* init color span */ - INIT_SPAN(span, GL_BITMAP); - span.end = width; - span.arrayMask = SPAN_RGBA; - span.x = xpos; - span.y = ypos + i; - - 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); - span.array->rgba[j][RCOMP] = multTable[acc[j * 4 + 0]]; - span.array->rgba[j][GCOMP] = multTable[acc[j * 4 + 1]]; - span.array->rgba[j][BCOMP] = multTable[acc[j * 4 + 2]]; - span.array->rgba[j][ACOMP] = multTable[acc[j * 4 + 3]]; - } - } - else { - /* scaled integer (or float) accum buffer */ - GLint j; - for (j = 0; j < width; j++) { -#if CHAN_BITS==32 - GLchan r = acc[j * 4 + 0] * scale; - GLchan g = acc[j * 4 + 1] * scale; - GLchan b = acc[j * 4 + 2] * scale; - GLchan a = acc[j * 4 + 3] * scale; -#else - 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 ); -#endif - span.array->rgba[j][RCOMP] = CLAMP( r, 0, CHAN_MAX ); - span.array->rgba[j][GCOMP] = CLAMP( g, 0, CHAN_MAX ); - span.array->rgba[j][BCOMP] = CLAMP( b, 0, CHAN_MAX ); - span.array->rgba[j][ACOMP] = CLAMP( a, 0, CHAN_MAX ); - } - } - - /* store colors */ - for (buffer = 0; buffer < fb->_NumColorDrawBuffers; buffer++) { - struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buffer]; - const GLboolean masking = (!ctx->Color.ColorMask[buffer][RCOMP] || - !ctx->Color.ColorMask[buffer][GCOMP] || - !ctx->Color.ColorMask[buffer][BCOMP] || - !ctx->Color.ColorMask[buffer][ACOMP]); - if (masking) { - _swrast_mask_rgba_span(ctx, rb, &span, buffer); - } - rb->PutRow(ctx, rb, width, xpos, ypos + i, span.array->rgba, NULL); - } - } - } - else { - /* other types someday */ - } -} - - - -/** - * Software fallback for glAccum. - */ -void -_swrast_Accum(struct gl_context *ctx, GLenum op, GLfloat value) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLint xpos, ypos, width, height; - - if (swrast->NewState) - _swrast_validate_derived( ctx ); - - if (!ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer) { - _mesa_warning(ctx, "Calling glAccum() without an accumulation buffer"); - return; - } - - if (!_mesa_check_conditional_render(ctx)) - return; - - swrast_render_start(ctx); - - /* Compute region after calling swrast_render_start() so that we know the - * drawbuffer's size/bounds are up to date. - */ - xpos = ctx->DrawBuffer->_Xmin; - ypos = ctx->DrawBuffer->_Ymin; - width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - - switch (op) { - case GL_ADD: - if (value != 0.0F) { - accum_add(ctx, value, xpos, ypos, width, height); - } - 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_problem(ctx, "invalid mode in _swrast_Accum()"); - break; - } - - swrast_render_finish(ctx); -} diff --git a/mesalib/src/mesa/swrast/s_clear.c b/mesalib/src/mesa/swrast/s_clear.c index 980d29bba..615747d69 100644 --- a/mesalib/src/mesa/swrast/s_clear.c +++ b/mesalib/src/mesa/swrast/s_clear.c @@ -23,13 +23,13 @@ */ #include "main/glheader.h" +#include "main/accum.h" #include "main/colormac.h" #include "main/condrender.h" #include "main/macros.h" #include "main/imports.h" #include "main/mtypes.h" -#include "s_accum.h" #include "s_context.h" #include "s_depth.h" #include "s_masking.h" @@ -225,8 +225,7 @@ _swrast_Clear(struct gl_context *ctx, GLbitfield buffers) _swrast_clear_depth_buffer(ctx, ctx->DrawBuffer->_DepthBuffer); } if (buffers & BUFFER_BIT_ACCUM) { - _swrast_clear_accum_buffer(ctx, - ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer); + _mesa_clear_accum_buffer(ctx); } if (buffers & BUFFER_BIT_STENCIL) { _swrast_clear_stencil_buffer(ctx, ctx->DrawBuffer->_StencilBuffer); diff --git a/mesalib/src/mesa/swrast/s_context.c b/mesalib/src/mesa/swrast/s_context.c index 98702f068..924612578 100644 --- a/mesalib/src/mesa/swrast/s_context.c +++ b/mesalib/src/mesa/swrast/s_context.c @@ -597,7 +597,7 @@ _swrast_validate_derived( struct gl_context *ctx ) #define SWRAST_DEBUG 0 -/* Public entrypoints: See also s_accum.c, s_bitmap.c, etc. +/* Public entrypoints: See also s_bitmap.c, etc. */ void _swrast_Quad( struct gl_context *ctx, @@ -755,10 +755,6 @@ _swrast_CreateContext( struct gl_context *ctx ) ctx->Driver.MapTexture = _swrast_map_texture; ctx->Driver.UnmapTexture = _swrast_unmap_texture; - /* Optimized Accum buffer */ - swrast->_IntegerAccumMode = GL_FALSE; - swrast->_IntegerAccumScaler = 0.0; - for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) swrast->TextureSample[i] = NULL; diff --git a/mesalib/src/mesa/swrast/s_context.h b/mesalib/src/mesa/swrast/s_context.h index d3ba37819..446b990d9 100644 --- a/mesalib/src/mesa/swrast/s_context.h +++ b/mesalib/src/mesa/swrast/s_context.h @@ -203,11 +203,6 @@ typedef struct /** Indicates how each attrib is to be interpolated (lines/tris) */ GLenum _InterpMode[FRAG_ATTRIB_MAX]; /* GL_FLAT or GL_SMOOTH (for now) */ - /* Accum buffer temporaries. - */ - GLboolean _IntegerAccumMode; /**< Storing unscaled integers? */ - GLfloat _IntegerAccumScaler; /**< Implicit scale factor */ - /* Working values: */ GLuint StippleCounter; /**< Line stipple counter */ diff --git a/mesalib/src/mesa/swrast/s_copypix.c b/mesalib/src/mesa/swrast/s_copypix.c index 3ba31f22c..3bdf48b25 100644 --- a/mesalib/src/mesa/swrast/s_copypix.c +++ b/mesalib/src/mesa/swrast/s_copypix.c @@ -610,6 +610,7 @@ fast_copy_pixels(struct gl_context *ctx, struct gl_framebuffer *dstFb = ctx->DrawBuffer; struct gl_renderbuffer *srcRb, *dstRb; GLint row, yStep; + void *temp; if (SWRAST_CONTEXT(ctx)->_RasterMask != 0x0 || ctx->Pixel.ZoomX != 1.0F || @@ -667,14 +668,21 @@ fast_copy_pixels(struct gl_context *ctx, yStep = 1; } + temp = malloc(width * MAX_PIXEL_BYTES); + if (!temp) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); + return GL_FALSE; + } + for (row = 0; row < height; row++) { - GLuint temp[MAX_WIDTH][4]; srcRb->GetRow(ctx, srcRb, width, srcX, srcY, temp); dstRb->PutRow(ctx, dstRb, width, dstX, dstY, temp, NULL); srcY += yStep; dstY += yStep; } + free(temp); + return GL_TRUE; } diff --git a/mesalib/src/mesa/swrast/s_renderbuffer.c b/mesalib/src/mesa/swrast/s_renderbuffer.c new file mode 100644 index 000000000..7622e38fd --- /dev/null +++ b/mesalib/src/mesa/swrast/s_renderbuffer.c @@ -0,0 +1,2034 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 1999-2006 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. + */ + + +/** + * Functions for allocating/managing software-based renderbuffers. + * Also, routines for reading/writing software-based renderbuffer data as + * ubytes, ushorts, uints, etc. + */ + + +#include "main/glheader.h" +#include "main/imports.h" +#include "main/context.h" +#include "main/fbobject.h" +#include "main/formats.h" +#include "main/mtypes.h" +#include "main/renderbuffer.h" +#include "swrast/s_renderbuffer.h" + + +/* + * Routines for get/put values in common buffer formats follow. + */ + +/* Returns a bytes per pixel of the DataType in the get/put span + * functions for at least a subset of the available combinations a + * renderbuffer can have. + * + * It would be nice to see gl_renderbuffer start talking about a + * gl_format instead of a GLenum DataType. + */ +static int +get_datatype_bytes(struct gl_renderbuffer *rb) +{ + int component_size; + + switch (rb->DataType) { + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + component_size = 8; + break; + case GL_FLOAT: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_24_8_EXT: + component_size = 4; + break; + case GL_UNSIGNED_SHORT: + component_size = 2; + break; + case GL_UNSIGNED_BYTE: + component_size = 1; + break; + default: + component_size = 1; + assert(0); + } + + switch (rb->_BaseFormat) { + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL: + return component_size; + default: + return 4 * component_size; + } +} + +/* This is commonly used by most of the accessors. */ +static void * +get_pointer_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLint x, GLint y) +{ + if (!rb->Data) + return NULL; + + return ((char *) rb->Data + + (y * rb->RowStride + x) * _mesa_get_format_bytes(rb->Format)); +} + +/* GetRow() implementation for formats where DataType matches the rb->Format. + */ +static void +get_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, void *values) +{ + void *src = rb->GetPointer(ctx, rb, x, y); + memcpy(values, src, count * _mesa_get_format_bytes(rb->Format)); +} + +/* Only used for float textures currently, but might also be used for + * RGBA8888, RGBA16, etc. + */ +static void +get_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], void *values) +{ + int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); + GLuint i; + + for (i = 0; i < count; i++) { + const void *src = rb->GetPointer(ctx, rb, x[i], y[i]); + char *dst = (char *) values + i * format_bytes; + memcpy(dst, src, format_bytes); + } +} + +/* For the GL_RED/GL_RG/GL_RGB format/DataType combinations (and + * GL_LUMINANCE/GL_INTENSITY?), the Put functions are a matter of + * storing those initial components of the value per pixel into the + * destination. + */ +static void +put_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, + const void *values, const GLubyte *mask) +{ + void *row = rb->GetPointer(ctx, rb, x, y); + int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); + int datatype_bytes = get_datatype_bytes(rb); + unsigned int i; + + if (mask) { + for (i = 0; i < count; i++) { + char *dst = (char *) row + i * format_bytes; + const char *src = (const char *) values + i * datatype_bytes; + + if (mask[i]) { + memcpy(dst, src, format_bytes); + } + } + } + else { + for (i = 0; i < count; i++) { + char *dst = (char *) row + i * format_bytes; + const char *src = (const char *) values + i * datatype_bytes; + memcpy(dst, src, format_bytes); + } + } +} + +static void +put_mono_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, + const void *value, const GLubyte *mask) +{ + void *row = rb->GetPointer(ctx, rb, x, y); + int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); + unsigned int i; + + if (mask) { + for (i = 0; i < count; i++) { + char *dst = (char *) row + i * format_bytes; + if (mask[i]) { + memcpy(dst, value, format_bytes); + } + } + } + else { + for (i = 0; i < count; i++) { + char *dst = (char *) row + i * format_bytes; + memcpy(dst, value, format_bytes); + } + } +} + + +static void +put_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *values, const GLubyte *mask) +{ + int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); + int datatype_bytes = get_datatype_bytes(rb); + unsigned int i; + + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + void *dst = rb->GetPointer(ctx, rb, x[i], y[i]); + const char *src = (const char *) values + i * datatype_bytes; + memcpy(dst, src, format_bytes); + } + } +} + + +static void +put_mono_values_generic(struct gl_context *ctx, + struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *value, const GLubyte *mask) +{ + int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); + unsigned int i; + + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + void *dst = rb->GetPointer(ctx, rb, x[i], y[i]); + memcpy(dst, value, format_bytes); + } + } +} + +/********************************************************************** + * Functions for buffers of 1 X GLubyte values. + * Typically stencil. + */ + +static void +get_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], void *values) +{ + GLubyte *dst = (GLubyte *) values; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < count; i++) { + const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i]; + dst[i] = *src; + } +} + + +static void +put_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + const GLubyte *src = (const GLubyte *) values; + GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x; + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + if (mask) { + GLuint i; + for (i = 0; i < count; i++) { + if (mask[i]) { + dst[i] = src[i]; + } + } + } + else { + memcpy(dst, values, count * sizeof(GLubyte)); + } +} + + +static void +put_mono_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *value, const GLubyte *mask) +{ + const GLubyte val = *((const GLubyte *) value); + GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x; + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + if (mask) { + GLuint i; + for (i = 0; i < count; i++) { + if (mask[i]) { + dst[i] = val; + } + } + } + else { + GLuint i; + for (i = 0; i < count; i++) { + dst[i] = val; + } + } +} + + +static void +put_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], + const void *values, const GLubyte *mask) +{ + const GLubyte *src = (const GLubyte *) values; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i]; + *dst = src[i]; + } + } +} + + +static void +put_mono_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], + const void *value, const GLubyte *mask) +{ + const GLubyte val = *((const GLubyte *) value); + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i]; + *dst = val; + } + } +} + + +/********************************************************************** + * Functions for buffers of 1 X GLushort values. + * Typically depth/Z. + */ + +static void +get_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], void *values) +{ + GLushort *dst = (GLushort *) values; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT); + for (i = 0; i < count; i++) { + const GLushort *src = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; + dst[i] = *src; + } +} + + +static void +put_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + const GLushort *src = (const GLushort *) values; + GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT); + if (mask) { + GLuint i; + for (i = 0; i < count; i++) { + if (mask[i]) { + dst[i] = src[i]; + } + } + } + else { + memcpy(dst, src, count * sizeof(GLushort)); + } +} + + +static void +put_mono_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *value, const GLubyte *mask) +{ + const GLushort val = *((const GLushort *) value); + GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT); + if (mask) { + GLuint i; + for (i = 0; i < count; i++) { + if (mask[i]) { + dst[i] = val; + } + } + } + else { + GLuint i; + for (i = 0; i < count; i++) { + dst[i] = val; + } + } +} + + +static void +put_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], const void *values, + const GLubyte *mask) +{ + const GLushort *src = (const GLushort *) values; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; + *dst = src[i]; + } + } +} + + +static void +put_mono_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *value, const GLubyte *mask) +{ + const GLushort val = *((const GLushort *) value); + ASSERT(rb->DataType == GL_UNSIGNED_SHORT); + if (mask) { + GLuint i; + for (i = 0; i < count; i++) { + if (mask[i]) { + GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; + *dst = val; + } + } + } + else { + GLuint i; + for (i = 0; i < count; i++) { + GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; + *dst = val; + } + } +} + + +/********************************************************************** + * Functions for buffers of 1 X GLuint values. + * Typically depth/Z or color index. + */ + +static void +get_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], void *values) +{ + GLuint *dst = (GLuint *) values; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_INT || + rb->DataType == GL_UNSIGNED_INT_24_8_EXT); + for (i = 0; i < count; i++) { + const GLuint *src = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i]; + dst[i] = *src; + } +} + + +static void +put_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + const GLuint *src = (const GLuint *) values; + GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x; + ASSERT(rb->DataType == GL_UNSIGNED_INT || + rb->DataType == GL_UNSIGNED_INT_24_8_EXT); + if (mask) { + GLuint i; + for (i = 0; i < count; i++) { + if (mask[i]) { + dst[i] = src[i]; + } + } + } + else { + memcpy(dst, src, count * sizeof(GLuint)); + } +} + + +static void +put_mono_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *value, const GLubyte *mask) +{ + const GLuint val = *((const GLuint *) value); + GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x; + ASSERT(rb->DataType == GL_UNSIGNED_INT || + rb->DataType == GL_UNSIGNED_INT_24_8_EXT); + if (mask) { + GLuint i; + for (i = 0; i < count; i++) { + if (mask[i]) { + dst[i] = val; + } + } + } + else { + GLuint i; + for (i = 0; i < count; i++) { + dst[i] = val; + } + } +} + + +static void +put_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], const void *values, + const GLubyte *mask) +{ + const GLuint *src = (const GLuint *) values; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_INT || + rb->DataType == GL_UNSIGNED_INT_24_8_EXT); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i]; + *dst = src[i]; + } + } +} + + +static void +put_mono_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], const void *value, + const GLubyte *mask) +{ + const GLuint val = *((const GLuint *) value); + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_INT || + rb->DataType == GL_UNSIGNED_INT_24_8_EXT); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i]; + *dst = val; + } + } +} + + +/********************************************************************** + * Functions for buffers of 3 X GLubyte (or GLbyte) values. + * Typically color buffers. + * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming + * alpha values and return 255 for outgoing alpha values. + */ + +static void * +get_pointer_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLint x, GLint y) +{ + ASSERT(rb->Format == MESA_FORMAT_RGB888); + /* No direct access since this buffer is RGB but caller will be + * treating it as if it were RGBA. + */ + return NULL; +} + + +static void +get_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values) +{ + const GLubyte *src = ((const GLubyte *) rb->Data) + + 3 * (y * rb->RowStride + x); + GLubyte *dst = (GLubyte *) values; + GLuint i; + ASSERT(rb->Format == MESA_FORMAT_RGB888); + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < count; i++) { + dst[i * 4 + 0] = src[i * 3 + 0]; + dst[i * 4 + 1] = src[i * 3 + 1]; + dst[i * 4 + 2] = src[i * 3 + 2]; + dst[i * 4 + 3] = 255; + } +} + + +static void +get_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], void *values) +{ + GLubyte *dst = (GLubyte *) values; + GLuint i; + ASSERT(rb->Format == MESA_FORMAT_RGB888); + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < count; i++) { + const GLubyte *src + = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]); + dst[i * 4 + 0] = src[0]; + dst[i * 4 + 1] = src[1]; + dst[i * 4 + 2] = src[2]; + dst[i * 4 + 3] = 255; + } +} + + +static void +put_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + /* note: incoming values are RGB+A! */ + const GLubyte *src = (const GLubyte *) values; + GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x); + GLuint i; + ASSERT(rb->Format == MESA_FORMAT_RGB888); + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + dst[i * 3 + 0] = src[i * 4 + 0]; + dst[i * 3 + 1] = src[i * 4 + 1]; + dst[i * 3 + 2] = src[i * 4 + 2]; + } + } +} + + +static void +put_row_rgb_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + /* note: incoming values are RGB+A! */ + const GLubyte *src = (const GLubyte *) values; + GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x); + GLuint i; + ASSERT(rb->Format == MESA_FORMAT_RGB888); + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + dst[i * 3 + 0] = src[i * 3 + 0]; + dst[i * 3 + 1] = src[i * 3 + 1]; + dst[i * 3 + 2] = src[i * 3 + 2]; + } + } +} + + +static void +put_mono_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *value, const GLubyte *mask) +{ + /* note: incoming value is RGB+A! */ + const GLubyte val0 = ((const GLubyte *) value)[0]; + const GLubyte val1 = ((const GLubyte *) value)[1]; + const GLubyte val2 = ((const GLubyte *) value)[2]; + GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x); + ASSERT(rb->Format == MESA_FORMAT_RGB888); + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + if (!mask && val0 == val1 && val1 == val2) { + /* optimized case */ + memset(dst, val0, 3 * count); + } + else { + GLuint i; + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + dst[i * 3 + 0] = val0; + dst[i * 3 + 1] = val1; + dst[i * 3 + 2] = val2; + } + } + } +} + + +static void +put_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], const void *values, + const GLubyte *mask) +{ + /* note: incoming values are RGB+A! */ + const GLubyte *src = (const GLubyte *) values; + GLuint i; + ASSERT(rb->Format == MESA_FORMAT_RGB888); + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]); + dst[0] = src[i * 4 + 0]; + dst[1] = src[i * 4 + 1]; + dst[2] = src[i * 4 + 2]; + } + } +} + + +static void +put_mono_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *value, const GLubyte *mask) +{ + /* note: incoming value is RGB+A! */ + const GLubyte val0 = ((const GLubyte *) value)[0]; + const GLubyte val1 = ((const GLubyte *) value)[1]; + const GLubyte val2 = ((const GLubyte *) value)[2]; + GLuint i; + ASSERT(rb->Format == MESA_FORMAT_RGB888); + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLubyte *dst = ((GLubyte *) rb->Data) + + 3 * (y[i] * rb->RowStride + x[i]); + dst[0] = val0; + dst[1] = val1; + dst[2] = val2; + } + } +} + + +/********************************************************************** + * Functions for buffers of 4 X GLubyte (or GLbyte) values. + * Typically color buffers. + */ + +static void +get_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], void *values) +{ + /* treat 4*GLubyte as 1*GLuint */ + GLuint *dst = (GLuint *) values; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || + rb->Format == MESA_FORMAT_RGBA8888_REV); + for (i = 0; i < count; i++) { + const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); + dst[i] = *src; + } +} + + +static void +put_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + /* treat 4*GLubyte as 1*GLuint */ + const GLuint *src = (const GLuint *) values; + GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x); + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || + rb->Format == MESA_FORMAT_RGBA8888_REV); + if (mask) { + GLuint i; + for (i = 0; i < count; i++) { + if (mask[i]) { + dst[i] = src[i]; + } + } + } + else { + memcpy(dst, src, 4 * count * sizeof(GLubyte)); + } +} + + +static void +put_row_rgb_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + /* Store RGB values in RGBA buffer */ + const GLubyte *src = (const GLubyte *) values; + GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->RowStride + x); + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || + rb->Format == MESA_FORMAT_RGBA8888_REV); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + dst[i * 4 + 0] = src[i * 3 + 0]; + dst[i * 4 + 1] = src[i * 3 + 1]; + dst[i * 4 + 2] = src[i * 3 + 2]; + dst[i * 4 + 3] = 0xff; + } + } +} + + +static void +put_mono_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *value, const GLubyte *mask) +{ + /* treat 4*GLubyte as 1*GLuint */ + const GLuint val = *((const GLuint *) value); + GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x); + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || + rb->Format == MESA_FORMAT_RGBA8888_REV); + if (!mask && val == 0) { + /* common case */ + memset(dst, 0, count * 4 * sizeof(GLubyte)); + } + else { + /* general case */ + if (mask) { + GLuint i; + for (i = 0; i < count; i++) { + if (mask[i]) { + dst[i] = val; + } + } + } + else { + GLuint i; + for (i = 0; i < count; i++) { + dst[i] = val; + } + } + } +} + + +static void +put_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], const void *values, + const GLubyte *mask) +{ + /* treat 4*GLubyte as 1*GLuint */ + const GLuint *src = (const GLuint *) values; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || + rb->Format == MESA_FORMAT_RGBA8888_REV); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); + *dst = src[i]; + } + } +} + + +static void +put_mono_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *value, const GLubyte *mask) +{ + /* treat 4*GLubyte as 1*GLuint */ + const GLuint val = *((const GLuint *) value); + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || + rb->Format == MESA_FORMAT_RGBA8888_REV); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); + *dst = val; + } + } +} + + +/********************************************************************** + * Functions for buffers of 4 X GLushort (or GLshort) values. + * Typically accum buffer. + */ + +static void +get_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], void *values) +{ + GLushort *dst = (GLushort *) values; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); + for (i = 0; i < count; i++) { + const GLushort *src + = (GLushort *) rb->Data + 4 * (y[i] * rb->RowStride + x[i]); + dst[i] = *src; + } +} + + +static void +put_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + const GLushort *src = (const GLushort *) values; + GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); + ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); + if (mask) { + GLuint i; + for (i = 0; i < count; i++) { + if (mask[i]) { + dst[i * 4 + 0] = src[i * 4 + 0]; + dst[i * 4 + 1] = src[i * 4 + 1]; + dst[i * 4 + 2] = src[i * 4 + 2]; + dst[i * 4 + 3] = src[i * 4 + 3]; + } + } + } + else { + memcpy(dst, src, 4 * count * sizeof(GLushort)); + } +} + + +static void +put_row_rgb_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + /* Put RGB values in RGBA buffer */ + const GLushort *src = (const GLushort *) values; + GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); + ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); + if (mask) { + GLuint i; + for (i = 0; i < count; i++) { + if (mask[i]) { + dst[i * 4 + 0] = src[i * 3 + 0]; + dst[i * 4 + 1] = src[i * 3 + 1]; + dst[i * 4 + 2] = src[i * 3 + 2]; + dst[i * 4 + 3] = 0xffff; + } + } + } + else { + memcpy(dst, src, 4 * count * sizeof(GLushort)); + } +} + + +static void +put_mono_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *value, const GLubyte *mask) +{ + const GLushort val0 = ((const GLushort *) value)[0]; + const GLushort val1 = ((const GLushort *) value)[1]; + const GLushort val2 = ((const GLushort *) value)[2]; + const GLushort val3 = ((const GLushort *) value)[3]; + GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); + ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); + if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) { + /* common case for clearing accum buffer */ + memset(dst, 0, count * 4 * sizeof(GLushort)); + } + else { + GLuint i; + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + dst[i * 4 + 0] = val0; + dst[i * 4 + 1] = val1; + dst[i * 4 + 2] = val2; + dst[i * 4 + 3] = val3; + } + } + } +} + + +static void +put_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], const void *values, + const GLubyte *mask) +{ + const GLushort *src = (const GLushort *) values; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLushort *dst = + ((GLushort *) rb->Data) + 4 * (y[i] * rb->RowStride + x[i]); + dst[0] = src[i * 4 + 0]; + dst[1] = src[i * 4 + 1]; + dst[2] = src[i * 4 + 2]; + dst[3] = src[i * 4 + 3]; + } + } +} + + +static void +put_mono_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *value, const GLubyte *mask) +{ + const GLushort val0 = ((const GLushort *) value)[0]; + const GLushort val1 = ((const GLushort *) value)[1]; + const GLushort val2 = ((const GLushort *) value)[2]; + const GLushort val3 = ((const GLushort *) value)[3]; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLushort *dst = ((GLushort *) rb->Data) + + 4 * (y[i] * rb->RowStride + x[i]); + dst[0] = val0; + dst[1] = val1; + dst[2] = val2; + dst[3] = val3; + } + } +} + +/********************************************************************** + * Functions for MESA_FORMAT_R8. + */ +static void +get_row_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values) +{ + const GLubyte *src = rb->GetPointer(ctx, rb, x, y); + GLuint *dst = values; + GLuint i; + + for (i = 0; i < count; i++) { + dst[i] = 0xff000000 | src[i]; + } +} + +static void +get_values_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], void *values) +{ + GLuint *dst = (GLuint *) values; + GLuint i; + + for (i = 0; i < count; i++) { + const GLubyte *src = rb->GetPointer(ctx, rb, x[i], y[i]); + dst[i] = 0xff000000 | *src; + } +} + +/********************************************************************** + * Functions for MESA_FORMAT_GR88. + */ +static void +get_row_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values) +{ + const GLushort *src = rb->GetPointer(ctx, rb, x, y); + GLuint *dst = values; + GLuint i; + + for (i = 0; i < count; i++) { + dst[i] = 0xff000000 | src[i]; + } +} + +static void +get_values_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], void *values) +{ + GLuint *dst = (GLuint *) values; + GLuint i; + + for (i = 0; i < count; i++) { + const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]); + dst[i] = 0xff000000 | *src; + } +} + +/********************************************************************** + * Functions for MESA_FORMAT_R16. + */ +static void +get_row_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values) +{ + const GLushort *src = rb->GetPointer(ctx, rb, x, y); + GLushort *dst = values; + GLuint i; + + for (i = 0; i < count; i++) { + dst[i * 4 + RCOMP] = src[i]; + dst[i * 4 + GCOMP] = 0; + dst[i * 4 + BCOMP] = 0; + dst[i * 4 + ACOMP] = 0xffff; + } +} + +static void +get_values_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], void *values) +{ + GLushort *dst = values; + GLuint i; + + for (i = 0; i < count; i++) { + const GLushort *src = rb->GetPointer(ctx, rb, x[i], y[i]); + dst[i * 4 + RCOMP] = *src; + dst[i * 4 + GCOMP] = 0; + dst[i * 4 + BCOMP] = 0; + dst[i * 4 + ACOMP] = 0xffff; + } +} + +/********************************************************************** + * Functions for MESA_FORMAT_RG1616. + */ +static void +get_row_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values) +{ + const GLushort *src = rb->GetPointer(ctx, rb, x, y); + GLushort *dst = values; + GLuint i; + + for (i = 0; i < count; i++) { + dst[i * 4 + RCOMP] = src[i * 2]; + dst[i * 4 + GCOMP] = src[i * 2 + 1]; + dst[i * 4 + BCOMP] = 0; + dst[i * 4 + ACOMP] = 0xffff; + } +} + +static void +get_values_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], void *values) +{ + GLushort *dst = values; + GLuint i; + + for (i = 0; i < count; i++) { + const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]); + dst[i * 4 + RCOMP] = src[0]; + dst[i * 4 + GCOMP] = src[1]; + dst[i * 4 + BCOMP] = 0; + dst[i * 4 + ACOMP] = 0xffff; + } +} + +/********************************************************************** + * Functions for MESA_FORMAT_INTENSITY_FLOAT32. + */ +static void +get_row_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, void *values) +{ + const GLfloat *src = rb->GetPointer(ctx, rb, x, y); + GLfloat *dst = values; + GLuint i; + + for (i = 0; i < count; i++) { + dst[i * 4 + RCOMP] = + dst[i * 4 + GCOMP] = + dst[i * 4 + BCOMP] = + dst[i * 4 + ACOMP] = src[i]; + } +} + +static void +get_values_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + void *values) +{ + GLfloat *dst = values; + GLuint i; + + for (i = 0; i < count; i++) { + const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); + dst[i * 4 + RCOMP] = + dst[i * 4 + GCOMP] = + dst[i * 4 + BCOMP] = + dst[i * 4 + ACOMP] = src[0]; + } +} + +/********************************************************************** + * Functions for MESA_FORMAT_LUMINANCE_FLOAT32. + */ +static void +get_row_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, void *values) +{ + const GLfloat *src = rb->GetPointer(ctx, rb, x, y); + GLfloat *dst = values; + GLuint i; + + for (i = 0; i < count; i++) { + dst[i * 4 + RCOMP] = + dst[i * 4 + GCOMP] = + dst[i * 4 + BCOMP] = src[i]; + dst[i * 4 + ACOMP] = 1.0; + } +} + +static void +get_values_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + void *values) +{ + GLfloat *dst = values; + GLuint i; + + for (i = 0; i < count; i++) { + const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); + dst[i * 4 + RCOMP] = + dst[i * 4 + GCOMP] = + dst[i * 4 + BCOMP] = src[0]; + dst[i * 4 + ACOMP] = 1.0; + } +} + +/********************************************************************** + * Functions for MESA_FORMAT_ALPHA_FLOAT32. + */ +static void +get_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, void *values) +{ + const GLfloat *src = rb->GetPointer(ctx, rb, x, y); + GLfloat *dst = values; + GLuint i; + + for (i = 0; i < count; i++) { + dst[i * 4 + RCOMP] = 0.0; + dst[i * 4 + GCOMP] = 0.0; + dst[i * 4 + BCOMP] = 0.0; + dst[i * 4 + ACOMP] = src[i]; + } +} + +static void +get_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + void *values) +{ + GLfloat *dst = values; + GLuint i; + + for (i = 0; i < count; i++) { + const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); + dst[i * 4 + RCOMP] = 0.0; + dst[i * 4 + GCOMP] = 0.0; + dst[i * 4 + BCOMP] = 0.0; + dst[i * 4 + ACOMP] = src[0]; + } +} + +static void +put_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, + const void *values, const GLubyte *mask) +{ + float *dst = rb->GetPointer(ctx, rb, x, y); + const float *src = values; + unsigned int i; + + if (mask) { + for (i = 0; i < count; i++) { + if (mask[i]) { + dst[i] = src[i * 4 + ACOMP]; + } + } + } + else { + for (i = 0; i < count; i++) { + dst[i] = src[i * 4 + ACOMP]; + } + } +} + +static void +put_mono_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, + const void *value, const GLubyte *mask) +{ + float *dst = rb->GetPointer(ctx, rb, x, y); + const float *src = value; + unsigned int i; + + if (mask) { + for (i = 0; i < count; i++) { + if (mask[i]) { + dst[i] = src[ACOMP]; + } + } + } + else { + for (i = 0; i < count; i++) { + dst[i] = src[ACOMP]; + } + } +} + +static void +put_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *values, const GLubyte *mask) +{ + const float *src = values; + unsigned int i; + + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + float *dst = rb->GetPointer(ctx, rb, x[i], y[i]); + + *dst = src[i * 4 + ACOMP]; + } + } +} + +static void +put_mono_values_a_float32(struct gl_context *ctx, + struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *value, const GLubyte *mask) +{ + const float *src = value; + unsigned int i; + + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + float *dst = rb->GetPointer(ctx, rb, x[i], y[i]); + *dst = src[ACOMP]; + } + } +} + +/********************************************************************** + * Functions for MESA_FORMAT_R_FLOAT32. + */ +static void +get_row_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, void *values) +{ + const GLfloat *src = rb->GetPointer(ctx, rb, x, y); + GLfloat *dst = values; + GLuint i; + + for (i = 0; i < count; i++) { + dst[i * 4 + RCOMP] = src[i]; + dst[i * 4 + GCOMP] = 0.0; + dst[i * 4 + BCOMP] = 0.0; + dst[i * 4 + ACOMP] = 1.0; + } +} + +static void +get_values_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + void *values) +{ + GLfloat *dst = values; + GLuint i; + + for (i = 0; i < count; i++) { + const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); + dst[i * 4 + RCOMP] = src[0]; + dst[i * 4 + GCOMP] = 0.0; + dst[i * 4 + BCOMP] = 0.0; + dst[i * 4 + ACOMP] = 1.0; + } +} + +/********************************************************************** + * Functions for MESA_FORMAT_RG_FLOAT32. + */ +static void +get_row_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, void *values) +{ + const GLfloat *src = rb->GetPointer(ctx, rb, x, y); + GLfloat *dst = values; + GLuint i; + + for (i = 0; i < count; i++) { + dst[i * 4 + RCOMP] = src[i * 2 + 0]; + dst[i * 4 + GCOMP] = src[i * 2 + 1]; + dst[i * 4 + BCOMP] = 0.0; + dst[i * 4 + ACOMP] = 1.0; + } +} + +static void +get_values_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + void *values) +{ + GLfloat *dst = values; + GLuint i; + + for (i = 0; i < count; i++) { + const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); + dst[i * 4 + RCOMP] = src[0]; + dst[i * 4 + GCOMP] = src[1]; + dst[i * 4 + BCOMP] = 0.0; + dst[i * 4 + ACOMP] = 1.0; + } +} + +/** + * This is the default software fallback for gl_renderbuffer's span + * access functions. + * + * The assumptions are that rb->Data will be a pointer to (0,0), that pixels + * are packed in the type of rb->Format, and that subsequent rows appear + * rb->RowStride pixels later. + */ +void +_swrast_set_renderbuffer_accessors(struct gl_renderbuffer *rb) +{ + rb->GetPointer = get_pointer_generic; + rb->GetRow = get_row_generic; + + switch (rb->Format) { + case MESA_FORMAT_RGB888: + rb->DataType = GL_UNSIGNED_BYTE; + rb->GetPointer = get_pointer_ubyte3; + rb->GetRow = get_row_ubyte3; + rb->GetValues = get_values_ubyte3; + rb->PutRow = put_row_ubyte3; + rb->PutRowRGB = put_row_rgb_ubyte3; + rb->PutMonoRow = put_mono_row_ubyte3; + rb->PutValues = put_values_ubyte3; + rb->PutMonoValues = put_mono_values_ubyte3; + break; + + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + rb->DataType = GL_UNSIGNED_BYTE; + rb->GetValues = get_values_ubyte4; + rb->PutRow = put_row_ubyte4; + rb->PutRowRGB = put_row_rgb_ubyte4; + rb->PutMonoRow = put_mono_row_ubyte4; + rb->PutValues = put_values_ubyte4; + rb->PutMonoValues = put_mono_values_ubyte4; + break; + + case MESA_FORMAT_R8: + rb->DataType = GL_UNSIGNED_BYTE; + rb->GetValues = get_values_r8; + rb->GetRow = get_row_r8; + rb->PutRow = put_row_generic; + rb->PutRowRGB = put_row_generic; + rb->PutMonoRow = put_mono_row_generic; + rb->PutValues = put_values_generic; + rb->PutMonoValues = put_mono_values_generic; + break; + + case MESA_FORMAT_GR88: + rb->DataType = GL_UNSIGNED_BYTE; + rb->GetValues = get_values_rg88; + rb->GetRow = get_row_rg88; + rb->PutRow = put_row_generic; + rb->PutRowRGB = put_row_generic; + rb->PutMonoRow = put_mono_row_generic; + rb->PutValues = put_values_generic; + rb->PutMonoValues = put_mono_values_generic; + break; + + case MESA_FORMAT_R16: + rb->DataType = GL_UNSIGNED_SHORT; + rb->GetValues = get_values_r16; + rb->GetRow = get_row_r16; + rb->PutRow = put_row_generic; + rb->PutRowRGB = put_row_generic; + rb->PutMonoRow = put_mono_row_generic; + rb->PutValues = put_values_generic; + rb->PutMonoValues = put_mono_values_generic; + break; + + case MESA_FORMAT_RG1616: + rb->DataType = GL_UNSIGNED_SHORT; + rb->GetValues = get_values_rg1616; + rb->GetRow = get_row_rg1616; + rb->PutRow = put_row_generic; + rb->PutRowRGB = put_row_generic; + rb->PutMonoRow = put_mono_row_generic; + rb->PutValues = put_values_generic; + rb->PutMonoValues = put_mono_values_generic; + break; + + case MESA_FORMAT_SIGNED_RGBA_16: + rb->DataType = GL_SHORT; + rb->GetValues = get_values_ushort4; + rb->PutRow = put_row_ushort4; + rb->PutRowRGB = put_row_rgb_ushort4; + rb->PutMonoRow = put_mono_row_ushort4; + rb->PutValues = put_values_ushort4; + rb->PutMonoValues = put_mono_values_ushort4; + break; + + case MESA_FORMAT_S8: + rb->DataType = GL_UNSIGNED_BYTE; + rb->GetValues = get_values_ubyte; + rb->PutRow = put_row_ubyte; + rb->PutRowRGB = NULL; + rb->PutMonoRow = put_mono_row_ubyte; + rb->PutValues = put_values_ubyte; + rb->PutMonoValues = put_mono_values_ubyte; + break; + + case MESA_FORMAT_Z16: + rb->DataType = GL_UNSIGNED_SHORT; + rb->GetValues = get_values_ushort; + rb->PutRow = put_row_ushort; + rb->PutRowRGB = NULL; + rb->PutMonoRow = put_mono_row_ushort; + rb->PutValues = put_values_ushort; + rb->PutMonoValues = put_mono_values_ushort; + break; + + case MESA_FORMAT_Z32: + case MESA_FORMAT_X8_Z24: + case MESA_FORMAT_Z24_X8: + rb->DataType = GL_UNSIGNED_INT; + rb->GetValues = get_values_uint; + rb->PutRow = put_row_uint; + rb->PutRowRGB = NULL; + rb->PutMonoRow = put_mono_row_uint; + rb->PutValues = put_values_uint; + rb->PutMonoValues = put_mono_values_uint; + break; + + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_S8_Z24: + rb->DataType = GL_UNSIGNED_INT_24_8_EXT; + rb->GetValues = get_values_uint; + rb->PutRow = put_row_uint; + rb->PutRowRGB = NULL; + rb->PutMonoRow = put_mono_row_uint; + rb->PutValues = put_values_uint; + rb->PutMonoValues = put_mono_values_uint; + break; + + case MESA_FORMAT_RGBA_FLOAT32: + rb->GetRow = get_row_generic; + rb->GetValues = get_values_generic; + rb->PutRow = put_row_generic; + rb->PutRowRGB = NULL; + rb->PutMonoRow = put_mono_row_generic; + rb->PutValues = put_values_generic; + rb->PutMonoValues = put_mono_values_generic; + break; + + case MESA_FORMAT_INTENSITY_FLOAT32: + rb->GetRow = get_row_i_float32; + rb->GetValues = get_values_i_float32; + rb->PutRow = put_row_generic; + rb->PutRowRGB = NULL; + rb->PutMonoRow = put_mono_row_generic; + rb->PutValues = put_values_generic; + rb->PutMonoValues = put_mono_values_generic; + break; + + case MESA_FORMAT_LUMINANCE_FLOAT32: + rb->GetRow = get_row_l_float32; + rb->GetValues = get_values_l_float32; + rb->PutRow = put_row_generic; + rb->PutRowRGB = NULL; + rb->PutMonoRow = put_mono_row_generic; + rb->PutValues = put_values_generic; + rb->PutMonoValues = put_mono_values_generic; + break; + + case MESA_FORMAT_ALPHA_FLOAT32: + rb->GetRow = get_row_a_float32; + rb->GetValues = get_values_a_float32; + rb->PutRow = put_row_a_float32; + rb->PutRowRGB = NULL; + rb->PutMonoRow = put_mono_row_a_float32; + rb->PutValues = put_values_a_float32; + rb->PutMonoValues = put_mono_values_a_float32; + break; + + case MESA_FORMAT_RG_FLOAT32: + rb->GetRow = get_row_rg_float32; + rb->GetValues = get_values_rg_float32; + rb->PutRow = put_row_generic; + rb->PutRowRGB = NULL; + rb->PutMonoRow = put_mono_row_generic; + rb->PutValues = put_values_generic; + rb->PutMonoValues = put_mono_values_generic; + break; + + case MESA_FORMAT_R_FLOAT32: + rb->GetRow = get_row_r_float32; + rb->GetValues = get_values_r_float32; + rb->PutRow = put_row_generic; + rb->PutRowRGB = NULL; + rb->PutMonoRow = put_mono_row_generic; + rb->PutValues = put_values_generic; + rb->PutMonoValues = put_mono_values_generic; + break; + + default: + break; + } +} + +/** + * This is a software fallback for the gl_renderbuffer->AllocStorage + * function. + * Device drivers will typically override this function for the buffers + * which it manages (typically color buffers, Z and stencil). + * Other buffers (like software accumulation and aux buffers) which the driver + * doesn't manage can be handled with this function. + * + * This one multi-purpose function can allocate stencil, depth, accum, color + * or color-index buffers! + * + * This function also plugs in the appropriate GetPointer, Get/PutRow and + * Get/PutValues functions. + */ +static GLboolean +soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + switch (internalFormat) { + case GL_RGB: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + rb->Format = MESA_FORMAT_RGB888; + break; + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: +#if 1 + case GL_RGB10_A2: + case GL_RGBA12: +#endif + if (_mesa_little_endian()) + rb->Format = MESA_FORMAT_RGBA8888_REV; + else + rb->Format = MESA_FORMAT_RGBA8888; + break; + case GL_RGBA16: + case GL_RGBA16_SNORM: + /* for accum buffer */ + rb->Format = MESA_FORMAT_SIGNED_RGBA_16; + break; + case GL_STENCIL_INDEX: + case GL_STENCIL_INDEX1_EXT: + case GL_STENCIL_INDEX4_EXT: + case GL_STENCIL_INDEX8_EXT: + case GL_STENCIL_INDEX16_EXT: + rb->Format = MESA_FORMAT_S8; + break; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + rb->Format = MESA_FORMAT_Z16; + break; + case GL_DEPTH_COMPONENT24: + rb->Format = MESA_FORMAT_X8_Z24; + break; + case GL_DEPTH_COMPONENT32: + rb->Format = MESA_FORMAT_Z32; + break; + case GL_DEPTH_STENCIL_EXT: + case GL_DEPTH24_STENCIL8_EXT: + rb->Format = MESA_FORMAT_Z24_S8; + break; + default: + /* unsupported format */ + return GL_FALSE; + } + + _swrast_set_renderbuffer_accessors(rb); + + ASSERT(rb->DataType); + ASSERT(rb->GetPointer); + ASSERT(rb->GetRow); + ASSERT(rb->GetValues); + ASSERT(rb->PutRow); + ASSERT(rb->PutMonoRow); + ASSERT(rb->PutValues); + ASSERT(rb->PutMonoValues); + + /* free old buffer storage */ + if (rb->Data) { + free(rb->Data); + rb->Data = NULL; + } + + rb->RowStride = width; + + if (width > 0 && height > 0) { + /* allocate new buffer storage */ + rb->Data = malloc(width * height * _mesa_get_format_bytes(rb->Format)); + + if (rb->Data == NULL) { + rb->Width = 0; + rb->Height = 0; + rb->RowStride = 0; + _mesa_error(ctx, GL_OUT_OF_MEMORY, + "software renderbuffer allocation (%d x %d x %d)", + width, height, _mesa_get_format_bytes(rb->Format)); + return GL_FALSE; + } + } + + rb->Width = width; + rb->Height = height; + rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); + + if (rb->Name == 0 && + internalFormat == GL_RGBA16_SNORM && + rb->_BaseFormat == 0) { + /* NOTE: This is a special case just for accumulation buffers. + * This is a very limited use case- there's no snorm texturing or + * rendering going on. + */ + rb->_BaseFormat = GL_RGBA; + } + else { + /* the internalFormat should have been error checked long ago */ + ASSERT(rb->_BaseFormat); + } + + return GL_TRUE; +} + + +void +_swrast_map_soft_renderbuffer(struct gl_context *ctx, + struct gl_renderbuffer *rb, + GLuint x, GLuint y, GLuint w, GLuint h, + GLbitfield mode, + GLubyte **out_map, + GLint *out_stride) +{ + GLubyte *map = rb->Data; + int cpp = _mesa_get_format_bytes(rb->Format); + int stride = rb->RowStride * cpp; + + ASSERT(rb->Data); + + map += y * stride; + map += x * cpp; + + *out_map = map; + *out_stride = stride; +} + + +void +_swrast_unmap_soft_renderbuffer(struct gl_context *ctx, + struct gl_renderbuffer *rb) +{ +} + + + +/** + * Allocate a software-based renderbuffer. This is called via the + * ctx->Driver.NewRenderbuffer() function when the user creates a new + * renderbuffer. + * This would not be used for hardware-based renderbuffers. + */ +struct gl_renderbuffer * +_swrast_new_soft_renderbuffer(struct gl_context *ctx, GLuint name) +{ + struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name); + if (rb) { + rb->AllocStorage = soft_renderbuffer_storage; + /* Normally, one would setup the PutRow, GetRow, etc functions here. + * But we're doing that in the soft_renderbuffer_storage() function + * instead. + */ + } + return rb; +} + + +/** + * Add software-based color renderbuffers to the given framebuffer. + * This is a helper routine for device drivers when creating a + * window system framebuffer (not a user-created render/framebuffer). + * Once this function is called, you can basically forget about this + * renderbuffer; core Mesa will handle all the buffer management and + * rendering! + */ +static GLboolean +add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, + GLuint rgbBits, GLuint alphaBits, + GLboolean frontLeft, GLboolean backLeft, + GLboolean frontRight, GLboolean backRight) +{ + gl_buffer_index b; + + if (rgbBits > 16 || alphaBits > 16) { + _mesa_problem(ctx, + "Unsupported bit depth in add_color_renderbuffers"); + return GL_FALSE; + } + + assert(MAX_COLOR_ATTACHMENTS >= 4); + + for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { + struct gl_renderbuffer *rb; + + if (b == BUFFER_FRONT_LEFT && !frontLeft) + continue; + else if (b == BUFFER_BACK_LEFT && !backLeft) + continue; + else if (b == BUFFER_FRONT_RIGHT && !frontRight) + continue; + else if (b == BUFFER_BACK_RIGHT && !backRight) + continue; + + assert(fb->Attachment[b].Renderbuffer == NULL); + + rb = _mesa_new_renderbuffer(ctx, 0); + if (!rb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer"); + return GL_FALSE; + } + + rb->InternalFormat = GL_RGBA; + + rb->AllocStorage = soft_renderbuffer_storage; + _mesa_add_renderbuffer(fb, b, rb); + } + + return GL_TRUE; +} + + +/** + * Add a software-based depth renderbuffer to the given framebuffer. + * This is a helper routine for device drivers when creating a + * window system framebuffer (not a user-created render/framebuffer). + * Once this function is called, you can basically forget about this + * renderbuffer; core Mesa will handle all the buffer management and + * rendering! + */ +static GLboolean +add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, + GLuint depthBits) +{ + struct gl_renderbuffer *rb; + + if (depthBits > 32) { + _mesa_problem(ctx, + "Unsupported depthBits in add_depth_renderbuffer"); + return GL_FALSE; + } + + assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); + + rb = _mesa_new_renderbuffer(ctx, 0); + if (!rb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer"); + return GL_FALSE; + } + + if (depthBits <= 16) { + rb->InternalFormat = GL_DEPTH_COMPONENT16; + } + else if (depthBits <= 24) { + rb->InternalFormat = GL_DEPTH_COMPONENT24; + } + else { + rb->InternalFormat = GL_DEPTH_COMPONENT32; + } + + rb->AllocStorage = soft_renderbuffer_storage; + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); + + return GL_TRUE; +} + + +/** + * Add a software-based stencil renderbuffer to the given framebuffer. + * This is a helper routine for device drivers when creating a + * window system framebuffer (not a user-created render/framebuffer). + * Once this function is called, you can basically forget about this + * renderbuffer; core Mesa will handle all the buffer management and + * rendering! + */ +static GLboolean +add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, + GLuint stencilBits) +{ + struct gl_renderbuffer *rb; + + if (stencilBits > 16) { + _mesa_problem(ctx, + "Unsupported stencilBits in add_stencil_renderbuffer"); + return GL_FALSE; + } + + assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); + + rb = _mesa_new_renderbuffer(ctx, 0); + if (!rb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer"); + return GL_FALSE; + } + + assert(stencilBits <= 8); + rb->InternalFormat = GL_STENCIL_INDEX8; + + rb->AllocStorage = soft_renderbuffer_storage; + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); + + return GL_TRUE; +} + + +/** + * Add a software-based accumulation renderbuffer to the given framebuffer. + * This is a helper routine for device drivers when creating a + * window system framebuffer (not a user-created render/framebuffer). + * Once this function is called, you can basically forget about this + * renderbuffer; core Mesa will handle all the buffer management and + * rendering! + */ +static GLboolean +add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, + GLuint redBits, GLuint greenBits, + GLuint blueBits, GLuint alphaBits) +{ + struct gl_renderbuffer *rb; + + if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) { + _mesa_problem(ctx, + "Unsupported accumBits in add_accum_renderbuffer"); + return GL_FALSE; + } + + assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL); + + rb = _mesa_new_renderbuffer(ctx, 0); + if (!rb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); + return GL_FALSE; + } + + rb->InternalFormat = GL_RGBA16_SNORM; + rb->AllocStorage = soft_renderbuffer_storage; + _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb); + + return GL_TRUE; +} + + + +/** + * Add a software-based aux renderbuffer to the given framebuffer. + * This is a helper routine for device drivers when creating a + * window system framebuffer (not a user-created render/framebuffer). + * Once this function is called, you can basically forget about this + * renderbuffer; core Mesa will handle all the buffer management and + * rendering! + * + * NOTE: color-index aux buffers not supported. + */ +static GLboolean +add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, + GLuint colorBits, GLuint numBuffers) +{ + GLuint i; + + if (colorBits > 16) { + _mesa_problem(ctx, + "Unsupported colorBits in add_aux_renderbuffers"); + return GL_FALSE; + } + + assert(numBuffers <= MAX_AUX_BUFFERS); + + for (i = 0; i < numBuffers; i++) { + struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0); + + assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL); + + if (!rb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating aux buffer"); + return GL_FALSE; + } + + assert (colorBits <= 8); + rb->InternalFormat = GL_RGBA; + + rb->AllocStorage = soft_renderbuffer_storage; + _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb); + } + return GL_TRUE; +} + + +/** + * Create/attach software-based renderbuffers to the given framebuffer. + * This is a helper routine for device drivers. Drivers can just as well + * call the individual _mesa_add_*_renderbuffer() routines directly. + */ +void +_swrast_add_soft_renderbuffers(struct gl_framebuffer *fb, + GLboolean color, + GLboolean depth, + GLboolean stencil, + GLboolean accum, + GLboolean alpha, + GLboolean aux) +{ + GLboolean frontLeft = GL_TRUE; + GLboolean backLeft = fb->Visual.doubleBufferMode; + GLboolean frontRight = fb->Visual.stereoMode; + GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode; + + if (color) { + assert(fb->Visual.redBits == fb->Visual.greenBits); + assert(fb->Visual.redBits == fb->Visual.blueBits); + add_color_renderbuffers(NULL, fb, + fb->Visual.redBits, + fb->Visual.alphaBits, + frontLeft, backLeft, + frontRight, backRight); + } + + if (depth) { + assert(fb->Visual.depthBits > 0); + add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits); + } + + if (stencil) { + assert(fb->Visual.stencilBits > 0); + add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits); + } + + if (accum) { + assert(fb->Visual.accumRedBits > 0); + assert(fb->Visual.accumGreenBits > 0); + assert(fb->Visual.accumBlueBits > 0); + add_accum_renderbuffer(NULL, fb, + fb->Visual.accumRedBits, + fb->Visual.accumGreenBits, + fb->Visual.accumBlueBits, + fb->Visual.accumAlphaBits); + } + + if (aux) { + assert(fb->Visual.numAuxBuffers > 0); + add_aux_renderbuffers(NULL, fb, fb->Visual.redBits, + fb->Visual.numAuxBuffers); + } + +#if 0 + if (multisample) { + /* maybe someday */ + } +#endif +} diff --git a/mesalib/src/mesa/swrast/s_accum.h b/mesalib/src/mesa/swrast/s_renderbuffer.h index bdd6ac326..266ebd934 100644 --- a/mesalib/src/mesa/swrast/s_accum.h +++ b/mesalib/src/mesa/swrast/s_renderbuffer.h @@ -1,38 +1,66 @@ -/*
- * Mesa 3-D graphics library
- * Version: 6.3
- *
- * 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"),
- * 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_ACCUM_H
-#define S_ACCUM_H
-
-
-struct gl_context;
-struct gl_renderbuffer;
-
-
-extern void
-_swrast_clear_accum_buffer(struct gl_context *ctx, struct gl_renderbuffer *rb);
-
-
-#endif
+/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * 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"), + * 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_RENDERBUFFER_H +#define S_RENDERBUFFER_H + +#include "main/glheader.h" + + +struct gl_context; +struct gl_framebuffer; +struct gl_renderbuffer; + + +extern struct gl_renderbuffer * +_swrast_new_soft_renderbuffer(struct gl_context *ctx, GLuint name); + +extern void +_swrast_map_soft_renderbuffer(struct gl_context *ctx, + struct gl_renderbuffer *rb, + GLuint x, GLuint y, GLuint w, GLuint h, + GLbitfield mode, + GLubyte **out_map, + GLint *out_stride); + +extern void +_swrast_unmap_soft_renderbuffer(struct gl_context *ctx, + struct gl_renderbuffer *rb); + +extern void +_swrast_set_renderbuffer_accessors(struct gl_renderbuffer *rb); + + +extern void +_swrast_add_soft_renderbuffers(struct gl_framebuffer *fb, + GLboolean color, + GLboolean depth, + GLboolean stencil, + GLboolean accum, + GLboolean alpha, + GLboolean aux); + + +#endif /* S_RENDERBUFFER_H */ diff --git a/mesalib/src/mesa/swrast/s_texfetch_tmp.h b/mesalib/src/mesa/swrast/s_texfetch_tmp.h index e9512b561..877c29c9b 100644 --- a/mesalib/src/mesa/swrast/s_texfetch_tmp.h +++ b/mesalib/src/mesa/swrast/s_texfetch_tmp.h @@ -2270,7 +2270,7 @@ static void FETCH(f_z24_s8)( const struct swrast_texture_image *texImage, { /* only return Z, not stencil data */ const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - const GLfloat scale = 1.0F / (GLfloat) 0xffffff; + const GLdouble scale = 1.0 / (GLdouble) 0xffffff; texel[0] = ((*src) >> 8) * scale; ASSERT(texImage->Base.TexFormat == MESA_FORMAT_Z24_S8 || texImage->Base.TexFormat == MESA_FORMAT_Z24_X8); @@ -2298,7 +2298,7 @@ static void FETCH(f_s8_z24)( const struct swrast_texture_image *texImage, { /* only return Z, not stencil data */ const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 1); - const GLfloat scale = 1.0F / (GLfloat) 0xffffff; + const GLdouble scale = 1.0 / (GLdouble) 0xffffff; texel[0] = ((*src) & 0x00ffffff) * scale; ASSERT(texImage->Base.TexFormat == MESA_FORMAT_S8_Z24 || texImage->Base.TexFormat == MESA_FORMAT_X8_Z24); diff --git a/mesalib/src/mesa/swrast/s_zoom.c b/mesalib/src/mesa/swrast/s_zoom.c index 16bb997f3..f407fdcf4 100644 --- a/mesalib/src/mesa/swrast/s_zoom.c +++ b/mesalib/src/mesa/swrast/s_zoom.c @@ -299,11 +299,17 @@ zoom_span( struct gl_context *ctx, GLint imgX, GLint imgY, const SWspan *span, * Also, clipping may change the span end value, so store it as well. */ const GLint end = zoomed.end; /* save */ - GLuint rgbaSave[MAX_WIDTH][4]; + void *rgbaSave; const GLint pixelSize = (zoomed.array->ChanType == GL_UNSIGNED_BYTE) ? 4 * sizeof(GLubyte) : ((zoomed.array->ChanType == GL_UNSIGNED_SHORT) ? 4 * sizeof(GLushort) : 4 * sizeof(GLfloat)); + + rgbaSave = malloc(zoomed.end * pixelSize); + if (!rgbaSave) { + return; + } + if (y1 - y0 > 1) { memcpy(rgbaSave, zoomed.array->rgba, zoomed.end * pixelSize); } @@ -315,6 +321,8 @@ zoom_span( struct gl_context *ctx, GLint imgX, GLint imgY, const SWspan *span, memcpy(zoomed.array->rgba, rgbaSave, zoomed.end * pixelSize); } } + + free(rgbaSave); } } diff --git a/mesalib/src/mesa/swrast/swrast.h b/mesalib/src/mesa/swrast/swrast.h index 17b66c664..dd4055159 100644 --- a/mesalib/src/mesa/swrast/swrast.h +++ b/mesalib/src/mesa/swrast/swrast.h @@ -127,9 +127,6 @@ _swrast_BlitFramebuffer(struct gl_context *ctx, extern void _swrast_Clear(struct gl_context *ctx, GLbitfield buffers); -extern void -_swrast_Accum(struct gl_context *ctx, GLenum op, GLfloat value); - /* Reset the stipple counter |