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#include "format_utils.h"
43#include "pixeltransfer.h"
44
45
46/**
47 * Return true if the conversion L=R+G+B is needed.
48 */
49GLboolean
50_mesa_need_rgb_to_luminance_conversion(GLenum srcBaseFormat,
51                                       GLenum dstBaseFormat)
52{
53   return (srcBaseFormat == GL_RG ||
54           srcBaseFormat == GL_RGB ||
55           srcBaseFormat == GL_RGBA) &&
56          (dstBaseFormat == GL_LUMINANCE ||
57           dstBaseFormat == GL_LUMINANCE_ALPHA);
58}
59
60/**
61 * Return true if the conversion L,I to RGB conversion is needed.
62 */
63GLboolean
64_mesa_need_luminance_to_rgb_conversion(GLenum srcBaseFormat,
65                                       GLenum dstBaseFormat)
66{
67   return (srcBaseFormat == GL_LUMINANCE ||
68           srcBaseFormat == GL_LUMINANCE_ALPHA ||
69           srcBaseFormat == GL_INTENSITY) &&
70          (dstBaseFormat == GL_GREEN ||
71           dstBaseFormat == GL_BLUE ||
72           dstBaseFormat == GL_RG ||
73           dstBaseFormat == GL_RGB ||
74           dstBaseFormat == GL_BGR ||
75           dstBaseFormat == GL_RGBA ||
76           dstBaseFormat == GL_BGRA);
77}
78
79/**
80 * Return transfer op flags for this ReadPixels operation.
81 */
82GLbitfield
83_mesa_get_readpixels_transfer_ops(const struct gl_context *ctx,
84                                  mesa_format texFormat,
85                                  GLenum format, GLenum type,
86                                  GLboolean uses_blit)
87{
88   GLbitfield transferOps = ctx->_ImageTransferState;
89   GLenum srcBaseFormat = _mesa_get_format_base_format(texFormat);
90   GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
91
92   if (format == GL_DEPTH_COMPONENT ||
93       format == GL_DEPTH_STENCIL ||
94       format == GL_STENCIL_INDEX) {
95      return 0;
96   }
97
98   /* Pixel transfer ops (scale, bias, table lookup) do not apply
99    * to integer formats.
100    */
101   if (_mesa_is_enum_format_integer(format)) {
102      return 0;
103   }
104
105   if (uses_blit) {
106      /* For blit-based ReadPixels packing, the clamping is done automatically
107       * unless the type is float. */
108      if (_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) &&
109          (type == GL_FLOAT || type == GL_HALF_FLOAT ||
110           type == GL_UNSIGNED_INT_10F_11F_11F_REV)) {
111         transferOps |= IMAGE_CLAMP_BIT;
112      }
113   }
114   else {
115      /* For CPU-based ReadPixels packing, the clamping must always be done
116       * for non-float types, */
117      if (_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) ||
118          (type != GL_FLOAT && type != GL_HALF_FLOAT &&
119           type != GL_UNSIGNED_INT_10F_11F_11F_REV)) {
120         transferOps |= IMAGE_CLAMP_BIT;
121      }
122   }
123
124   /* If the format is unsigned normalized, we can ignore clamping
125    * because the values are already in the range [0,1] so it won't
126    * have any effect anyway.
127    */
128   if (_mesa_get_format_datatype(texFormat) == GL_UNSIGNED_NORMALIZED &&
129       !_mesa_need_rgb_to_luminance_conversion(srcBaseFormat, dstBaseFormat)) {
130      transferOps &= ~IMAGE_CLAMP_BIT;
131   }
132
133   return transferOps;
134}
135
136
137/**
138 * Return true if memcpy cannot be used for ReadPixels.
139 *
140 * If uses_blit is true, the function returns true if a simple 3D engine blit
141 * cannot be used for ReadPixels packing.
142 *
143 * NOTE: This doesn't take swizzling and format conversions between
144 *       the readbuffer and the pixel pack buffer into account.
145 */
146GLboolean
147_mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format,
148                                 GLenum type, GLboolean uses_blit)
149{
150   struct gl_renderbuffer *rb =
151         _mesa_get_read_renderbuffer_for_format(ctx, format);
152   GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
153
154   assert(rb);
155
156   /* There are different rules depending on the base format. */
157   switch (format) {
158   case GL_DEPTH_STENCIL:
159      return !_mesa_has_depthstencil_combined(ctx->ReadBuffer) ||
160             ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f ||
161             ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
162             ctx->Pixel.MapStencilFlag;
163
164   case GL_DEPTH_COMPONENT:
165      return ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f;
166
167   case GL_STENCIL_INDEX:
168      return ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
169             ctx->Pixel.MapStencilFlag;
170
171   default:
172      /* Color formats. */
173      if (_mesa_need_rgb_to_luminance_conversion(rb->_BaseFormat,
174                                                 dstBaseFormat)) {
175         return GL_TRUE;
176      }
177
178      /* And finally, see if there are any transfer ops. */
179      return _mesa_get_readpixels_transfer_ops(ctx, rb->Format, format, type,
180                                               uses_blit) != 0;
181   }
182   return GL_FALSE;
183}
184
185
186static GLboolean
187readpixels_can_use_memcpy(const struct gl_context *ctx, GLenum format, GLenum type,
188                          const struct gl_pixelstore_attrib *packing)
189{
190   struct gl_renderbuffer *rb =
191         _mesa_get_read_renderbuffer_for_format(ctx, format);
192
193   assert(rb);
194
195   if (_mesa_readpixels_needs_slow_path(ctx, format, type, GL_FALSE)) {
196      return GL_FALSE;
197   }
198
199   /* The base internal format and the base Mesa format must match. */
200   if (rb->_BaseFormat != _mesa_get_format_base_format(rb->Format)) {
201      return GL_FALSE;
202   }
203
204   /* The Mesa format must match the input format and type. */
205   if (!_mesa_format_matches_format_and_type(rb->Format, format, type,
206                                             packing->SwapBytes, NULL)) {
207      return GL_FALSE;
208   }
209
210   return GL_TRUE;
211}
212
213
214static GLboolean
215readpixels_memcpy(struct gl_context *ctx,
216                  GLint x, GLint y,
217                  GLsizei width, GLsizei height,
218                  GLenum format, GLenum type,
219                  GLvoid *pixels,
220                  const struct gl_pixelstore_attrib *packing)
221{
222   struct gl_renderbuffer *rb =
223         _mesa_get_read_renderbuffer_for_format(ctx, format);
224   GLubyte *dst, *map;
225   int dstStride, stride, j, texelBytes, bytesPerRow;
226
227   /* Fail if memcpy cannot be used. */
228   if (!readpixels_can_use_memcpy(ctx, format, type, packing)) {
229      return GL_FALSE;
230   }
231
232   dstStride = _mesa_image_row_stride(packing, width, format, type);
233   dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
234					   format, type, 0, 0);
235
236   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
237			       &map, &stride, ctx->ReadBuffer->FlipY);
238   if (!map) {
239      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
240      return GL_TRUE;  /* don't bother trying the slow path */
241   }
242
243   texelBytes = _mesa_get_format_bytes(rb->Format);
244   bytesPerRow = texelBytes * width;
245
246   /* memcpy*/
247   if (dstStride == stride && dstStride == bytesPerRow) {
248      memcpy(dst, map, bytesPerRow * height);
249   } else {
250      for (j = 0; j < height; j++) {
251         memcpy(dst, map, bytesPerRow);
252         dst += dstStride;
253         map += stride;
254      }
255   }
256
257   ctx->Driver.UnmapRenderbuffer(ctx, rb);
258   return GL_TRUE;
259}
260
261
262/**
263 * Optimized path for conversion of depth values to GL_DEPTH_COMPONENT,
264 * GL_UNSIGNED_INT.
265 */
266static GLboolean
267read_uint_depth_pixels( struct gl_context *ctx,
268			GLint x, GLint y,
269			GLsizei width, GLsizei height,
270			GLenum type, GLvoid *pixels,
271			const struct gl_pixelstore_attrib *packing )
272{
273   struct gl_framebuffer *fb = ctx->ReadBuffer;
274   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
275   GLubyte *map, *dst;
276   int stride, dstStride, j;
277
278   if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F)
279      return GL_FALSE;
280
281   if (packing->SwapBytes)
282      return GL_FALSE;
283
284   if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED)
285      return GL_FALSE;
286
287   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
288			       &map, &stride, fb->FlipY);
289
290   if (!map) {
291      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
292      return GL_TRUE;  /* don't bother trying the slow path */
293   }
294
295   dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
296   dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
297					   GL_DEPTH_COMPONENT, type, 0, 0);
298
299   for (j = 0; j < height; j++) {
300      _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst);
301
302      map += stride;
303      dst += dstStride;
304   }
305   ctx->Driver.UnmapRenderbuffer(ctx, rb);
306
307   return GL_TRUE;
308}
309
310/**
311 * Read pixels for format=GL_DEPTH_COMPONENT.
312 */
313static void
314read_depth_pixels( struct gl_context *ctx,
315                   GLint x, GLint y,
316                   GLsizei width, GLsizei height,
317                   GLenum type, GLvoid *pixels,
318                   const struct gl_pixelstore_attrib *packing )
319{
320   struct gl_framebuffer *fb = ctx->ReadBuffer;
321   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
322   GLint j;
323   GLubyte *dst, *map;
324   int dstStride, stride;
325   GLfloat *depthValues;
326
327   if (!rb)
328      return;
329
330   /* clipping should have been done already */
331   assert(x >= 0);
332   assert(y >= 0);
333   assert(x + width <= (GLint) rb->Width);
334   assert(y + height <= (GLint) rb->Height);
335
336   if (type == GL_UNSIGNED_INT &&
337       read_uint_depth_pixels(ctx, x, y, width, height, type, pixels, packing)) {
338      return;
339   }
340
341   dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
342   dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
343					   GL_DEPTH_COMPONENT, type, 0, 0);
344
345   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
346			       &map, &stride, fb->FlipY);
347   if (!map) {
348      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
349      return;
350   }
351
352   depthValues = malloc(width * sizeof(GLfloat));
353
354   if (depthValues) {
355      /* General case (slower) */
356      for (j = 0; j < height; j++, y++) {
357         _mesa_unpack_float_z_row(rb->Format, width, map, depthValues);
358         _mesa_pack_depth_span(ctx, width, dst, type, depthValues, packing);
359
360         dst += dstStride;
361         map += stride;
362      }
363   }
364   else {
365      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
366   }
367
368   free(depthValues);
369
370   ctx->Driver.UnmapRenderbuffer(ctx, rb);
371}
372
373
374/**
375 * Read pixels for format=GL_STENCIL_INDEX.
376 */
377static void
378read_stencil_pixels( struct gl_context *ctx,
379                     GLint x, GLint y,
380                     GLsizei width, GLsizei height,
381                     GLenum type, GLvoid *pixels,
382                     const struct gl_pixelstore_attrib *packing )
383{
384   struct gl_framebuffer *fb = ctx->ReadBuffer;
385   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
386   GLint j;
387   GLubyte *map, *stencil;
388   GLint stride;
389
390   if (!rb)
391      return;
392
393   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
394			       &map, &stride, fb->FlipY);
395   if (!map) {
396      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
397      return;
398   }
399
400   stencil = malloc(width * sizeof(GLubyte));
401
402   if (stencil) {
403      /* process image row by row */
404      for (j = 0; j < height; j++) {
405         GLvoid *dest;
406
407         _mesa_unpack_ubyte_stencil_row(rb->Format, width, map, stencil);
408         dest = _mesa_image_address2d(packing, pixels, width, height,
409                                      GL_STENCIL_INDEX, type, j, 0);
410
411         _mesa_pack_stencil_span(ctx, width, type, dest, stencil, packing);
412
413         map += stride;
414      }
415   }
416   else {
417      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
418   }
419
420   free(stencil);
421
422   ctx->Driver.UnmapRenderbuffer(ctx, rb);
423}
424
425/*
426 * Read R, G, B, A, RGB, L, or LA pixels.
427 */
428static void
429read_rgba_pixels( struct gl_context *ctx,
430                  GLint x, GLint y,
431                  GLsizei width, GLsizei height,
432                  GLenum format, GLenum type, GLvoid *pixels,
433                  const struct gl_pixelstore_attrib *packing )
434{
435   GLbitfield transferOps;
436   bool dst_is_integer, convert_rgb_to_lum, needs_rebase;
437   int dst_stride, src_stride, rb_stride;
438   uint32_t dst_format, src_format;
439   GLubyte *dst, *map;
440   mesa_format rb_format;
441   bool needs_rgba;
442   void *rgba, *src;
443   bool src_is_uint = false;
444   uint8_t rebase_swizzle[4];
445   struct gl_framebuffer *fb = ctx->ReadBuffer;
446   struct gl_renderbuffer *rb = fb->_ColorReadBuffer;
447   GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
448
449   if (!rb)
450      return;
451
452   transferOps = _mesa_get_readpixels_transfer_ops(ctx, rb->Format, format,
453                                                   type, GL_FALSE);
454   /* Describe the dst format */
455   dst_is_integer = _mesa_is_enum_format_integer(format);
456   dst_stride = _mesa_image_row_stride(packing, width, format, type);
457   dst_format = _mesa_format_from_format_and_type(format, type);
458   convert_rgb_to_lum =
459      _mesa_need_rgb_to_luminance_conversion(rb->_BaseFormat, dstBaseFormat);
460   dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
461                                           format, type, 0, 0);
462
463   /* Map the source render buffer */
464   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
465                               &map, &rb_stride, fb->FlipY);
466   if (!map) {
467      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
468      return;
469   }
470   rb_format = _mesa_get_srgb_format_linear(rb->Format);
471
472   /*
473    * Depending on the base formats involved in the conversion we might need to
474    * rebase some values, so for these formats we compute a rebase swizzle.
475    */
476   if (rb->_BaseFormat == GL_LUMINANCE || rb->_BaseFormat == GL_INTENSITY) {
477      needs_rebase = true;
478      rebase_swizzle[0] = MESA_FORMAT_SWIZZLE_X;
479      rebase_swizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
480      rebase_swizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
481      rebase_swizzle[3] = MESA_FORMAT_SWIZZLE_ONE;
482   } else if (rb->_BaseFormat == GL_LUMINANCE_ALPHA) {
483      needs_rebase = true;
484      rebase_swizzle[0] = MESA_FORMAT_SWIZZLE_X;
485      rebase_swizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
486      rebase_swizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
487      rebase_swizzle[3] = MESA_FORMAT_SWIZZLE_W;
488   } else if (_mesa_get_format_base_format(rb_format) != rb->_BaseFormat) {
489      needs_rebase =
490         _mesa_compute_rgba2base2rgba_component_mapping(rb->_BaseFormat,
491                                                        rebase_swizzle);
492   } else {
493      needs_rebase = false;
494   }
495
496   /* Since _mesa_format_convert does not handle transferOps we need to handle
497    * them before we call the function. This requires to convert to RGBA float
498    * first so we can call _mesa_apply_rgba_transfer_ops. If the dst format is
499    * integer transferOps do not apply.
500    *
501    * Converting to luminance also requires converting to RGBA first, so we can
502    * then compute luminance values as L=R+G+B. Notice that this is different
503    * from GetTexImage, where we compute L=R.
504    */
505   assert(!transferOps || (transferOps && !dst_is_integer));
506
507   needs_rgba = transferOps || convert_rgb_to_lum;
508   rgba = NULL;
509   if (needs_rgba) {
510      uint32_t rgba_format;
511      int rgba_stride;
512      bool need_convert;
513
514      /* Convert to RGBA float or int/uint depending on the type of the src */
515      if (dst_is_integer) {
516         src_is_uint = _mesa_is_format_unsigned(rb_format);
517         if (src_is_uint) {
518            rgba_format = RGBA32_UINT;
519            rgba_stride = width * 4 * sizeof(GLuint);
520         } else {
521            rgba_format = RGBA32_INT;
522            rgba_stride = width * 4 * sizeof(GLint);
523         }
524      } else {
525         rgba_format = RGBA32_FLOAT;
526         rgba_stride = width * 4 * sizeof(GLfloat);
527      }
528
529      /* If we are lucky and the dst format matches the RGBA format we need to
530       * convert to, then we can convert directly into the dst buffer and avoid
531       * the final conversion/copy from the rgba buffer to the dst buffer.
532       */
533      if (dst_format == rgba_format &&
534          dst_stride == rgba_stride) {
535         need_convert = false;
536         rgba = dst;
537      } else {
538         need_convert = true;
539         rgba = malloc(height * rgba_stride);
540         if (!rgba) {
541            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
542            goto done_unmap;
543         }
544      }
545
546      /* Convert to RGBA now */
547      _mesa_format_convert(rgba, rgba_format, rgba_stride,
548                           map, rb_format, rb_stride,
549                           width, height,
550                           needs_rebase ? rebase_swizzle : NULL);
551
552      /* Handle transfer ops if necessary */
553      if (transferOps)
554         _mesa_apply_rgba_transfer_ops(ctx, transferOps, width * height, rgba);
555
556      /* If we had to rebase, we have already taken care of that */
557      needs_rebase = false;
558
559      /* If we were lucky and our RGBA conversion matches the dst format, then
560       * we are done.
561       */
562      if (!need_convert)
563         goto done_swap;
564
565      /* Otherwise, we need to convert from RGBA to dst next */
566      src = rgba;
567      src_format = rgba_format;
568      src_stride = rgba_stride;
569   } else {
570      /* No RGBA conversion needed, convert directly to dst */
571      src = map;
572      src_format = rb_format;
573      src_stride = rb_stride;
574   }
575
576   /* Do the conversion.
577    *
578    * If the dst format is Luminance, we need to do the conversion by computing
579    * L=R+G+B values.
580    */
581   if (!convert_rgb_to_lum) {
582      _mesa_format_convert(dst, dst_format, dst_stride,
583                           src, src_format, src_stride,
584                           width, height,
585                           needs_rebase ? rebase_swizzle : NULL);
586   } else if (!dst_is_integer) {
587      /* Compute float Luminance values from RGBA float */
588      int luminance_stride, luminance_bytes;
589      void *luminance;
590      uint32_t luminance_format;
591
592      luminance_stride = width * sizeof(GLfloat);
593      if (format == GL_LUMINANCE_ALPHA)
594         luminance_stride *= 2;
595      luminance_bytes = height * luminance_stride;
596      luminance = malloc(luminance_bytes);
597      if (!luminance) {
598         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
599         free(rgba);
600         goto done_unmap;
601      }
602      _mesa_pack_luminance_from_rgba_float(width * height, src,
603                                           luminance, format, transferOps);
604
605      /* Convert from Luminance float to dst (this will hadle type conversion
606       * from float to the type of dst if necessary)
607       */
608      luminance_format = _mesa_format_from_format_and_type(format, GL_FLOAT);
609      _mesa_format_convert(dst, dst_format, dst_stride,
610                           luminance, luminance_format, luminance_stride,
611                           width, height, NULL);
612      free(luminance);
613   } else {
614      _mesa_pack_luminance_from_rgba_integer(width * height, src, !src_is_uint,
615                                             dst, format, type);
616   }
617
618   free(rgba);
619
620done_swap:
621   /* Handle byte swapping if required */
622   if (packing->SwapBytes) {
623      _mesa_swap_bytes_2d_image(format, type, packing,
624                                width, height, dst, dst);
625   }
626
627done_unmap:
628   ctx->Driver.UnmapRenderbuffer(ctx, rb);
629}
630
631/**
632 * For a packed depth/stencil buffer being read as depth/stencil, just memcpy the
633 * data (possibly swapping 8/24 vs 24/8 as we go).
634 */
635static GLboolean
636fast_read_depth_stencil_pixels(struct gl_context *ctx,
637			       GLint x, GLint y,
638			       GLsizei width, GLsizei height,
639			       GLubyte *dst, int dstStride)
640{
641   struct gl_framebuffer *fb = ctx->ReadBuffer;
642   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
643   struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
644   GLubyte *map;
645   int stride, i;
646
647   if (rb != stencilRb)
648      return GL_FALSE;
649
650   if (rb->Format != MESA_FORMAT_S8_UINT_Z24_UNORM &&
651       rb->Format != MESA_FORMAT_Z24_UNORM_S8_UINT)
652      return GL_FALSE;
653
654   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
655			       &map, &stride, fb->FlipY);
656   if (!map) {
657      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
658      return GL_TRUE;  /* don't bother trying the slow path */
659   }
660
661   for (i = 0; i < height; i++) {
662      _mesa_unpack_uint_24_8_depth_stencil_row(rb->Format, width,
663					       map, (GLuint *)dst);
664      map += stride;
665      dst += dstStride;
666   }
667
668   ctx->Driver.UnmapRenderbuffer(ctx, rb);
669
670   return GL_TRUE;
671}
672
673
674/**
675 * For non-float-depth and stencil buffers being read as 24/8 depth/stencil,
676 * copy the integer data directly instead of converting depth to float and
677 * re-packing.
678 */
679static GLboolean
680fast_read_depth_stencil_pixels_separate(struct gl_context *ctx,
681					GLint x, GLint y,
682					GLsizei width, GLsizei height,
683					uint32_t *dst, int dstStride)
684{
685   struct gl_framebuffer *fb = ctx->ReadBuffer;
686   struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
687   struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
688   GLubyte *depthMap, *stencilMap, *stencilVals;
689   int depthStride, stencilStride, i, j;
690
691   if (_mesa_get_format_datatype(depthRb->Format) != GL_UNSIGNED_NORMALIZED)
692      return GL_FALSE;
693
694   ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
695			       GL_MAP_READ_BIT, &depthMap, &depthStride, fb->FlipY);
696   if (!depthMap) {
697      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
698      return GL_TRUE;  /* don't bother trying the slow path */
699   }
700
701   ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
702			       GL_MAP_READ_BIT, &stencilMap, &stencilStride, fb->FlipY);
703   if (!stencilMap) {
704      ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
705      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
706      return GL_TRUE;  /* don't bother trying the slow path */
707   }
708
709   stencilVals = malloc(width * sizeof(GLubyte));
710
711   if (stencilVals) {
712      for (j = 0; j < height; j++) {
713         _mesa_unpack_uint_z_row(depthRb->Format, width, depthMap, dst);
714         _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
715                                        stencilMap, stencilVals);
716
717         for (i = 0; i < width; i++) {
718            dst[i] = (dst[i] & 0xffffff00) | stencilVals[i];
719         }
720
721         depthMap += depthStride;
722         stencilMap += stencilStride;
723         dst += dstStride / 4;
724      }
725   }
726   else {
727      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
728   }
729
730   free(stencilVals);
731
732   ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
733   ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
734
735   return GL_TRUE;
736}
737
738static void
739slow_read_depth_stencil_pixels_separate(struct gl_context *ctx,
740					GLint x, GLint y,
741					GLsizei width, GLsizei height,
742					GLenum type,
743					const struct gl_pixelstore_attrib *packing,
744					GLubyte *dst, int dstStride)
745{
746   struct gl_framebuffer *fb = ctx->ReadBuffer;
747   struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
748   struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
749   GLubyte *depthMap, *stencilMap;
750   int depthStride, stencilStride, j;
751   GLubyte *stencilVals;
752   GLfloat *depthVals;
753
754
755   /* The depth and stencil buffers might be separate, or a single buffer.
756    * If one buffer, only map it once.
757    */
758   ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
759			       GL_MAP_READ_BIT, &depthMap, &depthStride, fb->FlipY);
760   if (!depthMap) {
761      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
762      return;
763   }
764
765   if (stencilRb != depthRb) {
766      ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
767                                  GL_MAP_READ_BIT, &stencilMap,
768                                  &stencilStride, fb->FlipY);
769      if (!stencilMap) {
770         ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
771         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
772         return;
773      }
774   }
775   else {
776      stencilMap = depthMap;
777      stencilStride = depthStride;
778   }
779
780   stencilVals = malloc(width * sizeof(GLubyte));
781   depthVals = malloc(width * sizeof(GLfloat));
782
783   if (stencilVals && depthVals) {
784      for (j = 0; j < height; j++) {
785         _mesa_unpack_float_z_row(depthRb->Format, width, depthMap, depthVals);
786         _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
787                                        stencilMap, stencilVals);
788
789         _mesa_pack_depth_stencil_span(ctx, width, type, (GLuint *)dst,
790                                       depthVals, stencilVals, packing);
791
792         depthMap += depthStride;
793         stencilMap += stencilStride;
794         dst += dstStride;
795      }
796   }
797   else {
798      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
799   }
800
801   free(stencilVals);
802   free(depthVals);
803
804   ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
805   if (stencilRb != depthRb) {
806      ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
807   }
808}
809
810
811/**
812 * Read combined depth/stencil values.
813 * We'll have already done error checking to be sure the expected
814 * depth and stencil buffers really exist.
815 */
816static void
817read_depth_stencil_pixels(struct gl_context *ctx,
818                          GLint x, GLint y,
819                          GLsizei width, GLsizei height,
820                          GLenum type, GLvoid *pixels,
821                          const struct gl_pixelstore_attrib *packing )
822{
823   const GLboolean scaleOrBias
824      = ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F;
825   const GLboolean stencilTransfer = ctx->Pixel.IndexShift
826      || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag;
827   GLubyte *dst;
828   int dstStride;
829
830   dst = (GLubyte *) _mesa_image_address2d(packing, pixels,
831					   width, height,
832					   GL_DEPTH_STENCIL_EXT,
833					   type, 0, 0);
834   dstStride = _mesa_image_row_stride(packing, width,
835				      GL_DEPTH_STENCIL_EXT, type);
836
837   /* Fast 24/8 reads. */
838   if (type == GL_UNSIGNED_INT_24_8 &&
839       !scaleOrBias && !stencilTransfer && !packing->SwapBytes) {
840      if (fast_read_depth_stencil_pixels(ctx, x, y, width, height,
841					 dst, dstStride))
842	 return;
843
844      if (fast_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
845						  (uint32_t *)dst, dstStride))
846	 return;
847   }
848
849   slow_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
850					   type, packing,
851					   dst, dstStride);
852}
853
854
855
856/**
857 * Software fallback routine for ctx->Driver.ReadPixels().
858 * By time we get here, all error checking will have been done.
859 */
860void
861_mesa_readpixels(struct gl_context *ctx,
862                 GLint x, GLint y, GLsizei width, GLsizei height,
863                 GLenum format, GLenum type,
864                 const struct gl_pixelstore_attrib *packing,
865                 GLvoid *pixels)
866{
867   if (ctx->NewState)
868      _mesa_update_state(ctx);
869
870   pixels = _mesa_map_pbo_dest(ctx, packing, pixels);
871
872   if (pixels) {
873      /* Try memcpy first. */
874      if (readpixels_memcpy(ctx, x, y, width, height, format, type,
875                            pixels, packing)) {
876         _mesa_unmap_pbo_dest(ctx, packing);
877         return;
878      }
879
880      /* Otherwise take the slow path. */
881      switch (format) {
882      case GL_STENCIL_INDEX:
883         read_stencil_pixels(ctx, x, y, width, height, type, pixels,
884                             packing);
885         break;
886      case GL_DEPTH_COMPONENT:
887         read_depth_pixels(ctx, x, y, width, height, type, pixels,
888                           packing);
889         break;
890      case GL_DEPTH_STENCIL_EXT:
891         read_depth_stencil_pixels(ctx, x, y, width, height, type, pixels,
892                                   packing);
893         break;
894      default:
895         /* all other formats should be color formats */
896         read_rgba_pixels(ctx, x, y, width, height, format, type, pixels,
897                          packing);
898      }
899
900      _mesa_unmap_pbo_dest(ctx, packing);
901   }
902}
903
904
905static GLenum
906read_pixels_es3_error_check(struct gl_context *ctx, GLenum format, GLenum type,
907                            const struct gl_renderbuffer *rb)
908{
909   const GLenum internalFormat = rb->InternalFormat;
910   const GLenum data_type = _mesa_get_format_datatype(rb->Format);
911   GLboolean is_unsigned_int = GL_FALSE;
912   GLboolean is_signed_int = GL_FALSE;
913   GLboolean is_float_depth = (internalFormat == GL_DEPTH_COMPONENT32F) ||
914         (internalFormat == GL_DEPTH32F_STENCIL8);
915
916   is_unsigned_int = _mesa_is_enum_format_unsigned_int(internalFormat);
917   if (!is_unsigned_int) {
918      is_signed_int = _mesa_is_enum_format_signed_int(internalFormat);
919   }
920
921   switch (format) {
922   case GL_RGBA:
923      if (type == GL_FLOAT && data_type == GL_FLOAT)
924         return GL_NO_ERROR; /* EXT_color_buffer_float */
925      if (type == GL_UNSIGNED_BYTE && data_type == GL_UNSIGNED_NORMALIZED)
926         return GL_NO_ERROR;
927      if (internalFormat == GL_RGB10_A2 &&
928          type == GL_UNSIGNED_INT_2_10_10_10_REV)
929         return GL_NO_ERROR;
930      if (internalFormat == GL_RGB10_A2UI && type == GL_UNSIGNED_BYTE)
931         return GL_NO_ERROR;
932      if (type == GL_UNSIGNED_SHORT) {
933         switch (internalFormat) {
934         case GL_R16:
935         case GL_RG16:
936         case GL_RGB16:
937         case GL_RGBA16:
938            if (_mesa_has_EXT_texture_norm16(ctx))
939               return GL_NO_ERROR;
940         }
941      }
942      if (type == GL_SHORT) {
943         switch (internalFormat) {
944         case GL_R16_SNORM:
945         case GL_RG16_SNORM:
946         case GL_RGBA16_SNORM:
947            if (_mesa_has_EXT_texture_norm16(ctx) &&
948                _mesa_has_EXT_render_snorm(ctx))
949               return GL_NO_ERROR;
950         }
951      }
952      if (type == GL_BYTE) {
953         switch (internalFormat) {
954         case GL_R8_SNORM:
955         case GL_RG8_SNORM:
956         case GL_RGBA8_SNORM:
957            if (_mesa_has_EXT_render_snorm(ctx))
958               return GL_NO_ERROR;
959         }
960      }
961      if (type == GL_UNSIGNED_BYTE) {
962         switch (internalFormat) {
963         case GL_R8_SNORM:
964         case GL_RG8_SNORM:
965         case GL_RGBA8_SNORM:
966            if (_mesa_has_EXT_render_snorm(ctx))
967               return GL_NO_ERROR;
968         }
969      }
970      break;
971   case GL_BGRA:
972      /* GL_EXT_read_format_bgra */
973      if (type == GL_UNSIGNED_BYTE ||
974          type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
975          type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
976         return GL_NO_ERROR;
977      break;
978   case GL_RGBA_INTEGER:
979      if ((is_signed_int && type == GL_INT) ||
980          (is_unsigned_int && type == GL_UNSIGNED_INT))
981         return GL_NO_ERROR;
982      break;
983   case GL_DEPTH_STENCIL:
984      switch (type) {
985      case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
986         if (is_float_depth)
987            return GL_NO_ERROR;
988         break;
989      case GL_UNSIGNED_INT_24_8:
990         if (!is_float_depth)
991            return GL_NO_ERROR;
992         break;
993      default:
994         return GL_INVALID_ENUM;
995      }
996      break;
997   case GL_DEPTH_COMPONENT:
998      switch (type) {
999      case GL_FLOAT:
1000         if (is_float_depth)
1001            return GL_NO_ERROR;
1002         break;
1003      case GL_UNSIGNED_SHORT:
1004      case GL_UNSIGNED_INT:
1005      case GL_UNSIGNED_INT_24_8:
1006         if (!is_float_depth)
1007            return GL_NO_ERROR;
1008         break;
1009      default:
1010         return GL_INVALID_ENUM;
1011      }
1012      break;
1013   case GL_STENCIL_INDEX:
1014      switch (type) {
1015      case GL_UNSIGNED_BYTE:
1016         return GL_NO_ERROR;
1017      default:
1018         return GL_INVALID_ENUM;
1019      }
1020      break;
1021   }
1022
1023   return GL_INVALID_OPERATION;
1024}
1025
1026
1027static ALWAYS_INLINE void
1028read_pixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
1029            GLenum type, GLsizei bufSize, GLvoid *pixels, bool no_error)
1030{
1031   GLenum err = GL_NO_ERROR;
1032   struct gl_renderbuffer *rb;
1033   struct gl_pixelstore_attrib clippedPacking;
1034
1035   GET_CURRENT_CONTEXT(ctx);
1036
1037   FLUSH_VERTICES(ctx, 0);
1038   FLUSH_CURRENT(ctx, 0);
1039
1040   if (MESA_VERBOSE & VERBOSE_API)
1041      _mesa_debug(ctx, "glReadPixels(%d, %d, %s, %s, %p)\n",
1042                  width, height,
1043                  _mesa_enum_to_string(format),
1044                  _mesa_enum_to_string(type),
1045                  pixels);
1046
1047   if (!no_error && (width < 0 || height < 0)) {
1048      _mesa_error( ctx, GL_INVALID_VALUE,
1049                   "glReadPixels(width=%d height=%d)", width, height );
1050      return;
1051   }
1052
1053   if (ctx->NewState)
1054      _mesa_update_state(ctx);
1055
1056   if (!no_error && ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
1057      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
1058                  "glReadPixels(incomplete framebuffer)" );
1059      return;
1060   }
1061
1062   rb = _mesa_get_read_renderbuffer_for_format(ctx, format);
1063   if (!no_error) {
1064      if (rb == NULL) {
1065         _mesa_error(ctx, GL_INVALID_OPERATION,
1066                     "glReadPixels(read buffer)");
1067         return;
1068      }
1069
1070      /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
1071       * combinations of format and type that can be used.
1072       *
1073       * Technically, only two combinations are actually allowed:
1074       * GL_RGBA/GL_UNSIGNED_BYTE, and some implementation-specific internal
1075       * preferred combination.  This code doesn't know what that preferred
1076       * combination is, and Mesa can handle anything valid.  Just work instead.
1077       */
1078      if (_mesa_is_gles(ctx)) {
1079         if (ctx->API == API_OPENGLES2 &&
1080             _mesa_is_color_format(format) &&
1081             _mesa_get_color_read_format(ctx, NULL, "glReadPixels") == format &&
1082             _mesa_get_color_read_type(ctx, NULL, "glReadPixels") == type) {
1083            err = GL_NO_ERROR;
1084         } else if (ctx->Version < 30) {
1085            err = _mesa_es_error_check_format_and_type(ctx, format, type, 2);
1086            if (err == GL_NO_ERROR) {
1087               if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) {
1088                  err = GL_INVALID_OPERATION;
1089               }
1090            }
1091         } else {
1092            err = read_pixels_es3_error_check(ctx, format, type, rb);
1093         }
1094
1095         if (err != GL_NO_ERROR) {
1096            _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
1097                        _mesa_enum_to_string(format),
1098                        _mesa_enum_to_string(type));
1099            return;
1100         }
1101      }
1102
1103      err = _mesa_error_check_format_and_type(ctx, format, type);
1104      if (err != GL_NO_ERROR) {
1105         _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
1106                     _mesa_enum_to_string(format),
1107                     _mesa_enum_to_string(type));
1108         return;
1109      }
1110
1111      if (_mesa_is_user_fbo(ctx->ReadBuffer) &&
1112          ctx->ReadBuffer->Visual.samples > 0) {
1113         _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)");
1114         return;
1115      }
1116
1117      if (!_mesa_source_buffer_exists(ctx, format)) {
1118         _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)");
1119         return;
1120      }
1121
1122      /* Check that the destination format and source buffer are both
1123       * integer-valued or both non-integer-valued.
1124       */
1125      if (ctx->Extensions.EXT_texture_integer && _mesa_is_color_format(format)) {
1126         const struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
1127         const GLboolean srcInteger = _mesa_is_format_integer_color(rb->Format);
1128         const GLboolean dstInteger = _mesa_is_enum_format_integer(format);
1129         if (dstInteger != srcInteger) {
1130            _mesa_error(ctx, GL_INVALID_OPERATION,
1131                        "glReadPixels(integer / non-integer format mismatch");
1132            return;
1133         }
1134      }
1135   }
1136
1137   /* Do all needed clipping here, so that we can forget about it later */
1138   clippedPacking = ctx->Pack;
1139   if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking))
1140      return; /* nothing to do */
1141
1142   if (!no_error) {
1143      if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
1144                                     format, type, bufSize, pixels)) {
1145         if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
1146            _mesa_error(ctx, GL_INVALID_OPERATION,
1147                        "glReadPixels(out of bounds PBO access)");
1148         } else {
1149            _mesa_error(ctx, GL_INVALID_OPERATION,
1150                        "glReadnPixelsARB(out of bounds access:"
1151                        " bufSize (%d) is too small)", bufSize);
1152         }
1153         return;
1154      }
1155
1156      if (_mesa_is_bufferobj(ctx->Pack.BufferObj) &&
1157          _mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
1158         /* buffer is mapped - that's an error */
1159         _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
1160         return;
1161      }
1162   }
1163
1164   ctx->Driver.ReadPixels(ctx, x, y, width, height,
1165                          format, type, &clippedPacking, pixels);
1166}
1167
1168void GLAPIENTRY
1169_mesa_ReadnPixelsARB_no_error(GLint x, GLint y, GLsizei width, GLsizei height,
1170                              GLenum format, GLenum type, GLsizei bufSize,
1171                              GLvoid *pixels)
1172{
1173   read_pixels(x, y, width, height, format, type, bufSize, pixels, true);
1174}
1175
1176void GLAPIENTRY
1177_mesa_ReadnPixelsARB(GLint x, GLint y, GLsizei width, GLsizei height,
1178                     GLenum format, GLenum type, GLsizei bufSize,
1179                     GLvoid *pixels)
1180{
1181   read_pixels(x, y, width, height, format, type, bufSize, pixels, false);
1182}
1183
1184void GLAPIENTRY
1185_mesa_ReadPixels_no_error(GLint x, GLint y, GLsizei width, GLsizei height,
1186                          GLenum format, GLenum type, GLvoid *pixels)
1187{
1188   _mesa_ReadnPixelsARB_no_error(x, y, width, height, format, type, INT_MAX,
1189                                 pixels);
1190}
1191
1192void GLAPIENTRY
1193_mesa_ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
1194                 GLenum format, GLenum type, GLvoid *pixels)
1195{
1196   _mesa_ReadnPixelsARB(x, y, width, height, format, type, INT_MAX, pixels);
1197}
1198