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