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