readpix.c revision 848b8605
1/*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#include "glheader.h"
26#include "imports.h"
27#include "blend.h"
28#include "bufferobj.h"
29#include "context.h"
30#include "enums.h"
31#include "readpix.h"
32#include "framebuffer.h"
33#include "formats.h"
34#include "format_unpack.h"
35#include "image.h"
36#include "mtypes.h"
37#include "pack.h"
38#include "pbo.h"
39#include "state.h"
40#include "glformats.h"
41#include "fbobject.h"
42
43
44/**
45 * Return true if the conversion L=R+G+B is needed.
46 */
47static GLboolean
48need_rgb_to_luminance_conversion(mesa_format texFormat, GLenum format)
49{
50   GLenum baseTexFormat = _mesa_get_format_base_format(texFormat);
51
52   return (baseTexFormat == GL_RG ||
53           baseTexFormat == GL_RGB ||
54           baseTexFormat == GL_RGBA) &&
55          (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA);
56}
57
58
59/**
60 * Return transfer op flags for this ReadPixels operation.
61 */
62static GLbitfield
63get_readpixels_transfer_ops(const struct gl_context *ctx, mesa_format texFormat,
64                            GLenum format, GLenum type, GLboolean uses_blit)
65{
66   GLbitfield transferOps = ctx->_ImageTransferState;
67
68   if (format == GL_DEPTH_COMPONENT ||
69       format == GL_DEPTH_STENCIL ||
70       format == GL_STENCIL_INDEX) {
71      return 0;
72   }
73
74   /* Pixel transfer ops (scale, bias, table lookup) do not apply
75    * to integer formats.
76    */
77   if (_mesa_is_enum_format_integer(format)) {
78      return 0;
79   }
80
81   if (uses_blit) {
82      /* For blit-based ReadPixels packing, the clamping is done automatically
83       * unless the type is float. */
84      if (_mesa_get_clamp_read_color(ctx) &&
85          (type == GL_FLOAT || type == GL_HALF_FLOAT)) {
86         transferOps |= IMAGE_CLAMP_BIT;
87      }
88   }
89   else {
90      /* For CPU-based ReadPixels packing, the clamping must always be done
91       * for non-float types, */
92      if (_mesa_get_clamp_read_color(ctx) ||
93          (type != GL_FLOAT && type != GL_HALF_FLOAT)) {
94         transferOps |= IMAGE_CLAMP_BIT;
95      }
96   }
97
98   /* If the format is unsigned normalized, we can ignore clamping
99    * because the values are already in the range [0,1] so it won't
100    * have any effect anyway.
101    */
102   if (_mesa_get_format_datatype(texFormat) == GL_UNSIGNED_NORMALIZED &&
103       !need_rgb_to_luminance_conversion(texFormat, format)) {
104      transferOps &= ~IMAGE_CLAMP_BIT;
105   }
106
107   return transferOps;
108}
109
110
111/**
112 * Return true if memcpy cannot be used for ReadPixels.
113 *
114 * If uses_blit is true, the function returns true if a simple 3D engine blit
115 * cannot be used for ReadPixels packing.
116 *
117 * NOTE: This doesn't take swizzling and format conversions between
118 *       the readbuffer and the pixel pack buffer into account.
119 */
120GLboolean
121_mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format,
122                                 GLenum type, GLboolean uses_blit)
123{
124   struct gl_renderbuffer *rb =
125         _mesa_get_read_renderbuffer_for_format(ctx, format);
126   GLenum srcType;
127
128   ASSERT(rb);
129
130   /* There are different rules depending on the base format. */
131   switch (format) {
132   case GL_DEPTH_STENCIL:
133      return !_mesa_has_depthstencil_combined(ctx->ReadBuffer) ||
134             ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f ||
135             ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
136             ctx->Pixel.MapStencilFlag;
137
138   case GL_DEPTH_COMPONENT:
139      return ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f;
140
141   case GL_STENCIL_INDEX:
142      return ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
143             ctx->Pixel.MapStencilFlag;
144
145   default:
146      /* Color formats. */
147      if (need_rgb_to_luminance_conversion(rb->Format, format)) {
148         return GL_TRUE;
149      }
150
151      /* Conversion between signed and unsigned integers needs masking
152       * (it isn't just memcpy). */
153      srcType = _mesa_get_format_datatype(rb->Format);
154
155      if ((srcType == GL_INT &&
156           (type == GL_UNSIGNED_INT ||
157            type == GL_UNSIGNED_SHORT ||
158            type == GL_UNSIGNED_BYTE)) ||
159          (srcType == GL_UNSIGNED_INT &&
160           (type == GL_INT ||
161            type == GL_SHORT ||
162            type == GL_BYTE))) {
163         return GL_TRUE;
164      }
165
166      /* And finally, see if there are any transfer ops. */
167      return get_readpixels_transfer_ops(ctx, rb->Format, format, type,
168                                         uses_blit) != 0;
169   }
170   return GL_FALSE;
171}
172
173
174static GLboolean
175readpixels_can_use_memcpy(const struct gl_context *ctx, GLenum format, GLenum type,
176                          const struct gl_pixelstore_attrib *packing)
177{
178   struct gl_renderbuffer *rb =
179         _mesa_get_read_renderbuffer_for_format(ctx, format);
180
181   ASSERT(rb);
182
183   if (_mesa_readpixels_needs_slow_path(ctx, format, type, GL_FALSE)) {
184      return GL_FALSE;
185   }
186
187   /* The base internal format and the base Mesa format must match. */
188   if (rb->_BaseFormat != _mesa_get_format_base_format(rb->Format)) {
189      return GL_FALSE;
190   }
191
192   /* The Mesa format must match the input format and type. */
193   if (!_mesa_format_matches_format_and_type(rb->Format, format, type,
194                                             packing->SwapBytes)) {
195      return GL_FALSE;
196   }
197
198   return GL_TRUE;
199}
200
201
202static GLboolean
203readpixels_memcpy(struct gl_context *ctx,
204                  GLint x, GLint y,
205                  GLsizei width, GLsizei height,
206                  GLenum format, GLenum type,
207                  GLvoid *pixels,
208                  const struct gl_pixelstore_attrib *packing)
209{
210   struct gl_renderbuffer *rb =
211         _mesa_get_read_renderbuffer_for_format(ctx, format);
212   GLubyte *dst, *map;
213   int dstStride, stride, j, texelBytes;
214
215   /* Fail if memcpy cannot be used. */
216   if (!readpixels_can_use_memcpy(ctx, format, type, packing)) {
217      return GL_FALSE;
218   }
219
220   dstStride = _mesa_image_row_stride(packing, width, format, type);
221   dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
222					   format, type, 0, 0);
223
224   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
225			       &map, &stride);
226   if (!map) {
227      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
228      return GL_TRUE;  /* don't bother trying the slow path */
229   }
230
231   texelBytes = _mesa_get_format_bytes(rb->Format);
232
233   /* memcpy*/
234   for (j = 0; j < height; j++) {
235      memcpy(dst, map, width * texelBytes);
236      dst += dstStride;
237      map += stride;
238   }
239
240   ctx->Driver.UnmapRenderbuffer(ctx, rb);
241   return GL_TRUE;
242}
243
244
245/**
246 * Optimized path for conversion of depth values to GL_DEPTH_COMPONENT,
247 * GL_UNSIGNED_INT.
248 */
249static GLboolean
250read_uint_depth_pixels( struct gl_context *ctx,
251			GLint x, GLint y,
252			GLsizei width, GLsizei height,
253			GLenum type, GLvoid *pixels,
254			const struct gl_pixelstore_attrib *packing )
255{
256   struct gl_framebuffer *fb = ctx->ReadBuffer;
257   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
258   GLubyte *map, *dst;
259   int stride, dstStride, j;
260
261   if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0)
262      return GL_FALSE;
263
264   if (packing->SwapBytes)
265      return GL_FALSE;
266
267   if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED)
268      return GL_FALSE;
269
270   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
271			       &map, &stride);
272
273   if (!map) {
274      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
275      return GL_TRUE;  /* don't bother trying the slow path */
276   }
277
278   dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
279   dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
280					   GL_DEPTH_COMPONENT, type, 0, 0);
281
282   for (j = 0; j < height; j++) {
283      _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst);
284
285      map += stride;
286      dst += dstStride;
287   }
288   ctx->Driver.UnmapRenderbuffer(ctx, rb);
289
290   return GL_TRUE;
291}
292
293/**
294 * Read pixels for format=GL_DEPTH_COMPONENT.
295 */
296static void
297read_depth_pixels( struct gl_context *ctx,
298                   GLint x, GLint y,
299                   GLsizei width, GLsizei height,
300                   GLenum type, GLvoid *pixels,
301                   const struct gl_pixelstore_attrib *packing )
302{
303   struct gl_framebuffer *fb = ctx->ReadBuffer;
304   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
305   GLint j;
306   GLubyte *dst, *map;
307   int dstStride, stride;
308   GLfloat *depthValues;
309
310   if (!rb)
311      return;
312
313   /* clipping should have been done already */
314   ASSERT(x >= 0);
315   ASSERT(y >= 0);
316   ASSERT(x + width <= (GLint) rb->Width);
317   ASSERT(y + height <= (GLint) rb->Height);
318
319   if (type == GL_UNSIGNED_INT &&
320       read_uint_depth_pixels(ctx, x, y, width, height, type, pixels, packing)) {
321      return;
322   }
323
324   dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
325   dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
326					   GL_DEPTH_COMPONENT, type, 0, 0);
327
328   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
329			       &map, &stride);
330   if (!map) {
331      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
332      return;
333   }
334
335   depthValues = malloc(width * sizeof(GLfloat));
336
337   if (depthValues) {
338      /* General case (slower) */
339      for (j = 0; j < height; j++, y++) {
340         _mesa_unpack_float_z_row(rb->Format, width, map, depthValues);
341         _mesa_pack_depth_span(ctx, width, dst, type, depthValues, packing);
342
343         dst += dstStride;
344         map += stride;
345      }
346   }
347   else {
348      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
349   }
350
351   free(depthValues);
352
353   ctx->Driver.UnmapRenderbuffer(ctx, rb);
354}
355
356
357/**
358 * Read pixels for format=GL_STENCIL_INDEX.
359 */
360static void
361read_stencil_pixels( struct gl_context *ctx,
362                     GLint x, GLint y,
363                     GLsizei width, GLsizei height,
364                     GLenum type, GLvoid *pixels,
365                     const struct gl_pixelstore_attrib *packing )
366{
367   struct gl_framebuffer *fb = ctx->ReadBuffer;
368   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
369   GLint j;
370   GLubyte *map, *stencil;
371   GLint stride;
372
373   if (!rb)
374      return;
375
376   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
377			       &map, &stride);
378   if (!map) {
379      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
380      return;
381   }
382
383   stencil = malloc(width * sizeof(GLubyte));
384
385   if (stencil) {
386      /* process image row by row */
387      for (j = 0; j < height; j++) {
388         GLvoid *dest;
389
390         _mesa_unpack_ubyte_stencil_row(rb->Format, width, map, stencil);
391         dest = _mesa_image_address2d(packing, pixels, width, height,
392                                      GL_STENCIL_INDEX, type, j, 0);
393
394         _mesa_pack_stencil_span(ctx, width, type, dest, stencil, packing);
395
396         map += stride;
397      }
398   }
399   else {
400      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
401   }
402
403   free(stencil);
404
405   ctx->Driver.UnmapRenderbuffer(ctx, rb);
406}
407
408
409/**
410 * Try to do glReadPixels of RGBA data using swizzle.
411 * \return GL_TRUE if successful, GL_FALSE otherwise (use the slow path)
412 */
413static GLboolean
414read_rgba_pixels_swizzle(struct gl_context *ctx,
415                         GLint x, GLint y,
416                         GLsizei width, GLsizei height,
417                         GLenum format, GLenum type,
418                         GLvoid *pixels,
419                         const struct gl_pixelstore_attrib *packing)
420{
421   struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
422   GLubyte *dst, *map;
423   int dstStride, stride, j;
424   GLboolean swizzle_rb = GL_FALSE, copy_xrgb = GL_FALSE;
425
426   /* XXX we could check for other swizzle/special cases here as needed */
427   if (rb->Format == MESA_FORMAT_R8G8B8A8_UNORM &&
428       format == GL_BGRA &&
429       type == GL_UNSIGNED_INT_8_8_8_8_REV &&
430       !ctx->Pack.SwapBytes) {
431      swizzle_rb = GL_TRUE;
432   }
433   else if (rb->Format == MESA_FORMAT_B8G8R8X8_UNORM &&
434       format == GL_BGRA &&
435       type == GL_UNSIGNED_INT_8_8_8_8_REV &&
436       !ctx->Pack.SwapBytes) {
437      copy_xrgb = GL_TRUE;
438   }
439   else {
440      return GL_FALSE;
441   }
442
443   dstStride = _mesa_image_row_stride(packing, width, format, type);
444   dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
445					   format, type, 0, 0);
446
447   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
448			       &map, &stride);
449   if (!map) {
450      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
451      return GL_TRUE;  /* don't bother trying the slow path */
452   }
453
454   if (swizzle_rb) {
455      /* swap R/B */
456      for (j = 0; j < height; j++) {
457         int i;
458         for (i = 0; i < width; i++) {
459            GLuint *dst4 = (GLuint *) dst, *map4 = (GLuint *) map;
460            GLuint pixel = map4[i];
461            dst4[i] = (pixel & 0xff00ff00)
462                   | ((pixel & 0x00ff0000) >> 16)
463                   | ((pixel & 0x000000ff) << 16);
464         }
465         dst += dstStride;
466         map += stride;
467      }
468   } else if (copy_xrgb) {
469      /* convert xrgb -> argb */
470      for (j = 0; j < height; j++) {
471         GLuint *dst4 = (GLuint *) dst, *map4 = (GLuint *) map;
472         int i;
473         for (i = 0; i < width; i++) {
474            dst4[i] = map4[i] | 0xff000000;  /* set A=0xff */
475         }
476         dst += dstStride;
477         map += stride;
478      }
479   }
480
481   ctx->Driver.UnmapRenderbuffer(ctx, rb);
482
483   return GL_TRUE;
484}
485
486static void
487slow_read_rgba_pixels( struct gl_context *ctx,
488		       GLint x, GLint y,
489		       GLsizei width, GLsizei height,
490		       GLenum format, GLenum type,
491		       GLvoid *pixels,
492		       const struct gl_pixelstore_attrib *packing,
493		       GLbitfield transferOps )
494{
495   struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
496   const mesa_format rbFormat = _mesa_get_srgb_format_linear(rb->Format);
497   void *rgba;
498   GLubyte *dst, *map;
499   int dstStride, stride, j;
500   GLboolean dst_is_integer = _mesa_is_enum_format_integer(format);
501   GLboolean dst_is_uint = _mesa_is_format_unsigned(rbFormat);
502
503   dstStride = _mesa_image_row_stride(packing, width, format, type);
504   dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
505					   format, type, 0, 0);
506
507   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
508			       &map, &stride);
509   if (!map) {
510      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
511      return;
512   }
513
514   rgba = malloc(width * MAX_PIXEL_BYTES);
515   if (!rgba)
516      goto done;
517
518   for (j = 0; j < height; j++) {
519      if (dst_is_integer) {
520	 _mesa_unpack_uint_rgba_row(rbFormat, width, map, (GLuint (*)[4]) rgba);
521         _mesa_rebase_rgba_uint(width, (GLuint (*)[4]) rgba,
522                                rb->_BaseFormat);
523         if (dst_is_uint) {
524            _mesa_pack_rgba_span_from_uints(ctx, width, (GLuint (*)[4]) rgba, format,
525                                            type, dst);
526         } else {
527            _mesa_pack_rgba_span_from_ints(ctx, width, (GLint (*)[4]) rgba, format,
528                                           type, dst);
529         }
530      } else {
531	 _mesa_unpack_rgba_row(rbFormat, width, map, (GLfloat (*)[4]) rgba);
532         _mesa_rebase_rgba_float(width, (GLfloat (*)[4]) rgba,
533                                 rb->_BaseFormat);
534	 _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
535                                    type, dst, packing, transferOps);
536      }
537      dst += dstStride;
538      map += stride;
539   }
540
541   free(rgba);
542
543done:
544   ctx->Driver.UnmapRenderbuffer(ctx, rb);
545}
546
547/*
548 * Read R, G, B, A, RGB, L, or LA pixels.
549 */
550static void
551read_rgba_pixels( struct gl_context *ctx,
552                  GLint x, GLint y,
553                  GLsizei width, GLsizei height,
554                  GLenum format, GLenum type, GLvoid *pixels,
555                  const struct gl_pixelstore_attrib *packing )
556{
557   GLbitfield transferOps;
558   struct gl_framebuffer *fb = ctx->ReadBuffer;
559   struct gl_renderbuffer *rb = fb->_ColorReadBuffer;
560
561   if (!rb)
562      return;
563
564   transferOps = get_readpixels_transfer_ops(ctx, rb->Format, format, type,
565                                             GL_FALSE);
566
567   /* Try the optimized paths first. */
568   if (!transferOps &&
569       read_rgba_pixels_swizzle(ctx, x, y, width, height,
570                                    format, type, pixels, packing)) {
571      return;
572   }
573
574   slow_read_rgba_pixels(ctx, x, y, width, height,
575			 format, type, pixels, packing, transferOps);
576}
577
578/**
579 * For a packed depth/stencil buffer being read as depth/stencil, just memcpy the
580 * data (possibly swapping 8/24 vs 24/8 as we go).
581 */
582static GLboolean
583fast_read_depth_stencil_pixels(struct gl_context *ctx,
584			       GLint x, GLint y,
585			       GLsizei width, GLsizei height,
586			       GLubyte *dst, int dstStride)
587{
588   struct gl_framebuffer *fb = ctx->ReadBuffer;
589   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
590   struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
591   GLubyte *map;
592   int stride, i;
593
594   if (rb != stencilRb)
595      return GL_FALSE;
596
597   if (rb->Format != MESA_FORMAT_S8_UINT_Z24_UNORM &&
598       rb->Format != MESA_FORMAT_Z24_UNORM_S8_UINT)
599      return GL_FALSE;
600
601   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
602			       &map, &stride);
603   if (!map) {
604      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
605      return GL_TRUE;  /* don't bother trying the slow path */
606   }
607
608   for (i = 0; i < height; i++) {
609      _mesa_unpack_uint_24_8_depth_stencil_row(rb->Format, width,
610					       map, (GLuint *)dst);
611      map += stride;
612      dst += dstStride;
613   }
614
615   ctx->Driver.UnmapRenderbuffer(ctx, rb);
616
617   return GL_TRUE;
618}
619
620
621/**
622 * For non-float-depth and stencil buffers being read as 24/8 depth/stencil,
623 * copy the integer data directly instead of converting depth to float and
624 * re-packing.
625 */
626static GLboolean
627fast_read_depth_stencil_pixels_separate(struct gl_context *ctx,
628					GLint x, GLint y,
629					GLsizei width, GLsizei height,
630					uint32_t *dst, int dstStride)
631{
632   struct gl_framebuffer *fb = ctx->ReadBuffer;
633   struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
634   struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
635   GLubyte *depthMap, *stencilMap, *stencilVals;
636   int depthStride, stencilStride, i, j;
637
638   if (_mesa_get_format_datatype(depthRb->Format) != GL_UNSIGNED_NORMALIZED)
639      return GL_FALSE;
640
641   ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
642			       GL_MAP_READ_BIT, &depthMap, &depthStride);
643   if (!depthMap) {
644      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
645      return GL_TRUE;  /* don't bother trying the slow path */
646   }
647
648   ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
649			       GL_MAP_READ_BIT, &stencilMap, &stencilStride);
650   if (!stencilMap) {
651      ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
652      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
653      return GL_TRUE;  /* don't bother trying the slow path */
654   }
655
656   stencilVals = malloc(width * sizeof(GLubyte));
657
658   if (stencilVals) {
659      for (j = 0; j < height; j++) {
660         _mesa_unpack_uint_z_row(depthRb->Format, width, depthMap, dst);
661         _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
662                                        stencilMap, stencilVals);
663
664         for (i = 0; i < width; i++) {
665            dst[i] = (dst[i] & 0xffffff00) | stencilVals[i];
666         }
667
668         depthMap += depthStride;
669         stencilMap += stencilStride;
670         dst += dstStride / 4;
671      }
672   }
673   else {
674      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
675   }
676
677   free(stencilVals);
678
679   ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
680   ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
681
682   return GL_TRUE;
683}
684
685static void
686slow_read_depth_stencil_pixels_separate(struct gl_context *ctx,
687					GLint x, GLint y,
688					GLsizei width, GLsizei height,
689					GLenum type,
690					const struct gl_pixelstore_attrib *packing,
691					GLubyte *dst, int dstStride)
692{
693   struct gl_framebuffer *fb = ctx->ReadBuffer;
694   struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
695   struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
696   GLubyte *depthMap, *stencilMap;
697   int depthStride, stencilStride, j;
698   GLubyte *stencilVals;
699   GLfloat *depthVals;
700
701
702   /* The depth and stencil buffers might be separate, or a single buffer.
703    * If one buffer, only map it once.
704    */
705   ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
706			       GL_MAP_READ_BIT, &depthMap, &depthStride);
707   if (!depthMap) {
708      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
709      return;
710   }
711
712   if (stencilRb != depthRb) {
713      ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
714                                  GL_MAP_READ_BIT, &stencilMap,
715                                  &stencilStride);
716      if (!stencilMap) {
717         ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
718         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
719         return;
720      }
721   }
722   else {
723      stencilMap = depthMap;
724      stencilStride = depthStride;
725   }
726
727   stencilVals = malloc(width * sizeof(GLubyte));
728   depthVals = malloc(width * sizeof(GLfloat));
729
730   if (stencilVals && depthVals) {
731      for (j = 0; j < height; j++) {
732         _mesa_unpack_float_z_row(depthRb->Format, width, depthMap, depthVals);
733         _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
734                                        stencilMap, stencilVals);
735
736         _mesa_pack_depth_stencil_span(ctx, width, type, (GLuint *)dst,
737                                       depthVals, stencilVals, packing);
738
739         depthMap += depthStride;
740         stencilMap += stencilStride;
741         dst += dstStride;
742      }
743   }
744   else {
745      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
746   }
747
748   free(stencilVals);
749   free(depthVals);
750
751   ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
752   if (stencilRb != depthRb) {
753      ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
754   }
755}
756
757
758/**
759 * Read combined depth/stencil values.
760 * We'll have already done error checking to be sure the expected
761 * depth and stencil buffers really exist.
762 */
763static void
764read_depth_stencil_pixels(struct gl_context *ctx,
765                          GLint x, GLint y,
766                          GLsizei width, GLsizei height,
767                          GLenum type, GLvoid *pixels,
768                          const struct gl_pixelstore_attrib *packing )
769{
770   const GLboolean scaleOrBias
771      = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
772   const GLboolean stencilTransfer = ctx->Pixel.IndexShift
773      || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag;
774   GLubyte *dst;
775   int dstStride;
776
777   dst = (GLubyte *) _mesa_image_address2d(packing, pixels,
778					   width, height,
779					   GL_DEPTH_STENCIL_EXT,
780					   type, 0, 0);
781   dstStride = _mesa_image_row_stride(packing, width,
782				      GL_DEPTH_STENCIL_EXT, type);
783
784   /* Fast 24/8 reads. */
785   if (type == GL_UNSIGNED_INT_24_8 &&
786       !scaleOrBias && !stencilTransfer && !packing->SwapBytes) {
787      if (fast_read_depth_stencil_pixels(ctx, x, y, width, height,
788					 dst, dstStride))
789	 return;
790
791      if (fast_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
792						  (uint32_t *)dst, dstStride))
793	 return;
794   }
795
796   slow_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
797					   type, packing,
798					   dst, dstStride);
799}
800
801
802
803/**
804 * Software fallback routine for ctx->Driver.ReadPixels().
805 * By time we get here, all error checking will have been done.
806 */
807void
808_mesa_readpixels(struct gl_context *ctx,
809                 GLint x, GLint y, GLsizei width, GLsizei height,
810                 GLenum format, GLenum type,
811                 const struct gl_pixelstore_attrib *packing,
812                 GLvoid *pixels)
813{
814   struct gl_pixelstore_attrib clippedPacking = *packing;
815
816   if (ctx->NewState)
817      _mesa_update_state(ctx);
818
819   /* Do all needed clipping here, so that we can forget about it later */
820   if (_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) {
821
822      pixels = _mesa_map_pbo_dest(ctx, &clippedPacking, pixels);
823
824      if (pixels) {
825         /* Try memcpy first. */
826         if (readpixels_memcpy(ctx, x, y, width, height, format, type,
827                               pixels, packing)) {
828            _mesa_unmap_pbo_dest(ctx, &clippedPacking);
829            return;
830         }
831
832         /* Otherwise take the slow path. */
833         switch (format) {
834         case GL_STENCIL_INDEX:
835            read_stencil_pixels(ctx, x, y, width, height, type, pixels,
836                                &clippedPacking);
837            break;
838         case GL_DEPTH_COMPONENT:
839            read_depth_pixels(ctx, x, y, width, height, type, pixels,
840                              &clippedPacking);
841            break;
842         case GL_DEPTH_STENCIL_EXT:
843            read_depth_stencil_pixels(ctx, x, y, width, height, type, pixels,
844                                      &clippedPacking);
845            break;
846         default:
847            /* all other formats should be color formats */
848            read_rgba_pixels(ctx, x, y, width, height, format, type, pixels,
849                             &clippedPacking);
850         }
851
852         _mesa_unmap_pbo_dest(ctx, &clippedPacking);
853      }
854   }
855}
856
857
858static GLenum
859read_pixels_es3_error_check(GLenum format, GLenum type,
860                            const struct gl_renderbuffer *rb)
861{
862   const GLenum internalFormat = rb->InternalFormat;
863   const GLenum data_type = _mesa_get_format_datatype(rb->Format);
864   GLboolean is_unsigned_int = GL_FALSE;
865   GLboolean is_signed_int = GL_FALSE;
866
867   if (!_mesa_is_color_format(internalFormat)) {
868      return GL_INVALID_OPERATION;
869   }
870
871   is_unsigned_int = _mesa_is_enum_format_unsigned_int(internalFormat);
872   if (!is_unsigned_int) {
873      is_signed_int = _mesa_is_enum_format_signed_int(internalFormat);
874   }
875
876   switch (format) {
877   case GL_RGBA:
878      if (type == GL_FLOAT && data_type == GL_FLOAT)
879         return GL_NO_ERROR; /* EXT_color_buffer_float */
880      if (type == GL_UNSIGNED_BYTE && data_type == GL_UNSIGNED_NORMALIZED)
881         return GL_NO_ERROR;
882      if (internalFormat == GL_RGB10_A2 &&
883          type == GL_UNSIGNED_INT_2_10_10_10_REV)
884         return GL_NO_ERROR;
885      if (internalFormat == GL_RGB10_A2UI && type == GL_UNSIGNED_BYTE)
886         return GL_NO_ERROR;
887      break;
888   case GL_BGRA:
889      /* GL_EXT_read_format_bgra */
890      if (type == GL_UNSIGNED_BYTE ||
891          type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
892          type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
893         return GL_NO_ERROR;
894      break;
895   case GL_RGBA_INTEGER:
896      if ((is_signed_int && type == GL_INT) ||
897          (is_unsigned_int && type == GL_UNSIGNED_INT))
898         return GL_NO_ERROR;
899      break;
900   }
901
902   return GL_INVALID_OPERATION;
903}
904
905
906void GLAPIENTRY
907_mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
908		      GLenum format, GLenum type, GLsizei bufSize,
909                      GLvoid *pixels )
910{
911   GLenum err = GL_NO_ERROR;
912   struct gl_renderbuffer *rb;
913
914   GET_CURRENT_CONTEXT(ctx);
915
916   FLUSH_VERTICES(ctx, 0);
917   FLUSH_CURRENT(ctx, 0);
918
919   if (MESA_VERBOSE & VERBOSE_API)
920      _mesa_debug(ctx, "glReadPixels(%d, %d, %s, %s, %p)\n",
921                  width, height,
922                  _mesa_lookup_enum_by_nr(format),
923                  _mesa_lookup_enum_by_nr(type),
924                  pixels);
925
926   if (width < 0 || height < 0) {
927      _mesa_error( ctx, GL_INVALID_VALUE,
928                   "glReadPixels(width=%d height=%d)", width, height );
929      return;
930   }
931
932   if (ctx->NewState)
933      _mesa_update_state(ctx);
934
935   if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
936      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
937                  "glReadPixels(incomplete framebuffer)" );
938      return;
939   }
940
941   rb = _mesa_get_read_renderbuffer_for_format(ctx, format);
942   if (rb == NULL) {
943      _mesa_error(ctx, GL_INVALID_OPERATION,
944                  "glReadPixels(read buffer)");
945      return;
946   }
947
948   /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
949    * combinations of format and type that can be used.
950    *
951    * Technically, only two combinations are actually allowed:
952    * GL_RGBA/GL_UNSIGNED_BYTE, and some implementation-specific internal
953    * preferred combination.  This code doesn't know what that preferred
954    * combination is, and Mesa can handle anything valid.  Just work instead.
955    */
956   if (_mesa_is_gles(ctx)) {
957      if (ctx->API == API_OPENGLES2 &&
958          _mesa_is_color_format(format) &&
959          _mesa_get_color_read_format(ctx) == format &&
960          _mesa_get_color_read_type(ctx) == type) {
961         err = GL_NO_ERROR;
962      } else if (ctx->Version < 30) {
963         err = _mesa_es_error_check_format_and_type(format, type, 2);
964         if (err == GL_NO_ERROR) {
965            if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) {
966               err = GL_INVALID_OPERATION;
967            }
968         }
969      } else {
970         err = read_pixels_es3_error_check(format, type, rb);
971      }
972
973      if (err == GL_NO_ERROR && (format == GL_DEPTH_COMPONENT
974          || format == GL_DEPTH_STENCIL)) {
975         err = GL_INVALID_ENUM;
976      }
977
978      if (err != GL_NO_ERROR) {
979         _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
980                     _mesa_lookup_enum_by_nr(format),
981                     _mesa_lookup_enum_by_nr(type));
982         return;
983      }
984   }
985
986   err = _mesa_error_check_format_and_type(ctx, format, type);
987   if (err != GL_NO_ERROR) {
988      _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
989                  _mesa_lookup_enum_by_nr(format),
990                  _mesa_lookup_enum_by_nr(type));
991      return;
992   }
993
994   if (_mesa_is_user_fbo(ctx->ReadBuffer) &&
995       ctx->ReadBuffer->Visual.samples > 0) {
996      _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)");
997      return;
998   }
999
1000   if (!_mesa_source_buffer_exists(ctx, format)) {
1001      _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)");
1002      return;
1003   }
1004
1005   /* Check that the destination format and source buffer are both
1006    * integer-valued or both non-integer-valued.
1007    */
1008   if (ctx->Extensions.EXT_texture_integer && _mesa_is_color_format(format)) {
1009      const struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
1010      const GLboolean srcInteger = _mesa_is_format_integer_color(rb->Format);
1011      const GLboolean dstInteger = _mesa_is_enum_format_integer(format);
1012      if (dstInteger != srcInteger) {
1013         _mesa_error(ctx, GL_INVALID_OPERATION,
1014                     "glReadPixels(integer / non-integer format mismatch");
1015         return;
1016      }
1017   }
1018
1019   if (width == 0 || height == 0)
1020      return; /* nothing to do */
1021
1022   if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
1023                                  format, type, bufSize, pixels)) {
1024      if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
1025         _mesa_error(ctx, GL_INVALID_OPERATION,
1026                     "glReadPixels(out of bounds PBO access)");
1027      } else {
1028         _mesa_error(ctx, GL_INVALID_OPERATION,
1029                     "glReadnPixelsARB(out of bounds access:"
1030                     " bufSize (%d) is too small)", bufSize);
1031      }
1032      return;
1033   }
1034
1035   if (_mesa_is_bufferobj(ctx->Pack.BufferObj) &&
1036       _mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
1037      /* buffer is mapped - that's an error */
1038      _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
1039      return;
1040   }
1041
1042   ctx->Driver.ReadPixels(ctx, x, y, width, height,
1043			  format, type, &ctx->Pack, pixels);
1044}
1045
1046void GLAPIENTRY
1047_mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
1048		  GLenum format, GLenum type, GLvoid *pixels )
1049{
1050   _mesa_ReadnPixelsARB(x, y, width, height, format, type, INT_MAX, pixels);
1051}
1052