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