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