1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library
322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
4d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
6e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
7e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"),
8e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation
9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the
11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions:
1222144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
13e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included
14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software.
1522144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes *
16e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
193d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
203d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
213d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
223d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * OTHER DEALINGS IN THE SOFTWARE.
23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
25e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
26bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h"
27bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/context.h"
28ab26682eb4db0dbe160b13f1e320ec9164c3afc5Brian Paul#include "main/condrender.h"
29bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h"
30ca21c9ab28df24ef015ead28df1dcccd90387df6Anuj Phogat#include "main/blit.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{
5504aa8b58a09e3b415916fa569111c1f76d07a8d5Matt Turner   if (zoomX == 1.0F && zoomY == 1.0F) {
56ca21c9ab28df24ef015ead28df1dcccd90387df6Anuj Phogat      return _mesa_regions_overlap(srcx, srcy, srcx + width, srcy + height,
57ca21c9ab28df24ef015ead28df1dcccd90387df6Anuj Phogat                                   dstx, dsty, dstx + width, dsty + height);
58e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
59e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
60dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      /* add one pixel of slop when zooming, just to be safe */
61032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian Paul      if (srcx > (dstx + ((zoomX > 0.0F) ? (width * zoomX + 1.0F) : 0.0F))) {
62032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian Paul         /* src is completely right of dest */
63032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian Paul         return GL_FALSE;
64032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian Paul      }
65032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian Paul      else if (srcx + width + 1.0F < dstx + ((zoomX > 0.0F) ? 0.0F : (width * zoomX))) {
66032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian Paul         /* src is completely left of dest */
67dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul         return GL_FALSE;
68dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      }
69dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      else if ((srcy < dsty) && (srcy + height < dsty + (height * zoomY))) {
70032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian Paul         /* src is completely below dest */
71dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul         return GL_FALSE;
72dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      }
73dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      else if ((srcy > dsty) && (srcy + height > dsty + (height * zoomY))) {
74032707eeca2e6a0fd931ebd9ef4831bf30baf183Brian Paul         /* src is completely above dest */
75dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul         return GL_FALSE;
76dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      }
77dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      else {
78dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul         return GL_TRUE;
79dab76b4dc585f5833003ff3a0e53c256bf974d47Brian Paul      }
80e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
81e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
82e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
83e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
844923e1926ad7b7eb7de017eda8e7db64d357e5c8Brian Paul/**
85e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * RGBA copypixels
86e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
87e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellstatic void
88f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergcopy_rgba_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
89e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell                 GLint width, GLint height, GLint destx, GLint desty)
90e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
9176e778dce59aa6f290db50242df945943fc47b05Brian Paul   GLfloat *tmpImage, *p;
9276e778dce59aa6f290db50242df945943fc47b05Brian Paul   GLint sy, dy, stepy, row;
93e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
94e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLint overlapping;
95249b451d2068c781d29a6527e152b39d08b1c877Brian Paul   GLuint transferOps = ctx->_ImageTransferState;
96cdb27e8242215271364602995d85607cfc06d441Brian Paul   SWspan span;
972a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
98e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (!ctx->ReadBuffer->_ColorReadBuffer) {
99e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* no readbuffer - OK */
1009dca42a4a10acbf1980c0f2eafb3e28e11ca1bf3Brian Paul      return;
101e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
102e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
103d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul   if (ctx->DrawBuffer == ctx->ReadBuffer) {
104d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul      overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
105d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul                                    ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
106d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul   }
107d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul   else {
108d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul      overlapping = GL_FALSE;
109d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul   }
110d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul
111e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Determine if copy should be done bottom-to-top or top-to-bottom */
112d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul   if (!overlapping && srcy < desty) {
113e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* top-down  max-to-min */
114e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      sy = srcy + height - 1;
115e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      dy = desty + height - 1;
116e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      stepy = -1;
117e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
118e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
119e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* bottom-up  min-to-max */
120e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      sy = srcy;
121e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      dy = desty;
122e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      stepy = 1;
123e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
124e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
125f4b103dc993491355ec3e3640d9cb060138175c2Brian Paul   INIT_SPAN(span, GL_BITMAP);
1269e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian Paul   _swrast_span_default_attribs(ctx, &span);
127f4b103dc993491355ec3e3640d9cb060138175c2Brian Paul   span.arrayMask = SPAN_RGBA;
128eed6baf7621fa94e7888f8079b155fc67a08540cPaul Berry   span.arrayAttribs = VARYING_BIT_COL0; /* we'll fill in COL0 attrib values */
1292a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
130e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (overlapping) {
1312b7a972e3f36bfcdc6fbe2b59d7ffdcde49c9405Matt Turner      tmpImage = malloc(width * height * sizeof(GLfloat) * 4);
132e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (!tmpImage) {
13308836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul         _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
1349dca42a4a10acbf1980c0f2eafb3e28e11ca1bf3Brian Paul         return;
135e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
13676e778dce59aa6f290db50242df945943fc47b05Brian Paul      /* read the source image as RGBA/float */
137e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = tmpImage;
13876e778dce59aa6f290db50242df945943fc47b05Brian Paul      for (row = 0; row < height; row++) {
139e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
140267fb178844d3f17503dd0f921791f3ab059c4e7Brian Paul                                 width, srcx, sy + row, p );
141612fc012934d9ec61972c3cfd914923937339611Brian Paul         p += width * 4;
142e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
143e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = tmpImage;
144e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
145e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
146e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      tmpImage = NULL;  /* silence compiler warnings */
147e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = NULL;
148e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
149e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
150bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner   assert(width < SWRAST_MAX_WIDTH);
15176e778dce59aa6f290db50242df945943fc47b05Brian Paul
15276e778dce59aa6f290db50242df945943fc47b05Brian Paul   for (row = 0; row < height; row++, sy += stepy, dy += stepy) {
153eed6baf7621fa94e7888f8079b155fc67a08540cPaul Berry      GLvoid *rgba = span.array->attribs[VARYING_SLOT_COL0];
15476e778dce59aa6f290db50242df945943fc47b05Brian Paul
15576e778dce59aa6f290db50242df945943fc47b05Brian Paul      /* Get row/span of source pixels */
156e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (overlapping) {
157e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* get from buffered image */
158c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke         memcpy(rgba, p, width * sizeof(GLfloat) * 4);
159612fc012934d9ec61972c3cfd914923937339611Brian Paul         p += width * 4;
160e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
161e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
162e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         /* get from framebuffer */
163e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
164267fb178844d3f17503dd0f921791f3ab059c4e7Brian Paul                                 width, srcx, sy, rgba );
165e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
166e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
167e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (transferOps) {
16876e778dce59aa6f290db50242df945943fc47b05Brian Paul         _mesa_apply_rgba_transfer_ops(ctx, transferOps, width,
16976e778dce59aa6f290db50242df945943fc47b05Brian Paul                                       (GLfloat (*)[4]) rgba);
170e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
171e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1726e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul      /* Write color span */
17376e778dce59aa6f290db50242df945943fc47b05Brian Paul      span.x = destx;
17476e778dce59aa6f290db50242df945943fc47b05Brian Paul      span.y = dy;
17576e778dce59aa6f290db50242df945943fc47b05Brian Paul      span.end = width;
17676e778dce59aa6f290db50242df945943fc47b05Brian Paul      span.array->ChanType = GL_FLOAT;
17776e778dce59aa6f290db50242df945943fc47b05Brian Paul      if (zoom) {
17876e778dce59aa6f290db50242df945943fc47b05Brian Paul         _swrast_write_zoomed_rgba_span(ctx, destx, desty, &span, rgba);
179e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
180e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
18176e778dce59aa6f290db50242df945943fc47b05Brian Paul         _swrast_write_rgba_span(ctx, &span);
182e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
183e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
184e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
18576e778dce59aa6f290db50242df945943fc47b05Brian Paul   span.array->ChanType = CHAN_TYPE; /* restore */
18676e778dce59aa6f290db50242df945943fc47b05Brian Paul
187e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (overlapping)
18832f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      free(tmpImage);
189e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
190e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
191e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
1920c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul/**
1930c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul * Convert floating point Z values to integer Z values with pixel transfer's
1940c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul * Z scale and bias.
1950c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul */
1960c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paulstatic void
197f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergscale_and_bias_z(struct gl_context *ctx, GLuint width,
1980c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul                 const GLfloat depth[], GLuint z[])
1990c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul{
2000c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul   const GLuint depthMax = ctx->DrawBuffer->_DepthMax;
2010c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul   GLuint i;
2020c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul
2030c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul   if (depthMax <= 0xffffff &&
20404aa8b58a09e3b415916fa569111c1f76d07a8d5Matt Turner       ctx->Pixel.DepthScale == 1.0F &&
20504aa8b58a09e3b415916fa569111c1f76d07a8d5Matt Turner       ctx->Pixel.DepthBias == 0.0F) {
2060c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      /* no scale or bias and no clamping and no worry of overflow */
2070c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      const GLfloat depthMaxF = ctx->DrawBuffer->_DepthMaxF;
2080c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      for (i = 0; i < width; i++) {
2090c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul         z[i] = (GLuint) (depth[i] * depthMaxF);
2100c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      }
2110c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul   }
2120c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul   else {
2130c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      /* need to be careful with overflow */
2140c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      const GLdouble depthMaxF = ctx->DrawBuffer->_DepthMaxF;
2150c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      for (i = 0; i < width; i++) {
2160c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul         GLdouble d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
2170c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul         d = CLAMP(d, 0.0, 1.0) * depthMaxF;
2180c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul         if (d >= depthMaxF)
2190c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul            z[i] = depthMax;
2200c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul         else
2210c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul            z[i] = (GLuint) d;
2220c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      }
2230c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul   }
2240c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul}
2250c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul
2260c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul
227e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
228e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/*
229e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * TODO: Optimize!!!!
230e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */
2316e179ad9efe2b9febec6411704b7b08f769c434fBrian Paulstatic void
232f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergcopy_depth_pixels( struct gl_context *ctx, GLint srcx, GLint srcy,
2336e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul                   GLint width, GLint height,
2346e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul                   GLint destx, GLint desty )
235e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
236f1e2826856d7df00d0e98106b93ddab51b26ff04Brian Paul   struct gl_framebuffer *fb = ctx->ReadBuffer;
237e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul   struct gl_renderbuffer *readRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
238837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   GLfloat *p, *tmpImage, *depth;
239e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLint sy, dy, stepy;
2400c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul   GLint j;
241e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
242e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLint overlapping;
243cdb27e8242215271364602995d85607cfc06d441Brian Paul   SWspan span;
2442a182a98973edc9ecf2936b1288485bb2b3fa722Brian Paul
245e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (!readRb) {
246e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* no readbuffer - OK */
247e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      return;
248e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
249e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
250f4b103dc993491355ec3e3640d9cb060138175c2Brian Paul   INIT_SPAN(span, GL_BITMAP);
2519e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian Paul   _swrast_span_default_attribs(ctx, &span);
252f4b103dc993491355ec3e3640d9cb060138175c2Brian Paul   span.arrayMask = SPAN_Z;
253e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
254d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul   if (ctx->DrawBuffer == ctx->ReadBuffer) {
255d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul      overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
256d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul                                    ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
257d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul   }
258d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul   else {
259d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul      overlapping = GL_FALSE;
260d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul   }
261d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul
262e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Determine if copy should be bottom-to-top or top-to-bottom */
263d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul   if (!overlapping && srcy < desty) {
264e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* top-down  max-to-min */
265e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      sy = srcy + height - 1;
266e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      dy = desty + height - 1;
267e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      stepy = -1;
268e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
269e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
270e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* bottom-up  min-to-max */
271e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      sy = srcy;
272e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      dy = desty;
273e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      stepy = 1;
274e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
275e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
276e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (overlapping) {
277e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      GLint ssy = sy;
2782b7a972e3f36bfcdc6fbe2b59d7ffdcde49c9405Matt Turner      tmpImage = malloc(width * height * sizeof(GLfloat));
279e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (!tmpImage) {
28008836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul         _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
281e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         return;
282e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
283e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = tmpImage;
284e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      for (j = 0; j < height; j++, ssy += stepy) {
285e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         _swrast_read_depth_span_float(ctx, readRb, width, srcx, ssy, p);
286e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         p += width;
287e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
288e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = tmpImage;
289e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
290e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
291e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      tmpImage = NULL;  /* silence compiler warning */
292e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = NULL;
293e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
294e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
2952b7a972e3f36bfcdc6fbe2b59d7ffdcde49c9405Matt Turner   depth = malloc(width * sizeof(GLfloat));
296837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   if (!depth) {
297837b55517ecc1964205e1eb10578b146529abd0bBrian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels()");
298837b55517ecc1964205e1eb10578b146529abd0bBrian Paul      goto end;
299837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   }
300837b55517ecc1964205e1eb10578b146529abd0bBrian Paul
301e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
3026e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul      /* get depth values */
303e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (overlapping) {
304c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke         memcpy(depth, p, width * sizeof(GLfloat));
305e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         p += width;
306e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
307e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
308e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         _swrast_read_depth_span_float(ctx, readRb, width, srcx, sy, depth);
309e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
310e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3116e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul      /* apply scale and bias */
3120c7cbf0a7cbba93e4bcb2f0fdd0a7ea2ef4ebc94Brian Paul      scale_and_bias_z(ctx, width, depth, span.array->z);
313e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3146e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul      /* write depth values */
31577df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      span.x = destx;
31677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      span.y = dy;
31777df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul      span.end = width;
318e7e748cd04f5f014a1e4d8837ee7590d68115768Ian Romanick      if (zoom)
319e7e748cd04f5f014a1e4d8837ee7590d68115768Ian Romanick         _swrast_write_zoomed_depth_span(ctx, destx, desty, &span);
320e7e748cd04f5f014a1e4d8837ee7590d68115768Ian Romanick      else
321e7e748cd04f5f014a1e4d8837ee7590d68115768Ian Romanick         _swrast_write_rgba_span(ctx, &span);
322e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
323e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
324837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   free(depth);
325837b55517ecc1964205e1eb10578b146529abd0bBrian Paul
326837b55517ecc1964205e1eb10578b146529abd0bBrian Paulend:
32747cf442c1164b6b406117fccfb8b564602741ee3Brian Paul   if (overlapping)
32832f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      free(tmpImage);
329e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
330e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
331e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
332e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3336e179ad9efe2b9febec6411704b7b08f769c434fBrian Paulstatic void
334f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergcopy_stencil_pixels( struct gl_context *ctx, GLint srcx, GLint srcy,
3356e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul                     GLint width, GLint height,
3366e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul                     GLint destx, GLint desty )
337e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
338f1e2826856d7df00d0e98106b93ddab51b26ff04Brian Paul   struct gl_framebuffer *fb = ctx->ReadBuffer;
339e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
340e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLint sy, dy, stepy;
341e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLint j;
342837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   GLubyte *p, *tmpImage, *stencil;
343e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
344e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   GLint overlapping;
345e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
346e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   if (!rb) {
347e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      /* no readbuffer - OK */
348e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul      return;
349e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   }
350e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul
351d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul   if (ctx->DrawBuffer == ctx->ReadBuffer) {
352d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul      overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
353d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul                                    ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
354d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul   }
355d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul   else {
356d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul      overlapping = GL_FALSE;
357d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul   }
358d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul
359e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   /* Determine if copy should be bottom-to-top or top-to-bottom */
360d4dc57bb13386f4503000dc34c6bf67a8387fc9fBrian Paul   if (!overlapping && srcy < desty) {
361e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* top-down  max-to-min */
362e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      sy = srcy + height - 1;
363e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      dy = desty + height - 1;
364e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      stepy = -1;
365e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
366e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
367e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      /* bottom-up  min-to-max */
368e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      sy = srcy;
369e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      dy = desty;
370e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      stepy = 1;
371e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
372e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
373e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (overlapping) {
374e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      GLint ssy = sy;
3752b7a972e3f36bfcdc6fbe2b59d7ffdcde49c9405Matt Turner      tmpImage = malloc(width * height * sizeof(GLubyte));
376e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (!tmpImage) {
37708836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul         _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
378e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         return;
379e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
380e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = tmpImage;
381e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      for (j = 0; j < height; j++, ssy += stepy) {
382e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         _swrast_read_stencil_span( ctx, rb, width, srcx, ssy, p );
383e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         p += width;
384e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
385e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = tmpImage;
386e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
387e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   else {
388e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      tmpImage = NULL;  /* silence compiler warning */
389e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      p = NULL;
390e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
391e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
3922b7a972e3f36bfcdc6fbe2b59d7ffdcde49c9405Matt Turner   stencil = malloc(width * sizeof(GLubyte));
393837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   if (!stencil) {
394837b55517ecc1964205e1eb10578b146529abd0bBrian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels()");
395837b55517ecc1964205e1eb10578b146529abd0bBrian Paul      goto end;
396837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   }
397e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
398837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
3996e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul      /* Get stencil values */
400e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (overlapping) {
4016d68855df133bdd4891e8aa428787b520739e0feBrian Paul         memcpy(stencil, p, width * sizeof(GLubyte));
402e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell         p += width;
403e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
404e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
405e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul         _swrast_read_stencil_span( ctx, rb, width, srcx, sy, stencil );
406e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
407e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
4085b0edff412f45fe64bd42fb481adeda7d34b0fa8Brian Paul      _mesa_apply_stencil_transfer_ops(ctx, width, stencil);
409e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
4106e179ad9efe2b9febec6411704b7b08f769c434fBrian Paul      /* Write stencil values */
411e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      if (zoom) {
4128d0edf015d82a705796389890f6fe9b32e19414cBrian Paul         _swrast_write_zoomed_stencil_span(ctx, destx, desty, width,
4138d0edf015d82a705796389890f6fe9b32e19414cBrian Paul                                           destx, dy, stencil);
414e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
415e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      else {
41645bc887da226403f2c41077e40ca38b6f60f1359Brian Paul         _swrast_write_stencil_span( ctx, width, destx, dy, stencil );
417e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell      }
418e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
419e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
420837b55517ecc1964205e1eb10578b146529abd0bBrian Paul   free(stencil);
421837b55517ecc1964205e1eb10578b146529abd0bBrian Paul
422837b55517ecc1964205e1eb10578b146529abd0bBrian Paulend:
423e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   if (overlapping)
42432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg      free(tmpImage);
425e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
426e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
427e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell
428b2404b132dd7fc1058851d56414f9c1be17f0a2fBrian Paul/**
429fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt * Try to do a fast 1:1 blit with memcpy.
43089fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul * \return GL_TRUE if successful, GL_FALSE otherwise.
43176e778dce59aa6f290db50242df945943fc47b05Brian Paul */
432fb5252a3518dadd51e88e87382e6510998e9e2f4Eric AnholtGLboolean
433fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholtswrast_fast_copy_pixels(struct gl_context *ctx,
434e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                        struct gl_framebuffer *srcFb,
435e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                        struct gl_framebuffer *dstFb,
436e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                        GLint srcX, GLint srcY, GLsizei width, GLsizei height,
437e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                        GLint dstX, GLint dstY, GLenum type)
43876e778dce59aa6f290db50242df945943fc47b05Brian Paul{
43976e778dce59aa6f290db50242df945943fc47b05Brian Paul   struct gl_renderbuffer *srcRb, *dstRb;
44089fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   GLint row;
44189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   GLuint pixelBytes, widthInBytes;
44289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   GLubyte *srcMap, *dstMap;
44389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   GLint srcRowStride, dstRowStride;
44476e778dce59aa6f290db50242df945943fc47b05Brian Paul
44576e778dce59aa6f290db50242df945943fc47b05Brian Paul   if (type == GL_COLOR) {
446ff73c783cc47361ff0dd819c82d067b4b85870ddBrian Paul      if (dstFb->_NumColorDrawBuffers != 1)
44776e778dce59aa6f290db50242df945943fc47b05Brian Paul         return GL_FALSE;
44876e778dce59aa6f290db50242df945943fc47b05Brian Paul      srcRb = srcFb->_ColorReadBuffer;
449ff73c783cc47361ff0dd819c82d067b4b85870ddBrian Paul      dstRb = dstFb->_ColorDrawBuffers[0];
45076e778dce59aa6f290db50242df945943fc47b05Brian Paul   }
45176e778dce59aa6f290db50242df945943fc47b05Brian Paul   else if (type == GL_STENCIL) {
452e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul      srcRb = srcFb->Attachment[BUFFER_STENCIL].Renderbuffer;
453e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul      dstRb = dstFb->Attachment[BUFFER_STENCIL].Renderbuffer;
45476e778dce59aa6f290db50242df945943fc47b05Brian Paul   }
45576e778dce59aa6f290db50242df945943fc47b05Brian Paul   else if (type == GL_DEPTH) {
456e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul      srcRb = srcFb->Attachment[BUFFER_DEPTH].Renderbuffer;
457e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul      dstRb = dstFb->Attachment[BUFFER_DEPTH].Renderbuffer;
45876e778dce59aa6f290db50242df945943fc47b05Brian Paul   }
459ec9bbac7c7f42261de9df6f4029d7e051ae9225cBrian Paul   else {
460bfcdb843830bba0190e00e35e3c5c18c4bdb5de1Matt Turner      assert(type == GL_DEPTH_STENCIL_EXT);
46176e778dce59aa6f290db50242df945943fc47b05Brian Paul      /* XXX correct? */
46276e778dce59aa6f290db50242df945943fc47b05Brian Paul      srcRb = srcFb->Attachment[BUFFER_DEPTH].Renderbuffer;
46376e778dce59aa6f290db50242df945943fc47b05Brian Paul      dstRb = dstFb->Attachment[BUFFER_DEPTH].Renderbuffer;
46476e778dce59aa6f290db50242df945943fc47b05Brian Paul   }
46576e778dce59aa6f290db50242df945943fc47b05Brian Paul
46689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   /* src and dst renderbuffers must be same format */
46789fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   if (!srcRb || !dstRb || srcRb->Format != dstRb->Format) {
46876e778dce59aa6f290db50242df945943fc47b05Brian Paul      return GL_FALSE;
46976e778dce59aa6f290db50242df945943fc47b05Brian Paul   }
47076e778dce59aa6f290db50242df945943fc47b05Brian Paul
471e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul   if (type == GL_STENCIL || type == GL_DEPTH_COMPONENT) {
472e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul      /* can't handle packed depth+stencil here */
473e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul      if (_mesa_is_format_packed_depth_stencil(srcRb->Format) ||
474e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul          _mesa_is_format_packed_depth_stencil(dstRb->Format))
475e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul         return GL_FALSE;
476e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul   }
477e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul   else if (type == GL_DEPTH_STENCIL) {
478e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul      /* can't handle separate depth/stencil buffers */
479e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul      if (srcRb != srcFb->Attachment[BUFFER_STENCIL].Renderbuffer ||
480e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul          dstRb != dstFb->Attachment[BUFFER_STENCIL].Renderbuffer)
481e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul         return GL_FALSE;
482e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul   }
483e6c6b1c147f5079a1608234294e2b6cd29dd2a64Brian Paul
48476e778dce59aa6f290db50242df945943fc47b05Brian Paul   /* clipping not supported */
48518d1fdebebcb52e7fcf50e62c4c02862d173af51Brian Paul   if (srcX < 0 || srcX + width > (GLint) srcFb->Width ||
48618d1fdebebcb52e7fcf50e62c4c02862d173af51Brian Paul       srcY < 0 || srcY + height > (GLint) srcFb->Height ||
48776e778dce59aa6f290db50242df945943fc47b05Brian Paul       dstX < dstFb->_Xmin || dstX + width > dstFb->_Xmax ||
48876e778dce59aa6f290db50242df945943fc47b05Brian Paul       dstY < dstFb->_Ymin || dstY + height > dstFb->_Ymax) {
48976e778dce59aa6f290db50242df945943fc47b05Brian Paul      return GL_FALSE;
49076e778dce59aa6f290db50242df945943fc47b05Brian Paul   }
49176e778dce59aa6f290db50242df945943fc47b05Brian Paul
49289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   pixelBytes = _mesa_get_format_bytes(srcRb->Format);
49389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   widthInBytes = width * pixelBytes;
49489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul
49589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   if (srcRb == dstRb) {
49689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      /* map whole buffer for read/write */
49789fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      /* XXX we could be clever and just map the union region of the
49889fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul       * source and dest rects.
49989fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul       */
50089fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      GLubyte *map;
50189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      GLint rowStride;
50289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul
50389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      ctx->Driver.MapRenderbuffer(ctx, srcRb, 0, 0,
50489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul                                  srcRb->Width, srcRb->Height,
50589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul                                  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
50689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul                                  &map, &rowStride);
50738c6f1e6caf097c0aefc7a9b161e9da3d5235ea9Eric Anholt      if (!map) {
50889fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
50989fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         return GL_TRUE; /* don't retry with slow path */
51089fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      }
51189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul
51289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      srcMap = map + srcY * rowStride + srcX * pixelBytes;
51389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      dstMap = map + dstY * rowStride + dstX * pixelBytes;
51489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul
51589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      /* this handles overlapping copies */
51689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      if (srcY < dstY) {
51789fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         /* copy in reverse (top->down) order */
51889fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         srcMap += rowStride * (height - 1);
51989fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         dstMap += rowStride * (height - 1);
52089fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         srcRowStride = -rowStride;
52189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         dstRowStride = -rowStride;
52289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      }
52389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      else {
52489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         /* copy in normal (bottom->up) order */
52589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         srcRowStride = rowStride;
52689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         dstRowStride = rowStride;
52789fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      }
52876e778dce59aa6f290db50242df945943fc47b05Brian Paul   }
52976e778dce59aa6f290db50242df945943fc47b05Brian Paul   else {
53089fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      /* different src/dst buffers */
53189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      ctx->Driver.MapRenderbuffer(ctx, srcRb, srcX, srcY,
53289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul                                  width, height,
53389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul                                  GL_MAP_READ_BIT, &srcMap, &srcRowStride);
53489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      if (!srcMap) {
53589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
53689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         return GL_TRUE; /* don't retry with slow path */
53789fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      }
53889fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      ctx->Driver.MapRenderbuffer(ctx, dstRb, dstX, dstY,
53989fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul                                  width, height,
54089fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul                                  GL_MAP_WRITE_BIT, &dstMap, &dstRowStride);
54189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      if (!dstMap) {
54289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         ctx->Driver.UnmapRenderbuffer(ctx, srcRb);
54389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
54489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul         return GL_TRUE; /* don't retry with slow path */
54589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      }
54624e648490921a386fc3f65d1b1ed330067a4bb25Brian Paul   }
54724e648490921a386fc3f65d1b1ed330067a4bb25Brian Paul
54876e778dce59aa6f290db50242df945943fc47b05Brian Paul   for (row = 0; row < height; row++) {
54989fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      /* memmove() in case of overlap */
55089fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      memmove(dstMap, srcMap, widthInBytes);
55189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      dstMap += dstRowStride;
55289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      srcMap += srcRowStride;
55376e778dce59aa6f290db50242df945943fc47b05Brian Paul   }
55476e778dce59aa6f290db50242df945943fc47b05Brian Paul
55589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   ctx->Driver.UnmapRenderbuffer(ctx, srcRb);
55689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   if (dstRb != srcRb) {
55789fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      ctx->Driver.UnmapRenderbuffer(ctx, dstRb);
55889fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   }
55924e648490921a386fc3f65d1b1ed330067a4bb25Brian Paul
56076e778dce59aa6f290db50242df945943fc47b05Brian Paul   return GL_TRUE;
56176e778dce59aa6f290db50242df945943fc47b05Brian Paul}
56276e778dce59aa6f290db50242df945943fc47b05Brian Paul
56376e778dce59aa6f290db50242df945943fc47b05Brian Paul
56499796464c5f0fdb463c31a0e99b0896089b8bd80Brian Paul/**
5650ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul * Find/map the renderbuffer that we'll be reading from.
5660ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul * The swrast_render_start() function only maps the drawing buffers,
5670ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul * not the read buffer.
5680ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul */
5690ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paulstatic struct gl_renderbuffer *
5700ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paulmap_readbuffer(struct gl_context *ctx, GLenum type)
5710ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul{
5720ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   struct gl_framebuffer *fb = ctx->ReadBuffer;
5730ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   struct gl_renderbuffer *rb;
5740c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul   struct swrast_renderbuffer *srb;
5750ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul
5760ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   switch (type) {
5770ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   case GL_COLOR:
5780ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      rb = fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;
5790ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      break;
5800ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   case GL_DEPTH:
5810ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   case GL_DEPTH_STENCIL:
5820ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
5830ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      break;
5840ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   case GL_STENCIL:
5850ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
5860ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      break;
5870ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   default:
5880ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      return NULL;
5890ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   }
5900ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul
5910c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul   srb = swrast_renderbuffer(rb);
5920c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul
5930c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul   if (!srb || srb->Map) {
5940ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      /* no buffer, or buffer is mapped already, we're done */
5950ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      return NULL;
5960ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   }
5970ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul
5980ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   ctx->Driver.MapRenderbuffer(ctx, rb,
5990ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul                               0, 0, rb->Width, rb->Height,
6000ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul                               GL_MAP_READ_BIT,
6010c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul                               &srb->Map, &srb->RowStride);
6020ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul
6030ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   return rb;
6040ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul}
6050ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul
6060ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul
6070ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul/**
60899796464c5f0fdb463c31a0e99b0896089b8bd80Brian Paul * Do software-based glCopyPixels.
60999796464c5f0fdb463c31a0e99b0896089b8bd80Brian Paul * By time we get here, all parameters will have been error-checked.
61099796464c5f0fdb463c31a0e99b0896089b8bd80Brian Paul */
611e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwellvoid
612e9b86cb5d66867b66c6d453d7bd60bd56fe6587dLaura Ekstrand_swrast_CopyPixels(struct gl_context *ctx,
613e9b86cb5d66867b66c6d453d7bd60bd56fe6587dLaura Ekstrand                   GLint srcx, GLint srcy, GLsizei width, GLsizei height,
614e9b86cb5d66867b66c6d453d7bd60bd56fe6587dLaura Ekstrand                   GLint destx, GLint desty, GLenum type)
615e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell{
616709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell   SWcontext *swrast = SWRAST_CONTEXT(ctx);
6170ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   struct gl_renderbuffer *rb;
618709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell
619ab26682eb4db0dbe160b13f1e320ec9164c3afc5Brian Paul   if (!_mesa_check_conditional_render(ctx))
620ab26682eb4db0dbe160b13f1e320ec9164c3afc5Brian Paul      return; /* don't copy */
621ab26682eb4db0dbe160b13f1e320ec9164c3afc5Brian Paul
622709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell   if (swrast->NewState)
623cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell      _swrast_validate_derived( ctx );
624cd03ed4f54444d96e4e47cdb118a3dfd94d92bb0Keith Whitwell
625cedbfc0050af7391b6c8ed54abaa60898208f99dEric Anholt   if (!(SWRAST_CONTEXT(ctx)->_RasterMask != 0x0 ||
626e9b86cb5d66867b66c6d453d7bd60bd56fe6587dLaura Ekstrand       ctx->Pixel.ZoomX != 1.0F ||
627e9b86cb5d66867b66c6d453d7bd60bd56fe6587dLaura Ekstrand       ctx->Pixel.ZoomY != 1.0F ||
628e9b86cb5d66867b66c6d453d7bd60bd56fe6587dLaura Ekstrand       ctx->_ImageTransferState) &&
629e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand      swrast_fast_copy_pixels(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
630e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                              srcx, srcy, width, height, destx, desty,
631e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand                              type)) {
63289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      /* all done */
63389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      return;
63489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   }
63589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul
63689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   swrast_render_start(ctx);
6370ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   rb = map_readbuffer(ctx, type);
63889fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul
63989fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   switch (type) {
64089fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   case GL_COLOR:
64189fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      copy_rgba_pixels( ctx, srcx, srcy, width, height, destx, desty );
64289fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      break;
64389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   case GL_DEPTH:
64489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      copy_depth_pixels( ctx, srcx, srcy, width, height, destx, desty );
64589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      break;
64689fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   case GL_STENCIL:
64789fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      copy_stencil_pixels( ctx, srcx, srcy, width, height, destx, desty );
64889fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      break;
64989fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   case GL_DEPTH_STENCIL_EXT:
650826f36b1d8ae3881e6095d905fd10a7070742098Brian Paul      /* Copy buffers separately (if the fast copy path wasn't taken) */
651826f36b1d8ae3881e6095d905fd10a7070742098Brian Paul      copy_depth_pixels(ctx, srcx, srcy, width, height, destx, desty);
652826f36b1d8ae3881e6095d905fd10a7070742098Brian Paul      copy_stencil_pixels(ctx, srcx, srcy, width, height, destx, desty);
65389fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      break;
65489fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul   default:
65589fb81d521bdcd341a88d2bf54ae3d79ad232ccaBrian Paul      _mesa_problem(ctx, "unexpected type in _swrast_CopyPixels");
656e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell   }
657709892459922a32096fe9dd8261d0d92337bb02fKeith Whitwell
6582d5b86be25a7ccb729e746aa5e1bdd537d76df68Brian Paul   swrast_render_finish(ctx);
6590ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul
6600ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   if (rb) {
6610c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul      struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
6620ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul      ctx->Driver.UnmapRenderbuffer(ctx, rb);
6630c1862851f27c428a18ba5509636efcc2f0084f8Brian Paul      srb->Map = NULL;
6640ff817f200ef4cb4a5ab0d90eccfc83d0671fb65Brian Paul   }
665e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell}
666