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