• 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 
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            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  */
146 GLboolean
_mesa_readpixels_needs_slow_path(const struct gl_context * ctx,GLenum format,GLenum type,GLboolean uses_blit)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 
186 static GLboolean
readpixels_can_use_memcpy(const struct gl_context * ctx,GLenum format,GLenum type,const struct gl_pixelstore_attrib * packing)187 readpixels_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 
214 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)215 readpixels_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  */
266 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)267 read_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  */
313 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)314 read_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  */
377 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)378 read_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  */
428 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)429 read_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 
620 done_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 
627 done_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  */
635 static GLboolean
fast_read_depth_stencil_pixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLubyte * dst,int dstStride)636 fast_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  */
679 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)680 fast_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 
738 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)739 slow_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  */
816 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)817 read_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  */
860 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)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 
905 static GLenum
read_pixels_es3_error_check(struct gl_context * ctx,GLenum format,GLenum type,const struct gl_renderbuffer * rb)906 read_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 = _mesa_has_depth_float_channel(internalFormat);
914 
915    is_unsigned_int = _mesa_is_enum_format_unsigned_int(internalFormat);
916    if (!is_unsigned_int) {
917       is_signed_int = _mesa_is_enum_format_signed_int(internalFormat);
918    }
919 
920    switch (format) {
921    case GL_RGBA:
922       if (type == GL_FLOAT && data_type == GL_FLOAT)
923          return GL_NO_ERROR; /* EXT_color_buffer_float */
924       if (type == GL_UNSIGNED_BYTE && data_type == GL_UNSIGNED_NORMALIZED)
925          return GL_NO_ERROR;
926       if (internalFormat == GL_RGB10_A2 &&
927           type == GL_UNSIGNED_INT_2_10_10_10_REV)
928          return GL_NO_ERROR;
929       if (internalFormat == GL_RGB10_A2UI && type == GL_UNSIGNED_BYTE)
930          return GL_NO_ERROR;
931       if (type == GL_UNSIGNED_SHORT) {
932          switch (internalFormat) {
933          case GL_R16:
934          case GL_RG16:
935          case GL_RGB16:
936          case GL_RGBA16:
937             if (_mesa_has_EXT_texture_norm16(ctx))
938                return GL_NO_ERROR;
939          }
940       }
941       if (type == GL_SHORT) {
942          switch (internalFormat) {
943          case GL_R16_SNORM:
944          case GL_RG16_SNORM:
945          case GL_RGBA16_SNORM:
946             if (_mesa_has_EXT_texture_norm16(ctx) &&
947                 _mesa_has_EXT_render_snorm(ctx))
948                return GL_NO_ERROR;
949          }
950       }
951       if (type == GL_BYTE) {
952          switch (internalFormat) {
953          case GL_R8_SNORM:
954          case GL_RG8_SNORM:
955          case GL_RGBA8_SNORM:
956             if (_mesa_has_EXT_render_snorm(ctx))
957                return GL_NO_ERROR;
958          }
959       }
960       if (type == GL_UNSIGNED_BYTE) {
961          switch (internalFormat) {
962          case GL_R8_SNORM:
963          case GL_RG8_SNORM:
964          case GL_RGBA8_SNORM:
965             if (_mesa_has_EXT_render_snorm(ctx))
966                return GL_NO_ERROR;
967          }
968       }
969       break;
970    case GL_BGRA:
971       /* GL_EXT_read_format_bgra */
972       if (type == GL_UNSIGNED_BYTE ||
973           type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
974           type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
975          return GL_NO_ERROR;
976       break;
977    case GL_RGBA_INTEGER:
978       if ((is_signed_int && type == GL_INT) ||
979           (is_unsigned_int && type == GL_UNSIGNED_INT))
980          return GL_NO_ERROR;
981       break;
982    case GL_DEPTH_STENCIL:
983       switch (type) {
984       case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
985          if (is_float_depth)
986             return GL_NO_ERROR;
987          break;
988       case GL_UNSIGNED_INT_24_8:
989          if (!is_float_depth)
990             return GL_NO_ERROR;
991          break;
992       default:
993          return GL_INVALID_ENUM;
994       }
995       break;
996    case GL_DEPTH_COMPONENT:
997       switch (type) {
998       case GL_FLOAT:
999          if (is_float_depth)
1000             return GL_NO_ERROR;
1001          break;
1002       case GL_UNSIGNED_SHORT:
1003       case GL_UNSIGNED_INT:
1004       case GL_UNSIGNED_INT_24_8:
1005          if (!is_float_depth)
1006             return GL_NO_ERROR;
1007          break;
1008       default:
1009          return GL_INVALID_ENUM;
1010       }
1011       break;
1012    case GL_STENCIL_INDEX:
1013       switch (type) {
1014       case GL_UNSIGNED_BYTE:
1015          return GL_NO_ERROR;
1016       default:
1017          return GL_INVALID_ENUM;
1018       }
1019       break;
1020    }
1021 
1022    return GL_INVALID_OPERATION;
1023 }
1024 
1025 
1026 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)1027 read_pixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
1028             GLenum type, GLsizei bufSize, GLvoid *pixels, bool no_error)
1029 {
1030    GLenum err = GL_NO_ERROR;
1031    struct gl_renderbuffer *rb;
1032    struct gl_pixelstore_attrib clippedPacking;
1033 
1034    GET_CURRENT_CONTEXT(ctx);
1035 
1036    FLUSH_VERTICES(ctx, 0);
1037 
1038    if (MESA_VERBOSE & VERBOSE_API)
1039       _mesa_debug(ctx, "glReadPixels(%d, %d, %s, %s, %p)\n",
1040                   width, height,
1041                   _mesa_enum_to_string(format),
1042                   _mesa_enum_to_string(type),
1043                   pixels);
1044 
1045    if (!no_error && (width < 0 || height < 0)) {
1046       _mesa_error( ctx, GL_INVALID_VALUE,
1047                    "glReadPixels(width=%d height=%d)", width, height );
1048       return;
1049    }
1050 
1051    if (ctx->NewState)
1052       _mesa_update_state(ctx);
1053 
1054    if (!no_error && ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
1055       _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
1056                   "glReadPixels(incomplete framebuffer)" );
1057       return;
1058    }
1059 
1060    rb = _mesa_get_read_renderbuffer_for_format(ctx, format);
1061    if (!no_error) {
1062       if (rb == NULL) {
1063          _mesa_error(ctx, GL_INVALID_OPERATION,
1064                      "glReadPixels(read buffer)");
1065          return;
1066       }
1067 
1068       /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
1069        * combinations of format and type that can be used.
1070        *
1071        * Technically, only two combinations are actually allowed:
1072        * GL_RGBA/GL_UNSIGNED_BYTE, and some implementation-specific internal
1073        * preferred combination.  This code doesn't know what that preferred
1074        * combination is, and Mesa can handle anything valid.  Just work instead.
1075        */
1076       if (_mesa_is_gles(ctx)) {
1077          if (ctx->API == API_OPENGLES2 &&
1078              _mesa_is_color_format(format) &&
1079              _mesa_get_color_read_format(ctx, NULL, "glReadPixels") == format &&
1080              _mesa_get_color_read_type(ctx, NULL, "glReadPixels") == type) {
1081             err = GL_NO_ERROR;
1082          } else if (ctx->Version < 30) {
1083             err = _mesa_es_error_check_format_and_type(ctx, format, type, 2);
1084             if (err == GL_NO_ERROR) {
1085                if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) {
1086                   err = GL_INVALID_OPERATION;
1087                }
1088             }
1089          } else {
1090             err = read_pixels_es3_error_check(ctx, format, type, rb);
1091          }
1092 
1093          if (err != GL_NO_ERROR) {
1094             _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
1095                         _mesa_enum_to_string(format),
1096                         _mesa_enum_to_string(type));
1097             return;
1098          }
1099       }
1100 
1101       err = _mesa_error_check_format_and_type(ctx, format, type);
1102       if (err != GL_NO_ERROR) {
1103          _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
1104                      _mesa_enum_to_string(format),
1105                      _mesa_enum_to_string(type));
1106          return;
1107       }
1108 
1109       if (_mesa_is_user_fbo(ctx->ReadBuffer) &&
1110           ctx->ReadBuffer->Visual.samples > 0) {
1111          _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)");
1112          return;
1113       }
1114 
1115       if (!_mesa_source_buffer_exists(ctx, format)) {
1116          _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)");
1117          return;
1118       }
1119 
1120       /* Check that the destination format and source buffer are both
1121        * integer-valued or both non-integer-valued.
1122        */
1123       if (ctx->Extensions.EXT_texture_integer && _mesa_is_color_format(format)) {
1124          const struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
1125          const GLboolean srcInteger = _mesa_is_format_integer_color(rb->Format);
1126          const GLboolean dstInteger = _mesa_is_enum_format_integer(format);
1127          if (dstInteger != srcInteger) {
1128             _mesa_error(ctx, GL_INVALID_OPERATION,
1129                         "glReadPixels(integer / non-integer format mismatch");
1130             return;
1131          }
1132       }
1133    }
1134 
1135    /* Do all needed clipping here, so that we can forget about it later */
1136    clippedPacking = ctx->Pack;
1137    if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking))
1138       return; /* nothing to do */
1139 
1140    if (!no_error) {
1141       if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
1142                                      format, type, bufSize, pixels)) {
1143          if (ctx->Pack.BufferObj) {
1144             _mesa_error(ctx, GL_INVALID_OPERATION,
1145                         "glReadPixels(out of bounds PBO access)");
1146          } else {
1147             _mesa_error(ctx, GL_INVALID_OPERATION,
1148                         "glReadnPixelsARB(out of bounds access:"
1149                         " bufSize (%d) is too small)", bufSize);
1150          }
1151          return;
1152       }
1153 
1154       if (ctx->Pack.BufferObj &&
1155           _mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
1156          /* buffer is mapped - that's an error */
1157          _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
1158          return;
1159       }
1160    }
1161 
1162    ctx->Driver.ReadPixels(ctx, x, y, width, height,
1163                           format, type, &clippedPacking, pixels);
1164 }
1165 
1166 void GLAPIENTRY
_mesa_ReadnPixelsARB_no_error(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLvoid * pixels)1167 _mesa_ReadnPixelsARB_no_error(GLint x, GLint y, GLsizei width, GLsizei height,
1168                               GLenum format, GLenum type, GLsizei bufSize,
1169                               GLvoid *pixels)
1170 {
1171    read_pixels(x, y, width, height, format, type, bufSize, pixels, true);
1172 }
1173 
1174 void GLAPIENTRY
_mesa_ReadnPixelsARB(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLvoid * pixels)1175 _mesa_ReadnPixelsARB(GLint x, GLint y, GLsizei width, GLsizei height,
1176                      GLenum format, GLenum type, GLsizei bufSize,
1177                      GLvoid *pixels)
1178 {
1179    read_pixels(x, y, width, height, format, type, bufSize, pixels, false);
1180 }
1181 
1182 void GLAPIENTRY
_mesa_ReadPixels_no_error(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)1183 _mesa_ReadPixels_no_error(GLint x, GLint y, GLsizei width, GLsizei height,
1184                           GLenum format, GLenum type, GLvoid *pixels)
1185 {
1186    _mesa_ReadnPixelsARB_no_error(x, y, width, height, format, type, INT_MAX,
1187                                  pixels);
1188 }
1189 
1190 void GLAPIENTRY
_mesa_ReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)1191 _mesa_ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
1192                  GLenum format, GLenum type, GLvoid *pixels)
1193 {
1194    _mesa_ReadnPixelsARB(x, y, width, height, format, type, INT_MAX, pixels);
1195 }
1196