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