1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library
3032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian * Version:  7.1
422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
5d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
7e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
8e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"),
9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation
10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions:
1322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included
15e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software.
1622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
26bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h"
27bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/context.h"
28bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/colormac.h"
29ab26682eb4db0dbe160b13f1e320ec9164c3afc5Brian Paul#include "main/condrender.h"
30bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h"
311c131752c3e07ef91f49d4970dafca6d26585334Brian Paul#include "main/pixeltransfer.h"
32bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/imports.h"
33e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
34cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell#include "s_context.h"
35e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_depth.h"
36e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_span.h"
37e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_stencil.h"
38e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_zoom.h"
39e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
40e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
41e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
4276e778dce59aa6f290db50242df945943fc47b05Brian Paul/**
43dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul * Determine if there's overlap in an image copy.
44dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul * This test also compensates for the fact that copies are done from
45dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul * bottom to top and overlaps can sometimes be handled correctly
46dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul * without making a temporary image copy.
4776e778dce59aa6f290db50242df945943fc47b05Brian Paul * \return GL_TRUE if the regions overlap, GL_FALSE otherwise.
48e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
49e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic GLboolean
50dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paulregions_overlap(GLint srcx, GLint srcy,
51dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul                GLint dstx, GLint dsty,
52dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul                GLint width, GLint height,
53dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul                GLfloat zoomX, GLfloat zoomY)
54e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
55dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul   if (zoomX == 1.0 && zoomY == 1.0) {
56dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      /* no zoom */
57dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      if (srcx >= dstx + width || (srcx + width <= dstx)) {
58dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul         return GL_FALSE;
59dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      }
60dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      else if (srcy < dsty) { /* this is OK */
61dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul         return GL_FALSE;
62dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      }
6372574b959c39981033069e367a12c5ae595dd93aBrian Paul      else if (srcy > dsty + height) {
6472574b959c39981033069e367a12c5ae595dd93aBrian Paul         return GL_FALSE;
6572574b959c39981033069e367a12c5ae595dd93aBrian Paul      }
66dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      else {
67dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul         return GL_TRUE;
68dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      }
69e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
70e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
71dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      /* add one pixel of slop when zooming, just to be safe */
72032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian      if (srcx > (dstx + ((zoomX > 0.0F) ? (width * zoomX + 1.0F) : 0.0F))) {
73032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian         /* src is completely right of dest */
74032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian         return GL_FALSE;
75032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian      }
76032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian      else if (srcx + width + 1.0F < dstx + ((zoomX > 0.0F) ? 0.0F : (width * zoomX))) {
77032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian         /* src is completely left of dest */
78dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul         return GL_FALSE;
79dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      }
80dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      else if ((srcy < dsty) && (srcy + height < dsty + (height * zoomY))) {
81032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian         /* src is completely below dest */
82dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul         return GL_FALSE;
83dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      }
84dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      else if ((srcy > dsty) && (srcy + height > dsty + (height * zoomY))) {
85032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian         /* src is completely above dest */
86dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul         return GL_FALSE;
87dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      }
88dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      else {
89dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul         return GL_TRUE;
90dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      }
91e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
92e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
93e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
94e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
954923e1926ad7b7eb7de017eda8e7db64d357e5c8Brian Paul/**
96e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * RGBA copypixels
97e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
98e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void
99f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergcopy_rgba_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
100e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                 GLint width, GLint height, GLint destx, GLint desty)
101e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
10276e778dce59aa6f290db50242df945943fc47b05Brian Paul   GLfloat *tmpImage, *p;
10376e778dce59aa6f290db50242df945943fc47b05Brian Paul   GLint sy, dy, stepy, row;
104e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
105e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLint overlapping;
106249b451d2068c781d29a6527e152b39d08b1c877Brian   GLuint transferOps = ctx->_ImageTransferState;
107cdb27e8242215271364602995d85607cfc06d441Brian Paul   SWspan span;
1082a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
109e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (!ctx->ReadBuffer->_ColorReadBuffer) {
110e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* no readbuffer - OK */
1119dca42a4a10acbf1980c0f2eafb3e28e11ca1bf3Brian      return;
112e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
113e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
114d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian   if (ctx->DrawBuffer == ctx->ReadBuffer) {
115d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian      overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
116d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian                                    ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
117d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian   }
118d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian   else {
119d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian      overlapping = GL_FALSE;
120d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian   }
121d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian
122e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Determine if copy should be done bottom-to-top or top-to-bottom */
123d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian   if (!overlapping && srcy < desty) {
124e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* top-down  max-to-min */
125e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      sy = srcy + height - 1;
126e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      dy = desty + height - 1;
127e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      stepy = -1;
128e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
129e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
130e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* bottom-up  min-to-max */
131e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      sy = srcy;
132e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      dy = desty;
133e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      stepy = 1;
134e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
135e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
136f4b103dc993491355ec3e3640d9cb060138175c2Brian   INIT_SPAN(span, GL_BITMAP);
1379e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   _swrast_span_default_attribs(ctx, &span);
138f4b103dc993491355ec3e3640d9cb060138175c2Brian   span.arrayMask = SPAN_RGBA;
1399dca42a4a10acbf1980c0f2eafb3e28e11ca1bf3Brian   span.arrayAttribs = FRAG_BIT_COL0; /* we'll fill in COL0 attrib values */
1402a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
141e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (overlapping) {
14232f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      tmpImage = (GLfloat *) malloc(width * height * sizeof(GLfloat) * 4);
143e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (!tmpImage) {
14408836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul         _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
1459dca42a4a10acbf1980c0f2eafb3e28e11ca1bf3Brian         return;
146e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
14776e778dce59aa6f290db50242df945943fc47b05Brian Paul      /* read the source image as RGBA/float */
148e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = tmpImage;
14976e778dce59aa6f290db50242df945943fc47b05Brian Paul      for (row = 0; row < height; row++) {
150e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
151267fb178844d3f17503dd0f921791f3ab059c4e7Brian Paul                                 width, srcx, sy + row, p );
152612fc012934d9ec61972c3cfd914923937339611Brian Paul         p += width * 4;
153e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
154e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = tmpImage;
155e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
156e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
157e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      tmpImage = NULL;  /* silence compiler warnings */
158e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = NULL;
159e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
160e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
16147d88ef204b42a9220c6be3e98c92df9c9aa0860Brian Paul   ASSERT(width < SWRAST_MAX_WIDTH);
16276e778dce59aa6f290db50242df945943fc47b05Brian Paul
16376e778dce59aa6f290db50242df945943fc47b05Brian Paul   for (row = 0; row < height; row++, sy += stepy, dy += stepy) {
164f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian      GLvoid *rgba = span.array->attribs[FRAG_ATTRIB_COL0];
16576e778dce59aa6f290db50242df945943fc47b05Brian Paul
16676e778dce59aa6f290db50242df945943fc47b05Brian Paul      /* Get row/span of source pixels */
167e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (overlapping) {
168e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* get from buffered image */
169c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke         memcpy(rgba, p, width * sizeof(GLfloat) * 4);
170612fc012934d9ec61972c3cfd914923937339611Brian Paul         p += width * 4;
171e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
172e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
173e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* get from framebuffer */
174e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
175267fb178844d3f17503dd0f921791f3ab059c4e7Brian Paul                                 width, srcx, sy, rgba );
176e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
177e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
178e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (transferOps) {
17976e778dce59aa6f290db50242df945943fc47b05Brian Paul         _mesa_apply_rgba_transfer_ops(ctx, transferOps, width,
18076e778dce59aa6f290db50242df945943fc47b05Brian Paul                                       (GLfloat (*)[4]) rgba);
181e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
182e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1836e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul      /* Write color span */
18476e778dce59aa6f290db50242df945943fc47b05Brian Paul      span.x = destx;
18576e778dce59aa6f290db50242df945943fc47b05Brian Paul      span.y = dy;
18676e778dce59aa6f290db50242df945943fc47b05Brian Paul      span.end = width;
18776e778dce59aa6f290db50242df945943fc47b05Brian Paul      span.array->ChanType = GL_FLOAT;
18876e778dce59aa6f290db50242df945943fc47b05Brian Paul      if (zoom) {
18976e778dce59aa6f290db50242df945943fc47b05Brian Paul         _swrast_write_zoomed_rgba_span(ctx, destx, desty, &span, rgba);
190e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
191e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
19276e778dce59aa6f290db50242df945943fc47b05Brian Paul         _swrast_write_rgba_span(ctx, &span);
193e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
194e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
195e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
19676e778dce59aa6f290db50242df945943fc47b05Brian Paul   span.array->ChanType = CHAN_TYPE; /* restore */
19776e778dce59aa6f290db50242df945943fc47b05Brian Paul
198e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (overlapping)
19932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      free(tmpImage);
200e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
201e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
202e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
2030c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul/**
2040c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul * Convert floating point Z values to integer Z values with pixel transfer's
2050c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul * Z scale and bias.
2060c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul */
2070c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paulstatic void
208f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergscale_and_bias_z(struct gl_context *ctx, GLuint width,
2090c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul                 const GLfloat depth[], GLuint z[])
2100c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul{
2110c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul   const GLuint depthMax = ctx->DrawBuffer->_DepthMax;
2120c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul   GLuint i;
2130c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul
2140c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul   if (depthMax <= 0xffffff &&
2150c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul       ctx->Pixel.DepthScale == 1.0 &&
2160c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul       ctx->Pixel.DepthBias == 0.0) {
2170c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      /* no scale or bias and no clamping and no worry of overflow */
2180c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      const GLfloat depthMaxF = ctx->DrawBuffer->_DepthMaxF;
2190c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      for (i = 0; i < width; i++) {
2200c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul         z[i] = (GLuint) (depth[i] * depthMaxF);
2210c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      }
2220c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul   }
2230c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul   else {
2240c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      /* need to be careful with overflow */
2250c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      const GLdouble depthMaxF = ctx->DrawBuffer->_DepthMaxF;
2260c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      for (i = 0; i < width; i++) {
2270c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul         GLdouble d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
2280c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul         d = CLAMP(d, 0.0, 1.0) * depthMaxF;
2290c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul         if (d >= depthMaxF)
2300c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul            z[i] = depthMax;
2310c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul         else
2320c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul            z[i] = (GLuint) d;
2330c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      }
2340c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul   }
2350c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul}
2360c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul
2370c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul
238e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
239e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
240e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * TODO: Optimize!!!!
241e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
2426e179ad9efe2b9febec6411704b7b08f769c434fBrian Paulstatic void
243f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergcopy_depth_pixels( struct gl_context *ctx, GLint srcx, GLint srcy,
2446e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul                   GLint width, GLint height,
2456e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul                   GLint destx, GLint desty )
246e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
247f1e2826856d7df00d0e98106b93ddab51b26ff04Brian Paul   struct gl_framebuffer *fb = ctx->ReadBuffer;
248e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul   struct gl_renderbuffer *readRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
249837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   GLfloat *p, *tmpImage, *depth;
250e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLint sy, dy, stepy;
2510c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul   GLint j;
252e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
253e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLint overlapping;
254cdb27e8242215271364602995d85607cfc06d441Brian Paul   SWspan span;
2552a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
256e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (!readRb) {
257e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* no readbuffer - OK */
258e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      return;
259e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
260e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
261f4b103dc993491355ec3e3640d9cb060138175c2Brian   INIT_SPAN(span, GL_BITMAP);
2629e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian   _swrast_span_default_attribs(ctx, &span);
263f4b103dc993491355ec3e3640d9cb060138175c2Brian   span.arrayMask = SPAN_Z;
264e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
265d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian   if (ctx->DrawBuffer == ctx->ReadBuffer) {
266d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian      overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
267d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian                                    ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
268d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian   }
269d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian   else {
270d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian      overlapping = GL_FALSE;
271d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian   }
272d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian
273e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Determine if copy should be bottom-to-top or top-to-bottom */
274d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian   if (!overlapping && srcy < desty) {
275e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* top-down  max-to-min */
276e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      sy = srcy + height - 1;
277e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      dy = desty + height - 1;
278e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      stepy = -1;
279e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
280e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
281e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* bottom-up  min-to-max */
282e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      sy = srcy;
283e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      dy = desty;
284e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      stepy = 1;
285e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
286e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
287e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (overlapping) {
288e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      GLint ssy = sy;
28932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      tmpImage = (GLfloat *) malloc(width * height * sizeof(GLfloat));
290e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (!tmpImage) {
29108836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul         _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
292e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         return;
293e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
294e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = tmpImage;
295e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      for (j = 0; j < height; j++, ssy += stepy) {
296e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         _swrast_read_depth_span_float(ctx, readRb, width, srcx, ssy, p);
297e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         p += width;
298e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
299e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = tmpImage;
300e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
301e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
302e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      tmpImage = NULL;  /* silence compiler warning */
303e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = NULL;
304e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
305e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
306837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   depth = (GLfloat *) malloc(width * sizeof(GLfloat));
307837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   if (!depth) {
308837b55517ecc1964205e1eb10578b146529abd0bBrian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels()");
309837b55517ecc1964205e1eb10578b146529abd0bBrian Paul      goto end;
310837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   }
311837b55517ecc1964205e1eb10578b146529abd0bBrian Paul
312e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
3136e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul      /* get depth values */
314e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (overlapping) {
315c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke         memcpy(depth, p, width * sizeof(GLfloat));
316e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         p += width;
317e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
318e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
319e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         _swrast_read_depth_span_float(ctx, readRb, width, srcx, sy, depth);
320e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
321e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3226e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul      /* apply scale and bias */
3230c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      scale_and_bias_z(ctx, width, depth, span.array->z);
324e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3256e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul      /* write depth values */
32677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      span.x = destx;
32777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      span.y = dy;
32877df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      span.end = width;
329e7e748cd04f5f014a1e4d8837ee7590d68115768Ian Romanick      if (zoom)
330e7e748cd04f5f014a1e4d8837ee7590d68115768Ian Romanick         _swrast_write_zoomed_depth_span(ctx, destx, desty, &span);
331e7e748cd04f5f014a1e4d8837ee7590d68115768Ian Romanick      else
332e7e748cd04f5f014a1e4d8837ee7590d68115768Ian Romanick         _swrast_write_rgba_span(ctx, &span);
333e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
334e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
335837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   free(depth);
336837b55517ecc1964205e1eb10578b146529abd0bBrian Paul
337837b55517ecc1964205e1eb10578b146529abd0bBrian Paulend:
33847cf442c1164b6b406117fccfb8b564602741ee3Brian Paul   if (overlapping)
33932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      free(tmpImage);
340e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
341e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
342e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
343e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3446e179ad9efe2b9febec6411704b7b08f769c434fBrian Paulstatic void
345f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergcopy_stencil_pixels( struct gl_context *ctx, GLint srcx, GLint srcy,
3466e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul                     GLint width, GLint height,
3476e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul                     GLint destx, GLint desty )
348e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
349f1e2826856d7df00d0e98106b93ddab51b26ff04Brian Paul   struct gl_framebuffer *fb = ctx->ReadBuffer;
350e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
351e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLint sy, dy, stepy;
352e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLint j;
353837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   GLubyte *p, *tmpImage, *stencil;
354e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
355e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLint overlapping;
356e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
357e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (!rb) {
358e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* no readbuffer - OK */
359e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      return;
360e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
361e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
362d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian   if (ctx->DrawBuffer == ctx->ReadBuffer) {
363d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian      overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
364d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian                                    ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
365d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian   }
366d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian   else {
367d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian      overlapping = GL_FALSE;
368d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian   }
369d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian
370e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Determine if copy should be bottom-to-top or top-to-bottom */
371d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian   if (!overlapping && srcy < desty) {
372e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* top-down  max-to-min */
373e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      sy = srcy + height - 1;
374e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      dy = desty + height - 1;
375e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      stepy = -1;
376e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
377e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
378e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* bottom-up  min-to-max */
379e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      sy = srcy;
380e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      dy = desty;
381e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      stepy = 1;
382e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
383e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
384e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (overlapping) {
385e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      GLint ssy = sy;
3866d68855df133bdd4891e8aa428787b520739e0feBrian Paul      tmpImage = (GLubyte *) malloc(width * height * sizeof(GLubyte));
387e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (!tmpImage) {
38808836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul         _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
389e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         return;
390e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
391e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = tmpImage;
392e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      for (j = 0; j < height; j++, ssy += stepy) {
393e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         _swrast_read_stencil_span( ctx, rb, width, srcx, ssy, p );
394e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         p += width;
395e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
396e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = tmpImage;
397e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
398e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
399e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      tmpImage = NULL;  /* silence compiler warning */
400e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = NULL;
401e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
402e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
403837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   stencil = (GLubyte *) malloc(width * sizeof(GLubyte));
404837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   if (!stencil) {
405837b55517ecc1964205e1eb10578b146529abd0bBrian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels()");
406837b55517ecc1964205e1eb10578b146529abd0bBrian Paul      goto end;
407837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   }
408e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
409837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
4106e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul      /* Get stencil values */
411e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (overlapping) {
4126d68855df133bdd4891e8aa428787b520739e0feBrian Paul         memcpy(stencil, p, width * sizeof(GLubyte));
413e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         p += width;
414e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
415e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
416e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         _swrast_read_stencil_span( ctx, rb, width, srcx, sy, stencil );
417e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
418e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
4195b0edff412f45fe64bd42fb481adeda7d34b0fa8Brian Paul      _mesa_apply_stencil_transfer_ops(ctx, width, stencil);
420e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
4216e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul      /* Write stencil values */
422e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (zoom) {
4238d0edf015d82a705796389890f6fe9b32e19414cBrian Paul         _swrast_write_zoomed_stencil_span(ctx, destx, desty, width,
4248d0edf015d82a705796389890f6fe9b32e19414cBrian Paul                                           destx, dy, stencil);
425e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
426e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
42745bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_write_stencil_span( ctx, width, destx, dy, stencil );
428e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
429e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
430e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
431837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   free(stencil);
432837b55517ecc1964205e1eb10578b146529abd0bBrian Paul
433837b55517ecc1964205e1eb10578b146529abd0bBrian Paulend:
434e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (overlapping)
43532f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      free(tmpImage);
436e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
437e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
438e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
439b2404b132dd7fc1058851d56414f9c1be17f0a2fBrian Paul/**
440fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt * Try to do a fast 1:1 blit with memcpy.
44189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul * \return GL_TRUE if successful, GL_FALSE otherwise.
44276e778dce59aa6f290db50242df945943fc47b05Brian Paul */
443fb5252a3518dadd51e88e87382e6510998e9e2f4Eric AnholtGLboolean
444fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholtswrast_fast_copy_pixels(struct gl_context *ctx,
445fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt			GLint srcX, GLint srcY, GLsizei width, GLsizei height,
446fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt			GLint dstX, GLint dstY, GLenum type)
44776e778dce59aa6f290db50242df945943fc47b05Brian Paul{
44876e778dce59aa6f290db50242df945943fc47b05Brian Paul   struct gl_framebuffer *srcFb = ctx->ReadBuffer;
44976e778dce59aa6f290db50242df945943fc47b05Brian Paul   struct gl_framebuffer *dstFb = ctx->DrawBuffer;
45076e778dce59aa6f290db50242df945943fc47b05Brian Paul   struct gl_renderbuffer *srcRb, *dstRb;
45189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   GLint row;
45289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   GLuint pixelBytes, widthInBytes;
45389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   GLubyte *srcMap, *dstMap;
45489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   GLint srcRowStride, dstRowStride;
45576e778dce59aa6f290db50242df945943fc47b05Brian Paul
45676e778dce59aa6f290db50242df945943fc47b05Brian Paul   if (type == GL_COLOR) {
457ff73c783cc47361ff0dd819c82d067b4b85870ddBrian      if (dstFb->_NumColorDrawBuffers != 1)
45876e778dce59aa6f290db50242df945943fc47b05Brian Paul         return GL_FALSE;
45976e778dce59aa6f290db50242df945943fc47b05Brian Paul      srcRb = srcFb->_ColorReadBuffer;
460ff73c783cc47361ff0dd819c82d067b4b85870ddBrian      dstRb = dstFb->_ColorDrawBuffers[0];
46176e778dce59aa6f290db50242df945943fc47b05Brian Paul   }
46276e778dce59aa6f290db50242df945943fc47b05Brian Paul   else if (type == GL_STENCIL) {
463e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul      srcRb = srcFb->Attachment[BUFFER_STENCIL].Renderbuffer;
464e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul      dstRb = dstFb->Attachment[BUFFER_STENCIL].Renderbuffer;
46576e778dce59aa6f290db50242df945943fc47b05Brian Paul   }
46676e778dce59aa6f290db50242df945943fc47b05Brian Paul   else if (type == GL_DEPTH) {
467e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul      srcRb = srcFb->Attachment[BUFFER_DEPTH].Renderbuffer;
468e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul      dstRb = dstFb->Attachment[BUFFER_DEPTH].Renderbuffer;
46976e778dce59aa6f290db50242df945943fc47b05Brian Paul   }
470ec9bbac7c7f42261de9df6f4029d7e051ae9225cBrian Paul   else {
471ec9bbac7c7f42261de9df6f4029d7e051ae9225cBrian Paul      ASSERT(type == GL_DEPTH_STENCIL_EXT);
47276e778dce59aa6f290db50242df945943fc47b05Brian Paul      /* XXX correct? */
47376e778dce59aa6f290db50242df945943fc47b05Brian Paul      srcRb = srcFb->Attachment[BUFFER_DEPTH].Renderbuffer;
47476e778dce59aa6f290db50242df945943fc47b05Brian Paul      dstRb = dstFb->Attachment[BUFFER_DEPTH].Renderbuffer;
47576e778dce59aa6f290db50242df945943fc47b05Brian Paul   }
47676e778dce59aa6f290db50242df945943fc47b05Brian Paul
47789fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   /* src and dst renderbuffers must be same format */
47889fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   if (!srcRb || !dstRb || srcRb->Format != dstRb->Format) {
47976e778dce59aa6f290db50242df945943fc47b05Brian Paul      return GL_FALSE;
48076e778dce59aa6f290db50242df945943fc47b05Brian Paul   }
48176e778dce59aa6f290db50242df945943fc47b05Brian Paul
482e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul   if (type == GL_STENCIL || type == GL_DEPTH_COMPONENT) {
483e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul      /* can't handle packed depth+stencil here */
484e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul      if (_mesa_is_format_packed_depth_stencil(srcRb->Format) ||
485e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul          _mesa_is_format_packed_depth_stencil(dstRb->Format))
486e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul         return GL_FALSE;
487e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul   }
488e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul   else if (type == GL_DEPTH_STENCIL) {
489e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul      /* can't handle separate depth/stencil buffers */
490e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul      if (srcRb != srcFb->Attachment[BUFFER_STENCIL].Renderbuffer ||
491e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul          dstRb != dstFb->Attachment[BUFFER_STENCIL].Renderbuffer)
492e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul         return GL_FALSE;
493e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul   }
494e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul
49576e778dce59aa6f290db50242df945943fc47b05Brian Paul   /* clipping not supported */
49618d1fdebebcb52e7fcf50e62c4c02862d173af51Brian   if (srcX < 0 || srcX + width > (GLint) srcFb->Width ||
49718d1fdebebcb52e7fcf50e62c4c02862d173af51Brian       srcY < 0 || srcY + height > (GLint) srcFb->Height ||
49876e778dce59aa6f290db50242df945943fc47b05Brian Paul       dstX < dstFb->_Xmin || dstX + width > dstFb->_Xmax ||
49976e778dce59aa6f290db50242df945943fc47b05Brian Paul       dstY < dstFb->_Ymin || dstY + height > dstFb->_Ymax) {
50076e778dce59aa6f290db50242df945943fc47b05Brian Paul      return GL_FALSE;
50176e778dce59aa6f290db50242df945943fc47b05Brian Paul   }
50276e778dce59aa6f290db50242df945943fc47b05Brian Paul
50389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   pixelBytes = _mesa_get_format_bytes(srcRb->Format);
50489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   widthInBytes = width * pixelBytes;
50589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul
50689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   if (srcRb == dstRb) {
50789fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      /* map whole buffer for read/write */
50889fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      /* XXX we could be clever and just map the union region of the
50989fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul       * source and dest rects.
51089fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul       */
51189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      GLubyte *map;
51289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      GLint rowStride;
51389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul
51489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      ctx->Driver.MapRenderbuffer(ctx, srcRb, 0, 0,
51589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul                                  srcRb->Width, srcRb->Height,
51689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul                                  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
51789fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul                                  &map, &rowStride);
51838c6f1e6caf097c0aefc7a9b161e9da3d5235ea9Eric Anholt      if (!map) {
51989fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
52089fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         return GL_TRUE; /* don't retry with slow path */
52189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      }
52289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul
52389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      srcMap = map + srcY * rowStride + srcX * pixelBytes;
52489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      dstMap = map + dstY * rowStride + dstX * pixelBytes;
52589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul
52689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      /* this handles overlapping copies */
52789fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      if (srcY < dstY) {
52889fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         /* copy in reverse (top->down) order */
52989fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         srcMap += rowStride * (height - 1);
53089fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         dstMap += rowStride * (height - 1);
53189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         srcRowStride = -rowStride;
53289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         dstRowStride = -rowStride;
53389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      }
53489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      else {
53589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         /* copy in normal (bottom->up) order */
53689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         srcRowStride = rowStride;
53789fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         dstRowStride = rowStride;
53889fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      }
53976e778dce59aa6f290db50242df945943fc47b05Brian Paul   }
54076e778dce59aa6f290db50242df945943fc47b05Brian Paul   else {
54189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      /* different src/dst buffers */
54289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      ctx->Driver.MapRenderbuffer(ctx, srcRb, srcX, srcY,
54389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul                                  width, height,
54489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul                                  GL_MAP_READ_BIT, &srcMap, &srcRowStride);
54589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      if (!srcMap) {
54689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
54789fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         return GL_TRUE; /* don't retry with slow path */
54889fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      }
54989fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      ctx->Driver.MapRenderbuffer(ctx, dstRb, dstX, dstY,
55089fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul                                  width, height,
55189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul                                  GL_MAP_WRITE_BIT, &dstMap, &dstRowStride);
55289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      if (!dstMap) {
55389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         ctx->Driver.UnmapRenderbuffer(ctx, srcRb);
55489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
55589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         return GL_TRUE; /* don't retry with slow path */
55689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      }
55724e648490921a386fc3f65d1b1ed330067a4bb25Brian Paul   }
55824e648490921a386fc3f65d1b1ed330067a4bb25Brian Paul
55976e778dce59aa6f290db50242df945943fc47b05Brian Paul   for (row = 0; row < height; row++) {
56089fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      /* memmove() in case of overlap */
56189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      memmove(dstMap, srcMap, widthInBytes);
56289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      dstMap += dstRowStride;
56389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      srcMap += srcRowStride;
56476e778dce59aa6f290db50242df945943fc47b05Brian Paul   }
56576e778dce59aa6f290db50242df945943fc47b05Brian Paul
56689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   ctx->Driver.UnmapRenderbuffer(ctx, srcRb);
56789fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   if (dstRb != srcRb) {
56889fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      ctx->Driver.UnmapRenderbuffer(ctx, dstRb);
56989fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   }
57024e648490921a386fc3f65d1b1ed330067a4bb25Brian Paul
57176e778dce59aa6f290db50242df945943fc47b05Brian Paul   return GL_TRUE;
57276e778dce59aa6f290db50242df945943fc47b05Brian Paul}
57376e778dce59aa6f290db50242df945943fc47b05Brian Paul
57476e778dce59aa6f290db50242df945943fc47b05Brian Paul
57599796464c5f0fdb463c31a0e99b0896089b8bd80Brian Paul/**
5760ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul * Find/map the renderbuffer that we'll be reading from.
5770ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul * The swrast_render_start() function only maps the drawing buffers,
5780ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul * not the read buffer.
5790ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul */
5800ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paulstatic struct gl_renderbuffer *
5810ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paulmap_readbuffer(struct gl_context *ctx, GLenum type)
5820ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul{
5830ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   struct gl_framebuffer *fb = ctx->ReadBuffer;
5840ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   struct gl_renderbuffer *rb;
5850c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul   struct swrast_renderbuffer *srb;
5860ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul
5870ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   switch (type) {
5880ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   case GL_COLOR:
5890ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      rb = fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;
5900ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      break;
5910ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   case GL_DEPTH:
5920ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   case GL_DEPTH_STENCIL:
5930ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
5940ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      break;
5950ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   case GL_STENCIL:
5960ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
5970ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      break;
5980ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   default:
5990ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      return NULL;
6000ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   }
6010ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul
6020c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul   srb = swrast_renderbuffer(rb);
6030c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul
6040c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul   if (!srb || srb->Map) {
6050ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      /* no buffer, or buffer is mapped already, we're done */
6060ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      return NULL;
6070ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   }
6080ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul
6090ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   ctx->Driver.MapRenderbuffer(ctx, rb,
6100ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul                               0, 0, rb->Width, rb->Height,
6110ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul                               GL_MAP_READ_BIT,
6120c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul                               &srb->Map, &srb->RowStride);
6130ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul
6140ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   return rb;
6150ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul}
6160ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul
6170ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul
6180ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul/**
61999796464c5f0fdb463c31a0e99b0896089b8bd80Brian Paul * Do software-based glCopyPixels.
62099796464c5f0fdb463c31a0e99b0896089b8bd80Brian Paul * By time we get here, all parameters will have been error-checked.
62199796464c5f0fdb463c31a0e99b0896089b8bd80Brian Paul */
622e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellvoid
623f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_CopyPixels( struct gl_context *ctx,
624e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell		    GLint srcx, GLint srcy, GLsizei width, GLsizei height,
62599796464c5f0fdb463c31a0e99b0896089b8bd80Brian Paul		    GLint destx, GLint desty, GLenum type )
626e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
627709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
6280ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   struct gl_renderbuffer *rb;
629709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell
630ab26682eb4db0dbe160b13f1e320ec9164c3afc5Brian Paul   if (!_mesa_check_conditional_render(ctx))
631ab26682eb4db0dbe160b13f1e320ec9164c3afc5Brian Paul      return; /* don't copy */
632ab26682eb4db0dbe160b13f1e320ec9164c3afc5Brian Paul
633709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell   if (swrast->NewState)
634cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      _swrast_validate_derived( ctx );
635cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell
636cedbfc0050af7391b6c8ed54abaa60898208f99dEric Anholt   if (!(SWRAST_CONTEXT(ctx)->_RasterMask != 0x0 ||
637cedbfc0050af7391b6c8ed54abaa60898208f99dEric Anholt	 ctx->Pixel.ZoomX != 1.0F ||
638cedbfc0050af7391b6c8ed54abaa60898208f99dEric Anholt	 ctx->Pixel.ZoomY != 1.0F ||
639cedbfc0050af7391b6c8ed54abaa60898208f99dEric Anholt	 ctx->_ImageTransferState) &&
640fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt       swrast_fast_copy_pixels(ctx, srcx, srcy, width, height, destx, desty,
641fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt			       type)) {
64289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      /* all done */
64389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      return;
64489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   }
64589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul
64689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   swrast_render_start(ctx);
6470ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   rb = map_readbuffer(ctx, type);
64889fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul
64989fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   switch (type) {
65089fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   case GL_COLOR:
65189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      copy_rgba_pixels( ctx, srcx, srcy, width, height, destx, desty );
65289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      break;
65389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   case GL_DEPTH:
65489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      copy_depth_pixels( ctx, srcx, srcy, width, height, destx, desty );
65589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      break;
65689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   case GL_STENCIL:
65789fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      copy_stencil_pixels( ctx, srcx, srcy, width, height, destx, desty );
65889fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      break;
65989fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   case GL_DEPTH_STENCIL_EXT:
660826f36b1d8ae3881e6095d905fd10a7070742098Brian Paul      /* Copy buffers separately (if the fast copy path wasn't taken) */
661826f36b1d8ae3881e6095d905fd10a7070742098Brian Paul      copy_depth_pixels(ctx, srcx, srcy, width, height, destx, desty);
662826f36b1d8ae3881e6095d905fd10a7070742098Brian Paul      copy_stencil_pixels(ctx, srcx, srcy, width, height, destx, desty);
66389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      break;
66489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   default:
66589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      _mesa_problem(ctx, "unexpected type in _swrast_CopyPixels");
666e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
667709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell
6682d5b86be25a7ccb729e746aa5e1bdd537d76df68Brian Paul   swrast_render_finish(ctx);
6690ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul
6700ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   if (rb) {
6710c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul      struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
6720ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      ctx->Driver.UnmapRenderbuffer(ctx, rb);
6730c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul      srb->Map = NULL;
6740ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   }
675e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
676