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