aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/swrast
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/swrast')
-rw-r--r--mesalib/src/mesa/swrast/s_copypix.c1440
-rw-r--r--mesalib/src/mesa/swrast/s_depth.c3
-rw-r--r--mesalib/src/mesa/swrast/s_drawpix.c10
-rw-r--r--mesalib/src/mesa/swrast/s_readpix.c522
-rw-r--r--mesalib/src/mesa/swrast/s_stencil.c184
-rw-r--r--mesalib/src/mesa/swrast/s_stencil.h106
-rw-r--r--mesalib/src/mesa/swrast/s_texrender.c13
-rw-r--r--mesalib/src/mesa/swrast/s_zoom.c4
-rw-r--r--mesalib/src/mesa/swrast/s_zoom.h112
-rw-r--r--mesalib/src/mesa/swrast/swrast.h7
10 files changed, 940 insertions, 1461 deletions
diff --git a/mesalib/src/mesa/swrast/s_copypix.c b/mesalib/src/mesa/swrast/s_copypix.c
index e249e4ad5..3ba31f22c 100644
--- a/mesalib/src/mesa/swrast/s_copypix.c
+++ b/mesalib/src/mesa/swrast/s_copypix.c
@@ -1,720 +1,720 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2007 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/context.h"
-#include "main/colormac.h"
-#include "main/condrender.h"
-#include "main/macros.h"
-#include "main/pixeltransfer.h"
-#include "main/imports.h"
-
-#include "s_context.h"
-#include "s_depth.h"
-#include "s_span.h"
-#include "s_stencil.h"
-#include "s_zoom.h"
-
-
-
-/**
- * Determine if there's overlap in an image copy.
- * This test also compensates for the fact that copies are done from
- * bottom to top and overlaps can sometimes be handled correctly
- * without making a temporary image copy.
- * \return GL_TRUE if the regions overlap, GL_FALSE otherwise.
- */
-static GLboolean
-regions_overlap(GLint srcx, GLint srcy,
- GLint dstx, GLint dsty,
- GLint width, GLint height,
- GLfloat zoomX, GLfloat zoomY)
-{
- if (zoomX == 1.0 && zoomY == 1.0) {
- /* no zoom */
- if (srcx >= dstx + width || (srcx + width <= dstx)) {
- return GL_FALSE;
- }
- else if (srcy < dsty) { /* this is OK */
- return GL_FALSE;
- }
- else if (srcy > dsty + height) {
- return GL_FALSE;
- }
- else {
- return GL_TRUE;
- }
- }
- else {
- /* add one pixel of slop when zooming, just to be safe */
- if (srcx > (dstx + ((zoomX > 0.0F) ? (width * zoomX + 1.0F) : 0.0F))) {
- /* src is completely right of dest */
- return GL_FALSE;
- }
- else if (srcx + width + 1.0F < dstx + ((zoomX > 0.0F) ? 0.0F : (width * zoomX))) {
- /* src is completely left of dest */
- return GL_FALSE;
- }
- else if ((srcy < dsty) && (srcy + height < dsty + (height * zoomY))) {
- /* src is completely below dest */
- return GL_FALSE;
- }
- else if ((srcy > dsty) && (srcy + height > dsty + (height * zoomY))) {
- /* src is completely above dest */
- return GL_FALSE;
- }
- else {
- return GL_TRUE;
- }
- }
-}
-
-
-/**
- * RGBA copypixels
- */
-static void
-copy_rgba_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
- GLint width, GLint height, GLint destx, GLint desty)
-{
- GLfloat *tmpImage, *p;
- GLint sy, dy, stepy, row;
- const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
- GLint overlapping;
- GLuint transferOps = ctx->_ImageTransferState;
- SWspan span;
-
- if (!ctx->ReadBuffer->_ColorReadBuffer) {
- /* no readbuffer - OK */
- return;
- }
-
- if (ctx->DrawBuffer == ctx->ReadBuffer) {
- overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
- ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
- }
- else {
- overlapping = GL_FALSE;
- }
-
- /* Determine if copy should be done bottom-to-top or top-to-bottom */
- if (!overlapping && srcy < desty) {
- /* top-down max-to-min */
- sy = srcy + height - 1;
- dy = desty + height - 1;
- stepy = -1;
- }
- else {
- /* bottom-up min-to-max */
- sy = srcy;
- dy = desty;
- stepy = 1;
- }
-
- INIT_SPAN(span, GL_BITMAP);
- _swrast_span_default_attribs(ctx, &span);
- span.arrayMask = SPAN_RGBA;
- span.arrayAttribs = FRAG_BIT_COL0; /* we'll fill in COL0 attrib values */
-
- if (overlapping) {
- tmpImage = (GLfloat *) malloc(width * height * sizeof(GLfloat) * 4);
- if (!tmpImage) {
- _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
- return;
- }
- /* read the source image as RGBA/float */
- p = tmpImage;
- for (row = 0; row < height; row++) {
- _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
- width, srcx, sy + row, GL_FLOAT, p );
- p += width * 4;
- }
- p = tmpImage;
- }
- else {
- tmpImage = NULL; /* silence compiler warnings */
- p = NULL;
- }
-
- ASSERT(width < MAX_WIDTH);
-
- for (row = 0; row < height; row++, sy += stepy, dy += stepy) {
- GLvoid *rgba = span.array->attribs[FRAG_ATTRIB_COL0];
-
- /* Get row/span of source pixels */
- if (overlapping) {
- /* get from buffered image */
- memcpy(rgba, p, width * sizeof(GLfloat) * 4);
- p += width * 4;
- }
- else {
- /* get from framebuffer */
- _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
- width, srcx, sy, GL_FLOAT, rgba );
- }
-
- if (transferOps) {
- _mesa_apply_rgba_transfer_ops(ctx, transferOps, width,
- (GLfloat (*)[4]) rgba);
- }
-
- /* Write color span */
- span.x = destx;
- span.y = dy;
- span.end = width;
- span.array->ChanType = GL_FLOAT;
- if (zoom) {
- _swrast_write_zoomed_rgba_span(ctx, destx, desty, &span, rgba);
- }
- else {
- _swrast_write_rgba_span(ctx, &span);
- }
- }
-
- span.array->ChanType = CHAN_TYPE; /* restore */
-
- if (overlapping)
- free(tmpImage);
-}
-
-
-/**
- * Convert floating point Z values to integer Z values with pixel transfer's
- * Z scale and bias.
- */
-static void
-scale_and_bias_z(struct gl_context *ctx, GLuint width,
- const GLfloat depth[], GLuint z[])
-{
- const GLuint depthMax = ctx->DrawBuffer->_DepthMax;
- GLuint i;
-
- if (depthMax <= 0xffffff &&
- ctx->Pixel.DepthScale == 1.0 &&
- ctx->Pixel.DepthBias == 0.0) {
- /* no scale or bias and no clamping and no worry of overflow */
- const GLfloat depthMaxF = ctx->DrawBuffer->_DepthMaxF;
- for (i = 0; i < width; i++) {
- z[i] = (GLuint) (depth[i] * depthMaxF);
- }
- }
- else {
- /* need to be careful with overflow */
- const GLdouble depthMaxF = ctx->DrawBuffer->_DepthMaxF;
- for (i = 0; i < width; i++) {
- GLdouble d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
- d = CLAMP(d, 0.0, 1.0) * depthMaxF;
- if (d >= depthMaxF)
- z[i] = depthMax;
- else
- z[i] = (GLuint) d;
- }
- }
-}
-
-
-
-/*
- * TODO: Optimize!!!!
- */
-static void
-copy_depth_pixels( struct gl_context *ctx, GLint srcx, GLint srcy,
- GLint width, GLint height,
- GLint destx, GLint desty )
-{
- struct gl_framebuffer *fb = ctx->ReadBuffer;
- struct gl_renderbuffer *readRb = fb->_DepthBuffer;
- GLfloat *p, *tmpImage;
- GLint sy, dy, stepy;
- GLint j;
- const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
- GLint overlapping;
- SWspan span;
-
- if (!readRb) {
- /* no readbuffer - OK */
- return;
- }
-
- INIT_SPAN(span, GL_BITMAP);
- _swrast_span_default_attribs(ctx, &span);
- span.arrayMask = SPAN_Z;
-
- if (ctx->DrawBuffer == ctx->ReadBuffer) {
- overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
- ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
- }
- else {
- overlapping = GL_FALSE;
- }
-
- /* Determine if copy should be bottom-to-top or top-to-bottom */
- if (!overlapping && srcy < desty) {
- /* top-down max-to-min */
- sy = srcy + height - 1;
- dy = desty + height - 1;
- stepy = -1;
- }
- else {
- /* bottom-up min-to-max */
- sy = srcy;
- dy = desty;
- stepy = 1;
- }
-
- if (overlapping) {
- GLint ssy = sy;
- tmpImage = (GLfloat *) malloc(width * height * sizeof(GLfloat));
- if (!tmpImage) {
- _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
- return;
- }
- p = tmpImage;
- for (j = 0; j < height; j++, ssy += stepy) {
- _swrast_read_depth_span_float(ctx, readRb, width, srcx, ssy, p);
- p += width;
- }
- p = tmpImage;
- }
- else {
- tmpImage = NULL; /* silence compiler warning */
- p = NULL;
- }
-
- for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
- GLfloat depth[MAX_WIDTH];
- /* get depth values */
- if (overlapping) {
- memcpy(depth, p, width * sizeof(GLfloat));
- p += width;
- }
- else {
- _swrast_read_depth_span_float(ctx, readRb, width, srcx, sy, depth);
- }
-
- /* apply scale and bias */
- scale_and_bias_z(ctx, width, depth, span.array->z);
-
- /* write depth values */
- span.x = destx;
- span.y = dy;
- span.end = width;
- if (zoom)
- _swrast_write_zoomed_depth_span(ctx, destx, desty, &span);
- else
- _swrast_write_rgba_span(ctx, &span);
- }
-
- if (overlapping)
- free(tmpImage);
-}
-
-
-
-static void
-copy_stencil_pixels( struct gl_context *ctx, GLint srcx, GLint srcy,
- GLint width, GLint height,
- GLint destx, GLint desty )
-{
- struct gl_framebuffer *fb = ctx->ReadBuffer;
- struct gl_renderbuffer *rb = fb->_StencilBuffer;
- GLint sy, dy, stepy;
- GLint j;
- GLstencil *p, *tmpImage;
- const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
- GLint overlapping;
-
- if (!rb) {
- /* no readbuffer - OK */
- return;
- }
-
- if (ctx->DrawBuffer == ctx->ReadBuffer) {
- overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
- ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
- }
- else {
- overlapping = GL_FALSE;
- }
-
- /* Determine if copy should be bottom-to-top or top-to-bottom */
- if (!overlapping && srcy < desty) {
- /* top-down max-to-min */
- sy = srcy + height - 1;
- dy = desty + height - 1;
- stepy = -1;
- }
- else {
- /* bottom-up min-to-max */
- sy = srcy;
- dy = desty;
- stepy = 1;
- }
-
- if (overlapping) {
- GLint ssy = sy;
- tmpImage = (GLstencil *) malloc(width * height * sizeof(GLstencil));
- if (!tmpImage) {
- _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
- return;
- }
- p = tmpImage;
- for (j = 0; j < height; j++, ssy += stepy) {
- _swrast_read_stencil_span( ctx, rb, width, srcx, ssy, p );
- p += width;
- }
- p = tmpImage;
- }
- else {
- tmpImage = NULL; /* silence compiler warning */
- p = NULL;
- }
-
- for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
- GLstencil stencil[MAX_WIDTH];
-
- /* Get stencil values */
- if (overlapping) {
- memcpy(stencil, p, width * sizeof(GLstencil));
- p += width;
- }
- else {
- _swrast_read_stencil_span( ctx, rb, width, srcx, sy, stencil );
- }
-
- _mesa_apply_stencil_transfer_ops(ctx, width, stencil);
-
- /* Write stencil values */
- if (zoom) {
- _swrast_write_zoomed_stencil_span(ctx, destx, desty, width,
- destx, dy, stencil);
- }
- else {
- _swrast_write_stencil_span( ctx, width, destx, dy, stencil );
- }
- }
-
- if (overlapping)
- free(tmpImage);
-}
-
-
-/**
- * This isn't terribly efficient. If a driver really has combined
- * depth/stencil buffers the driver should implement an optimized
- * CopyPixels function.
- */
-static void
-copy_depth_stencil_pixels(struct gl_context *ctx,
- const GLint srcX, const GLint srcY,
- const GLint width, const GLint height,
- const GLint destX, const GLint destY)
-{
- struct gl_renderbuffer *stencilReadRb, *depthReadRb, *depthDrawRb;
- GLint sy, dy, stepy;
- GLint j;
- GLstencil *tempStencilImage = NULL, *stencilPtr = NULL;
- GLfloat *tempDepthImage = NULL, *depthPtr = NULL;
- const GLfloat depthScale = ctx->DrawBuffer->_DepthMaxF;
- const GLuint stencilMask = ctx->Stencil.WriteMask[0];
- const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
- const GLboolean scaleOrBias
- = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
- GLint overlapping;
-
- depthDrawRb = ctx->DrawBuffer->_DepthBuffer;
- depthReadRb = ctx->ReadBuffer->_DepthBuffer;
- stencilReadRb = ctx->ReadBuffer->_StencilBuffer;
-
- ASSERT(depthDrawRb);
- ASSERT(depthReadRb);
- ASSERT(stencilReadRb);
-
- if (ctx->DrawBuffer == ctx->ReadBuffer) {
- overlapping = regions_overlap(srcX, srcY, destX, destY, width, height,
- ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
- }
- else {
- overlapping = GL_FALSE;
- }
-
- /* Determine if copy should be bottom-to-top or top-to-bottom */
- if (!overlapping && srcY < destY) {
- /* top-down max-to-min */
- sy = srcY + height - 1;
- dy = destY + height - 1;
- stepy = -1;
- }
- else {
- /* bottom-up min-to-max */
- sy = srcY;
- dy = destY;
- stepy = 1;
- }
-
- if (overlapping) {
- GLint ssy = sy;
-
- if (stencilMask != 0x0) {
- tempStencilImage
- = (GLstencil *) malloc(width * height * sizeof(GLstencil));
- if (!tempStencilImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
- return;
- }
-
- /* get copy of stencil pixels */
- stencilPtr = tempStencilImage;
- for (j = 0; j < height; j++, ssy += stepy) {
- _swrast_read_stencil_span(ctx, stencilReadRb,
- width, srcX, ssy, stencilPtr);
- stencilPtr += width;
- }
- stencilPtr = tempStencilImage;
- }
-
- if (ctx->Depth.Mask) {
- tempDepthImage
- = (GLfloat *) malloc(width * height * sizeof(GLfloat));
- if (!tempDepthImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
- free(tempStencilImage);
- return;
- }
-
- /* get copy of depth pixels */
- depthPtr = tempDepthImage;
- for (j = 0; j < height; j++, ssy += stepy) {
- _swrast_read_depth_span_float(ctx, depthReadRb,
- width, srcX, ssy, depthPtr);
- depthPtr += width;
- }
- depthPtr = tempDepthImage;
- }
- }
-
- for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
- if (stencilMask != 0x0) {
- GLstencil stencil[MAX_WIDTH];
-
- /* Get stencil values */
- if (overlapping) {
- memcpy(stencil, stencilPtr, width * sizeof(GLstencil));
- stencilPtr += width;
- }
- else {
- _swrast_read_stencil_span(ctx, stencilReadRb,
- width, srcX, sy, stencil);
- }
-
- _mesa_apply_stencil_transfer_ops(ctx, width, stencil);
-
- /* Write values */
- if (zoom) {
- _swrast_write_zoomed_stencil_span(ctx, destX, destY, width,
- destX, dy, stencil);
- }
- else {
- _swrast_write_stencil_span( ctx, width, destX, dy, stencil );
- }
- }
-
- if (ctx->Depth.Mask) {
- GLfloat depth[MAX_WIDTH];
- GLuint zVals32[MAX_WIDTH];
- GLushort zVals16[MAX_WIDTH];
- GLvoid *zVals;
- GLuint zBytes;
-
- /* get depth values */
- if (overlapping) {
- memcpy(depth, depthPtr, width * sizeof(GLfloat));
- depthPtr += width;
- }
- else {
- _swrast_read_depth_span_float(ctx, depthReadRb,
- width, srcX, sy, depth);
- }
-
- /* scale & bias */
- if (scaleOrBias) {
- _mesa_scale_and_bias_depth(ctx, width, depth);
- }
- /* convert to integer Z values */
- if (depthDrawRb->DataType == GL_UNSIGNED_SHORT) {
- GLint k;
- for (k = 0; k < width; k++)
- zVals16[k] = (GLushort) (depth[k] * depthScale);
- zVals = zVals16;
- zBytes = 2;
- }
- else {
- GLint k;
- for (k = 0; k < width; k++)
- zVals32[k] = (GLuint) (depth[k] * depthScale);
- zVals = zVals32;
- zBytes = 4;
- }
-
- /* Write values */
- if (zoom) {
- _swrast_write_zoomed_z_span(ctx, destX, destY, width,
- destX, dy, zVals);
- }
- else {
- _swrast_put_row(ctx, depthDrawRb, width, destX, dy, zVals, zBytes);
- }
- }
- }
-
- if (tempStencilImage)
- free(tempStencilImage);
-
- if (tempDepthImage)
- free(tempDepthImage);
-}
-
-
-
-/**
- * Try to do a fast copy pixels.
- */
-static GLboolean
-fast_copy_pixels(struct gl_context *ctx,
- GLint srcX, GLint srcY, GLsizei width, GLsizei height,
- GLint dstX, GLint dstY, GLenum type)
-{
- struct gl_framebuffer *srcFb = ctx->ReadBuffer;
- struct gl_framebuffer *dstFb = ctx->DrawBuffer;
- struct gl_renderbuffer *srcRb, *dstRb;
- GLint row, yStep;
-
- if (SWRAST_CONTEXT(ctx)->_RasterMask != 0x0 ||
- ctx->Pixel.ZoomX != 1.0F ||
- ctx->Pixel.ZoomY != 1.0F ||
- ctx->_ImageTransferState) {
- /* can't handle these */
- return GL_FALSE;
- }
-
- if (type == GL_COLOR) {
- if (dstFb->_NumColorDrawBuffers != 1)
- return GL_FALSE;
- srcRb = srcFb->_ColorReadBuffer;
- dstRb = dstFb->_ColorDrawBuffers[0];
- }
- else if (type == GL_STENCIL) {
- srcRb = srcFb->_StencilBuffer;
- dstRb = dstFb->_StencilBuffer;
- }
- else if (type == GL_DEPTH) {
- srcRb = srcFb->_DepthBuffer;
- dstRb = dstFb->_DepthBuffer;
- }
- else {
- ASSERT(type == GL_DEPTH_STENCIL_EXT);
- /* XXX correct? */
- srcRb = srcFb->Attachment[BUFFER_DEPTH].Renderbuffer;
- dstRb = dstFb->Attachment[BUFFER_DEPTH].Renderbuffer;
- }
-
- /* src and dst renderbuffers must be same format and type */
- if (!srcRb || !dstRb ||
- srcRb->DataType != dstRb->DataType ||
- srcRb->_BaseFormat != dstRb->_BaseFormat) {
- return GL_FALSE;
- }
-
- /* clipping not supported */
- if (srcX < 0 || srcX + width > (GLint) srcFb->Width ||
- srcY < 0 || srcY + height > (GLint) srcFb->Height ||
- dstX < dstFb->_Xmin || dstX + width > dstFb->_Xmax ||
- dstY < dstFb->_Ymin || dstY + height > dstFb->_Ymax) {
- return GL_FALSE;
- }
-
- /* overlapping src/dst doesn't matter, just determine Y direction */
- if (srcY < dstY) {
- /* top-down max-to-min */
- srcY = srcY + height - 1;
- dstY = dstY + height - 1;
- yStep = -1;
- }
- else {
- /* bottom-up min-to-max */
- yStep = 1;
- }
-
- 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;
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Do software-based glCopyPixels.
- * By time we get here, all parameters will have been error-checked.
- */
-void
-_swrast_CopyPixels( struct gl_context *ctx,
- GLint srcx, GLint srcy, GLsizei width, GLsizei height,
- GLint destx, GLint desty, GLenum type )
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- swrast_render_start(ctx);
-
- if (!_mesa_check_conditional_render(ctx))
- return; /* don't copy */
-
- if (swrast->NewState)
- _swrast_validate_derived( ctx );
-
- if (!fast_copy_pixels(ctx, srcx, srcy, width, height, destx, desty, type)) {
- switch (type) {
- case GL_COLOR:
- copy_rgba_pixels( ctx, srcx, srcy, width, height, destx, desty );
- break;
- case GL_DEPTH:
- copy_depth_pixels( ctx, srcx, srcy, width, height, destx, desty );
- break;
- case GL_STENCIL:
- copy_stencil_pixels( ctx, srcx, srcy, width, height, destx, desty );
- break;
- case GL_DEPTH_STENCIL_EXT:
- copy_depth_stencil_pixels(ctx, srcx, srcy, width, height, destx, desty);
- break;
- default:
- _mesa_problem(ctx, "unexpected type in _swrast_CopyPixels");
- }
- }
-
- swrast_render_finish(ctx);
-}
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.1
+ *
+ * Copyright (C) 1999-2007 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/context.h"
+#include "main/colormac.h"
+#include "main/condrender.h"
+#include "main/macros.h"
+#include "main/pixeltransfer.h"
+#include "main/imports.h"
+
+#include "s_context.h"
+#include "s_depth.h"
+#include "s_span.h"
+#include "s_stencil.h"
+#include "s_zoom.h"
+
+
+
+/**
+ * Determine if there's overlap in an image copy.
+ * This test also compensates for the fact that copies are done from
+ * bottom to top and overlaps can sometimes be handled correctly
+ * without making a temporary image copy.
+ * \return GL_TRUE if the regions overlap, GL_FALSE otherwise.
+ */
+static GLboolean
+regions_overlap(GLint srcx, GLint srcy,
+ GLint dstx, GLint dsty,
+ GLint width, GLint height,
+ GLfloat zoomX, GLfloat zoomY)
+{
+ if (zoomX == 1.0 && zoomY == 1.0) {
+ /* no zoom */
+ if (srcx >= dstx + width || (srcx + width <= dstx)) {
+ return GL_FALSE;
+ }
+ else if (srcy < dsty) { /* this is OK */
+ return GL_FALSE;
+ }
+ else if (srcy > dsty + height) {
+ return GL_FALSE;
+ }
+ else {
+ return GL_TRUE;
+ }
+ }
+ else {
+ /* add one pixel of slop when zooming, just to be safe */
+ if (srcx > (dstx + ((zoomX > 0.0F) ? (width * zoomX + 1.0F) : 0.0F))) {
+ /* src is completely right of dest */
+ return GL_FALSE;
+ }
+ else if (srcx + width + 1.0F < dstx + ((zoomX > 0.0F) ? 0.0F : (width * zoomX))) {
+ /* src is completely left of dest */
+ return GL_FALSE;
+ }
+ else if ((srcy < dsty) && (srcy + height < dsty + (height * zoomY))) {
+ /* src is completely below dest */
+ return GL_FALSE;
+ }
+ else if ((srcy > dsty) && (srcy + height > dsty + (height * zoomY))) {
+ /* src is completely above dest */
+ return GL_FALSE;
+ }
+ else {
+ return GL_TRUE;
+ }
+ }
+}
+
+
+/**
+ * RGBA copypixels
+ */
+static void
+copy_rgba_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
+ GLint width, GLint height, GLint destx, GLint desty)
+{
+ GLfloat *tmpImage, *p;
+ GLint sy, dy, stepy, row;
+ const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
+ GLint overlapping;
+ GLuint transferOps = ctx->_ImageTransferState;
+ SWspan span;
+
+ if (!ctx->ReadBuffer->_ColorReadBuffer) {
+ /* no readbuffer - OK */
+ return;
+ }
+
+ if (ctx->DrawBuffer == ctx->ReadBuffer) {
+ overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
+ ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
+ }
+ else {
+ overlapping = GL_FALSE;
+ }
+
+ /* Determine if copy should be done bottom-to-top or top-to-bottom */
+ if (!overlapping && srcy < desty) {
+ /* top-down max-to-min */
+ sy = srcy + height - 1;
+ dy = desty + height - 1;
+ stepy = -1;
+ }
+ else {
+ /* bottom-up min-to-max */
+ sy = srcy;
+ dy = desty;
+ stepy = 1;
+ }
+
+ INIT_SPAN(span, GL_BITMAP);
+ _swrast_span_default_attribs(ctx, &span);
+ span.arrayMask = SPAN_RGBA;
+ span.arrayAttribs = FRAG_BIT_COL0; /* we'll fill in COL0 attrib values */
+
+ if (overlapping) {
+ tmpImage = (GLfloat *) malloc(width * height * sizeof(GLfloat) * 4);
+ if (!tmpImage) {
+ _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
+ return;
+ }
+ /* read the source image as RGBA/float */
+ p = tmpImage;
+ for (row = 0; row < height; row++) {
+ _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
+ width, srcx, sy + row, GL_FLOAT, p );
+ p += width * 4;
+ }
+ p = tmpImage;
+ }
+ else {
+ tmpImage = NULL; /* silence compiler warnings */
+ p = NULL;
+ }
+
+ ASSERT(width < MAX_WIDTH);
+
+ for (row = 0; row < height; row++, sy += stepy, dy += stepy) {
+ GLvoid *rgba = span.array->attribs[FRAG_ATTRIB_COL0];
+
+ /* Get row/span of source pixels */
+ if (overlapping) {
+ /* get from buffered image */
+ memcpy(rgba, p, width * sizeof(GLfloat) * 4);
+ p += width * 4;
+ }
+ else {
+ /* get from framebuffer */
+ _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
+ width, srcx, sy, GL_FLOAT, rgba );
+ }
+
+ if (transferOps) {
+ _mesa_apply_rgba_transfer_ops(ctx, transferOps, width,
+ (GLfloat (*)[4]) rgba);
+ }
+
+ /* Write color span */
+ span.x = destx;
+ span.y = dy;
+ span.end = width;
+ span.array->ChanType = GL_FLOAT;
+ if (zoom) {
+ _swrast_write_zoomed_rgba_span(ctx, destx, desty, &span, rgba);
+ }
+ else {
+ _swrast_write_rgba_span(ctx, &span);
+ }
+ }
+
+ span.array->ChanType = CHAN_TYPE; /* restore */
+
+ if (overlapping)
+ free(tmpImage);
+}
+
+
+/**
+ * Convert floating point Z values to integer Z values with pixel transfer's
+ * Z scale and bias.
+ */
+static void
+scale_and_bias_z(struct gl_context *ctx, GLuint width,
+ const GLfloat depth[], GLuint z[])
+{
+ const GLuint depthMax = ctx->DrawBuffer->_DepthMax;
+ GLuint i;
+
+ if (depthMax <= 0xffffff &&
+ ctx->Pixel.DepthScale == 1.0 &&
+ ctx->Pixel.DepthBias == 0.0) {
+ /* no scale or bias and no clamping and no worry of overflow */
+ const GLfloat depthMaxF = ctx->DrawBuffer->_DepthMaxF;
+ for (i = 0; i < width; i++) {
+ z[i] = (GLuint) (depth[i] * depthMaxF);
+ }
+ }
+ else {
+ /* need to be careful with overflow */
+ const GLdouble depthMaxF = ctx->DrawBuffer->_DepthMaxF;
+ for (i = 0; i < width; i++) {
+ GLdouble d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
+ d = CLAMP(d, 0.0, 1.0) * depthMaxF;
+ if (d >= depthMaxF)
+ z[i] = depthMax;
+ else
+ z[i] = (GLuint) d;
+ }
+ }
+}
+
+
+
+/*
+ * TODO: Optimize!!!!
+ */
+static void
+copy_depth_pixels( struct gl_context *ctx, GLint srcx, GLint srcy,
+ GLint width, GLint height,
+ GLint destx, GLint desty )
+{
+ struct gl_framebuffer *fb = ctx->ReadBuffer;
+ struct gl_renderbuffer *readRb = fb->_DepthBuffer;
+ GLfloat *p, *tmpImage;
+ GLint sy, dy, stepy;
+ GLint j;
+ const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
+ GLint overlapping;
+ SWspan span;
+
+ if (!readRb) {
+ /* no readbuffer - OK */
+ return;
+ }
+
+ INIT_SPAN(span, GL_BITMAP);
+ _swrast_span_default_attribs(ctx, &span);
+ span.arrayMask = SPAN_Z;
+
+ if (ctx->DrawBuffer == ctx->ReadBuffer) {
+ overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
+ ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
+ }
+ else {
+ overlapping = GL_FALSE;
+ }
+
+ /* Determine if copy should be bottom-to-top or top-to-bottom */
+ if (!overlapping && srcy < desty) {
+ /* top-down max-to-min */
+ sy = srcy + height - 1;
+ dy = desty + height - 1;
+ stepy = -1;
+ }
+ else {
+ /* bottom-up min-to-max */
+ sy = srcy;
+ dy = desty;
+ stepy = 1;
+ }
+
+ if (overlapping) {
+ GLint ssy = sy;
+ tmpImage = (GLfloat *) malloc(width * height * sizeof(GLfloat));
+ if (!tmpImage) {
+ _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
+ return;
+ }
+ p = tmpImage;
+ for (j = 0; j < height; j++, ssy += stepy) {
+ _swrast_read_depth_span_float(ctx, readRb, width, srcx, ssy, p);
+ p += width;
+ }
+ p = tmpImage;
+ }
+ else {
+ tmpImage = NULL; /* silence compiler warning */
+ p = NULL;
+ }
+
+ for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
+ GLfloat depth[MAX_WIDTH];
+ /* get depth values */
+ if (overlapping) {
+ memcpy(depth, p, width * sizeof(GLfloat));
+ p += width;
+ }
+ else {
+ _swrast_read_depth_span_float(ctx, readRb, width, srcx, sy, depth);
+ }
+
+ /* apply scale and bias */
+ scale_and_bias_z(ctx, width, depth, span.array->z);
+
+ /* write depth values */
+ span.x = destx;
+ span.y = dy;
+ span.end = width;
+ if (zoom)
+ _swrast_write_zoomed_depth_span(ctx, destx, desty, &span);
+ else
+ _swrast_write_rgba_span(ctx, &span);
+ }
+
+ if (overlapping)
+ free(tmpImage);
+}
+
+
+
+static void
+copy_stencil_pixels( struct gl_context *ctx, GLint srcx, GLint srcy,
+ GLint width, GLint height,
+ GLint destx, GLint desty )
+{
+ struct gl_framebuffer *fb = ctx->ReadBuffer;
+ struct gl_renderbuffer *rb = fb->_StencilBuffer;
+ GLint sy, dy, stepy;
+ GLint j;
+ GLubyte *p, *tmpImage;
+ const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
+ GLint overlapping;
+
+ if (!rb) {
+ /* no readbuffer - OK */
+ return;
+ }
+
+ if (ctx->DrawBuffer == ctx->ReadBuffer) {
+ overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
+ ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
+ }
+ else {
+ overlapping = GL_FALSE;
+ }
+
+ /* Determine if copy should be bottom-to-top or top-to-bottom */
+ if (!overlapping && srcy < desty) {
+ /* top-down max-to-min */
+ sy = srcy + height - 1;
+ dy = desty + height - 1;
+ stepy = -1;
+ }
+ else {
+ /* bottom-up min-to-max */
+ sy = srcy;
+ dy = desty;
+ stepy = 1;
+ }
+
+ if (overlapping) {
+ GLint ssy = sy;
+ tmpImage = (GLubyte *) malloc(width * height * sizeof(GLubyte));
+ if (!tmpImage) {
+ _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
+ return;
+ }
+ p = tmpImage;
+ for (j = 0; j < height; j++, ssy += stepy) {
+ _swrast_read_stencil_span( ctx, rb, width, srcx, ssy, p );
+ p += width;
+ }
+ p = tmpImage;
+ }
+ else {
+ tmpImage = NULL; /* silence compiler warning */
+ p = NULL;
+ }
+
+ for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
+ GLubyte stencil[MAX_WIDTH];
+
+ /* Get stencil values */
+ if (overlapping) {
+ memcpy(stencil, p, width * sizeof(GLubyte));
+ p += width;
+ }
+ else {
+ _swrast_read_stencil_span( ctx, rb, width, srcx, sy, stencil );
+ }
+
+ _mesa_apply_stencil_transfer_ops(ctx, width, stencil);
+
+ /* Write stencil values */
+ if (zoom) {
+ _swrast_write_zoomed_stencil_span(ctx, destx, desty, width,
+ destx, dy, stencil);
+ }
+ else {
+ _swrast_write_stencil_span( ctx, width, destx, dy, stencil );
+ }
+ }
+
+ if (overlapping)
+ free(tmpImage);
+}
+
+
+/**
+ * This isn't terribly efficient. If a driver really has combined
+ * depth/stencil buffers the driver should implement an optimized
+ * CopyPixels function.
+ */
+static void
+copy_depth_stencil_pixels(struct gl_context *ctx,
+ const GLint srcX, const GLint srcY,
+ const GLint width, const GLint height,
+ const GLint destX, const GLint destY)
+{
+ struct gl_renderbuffer *stencilReadRb, *depthReadRb, *depthDrawRb;
+ GLint sy, dy, stepy;
+ GLint j;
+ GLubyte *tempStencilImage = NULL, *stencilPtr = NULL;
+ GLfloat *tempDepthImage = NULL, *depthPtr = NULL;
+ const GLfloat depthScale = ctx->DrawBuffer->_DepthMaxF;
+ const GLuint stencilMask = ctx->Stencil.WriteMask[0];
+ const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
+ const GLboolean scaleOrBias
+ = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
+ GLint overlapping;
+
+ depthDrawRb = ctx->DrawBuffer->_DepthBuffer;
+ depthReadRb = ctx->ReadBuffer->_DepthBuffer;
+ stencilReadRb = ctx->ReadBuffer->_StencilBuffer;
+
+ ASSERT(depthDrawRb);
+ ASSERT(depthReadRb);
+ ASSERT(stencilReadRb);
+
+ if (ctx->DrawBuffer == ctx->ReadBuffer) {
+ overlapping = regions_overlap(srcX, srcY, destX, destY, width, height,
+ ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
+ }
+ else {
+ overlapping = GL_FALSE;
+ }
+
+ /* Determine if copy should be bottom-to-top or top-to-bottom */
+ if (!overlapping && srcY < destY) {
+ /* top-down max-to-min */
+ sy = srcY + height - 1;
+ dy = destY + height - 1;
+ stepy = -1;
+ }
+ else {
+ /* bottom-up min-to-max */
+ sy = srcY;
+ dy = destY;
+ stepy = 1;
+ }
+
+ if (overlapping) {
+ GLint ssy = sy;
+
+ if (stencilMask != 0x0) {
+ tempStencilImage
+ = (GLubyte *) malloc(width * height * sizeof(GLubyte));
+ if (!tempStencilImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
+ return;
+ }
+
+ /* get copy of stencil pixels */
+ stencilPtr = tempStencilImage;
+ for (j = 0; j < height; j++, ssy += stepy) {
+ _swrast_read_stencil_span(ctx, stencilReadRb,
+ width, srcX, ssy, stencilPtr);
+ stencilPtr += width;
+ }
+ stencilPtr = tempStencilImage;
+ }
+
+ if (ctx->Depth.Mask) {
+ tempDepthImage
+ = (GLfloat *) malloc(width * height * sizeof(GLfloat));
+ if (!tempDepthImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
+ free(tempStencilImage);
+ return;
+ }
+
+ /* get copy of depth pixels */
+ depthPtr = tempDepthImage;
+ for (j = 0; j < height; j++, ssy += stepy) {
+ _swrast_read_depth_span_float(ctx, depthReadRb,
+ width, srcX, ssy, depthPtr);
+ depthPtr += width;
+ }
+ depthPtr = tempDepthImage;
+ }
+ }
+
+ for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
+ if (stencilMask != 0x0) {
+ GLubyte stencil[MAX_WIDTH];
+
+ /* Get stencil values */
+ if (overlapping) {
+ memcpy(stencil, stencilPtr, width * sizeof(GLubyte));
+ stencilPtr += width;
+ }
+ else {
+ _swrast_read_stencil_span(ctx, stencilReadRb,
+ width, srcX, sy, stencil);
+ }
+
+ _mesa_apply_stencil_transfer_ops(ctx, width, stencil);
+
+ /* Write values */
+ if (zoom) {
+ _swrast_write_zoomed_stencil_span(ctx, destX, destY, width,
+ destX, dy, stencil);
+ }
+ else {
+ _swrast_write_stencil_span( ctx, width, destX, dy, stencil );
+ }
+ }
+
+ if (ctx->Depth.Mask) {
+ GLfloat depth[MAX_WIDTH];
+ GLuint zVals32[MAX_WIDTH];
+ GLushort zVals16[MAX_WIDTH];
+ GLvoid *zVals;
+ GLuint zBytes;
+
+ /* get depth values */
+ if (overlapping) {
+ memcpy(depth, depthPtr, width * sizeof(GLfloat));
+ depthPtr += width;
+ }
+ else {
+ _swrast_read_depth_span_float(ctx, depthReadRb,
+ width, srcX, sy, depth);
+ }
+
+ /* scale & bias */
+ if (scaleOrBias) {
+ _mesa_scale_and_bias_depth(ctx, width, depth);
+ }
+ /* convert to integer Z values */
+ if (depthDrawRb->DataType == GL_UNSIGNED_SHORT) {
+ GLint k;
+ for (k = 0; k < width; k++)
+ zVals16[k] = (GLushort) (depth[k] * depthScale);
+ zVals = zVals16;
+ zBytes = 2;
+ }
+ else {
+ GLint k;
+ for (k = 0; k < width; k++)
+ zVals32[k] = (GLuint) (depth[k] * depthScale);
+ zVals = zVals32;
+ zBytes = 4;
+ }
+
+ /* Write values */
+ if (zoom) {
+ _swrast_write_zoomed_z_span(ctx, destX, destY, width,
+ destX, dy, zVals);
+ }
+ else {
+ _swrast_put_row(ctx, depthDrawRb, width, destX, dy, zVals, zBytes);
+ }
+ }
+ }
+
+ if (tempStencilImage)
+ free(tempStencilImage);
+
+ if (tempDepthImage)
+ free(tempDepthImage);
+}
+
+
+
+/**
+ * Try to do a fast copy pixels.
+ */
+static GLboolean
+fast_copy_pixels(struct gl_context *ctx,
+ GLint srcX, GLint srcY, GLsizei width, GLsizei height,
+ GLint dstX, GLint dstY, GLenum type)
+{
+ struct gl_framebuffer *srcFb = ctx->ReadBuffer;
+ struct gl_framebuffer *dstFb = ctx->DrawBuffer;
+ struct gl_renderbuffer *srcRb, *dstRb;
+ GLint row, yStep;
+
+ if (SWRAST_CONTEXT(ctx)->_RasterMask != 0x0 ||
+ ctx->Pixel.ZoomX != 1.0F ||
+ ctx->Pixel.ZoomY != 1.0F ||
+ ctx->_ImageTransferState) {
+ /* can't handle these */
+ return GL_FALSE;
+ }
+
+ if (type == GL_COLOR) {
+ if (dstFb->_NumColorDrawBuffers != 1)
+ return GL_FALSE;
+ srcRb = srcFb->_ColorReadBuffer;
+ dstRb = dstFb->_ColorDrawBuffers[0];
+ }
+ else if (type == GL_STENCIL) {
+ srcRb = srcFb->_StencilBuffer;
+ dstRb = dstFb->_StencilBuffer;
+ }
+ else if (type == GL_DEPTH) {
+ srcRb = srcFb->_DepthBuffer;
+ dstRb = dstFb->_DepthBuffer;
+ }
+ else {
+ ASSERT(type == GL_DEPTH_STENCIL_EXT);
+ /* XXX correct? */
+ srcRb = srcFb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ dstRb = dstFb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ }
+
+ /* src and dst renderbuffers must be same format and type */
+ if (!srcRb || !dstRb ||
+ srcRb->DataType != dstRb->DataType ||
+ srcRb->_BaseFormat != dstRb->_BaseFormat) {
+ return GL_FALSE;
+ }
+
+ /* clipping not supported */
+ if (srcX < 0 || srcX + width > (GLint) srcFb->Width ||
+ srcY < 0 || srcY + height > (GLint) srcFb->Height ||
+ dstX < dstFb->_Xmin || dstX + width > dstFb->_Xmax ||
+ dstY < dstFb->_Ymin || dstY + height > dstFb->_Ymax) {
+ return GL_FALSE;
+ }
+
+ /* overlapping src/dst doesn't matter, just determine Y direction */
+ if (srcY < dstY) {
+ /* top-down max-to-min */
+ srcY = srcY + height - 1;
+ dstY = dstY + height - 1;
+ yStep = -1;
+ }
+ else {
+ /* bottom-up min-to-max */
+ yStep = 1;
+ }
+
+ 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;
+ }
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Do software-based glCopyPixels.
+ * By time we get here, all parameters will have been error-checked.
+ */
+void
+_swrast_CopyPixels( struct gl_context *ctx,
+ GLint srcx, GLint srcy, GLsizei width, GLsizei height,
+ GLint destx, GLint desty, GLenum type )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ swrast_render_start(ctx);
+
+ if (!_mesa_check_conditional_render(ctx))
+ return; /* don't copy */
+
+ if (swrast->NewState)
+ _swrast_validate_derived( ctx );
+
+ if (!fast_copy_pixels(ctx, srcx, srcy, width, height, destx, desty, type)) {
+ switch (type) {
+ case GL_COLOR:
+ copy_rgba_pixels( ctx, srcx, srcy, width, height, destx, desty );
+ break;
+ case GL_DEPTH:
+ copy_depth_pixels( ctx, srcx, srcy, width, height, destx, desty );
+ break;
+ case GL_STENCIL:
+ copy_stencil_pixels( ctx, srcx, srcy, width, height, destx, desty );
+ break;
+ case GL_DEPTH_STENCIL_EXT:
+ copy_depth_stencil_pixels(ctx, srcx, srcy, width, height, destx, desty);
+ break;
+ default:
+ _mesa_problem(ctx, "unexpected type in _swrast_CopyPixels");
+ }
+ }
+
+ swrast_render_finish(ctx);
+}
diff --git a/mesalib/src/mesa/swrast/s_depth.c b/mesalib/src/mesa/swrast/s_depth.c
index 6ffa0a310..8d3ad105b 100644
--- a/mesalib/src/mesa/swrast/s_depth.c
+++ b/mesalib/src/mesa/swrast/s_depth.c
@@ -1248,8 +1248,7 @@ _swrast_depth_bounds_test( struct gl_context *ctx, SWspan *span )
* Read a span of depth values from the given depth renderbuffer, returning
* the values as GLfloats.
* This function does clipping to prevent reading outside the depth buffer's
- * bounds. Though the clipping is redundant when we're called from
- * _swrast_ReadPixels.
+ * bounds.
*/
void
_swrast_read_depth_span_float( struct gl_context *ctx, struct gl_renderbuffer *rb,
diff --git a/mesalib/src/mesa/swrast/s_drawpix.c b/mesalib/src/mesa/swrast/s_drawpix.c
index 20bf4d626..b6c433753 100644
--- a/mesalib/src/mesa/swrast/s_drawpix.c
+++ b/mesalib/src/mesa/swrast/s_drawpix.c
@@ -320,6 +320,7 @@ draw_stencil_pixels( struct gl_context *ctx, GLint x, GLint y,
const GLvoid *pixels )
{
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
+ const GLenum destType = GL_UNSIGNED_BYTE;
GLint skipPixels;
/* if width > MAX_WIDTH, have to process image in chunks */
@@ -330,9 +331,7 @@ draw_stencil_pixels( struct gl_context *ctx, GLint x, GLint y,
GLint row;
for (row = 0; row < height; row++) {
const GLint spanY = y + row;
- GLstencil values[MAX_WIDTH];
- GLenum destType = (sizeof(GLstencil) == sizeof(GLubyte))
- ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
+ GLubyte values[MAX_WIDTH];
const GLvoid *source = _mesa_image_address2d(unpack, pixels,
width, height,
GL_STENCIL_INDEX, type,
@@ -570,8 +569,7 @@ draw_depth_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
= ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
const GLuint depthMax = ctx->DrawBuffer->_DepthMax;
const GLuint stencilMask = ctx->Stencil.WriteMask[0];
- const GLuint stencilType = (STENCIL_BITS == 8) ?
- GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
+ const GLenum stencilType = GL_UNSIGNED_BYTE;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
struct gl_renderbuffer *depthRb, *stencilRb;
struct gl_pixelstore_attrib clippedUnpack = *unpack;
@@ -672,7 +670,7 @@ draw_depth_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
}
if (stencilMask != 0x0) {
- GLstencil stencilValues[MAX_WIDTH];
+ GLubyte stencilValues[MAX_WIDTH];
/* get stencil values, with shift/offset/mapping */
_mesa_unpack_stencil_span(ctx, width, stencilType, stencilValues,
type, depthStencilSrc, &clippedUnpack,
diff --git a/mesalib/src/mesa/swrast/s_readpix.c b/mesalib/src/mesa/swrast/s_readpix.c
deleted file mode 100644
index 3cef7304a..000000000
--- a/mesalib/src/mesa/swrast/s_readpix.c
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.0.3
- *
- * Copyright (C) 1999-2007 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/colormac.h"
-#include "main/feedback.h"
-#include "main/formats.h"
-#include "main/format_unpack.h"
-#include "main/image.h"
-#include "main/imports.h"
-#include "main/macros.h"
-#include "main/pack.h"
-#include "main/pbo.h"
-#include "main/state.h"
-
-#include "s_context.h"
-#include "s_depth.h"
-#include "s_span.h"
-#include "s_stencil.h"
-
-/**
- * Tries to implement glReadPixels() of GL_DEPTH_COMPONENT using memcpy of the
- * mapping.
- */
-static GLboolean
-fast_read_depth_pixels( struct gl_context *ctx,
- GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum type, GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing )
-{
- struct gl_framebuffer *fb = ctx->ReadBuffer;
- struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
- GLubyte *map, *dst;
- int stride, dstStride, j;
-
- if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0)
- return GL_FALSE;
-
- if (packing->SwapBytes)
- return GL_FALSE;
-
- if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_INT)
- return GL_FALSE;
-
- if (!((type == GL_UNSIGNED_SHORT && rb->Format == MESA_FORMAT_Z16) ||
- type == GL_UNSIGNED_INT))
- return GL_FALSE;
-
- ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
- &map, &stride);
-
- dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
- dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
- GL_DEPTH_COMPONENT, type, 0, 0);
-
- for (j = 0; j < height; j++) {
- if (type == GL_UNSIGNED_INT) {
- _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst);
- } else {
- ASSERT(type == GL_UNSIGNED_SHORT && rb->Format == MESA_FORMAT_Z16);
- memcpy(dst, map, width * 2);
- }
-
- map += stride;
- dst += dstStride;
- }
- ctx->Driver.UnmapRenderbuffer(ctx, rb);
-
- return GL_TRUE;
-}
-
-/**
- * Read pixels for format=GL_DEPTH_COMPONENT.
- */
-static void
-read_depth_pixels( struct gl_context *ctx,
- GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum type, GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing )
-{
- struct gl_framebuffer *fb = ctx->ReadBuffer;
- struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
- GLint j;
- GLubyte *dst, *map;
- int dstStride, stride;
-
- if (!rb)
- return;
-
- /* clipping should have been done already */
- ASSERT(x >= 0);
- ASSERT(y >= 0);
- ASSERT(x + width <= (GLint) rb->Width);
- ASSERT(y + height <= (GLint) rb->Height);
- /* width should never be > MAX_WIDTH since we did clipping earlier */
- ASSERT(width <= MAX_WIDTH);
-
- if (fast_read_depth_pixels(ctx, x, y, width, height, type, pixels, packing))
- return;
-
- dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
- dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
- GL_DEPTH_COMPONENT, type, 0, 0);
-
- ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
- &map, &stride);
-
- /* General case (slower) */
- for (j = 0; j < height; j++, y++) {
- GLfloat depthValues[MAX_WIDTH];
- _mesa_unpack_float_z_row(rb->Format, width, map, depthValues);
- _mesa_pack_depth_span(ctx, width, dst, type, depthValues, packing);
-
- dst += dstStride;
- map += stride;
- }
-
- ctx->Driver.UnmapRenderbuffer(ctx, rb);
-}
-
-
-/**
- * Read pixels for format=GL_STENCIL_INDEX.
- */
-static void
-read_stencil_pixels( struct gl_context *ctx,
- GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum type, GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing )
-{
- struct gl_framebuffer *fb = ctx->ReadBuffer;
- struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
- GLint j;
- GLubyte *map;
- GLint stride;
-
- if (!rb)
- return;
-
- /* width should never be > MAX_WIDTH since we did clipping earlier */
- ASSERT(width <= MAX_WIDTH);
-
- ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
- &map, &stride);
-
- /* process image row by row */
- for (j = 0; j < height; j++) {
- GLvoid *dest;
- GLstencil stencil[MAX_WIDTH];
-
- _mesa_unpack_ubyte_stencil_row(rb->Format, width, map, stencil);
- dest = _mesa_image_address2d(packing, pixels, width, height,
- GL_STENCIL_INDEX, type, j, 0);
-
- _mesa_pack_stencil_span(ctx, width, type, dest, stencil, packing);
-
- map += stride;
- }
-
- ctx->Driver.UnmapRenderbuffer(ctx, rb);
-}
-
-static GLboolean
-fast_read_rgba_pixels_memcpy( struct gl_context *ctx,
- GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing,
- GLbitfield transferOps )
-{
- struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
- GLubyte *dst, *map;
- int dstStride, stride, j, texelBytes;
-
- if (!_mesa_format_matches_format_and_type(rb->Format, format, type))
- return GL_FALSE;
-
- /* check for things we can't handle here */
- if (packing->SwapBytes ||
- packing->LsbFirst) {
- return GL_FALSE;
- }
-
- dstStride = _mesa_image_row_stride(packing, width, format, type);
- dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
- format, type, 0, 0);
-
- ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
- &map, &stride);
-
- texelBytes = _mesa_get_format_bytes(rb->Format);
- for (j = 0; j < height; j++) {
- memcpy(dst, map, width * texelBytes);
- dst += dstStride;
- map += stride;
- }
-
- ctx->Driver.UnmapRenderbuffer(ctx, rb);
-
- return GL_TRUE;
-}
-
-static GLboolean
-slow_read_rgba_pixels( struct gl_context *ctx,
- GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing,
- GLbitfield transferOps )
-{
- struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
- const gl_format rbFormat = _mesa_get_srgb_format_linear(rb->Format);
- union {
- float f[MAX_WIDTH][4];
- unsigned int i[MAX_WIDTH][4];
- } rgba;
- GLubyte *dst, *map;
- int dstStride, stride, j;
-
- dstStride = _mesa_image_row_stride(packing, width, format, type);
- dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
- format, type, 0, 0);
-
- ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
- &map, &stride);
-
- for (j = 0; j < height; j++) {
- if (_mesa_is_integer_format(format)) {
- _mesa_unpack_int_rgba_row(rbFormat, width, map, rgba.i);
- _mesa_pack_rgba_span_int(ctx, width, rgba.i, format, type, dst);
- } else {
- _mesa_unpack_rgba_row(rbFormat, width, map, rgba.f);
- _mesa_pack_rgba_span_float(ctx, width, rgba.f, format, type, dst,
- packing, transferOps);
- }
- dst += dstStride;
- map += stride;
- }
-
- ctx->Driver.UnmapRenderbuffer(ctx, rb);
-
- return GL_TRUE;
-}
-
-/*
- * Read R, G, B, A, RGB, L, or LA pixels.
- */
-static void
-read_rgba_pixels( struct gl_context *ctx,
- GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing )
-{
- GLbitfield transferOps = ctx->_ImageTransferState;
- struct gl_framebuffer *fb = ctx->ReadBuffer;
- struct gl_renderbuffer *rb = fb->_ColorReadBuffer;
-
- if (!rb)
- return;
-
- if ((ctx->Color._ClampReadColor == GL_TRUE || type != GL_FLOAT) &&
- !_mesa_is_integer_format(format)) {
- transferOps |= IMAGE_CLAMP_BIT;
- }
-
- if (!transferOps) {
- /* Try the optimized paths first. */
- if (fast_read_rgba_pixels_memcpy(ctx, x, y, width, height,
- format, type, pixels, packing,
- transferOps)) {
- return;
- }
- }
-
- slow_read_rgba_pixels(ctx, x, y, width, height,
- format, type, pixels, packing, transferOps);
-}
-
-/**
- * For a packed depth/stencil buffer being read as depth/stencil, just memcpy the
- * data (possibly swapping 8/24 vs 24/8 as we go).
- */
-static GLboolean
-fast_read_depth_stencil_pixels(struct gl_context *ctx,
- GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLubyte *dst, int dstStride)
-{
- struct gl_framebuffer *fb = ctx->ReadBuffer;
- struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
- struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
- GLubyte *map;
- int stride, i;
-
- if (rb != stencilRb)
- return GL_FALSE;
-
- if (rb->Format != MESA_FORMAT_Z24_S8 &&
- rb->Format != MESA_FORMAT_S8_Z24)
- return GL_FALSE;
-
- ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
- &map, &stride);
-
- for (i = 0; i < height; i++) {
- _mesa_unpack_uint_24_8_depth_stencil_row(rb->Format, width,
- map, (GLuint *)dst);
- map += stride;
- dst += dstStride;
- }
-
- ctx->Driver.UnmapRenderbuffer(ctx, rb);
-
- return GL_TRUE;
-}
-
-
-/**
- * For non-float-depth and stencil buffers being read as 24/8 depth/stencil,
- * copy the integer data directly instead of converting depth to float and
- * re-packing.
- */
-static GLboolean
-fast_read_depth_stencil_pixels_separate(struct gl_context *ctx,
- GLint x, GLint y,
- GLsizei width, GLsizei height,
- uint32_t *dst, int dstStride)
-{
- struct gl_framebuffer *fb = ctx->ReadBuffer;
- struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
- struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
- GLubyte *depthMap, *stencilMap;
- int depthStride, stencilStride, i, j;
-
- if (_mesa_get_format_datatype(depthRb->Format) != GL_UNSIGNED_INT)
- return GL_FALSE;
-
- ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
- GL_MAP_READ_BIT, &depthMap, &depthStride);
- ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
- GL_MAP_READ_BIT, &stencilMap, &stencilStride);
-
- for (j = 0; j < height; j++) {
- GLstencil stencilVals[MAX_WIDTH];
-
- _mesa_unpack_uint_z_row(depthRb->Format, width, depthMap, dst);
- _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
- stencilMap, stencilVals);
-
- for (i = 0; i < width; i++) {
- dst[i] = (dst[i] & 0xffffff00) | stencilVals[i];
- }
-
- depthMap += depthStride;
- stencilMap += stencilStride;
- dst += dstStride / 4;
- }
-
- ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
- ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
-
- return GL_TRUE;
-}
-
-static void
-slow_read_depth_stencil_pixels_separate(struct gl_context *ctx,
- GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum type,
- const struct gl_pixelstore_attrib *packing,
- GLubyte *dst, int dstStride)
-{
- struct gl_framebuffer *fb = ctx->ReadBuffer;
- struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
- struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
- GLubyte *depthMap, *stencilMap;
- int depthStride, stencilStride, j;
-
- ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
- GL_MAP_READ_BIT, &depthMap, &depthStride);
- ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
- GL_MAP_READ_BIT, &stencilMap, &stencilStride);
-
- for (j = 0; j < height; j++) {
- GLstencil stencilVals[MAX_WIDTH];
- GLfloat depthVals[MAX_WIDTH];
-
- _mesa_unpack_float_z_row(depthRb->Format, width, depthMap, depthVals);
- _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
- stencilMap, stencilVals);
-
- _mesa_pack_depth_stencil_span(ctx, width, type, (GLuint *)dst,
- depthVals, stencilVals, packing);
-
- depthMap += depthStride;
- stencilMap += stencilStride;
- dst += dstStride;
- }
-
- ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
- ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
-}
-
-
-/**
- * Read combined depth/stencil values.
- * We'll have already done error checking to be sure the expected
- * depth and stencil buffers really exist.
- */
-static void
-read_depth_stencil_pixels(struct gl_context *ctx,
- GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum type, GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing )
-{
- const GLboolean scaleOrBias
- = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
- const GLboolean stencilTransfer = ctx->Pixel.IndexShift
- || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag;
- GLubyte *dst;
- int dstStride;
-
- dst = (GLubyte *) _mesa_image_address2d(packing, pixels,
- width, height,
- GL_DEPTH_STENCIL_EXT,
- type, 0, 0);
- dstStride = _mesa_image_row_stride(packing, width,
- GL_DEPTH_STENCIL_EXT, type);
-
- /* Fast 24/8 reads. */
- if (type == GL_UNSIGNED_INT_24_8 &&
- !scaleOrBias && !stencilTransfer && !packing->SwapBytes) {
- if (fast_read_depth_stencil_pixels(ctx, x, y, width, height,
- dst, dstStride))
- return;
-
- if (fast_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
- (uint32_t *)dst, dstStride))
- return;
- }
-
- slow_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
- type, packing,
- dst, dstStride);
-}
-
-
-
-/**
- * Software fallback routine for ctx->Driver.ReadPixels().
- * By time we get here, all error checking will have been done.
- */
-void
-_swrast_ReadPixels( struct gl_context *ctx,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const struct gl_pixelstore_attrib *packing,
- GLvoid *pixels )
-{
- struct gl_pixelstore_attrib clippedPacking = *packing;
-
- if (ctx->NewState)
- _mesa_update_state(ctx);
-
- /* Do all needed clipping here, so that we can forget about it later */
- if (_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) {
-
- pixels = _mesa_map_pbo_dest(ctx, &clippedPacking, pixels);
-
- if (pixels) {
- switch (format) {
- case GL_STENCIL_INDEX:
- read_stencil_pixels(ctx, x, y, width, height, type, pixels,
- &clippedPacking);
- break;
- case GL_DEPTH_COMPONENT:
- read_depth_pixels(ctx, x, y, width, height, type, pixels,
- &clippedPacking);
- break;
- case GL_DEPTH_STENCIL_EXT:
- read_depth_stencil_pixels(ctx, x, y, width, height, type, pixels,
- &clippedPacking);
- break;
- default:
- /* all other formats should be color formats */
- read_rgba_pixels(ctx, x, y, width, height, format, type, pixels,
- &clippedPacking);
- }
-
- _mesa_unmap_pbo_dest(ctx, &clippedPacking);
- }
- }
-}
diff --git a/mesalib/src/mesa/swrast/s_stencil.c b/mesalib/src/mesa/swrast/s_stencil.c
index e713e2393..101ee5056 100644
--- a/mesalib/src/mesa/swrast/s_stencil.c
+++ b/mesalib/src/mesa/swrast/s_stencil.c
@@ -62,12 +62,12 @@ ENDIF
*/
static void
apply_stencil_op( const struct gl_context *ctx, GLenum oper, GLuint face,
- GLuint n, GLstencil stencil[], const GLubyte mask[] )
+ GLuint n, GLubyte stencil[], const GLubyte mask[] )
{
- const GLstencil ref = ctx->Stencil.Ref[face];
- const GLstencil wrtmask = ctx->Stencil.WriteMask[face];
- const GLstencil invmask = (GLstencil) (~wrtmask);
- const GLstencil stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
+ const GLubyte ref = ctx->Stencil.Ref[face];
+ const GLubyte wrtmask = ctx->Stencil.WriteMask[face];
+ const GLubyte invmask = (GLubyte) (~wrtmask);
+ const GLubyte stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
GLuint i;
switch (oper) {
@@ -85,7 +85,7 @@ apply_stencil_op( const struct gl_context *ctx, GLenum oper, GLuint face,
else {
for (i=0;i<n;i++) {
if (mask[i]) {
- stencil[i] = (GLstencil) (stencil[i] & invmask);
+ stencil[i] = (GLubyte) (stencil[i] & invmask);
}
}
}
@@ -101,8 +101,8 @@ apply_stencil_op( const struct gl_context *ctx, GLenum oper, GLuint face,
else {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil s = stencil[i];
- stencil[i] = (GLstencil) ((invmask & s ) | (wrtmask & ref));
+ GLubyte s = stencil[i];
+ stencil[i] = (GLubyte) ((invmask & s ) | (wrtmask & ref));
}
}
}
@@ -111,9 +111,9 @@ apply_stencil_op( const struct gl_context *ctx, GLenum oper, GLuint face,
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil s = stencil[i];
+ GLubyte s = stencil[i];
if (s < stencilMax) {
- stencil[i] = (GLstencil) (s+1);
+ stencil[i] = (GLubyte) (s+1);
}
}
}
@@ -122,9 +122,9 @@ apply_stencil_op( const struct gl_context *ctx, GLenum oper, GLuint face,
for (i=0;i<n;i++) {
if (mask[i]) {
/* VERIFY logic of adding 1 to a write-masked value */
- GLstencil s = stencil[i];
+ GLubyte s = stencil[i];
if (s < stencilMax) {
- stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s+1)));
+ stencil[i] = (GLubyte) ((invmask & s) | (wrtmask & (s+1)));
}
}
}
@@ -134,9 +134,9 @@ apply_stencil_op( const struct gl_context *ctx, GLenum oper, GLuint face,
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil s = stencil[i];
+ GLubyte s = stencil[i];
if (s>0) {
- stencil[i] = (GLstencil) (s-1);
+ stencil[i] = (GLubyte) (s-1);
}
}
}
@@ -145,9 +145,9 @@ apply_stencil_op( const struct gl_context *ctx, GLenum oper, GLuint face,
for (i=0;i<n;i++) {
if (mask[i]) {
/* VERIFY logic of subtracting 1 to a write-masked value */
- GLstencil s = stencil[i];
+ GLubyte s = stencil[i];
if (s>0) {
- stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s-1)));
+ stencil[i] = (GLubyte) ((invmask & s) | (wrtmask & (s-1)));
}
}
}
@@ -164,8 +164,8 @@ apply_stencil_op( const struct gl_context *ctx, GLenum oper, GLuint face,
else {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil s = stencil[i];
- stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s+1)));
+ GLubyte s = stencil[i];
+ stencil[i] = (GLubyte) ((invmask & s) | (wrtmask & (s+1)));
}
}
}
@@ -181,8 +181,8 @@ apply_stencil_op( const struct gl_context *ctx, GLenum oper, GLuint face,
else {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil s = stencil[i];
- stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s-1)));
+ GLubyte s = stencil[i];
+ stencil[i] = (GLubyte) ((invmask & s) | (wrtmask & (s-1)));
}
}
}
@@ -191,16 +191,16 @@ apply_stencil_op( const struct gl_context *ctx, GLenum oper, GLuint face,
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil s = stencil[i];
- stencil[i] = (GLstencil) ~s;
+ GLubyte s = stencil[i];
+ stencil[i] = (GLubyte) ~s;
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil s = stencil[i];
- stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & ~s));
+ GLubyte s = stencil[i];
+ stencil[i] = (GLubyte) ((invmask & s) | (wrtmask & ~s));
}
}
}
@@ -225,15 +225,15 @@ apply_stencil_op( const struct gl_context *ctx, GLenum oper, GLuint face,
* Return: GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed.
*/
static GLboolean
-do_stencil_test( struct gl_context *ctx, GLuint face, GLuint n, GLstencil stencil[],
+do_stencil_test( struct gl_context *ctx, GLuint face, GLuint n, GLubyte stencil[],
GLubyte mask[] )
{
GLubyte fail[MAX_WIDTH];
GLboolean allfail = GL_FALSE;
GLuint i;
const GLuint valueMask = ctx->Stencil.ValueMask[face];
- const GLstencil r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
- GLstencil s;
+ const GLubyte r = (GLubyte) (ctx->Stencil.Ref[face] & valueMask);
+ GLubyte s;
ASSERT(n <= MAX_WIDTH);
@@ -263,7 +263,7 @@ do_stencil_test( struct gl_context *ctx, GLuint face, GLuint n, GLstencil stenci
case GL_LESS:
for (i=0;i<n;i++) {
if (mask[i]) {
- s = (GLstencil) (stencil[i] & valueMask);
+ s = (GLubyte) (stencil[i] & valueMask);
if (r < s) {
/* passed */
fail[i] = 0;
@@ -281,7 +281,7 @@ do_stencil_test( struct gl_context *ctx, GLuint face, GLuint n, GLstencil stenci
case GL_LEQUAL:
for (i=0;i<n;i++) {
if (mask[i]) {
- s = (GLstencil) (stencil[i] & valueMask);
+ s = (GLubyte) (stencil[i] & valueMask);
if (r <= s) {
/* pass */
fail[i] = 0;
@@ -299,7 +299,7 @@ do_stencil_test( struct gl_context *ctx, GLuint face, GLuint n, GLstencil stenci
case GL_GREATER:
for (i=0;i<n;i++) {
if (mask[i]) {
- s = (GLstencil) (stencil[i] & valueMask);
+ s = (GLubyte) (stencil[i] & valueMask);
if (r > s) {
/* passed */
fail[i] = 0;
@@ -317,7 +317,7 @@ do_stencil_test( struct gl_context *ctx, GLuint face, GLuint n, GLstencil stenci
case GL_GEQUAL:
for (i=0;i<n;i++) {
if (mask[i]) {
- s = (GLstencil) (stencil[i] & valueMask);
+ s = (GLubyte) (stencil[i] & valueMask);
if (r >= s) {
/* passed */
fail[i] = 0;
@@ -335,7 +335,7 @@ do_stencil_test( struct gl_context *ctx, GLuint face, GLuint n, GLstencil stenci
case GL_EQUAL:
for (i=0;i<n;i++) {
if (mask[i]) {
- s = (GLstencil) (stencil[i] & valueMask);
+ s = (GLubyte) (stencil[i] & valueMask);
if (r == s) {
/* passed */
fail[i] = 0;
@@ -353,7 +353,7 @@ do_stencil_test( struct gl_context *ctx, GLuint face, GLuint n, GLstencil stenci
case GL_NOTEQUAL:
for (i=0;i<n;i++) {
if (mask[i]) {
- s = (GLstencil) (stencil[i] & valueMask);
+ s = (GLubyte) (stencil[i] & valueMask);
if (r != s) {
/* passed */
fail[i] = 0;
@@ -422,8 +422,8 @@ stencil_and_ztest_span(struct gl_context *ctx, SWspan *span, GLuint face)
{
struct gl_framebuffer *fb = ctx->DrawBuffer;
struct gl_renderbuffer *rb = fb->_StencilBuffer;
- GLstencil stencilRow[MAX_WIDTH];
- GLstencil *stencil;
+ GLubyte stencilRow[MAX_WIDTH];
+ GLubyte *stencil;
const GLuint n = span->end;
const GLint x = span->x;
const GLint y = span->y;
@@ -438,7 +438,7 @@ stencil_and_ztest_span(struct gl_context *ctx, SWspan *span, GLuint face)
}
#endif
- stencil = (GLstencil *) rb->GetPointer(ctx, rb, x, y);
+ stencil = (GLubyte *) rb->GetPointer(ctx, rb, x, y);
if (!stencil) {
rb->GetRow(ctx, rb, n, x, y, stencilRow);
stencil = stencilRow;
@@ -531,16 +531,15 @@ apply_stencil_op_to_pixels( struct gl_context *ctx,
{
struct gl_framebuffer *fb = ctx->DrawBuffer;
struct gl_renderbuffer *rb = fb->_StencilBuffer;
- const GLstencil stencilMax = (1 << fb->Visual.stencilBits) - 1;
- const GLstencil ref = ctx->Stencil.Ref[face];
- const GLstencil wrtmask = ctx->Stencil.WriteMask[face];
- const GLstencil invmask = (GLstencil) (~wrtmask);
+ const GLubyte stencilMax = (1 << fb->Visual.stencilBits) - 1;
+ const GLubyte ref = ctx->Stencil.Ref[face];
+ const GLubyte wrtmask = ctx->Stencil.WriteMask[face];
+ const GLubyte invmask = (GLubyte) (~wrtmask);
GLuint i;
- GLstencil *stencilStart = (GLubyte *) rb->Data;
+ GLubyte *stencilStart = (GLubyte *) rb->Data;
const GLuint stride = rb->Width;
ASSERT(rb->GetPointer(ctx, rb, 0, 0));
- ASSERT(sizeof(GLstencil) == 1);
switch (oper) {
case GL_KEEP:
@@ -550,7 +549,7 @@ apply_stencil_op_to_pixels( struct gl_context *ctx,
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+ GLubyte *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = 0;
}
}
@@ -558,8 +557,8 @@ apply_stencil_op_to_pixels( struct gl_context *ctx,
else {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = (GLstencil) (invmask & *sptr);
+ GLubyte *sptr = STENCIL_ADDRESS( x[i], y[i] );
+ *sptr = (GLubyte) (invmask & *sptr);
}
}
}
@@ -568,7 +567,7 @@ apply_stencil_op_to_pixels( struct gl_context *ctx,
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+ GLubyte *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = ref;
}
}
@@ -576,8 +575,8 @@ apply_stencil_op_to_pixels( struct gl_context *ctx,
else {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = (GLstencil) ((invmask & *sptr ) | (wrtmask & ref));
+ GLubyte *sptr = STENCIL_ADDRESS( x[i], y[i] );
+ *sptr = (GLubyte) ((invmask & *sptr ) | (wrtmask & ref));
}
}
}
@@ -586,9 +585,9 @@ apply_stencil_op_to_pixels( struct gl_context *ctx,
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+ GLubyte *sptr = STENCIL_ADDRESS( x[i], y[i] );
if (*sptr < stencilMax) {
- *sptr = (GLstencil) (*sptr + 1);
+ *sptr = (GLubyte) (*sptr + 1);
}
}
}
@@ -596,9 +595,9 @@ apply_stencil_op_to_pixels( struct gl_context *ctx,
else {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+ GLubyte *sptr = STENCIL_ADDRESS( x[i], y[i] );
if (*sptr < stencilMax) {
- *sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr+1)));
+ *sptr = (GLubyte) ((invmask & *sptr) | (wrtmask & (*sptr+1)));
}
}
}
@@ -608,9 +607,9 @@ apply_stencil_op_to_pixels( struct gl_context *ctx,
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+ GLubyte *sptr = STENCIL_ADDRESS( x[i], y[i] );
if (*sptr>0) {
- *sptr = (GLstencil) (*sptr - 1);
+ *sptr = (GLubyte) (*sptr - 1);
}
}
}
@@ -618,9 +617,9 @@ apply_stencil_op_to_pixels( struct gl_context *ctx,
else {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
+ GLubyte *sptr = STENCIL_ADDRESS( x[i], y[i] );
if (*sptr>0) {
- *sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr-1)));
+ *sptr = (GLubyte) ((invmask & *sptr) | (wrtmask & (*sptr-1)));
}
}
}
@@ -630,16 +629,16 @@ apply_stencil_op_to_pixels( struct gl_context *ctx,
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = (GLstencil) (*sptr + 1);
+ GLubyte *sptr = STENCIL_ADDRESS( x[i], y[i] );
+ *sptr = (GLubyte) (*sptr + 1);
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr+1)));
+ GLubyte *sptr = STENCIL_ADDRESS( x[i], y[i] );
+ *sptr = (GLubyte) ((invmask & *sptr) | (wrtmask & (*sptr+1)));
}
}
}
@@ -648,16 +647,16 @@ apply_stencil_op_to_pixels( struct gl_context *ctx,
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = (GLstencil) (*sptr - 1);
+ GLubyte *sptr = STENCIL_ADDRESS( x[i], y[i] );
+ *sptr = (GLubyte) (*sptr - 1);
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr-1)));
+ GLubyte *sptr = STENCIL_ADDRESS( x[i], y[i] );
+ *sptr = (GLubyte) ((invmask & *sptr) | (wrtmask & (*sptr-1)));
}
}
}
@@ -666,16 +665,16 @@ apply_stencil_op_to_pixels( struct gl_context *ctx,
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = (GLstencil) (~*sptr);
+ GLubyte *sptr = STENCIL_ADDRESS( x[i], y[i] );
+ *sptr = (GLubyte) (~*sptr);
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
- GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
- *sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & ~*sptr));
+ GLubyte *sptr = STENCIL_ADDRESS( x[i], y[i] );
+ *sptr = (GLubyte) ((invmask & *sptr) | (wrtmask & ~*sptr));
}
}
}
@@ -705,15 +704,14 @@ stencil_test_pixels( struct gl_context *ctx, GLuint face, GLuint n,
const struct gl_framebuffer *fb = ctx->DrawBuffer;
struct gl_renderbuffer *rb = fb->_StencilBuffer;
GLubyte fail[MAX_WIDTH];
- GLstencil r, s;
+ GLubyte r, s;
GLuint i;
GLboolean allfail = GL_FALSE;
const GLuint valueMask = ctx->Stencil.ValueMask[face];
- const GLstencil *stencilStart = (GLstencil *) rb->Data;
+ const GLubyte *stencilStart = (GLubyte *) rb->Data;
const GLuint stride = rb->Width;
ASSERT(rb->GetPointer(ctx, rb, 0, 0));
- ASSERT(sizeof(GLstencil) == 1);
/*
* Perform stencil test. The results of this operation are stored
@@ -740,11 +738,11 @@ stencil_test_pixels( struct gl_context *ctx, GLuint face, GLuint n,
allfail = GL_TRUE;
break;
case GL_LESS:
- r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
+ r = (GLubyte) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
- const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & valueMask);
+ const GLubyte *sptr = STENCIL_ADDRESS(x[i],y[i]);
+ s = (GLubyte) (*sptr & valueMask);
if (r < s) {
/* passed */
fail[i] = 0;
@@ -760,11 +758,11 @@ stencil_test_pixels( struct gl_context *ctx, GLuint face, GLuint n,
}
break;
case GL_LEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
+ r = (GLubyte) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
- const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & valueMask);
+ const GLubyte *sptr = STENCIL_ADDRESS(x[i],y[i]);
+ s = (GLubyte) (*sptr & valueMask);
if (r <= s) {
/* pass */
fail[i] = 0;
@@ -780,11 +778,11 @@ stencil_test_pixels( struct gl_context *ctx, GLuint face, GLuint n,
}
break;
case GL_GREATER:
- r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
+ r = (GLubyte) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
- const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & valueMask);
+ const GLubyte *sptr = STENCIL_ADDRESS(x[i],y[i]);
+ s = (GLubyte) (*sptr & valueMask);
if (r > s) {
/* passed */
fail[i] = 0;
@@ -800,11 +798,11 @@ stencil_test_pixels( struct gl_context *ctx, GLuint face, GLuint n,
}
break;
case GL_GEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
+ r = (GLubyte) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
- const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & valueMask);
+ const GLubyte *sptr = STENCIL_ADDRESS(x[i],y[i]);
+ s = (GLubyte) (*sptr & valueMask);
if (r >= s) {
/* passed */
fail[i] = 0;
@@ -820,11 +818,11 @@ stencil_test_pixels( struct gl_context *ctx, GLuint face, GLuint n,
}
break;
case GL_EQUAL:
- r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
+ r = (GLubyte) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
- const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & valueMask);
+ const GLubyte *sptr = STENCIL_ADDRESS(x[i],y[i]);
+ s = (GLubyte) (*sptr & valueMask);
if (r == s) {
/* passed */
fail[i] = 0;
@@ -840,11 +838,11 @@ stencil_test_pixels( struct gl_context *ctx, GLuint face, GLuint n,
}
break;
case GL_NOTEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
+ r = (GLubyte) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
- const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
- s = (GLstencil) (*sptr & valueMask);
+ const GLubyte *sptr = STENCIL_ADDRESS(x[i],y[i]);
+ s = (GLubyte) (*sptr & valueMask);
if (r != s) {
/* passed */
fail[i] = 0;
@@ -914,7 +912,7 @@ stencil_and_ztest_pixels( struct gl_context *ctx, SWspan *span, GLuint face )
if (!rb->GetPointer(ctx, rb, 0, 0)) {
/* No direct access */
- GLstencil stencil[MAX_WIDTH];
+ GLubyte stencil[MAX_WIDTH];
ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
_swrast_get_values(ctx, rb, n, x, y, stencil, sizeof(GLubyte));
@@ -1044,7 +1042,7 @@ clip_span(GLuint bufferWidth, GLuint bufferHeight,
*/
void
_swrast_read_stencil_span(struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLint n, GLint x, GLint y, GLstencil stencil[])
+ GLint n, GLint x, GLint y, GLubyte stencil[])
{
if (y < 0 || y >= (GLint) rb->Height ||
x + n <= 0 || x >= (GLint) rb->Width) {
@@ -1081,7 +1079,7 @@ _swrast_read_stencil_span(struct gl_context *ctx, struct gl_renderbuffer *rb,
*/
void
_swrast_write_stencil_span(struct gl_context *ctx, GLint n, GLint x, GLint y,
- const GLstencil stencil[] )
+ const GLubyte stencil[] )
{
struct gl_framebuffer *fb = ctx->DrawBuffer;
struct gl_renderbuffer *rb = fb->_StencilBuffer;
@@ -1109,7 +1107,7 @@ _swrast_write_stencil_span(struct gl_context *ctx, GLint n, GLint x, GLint y,
if ((stencilMask & stencilMax) != stencilMax) {
/* need to apply writemask */
- GLstencil destVals[MAX_WIDTH], newVals[MAX_WIDTH];
+ GLubyte destVals[MAX_WIDTH], newVals[MAX_WIDTH];
GLint i;
rb->GetRow(ctx, rb, n, x, y, destVals);
for (i = 0; i < n; i++) {
diff --git a/mesalib/src/mesa/swrast/s_stencil.h b/mesalib/src/mesa/swrast/s_stencil.h
index 0bcfb799f..37f3c8da1 100644
--- a/mesalib/src/mesa/swrast/s_stencil.h
+++ b/mesalib/src/mesa/swrast/s_stencil.h
@@ -1,53 +1,53 @@
-/*
- * 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_STENCIL_H
-#define S_STENCIL_H
-
-
-#include "main/mtypes.h"
-#include "s_span.h"
-
-
-
-extern GLboolean
-_swrast_stencil_and_ztest_span(struct gl_context *ctx, SWspan *span);
-
-
-extern void
-_swrast_read_stencil_span(struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLint n, GLint x, GLint y, GLstencil stencil[]);
-
-
-extern void
-_swrast_write_stencil_span( struct gl_context *ctx, GLint n, GLint x, GLint y,
- const GLstencil stencil[] );
-
-
-extern void
-_swrast_clear_stencil_buffer( struct gl_context *ctx, struct gl_renderbuffer *rb );
-
-
-#endif
+/*
+ * 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_STENCIL_H
+#define S_STENCIL_H
+
+
+#include "main/mtypes.h"
+#include "s_span.h"
+
+
+
+extern GLboolean
+_swrast_stencil_and_ztest_span(struct gl_context *ctx, SWspan *span);
+
+
+extern void
+_swrast_read_stencil_span(struct gl_context *ctx, struct gl_renderbuffer *rb,
+ GLint n, GLint x, GLint y, GLubyte stencil[]);
+
+
+extern void
+_swrast_write_stencil_span( struct gl_context *ctx, GLint n, GLint x, GLint y,
+ const GLubyte stencil[] );
+
+
+extern void
+_swrast_clear_stencil_buffer( struct gl_context *ctx, struct gl_renderbuffer *rb );
+
+
+#endif
diff --git a/mesalib/src/mesa/swrast/s_texrender.c b/mesalib/src/mesa/swrast/s_texrender.c
index 83e7a6a03..3734ce6d5 100644
--- a/mesalib/src/mesa/swrast/s_texrender.c
+++ b/mesalib/src/mesa/swrast/s_texrender.c
@@ -567,6 +567,19 @@ update_wrapper(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
trb->Base.InternalFormat = trb->TexImage->Base.InternalFormat;
trb->Base.Format = trb->TexImage->Base.TexFormat;
+ /* Set the gl_renderbuffer::Data field so that mapping the buffer
+ * in renderbuffer.c succeeds.
+ */
+ if (att->Texture->Target == GL_TEXTURE_3D ||
+ att->Texture->Target == GL_TEXTURE_2D_ARRAY_EXT) {
+ trb->Base.Data = trb->TexImage->Buffer +
+ trb->TexImage->ImageOffsets[trb->Zoffset] *
+ _mesa_get_format_bytes(trb->TexImage->Base.TexFormat);
+ }
+ else {
+ trb->Base.Data = trb->TexImage->Buffer;
+ }
+
/* XXX may need more special cases here */
switch (trb->TexImage->Base.TexFormat) {
case MESA_FORMAT_Z24_S8:
diff --git a/mesalib/src/mesa/swrast/s_zoom.c b/mesalib/src/mesa/swrast/s_zoom.c
index 3fb784847..16bb997f3 100644
--- a/mesalib/src/mesa/swrast/s_zoom.c
+++ b/mesalib/src/mesa/swrast/s_zoom.c
@@ -351,9 +351,9 @@ _swrast_write_zoomed_depth_span(struct gl_context *ctx, GLint imgX, GLint imgY,
void
_swrast_write_zoomed_stencil_span(struct gl_context *ctx, GLint imgX, GLint imgY,
GLint width, GLint spanX, GLint spanY,
- const GLstencil stencil[])
+ const GLubyte stencil[])
{
- GLstencil zoomedVals[MAX_WIDTH];
+ GLubyte zoomedVals[MAX_WIDTH];
GLint x0, x1, y0, y1, y;
GLint i, zoomedWidth;
diff --git a/mesalib/src/mesa/swrast/s_zoom.h b/mesalib/src/mesa/swrast/s_zoom.h
index b8d17b5a4..0b82bb824 100644
--- a/mesalib/src/mesa/swrast/s_zoom.h
+++ b/mesalib/src/mesa/swrast/s_zoom.h
@@ -1,56 +1,56 @@
-/*
- * 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_ZOOM_H
-#define S_ZOOM_H
-
-#include "main/mtypes.h"
-#include "s_span.h"
-
-
-extern void
-_swrast_write_zoomed_rgba_span(struct gl_context *ctx, GLint imgX, GLint imgY,
- const SWspan *span, const GLvoid *rgba);
-
-extern void
-_swrast_write_zoomed_rgb_span(struct gl_context *ctx, GLint imgX, GLint imgY,
- const SWspan *span, const GLvoid *rgb);
-
-extern void
-_swrast_write_zoomed_depth_span(struct gl_context *ctx, GLint imgX, GLint imgY,
- const SWspan *span);
-
-
-extern void
-_swrast_write_zoomed_stencil_span(struct gl_context *ctx, GLint imgX, GLint imgY,
- GLint width, GLint spanX, GLint spanY,
- const GLstencil stencil[]);
-
-extern void
-_swrast_write_zoomed_z_span(struct gl_context *ctx, GLint imgX, GLint imgY,
- GLint width, GLint spanX, GLint spanY,
- const GLvoid *z);
-
-
-#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_ZOOM_H
+#define S_ZOOM_H
+
+#include "main/mtypes.h"
+#include "s_span.h"
+
+
+extern void
+_swrast_write_zoomed_rgba_span(struct gl_context *ctx, GLint imgX, GLint imgY,
+ const SWspan *span, const GLvoid *rgba);
+
+extern void
+_swrast_write_zoomed_rgb_span(struct gl_context *ctx, GLint imgX, GLint imgY,
+ const SWspan *span, const GLvoid *rgb);
+
+extern void
+_swrast_write_zoomed_depth_span(struct gl_context *ctx, GLint imgX, GLint imgY,
+ const SWspan *span);
+
+
+extern void
+_swrast_write_zoomed_stencil_span(struct gl_context *ctx, GLint imgX, GLint imgY,
+ GLint width, GLint spanX, GLint spanY,
+ const GLubyte stencil[]);
+
+extern void
+_swrast_write_zoomed_z_span(struct gl_context *ctx, GLint imgX, GLint imgY,
+ GLint width, GLint spanX, GLint spanY,
+ const GLvoid *z);
+
+
+#endif
diff --git a/mesalib/src/mesa/swrast/swrast.h b/mesalib/src/mesa/swrast/swrast.h
index 08d565ba0..17b66c664 100644
--- a/mesalib/src/mesa/swrast/swrast.h
+++ b/mesalib/src/mesa/swrast/swrast.h
@@ -119,13 +119,6 @@ _swrast_DrawPixels( struct gl_context *ctx,
const GLvoid *pixels );
extern void
-_swrast_ReadPixels( struct gl_context *ctx,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const struct gl_pixelstore_attrib *unpack,
- GLvoid *pixels );
-
-extern void
_swrast_BlitFramebuffer(struct gl_context *ctx,
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,