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