mesa: fix SwapBytes handling in numerous places
[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(GLenum srcBaseFormat,
51 GLenum dstBaseFormat)
52 {
53 return (srcBaseFormat == GL_RG ||
54 srcBaseFormat == GL_RGB ||
55 srcBaseFormat == GL_RGBA) &&
56 (dstBaseFormat == GL_LUMINANCE ||
57 dstBaseFormat == GL_LUMINANCE_ALPHA);
58 }
59
60 /**
61 * Return true if the conversion L,I to RGB conversion is needed.
62 */
63 GLboolean
64 _mesa_need_luminance_to_rgb_conversion(GLenum srcBaseFormat,
65 GLenum dstBaseFormat)
66 {
67 return (srcBaseFormat == GL_LUMINANCE ||
68 srcBaseFormat == GL_LUMINANCE_ALPHA ||
69 srcBaseFormat == GL_INTENSITY) &&
70 (dstBaseFormat == GL_GREEN ||
71 dstBaseFormat == GL_BLUE ||
72 dstBaseFormat == GL_RG ||
73 dstBaseFormat == GL_RGB ||
74 dstBaseFormat == GL_BGR ||
75 dstBaseFormat == GL_RGBA ||
76 dstBaseFormat == GL_BGRA);
77 }
78
79 /**
80 * Return transfer op flags for this ReadPixels operation.
81 */
82 GLbitfield
83 _mesa_get_readpixels_transfer_ops(const struct gl_context *ctx,
84 mesa_format texFormat,
85 GLenum format, GLenum type,
86 GLboolean uses_blit)
87 {
88 GLbitfield transferOps = ctx->_ImageTransferState;
89 GLenum srcBaseFormat = _mesa_get_format_base_format(texFormat);
90 GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
91
92 if (format == GL_DEPTH_COMPONENT ||
93 format == GL_DEPTH_STENCIL ||
94 format == GL_STENCIL_INDEX) {
95 return 0;
96 }
97
98 /* Pixel transfer ops (scale, bias, table lookup) do not apply
99 * to integer formats.
100 */
101 if (_mesa_is_enum_format_integer(format)) {
102 return 0;
103 }
104
105 if (uses_blit) {
106 /* For blit-based ReadPixels packing, the clamping is done automatically
107 * unless the type is float. */
108 if (_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) &&
109 (type == GL_FLOAT || type == GL_HALF_FLOAT)) {
110 transferOps |= IMAGE_CLAMP_BIT;
111 }
112 }
113 else {
114 /* For CPU-based ReadPixels packing, the clamping must always be done
115 * for non-float types, */
116 if (_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) ||
117 (type != GL_FLOAT && type != GL_HALF_FLOAT)) {
118 transferOps |= IMAGE_CLAMP_BIT;
119 }
120 }
121
122 /* If the format is unsigned normalized, we can ignore clamping
123 * because the values are already in the range [0,1] so it won't
124 * have any effect anyway.
125 */
126 if (_mesa_get_format_datatype(texFormat) == GL_UNSIGNED_NORMALIZED &&
127 !_mesa_need_rgb_to_luminance_conversion(srcBaseFormat, dstBaseFormat)) {
128 transferOps &= ~IMAGE_CLAMP_BIT;
129 }
130
131 return transferOps;
132 }
133
134
135 /**
136 * Return true if memcpy cannot be used for ReadPixels.
137 *
138 * If uses_blit is true, the function returns true if a simple 3D engine blit
139 * cannot be used for ReadPixels packing.
140 *
141 * NOTE: This doesn't take swizzling and format conversions between
142 * the readbuffer and the pixel pack buffer into account.
143 */
144 GLboolean
145 _mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format,
146 GLenum type, GLboolean uses_blit)
147 {
148 struct gl_renderbuffer *rb =
149 _mesa_get_read_renderbuffer_for_format(ctx, format);
150 GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
151
152 assert(rb);
153
154 /* There are different rules depending on the base format. */
155 switch (format) {
156 case GL_DEPTH_STENCIL:
157 return !_mesa_has_depthstencil_combined(ctx->ReadBuffer) ||
158 ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f ||
159 ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
160 ctx->Pixel.MapStencilFlag;
161
162 case GL_DEPTH_COMPONENT:
163 return ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f;
164
165 case GL_STENCIL_INDEX:
166 return ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
167 ctx->Pixel.MapStencilFlag;
168
169 default:
170 /* Color formats. */
171 if (_mesa_need_rgb_to_luminance_conversion(rb->_BaseFormat,
172 dstBaseFormat)) {
173 return GL_TRUE;
174 }
175
176 /* And finally, see if there are any transfer ops. */
177 return _mesa_get_readpixels_transfer_ops(ctx, rb->Format, format, type,
178 uses_blit) != 0;
179 }
180 return GL_FALSE;
181 }
182
183
184 static GLboolean
185 readpixels_can_use_memcpy(const struct gl_context *ctx, GLenum format, GLenum type,
186 const struct gl_pixelstore_attrib *packing)
187 {
188 struct gl_renderbuffer *rb =
189 _mesa_get_read_renderbuffer_for_format(ctx, format);
190
191 assert(rb);
192
193 if (_mesa_readpixels_needs_slow_path(ctx, format, type, GL_FALSE)) {
194 return GL_FALSE;
195 }
196
197 /* The base internal format and the base Mesa format must match. */
198 if (rb->_BaseFormat != _mesa_get_format_base_format(rb->Format)) {
199 return GL_FALSE;
200 }
201
202 /* The Mesa format must match the input format and type. */
203 if (!_mesa_format_matches_format_and_type(rb->Format, format, type,
204 packing->SwapBytes, NULL)) {
205 return GL_FALSE;
206 }
207
208 return GL_TRUE;
209 }
210
211
212 static GLboolean
213 readpixels_memcpy(struct gl_context *ctx,
214 GLint x, GLint y,
215 GLsizei width, GLsizei height,
216 GLenum format, GLenum type,
217 GLvoid *pixels,
218 const struct gl_pixelstore_attrib *packing)
219 {
220 struct gl_renderbuffer *rb =
221 _mesa_get_read_renderbuffer_for_format(ctx, format);
222 GLubyte *dst, *map;
223 int dstStride, stride, j, texelBytes;
224
225 /* Fail if memcpy cannot be used. */
226 if (!readpixels_can_use_memcpy(ctx, format, type, packing)) {
227 return GL_FALSE;
228 }
229
230 dstStride = _mesa_image_row_stride(packing, width, format, type);
231 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
232 format, type, 0, 0);
233
234 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
235 &map, &stride);
236 if (!map) {
237 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
238 return GL_TRUE; /* don't bother trying the slow path */
239 }
240
241 texelBytes = _mesa_get_format_bytes(rb->Format);
242
243 /* memcpy*/
244 for (j = 0; j < height; j++) {
245 memcpy(dst, map, width * texelBytes);
246 dst += dstStride;
247 map += stride;
248 }
249
250 ctx->Driver.UnmapRenderbuffer(ctx, rb);
251 return GL_TRUE;
252 }
253
254
255 /**
256 * Optimized path for conversion of depth values to GL_DEPTH_COMPONENT,
257 * GL_UNSIGNED_INT.
258 */
259 static GLboolean
260 read_uint_depth_pixels( struct gl_context *ctx,
261 GLint x, GLint y,
262 GLsizei width, GLsizei height,
263 GLenum type, GLvoid *pixels,
264 const struct gl_pixelstore_attrib *packing )
265 {
266 struct gl_framebuffer *fb = ctx->ReadBuffer;
267 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
268 GLubyte *map, *dst;
269 int stride, dstStride, j;
270
271 if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F)
272 return GL_FALSE;
273
274 if (packing->SwapBytes)
275 return GL_FALSE;
276
277 if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED)
278 return GL_FALSE;
279
280 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
281 &map, &stride);
282
283 if (!map) {
284 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
285 return GL_TRUE; /* don't bother trying the slow path */
286 }
287
288 dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
289 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
290 GL_DEPTH_COMPONENT, type, 0, 0);
291
292 for (j = 0; j < height; j++) {
293 _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst);
294
295 map += stride;
296 dst += dstStride;
297 }
298 ctx->Driver.UnmapRenderbuffer(ctx, rb);
299
300 return GL_TRUE;
301 }
302
303 /**
304 * Read pixels for format=GL_DEPTH_COMPONENT.
305 */
306 static void
307 read_depth_pixels( struct gl_context *ctx,
308 GLint x, GLint y,
309 GLsizei width, GLsizei height,
310 GLenum type, GLvoid *pixels,
311 const struct gl_pixelstore_attrib *packing )
312 {
313 struct gl_framebuffer *fb = ctx->ReadBuffer;
314 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
315 GLint j;
316 GLubyte *dst, *map;
317 int dstStride, stride;
318 GLfloat *depthValues;
319
320 if (!rb)
321 return;
322
323 /* clipping should have been done already */
324 assert(x >= 0);
325 assert(y >= 0);
326 assert(x + width <= (GLint) rb->Width);
327 assert(y + height <= (GLint) rb->Height);
328
329 if (type == GL_UNSIGNED_INT &&
330 read_uint_depth_pixels(ctx, x, y, width, height, type, pixels, packing)) {
331 return;
332 }
333
334 dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
335 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
336 GL_DEPTH_COMPONENT, type, 0, 0);
337
338 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
339 &map, &stride);
340 if (!map) {
341 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
342 return;
343 }
344
345 depthValues = malloc(width * sizeof(GLfloat));
346
347 if (depthValues) {
348 /* General case (slower) */
349 for (j = 0; j < height; j++, y++) {
350 _mesa_unpack_float_z_row(rb->Format, width, map, depthValues);
351 _mesa_pack_depth_span(ctx, width, dst, type, depthValues, packing);
352
353 dst += dstStride;
354 map += stride;
355 }
356 }
357 else {
358 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
359 }
360
361 free(depthValues);
362
363 ctx->Driver.UnmapRenderbuffer(ctx, rb);
364 }
365
366
367 /**
368 * Read pixels for format=GL_STENCIL_INDEX.
369 */
370 static void
371 read_stencil_pixels( struct gl_context *ctx,
372 GLint x, GLint y,
373 GLsizei width, GLsizei height,
374 GLenum type, GLvoid *pixels,
375 const struct gl_pixelstore_attrib *packing )
376 {
377 struct gl_framebuffer *fb = ctx->ReadBuffer;
378 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
379 GLint j;
380 GLubyte *map, *stencil;
381 GLint stride;
382
383 if (!rb)
384 return;
385
386 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
387 &map, &stride);
388 if (!map) {
389 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
390 return;
391 }
392
393 stencil = malloc(width * sizeof(GLubyte));
394
395 if (stencil) {
396 /* process image row by row */
397 for (j = 0; j < height; j++) {
398 GLvoid *dest;
399
400 _mesa_unpack_ubyte_stencil_row(rb->Format, width, map, stencil);
401 dest = _mesa_image_address2d(packing, pixels, width, height,
402 GL_STENCIL_INDEX, type, j, 0);
403
404 _mesa_pack_stencil_span(ctx, width, type, dest, stencil, packing);
405
406 map += stride;
407 }
408 }
409 else {
410 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
411 }
412
413 free(stencil);
414
415 ctx->Driver.UnmapRenderbuffer(ctx, rb);
416 }
417
418 /*
419 * Read R, G, B, A, RGB, L, or LA pixels.
420 */
421 static void
422 read_rgba_pixels( struct gl_context *ctx,
423 GLint x, GLint y,
424 GLsizei width, GLsizei height,
425 GLenum format, GLenum type, GLvoid *pixels,
426 const struct gl_pixelstore_attrib *packing )
427 {
428 GLbitfield transferOps;
429 bool dst_is_integer, convert_rgb_to_lum, needs_rebase;
430 int dst_stride, src_stride, rb_stride;
431 uint32_t dst_format, src_format;
432 GLubyte *dst, *map;
433 mesa_format rb_format;
434 bool needs_rgba;
435 void *rgba, *src;
436 bool src_is_uint = false;
437 uint8_t rebase_swizzle[4];
438 struct gl_framebuffer *fb = ctx->ReadBuffer;
439 struct gl_renderbuffer *rb = fb->_ColorReadBuffer;
440 GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
441
442 if (!rb)
443 return;
444
445 transferOps = _mesa_get_readpixels_transfer_ops(ctx, rb->Format, format,
446 type, GL_FALSE);
447 /* Describe the dst format */
448 dst_is_integer = _mesa_is_enum_format_integer(format);
449 dst_stride = _mesa_image_row_stride(packing, width, format, type);
450 dst_format = _mesa_format_from_format_and_type(format, type);
451 convert_rgb_to_lum =
452 _mesa_need_rgb_to_luminance_conversion(rb->_BaseFormat, dstBaseFormat);
453 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
454 format, type, 0, 0);
455
456 /* Map the source render buffer */
457 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
458 &map, &rb_stride);
459 if (!map) {
460 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
461 return;
462 }
463 rb_format = _mesa_get_srgb_format_linear(rb->Format);
464
465 /*
466 * Depending on the base formats involved in the conversion we might need to
467 * rebase some values, so for these formats we compute a rebase swizzle.
468 */
469 if (rb->_BaseFormat == GL_LUMINANCE || rb->_BaseFormat == GL_INTENSITY) {
470 needs_rebase = true;
471 rebase_swizzle[0] = MESA_FORMAT_SWIZZLE_X;
472 rebase_swizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
473 rebase_swizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
474 rebase_swizzle[3] = MESA_FORMAT_SWIZZLE_ONE;
475 } else if (rb->_BaseFormat == GL_LUMINANCE_ALPHA) {
476 needs_rebase = true;
477 rebase_swizzle[0] = MESA_FORMAT_SWIZZLE_X;
478 rebase_swizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
479 rebase_swizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
480 rebase_swizzle[3] = MESA_FORMAT_SWIZZLE_W;
481 } else if (_mesa_get_format_base_format(rb_format) != rb->_BaseFormat) {
482 needs_rebase =
483 _mesa_compute_rgba2base2rgba_component_mapping(rb->_BaseFormat,
484 rebase_swizzle);
485 } else {
486 needs_rebase = false;
487 }
488
489 /* Since _mesa_format_convert does not handle transferOps we need to handle
490 * them before we call the function. This requires to convert to RGBA float
491 * first so we can call _mesa_apply_rgba_transfer_ops. If the dst format is
492 * integer transferOps do not apply.
493 *
494 * Converting to luminance also requires converting to RGBA first, so we can
495 * then compute luminance values as L=R+G+B. Notice that this is different
496 * from GetTexImage, where we compute L=R.
497 */
498 assert(!transferOps || (transferOps && !dst_is_integer));
499
500 needs_rgba = transferOps || convert_rgb_to_lum;
501 rgba = NULL;
502 if (needs_rgba) {
503 uint32_t rgba_format;
504 int rgba_stride;
505 bool need_convert;
506
507 /* Convert to RGBA float or int/uint depending on the type of the src */
508 if (dst_is_integer) {
509 src_is_uint = _mesa_is_format_unsigned(rb_format);
510 if (src_is_uint) {
511 rgba_format = RGBA32_UINT;
512 rgba_stride = width * 4 * sizeof(GLuint);
513 } else {
514 rgba_format = RGBA32_INT;
515 rgba_stride = width * 4 * sizeof(GLint);
516 }
517 } else {
518 rgba_format = RGBA32_FLOAT;
519 rgba_stride = width * 4 * sizeof(GLfloat);
520 }
521
522 /* If we are lucky and the dst format matches the RGBA format we need to
523 * convert to, then we can convert directly into the dst buffer and avoid
524 * the final conversion/copy from the rgba buffer to the dst buffer.
525 */
526 if (dst_format == rgba_format) {
527 need_convert = false;
528 rgba = dst;
529 } else {
530 need_convert = true;
531 rgba = malloc(height * rgba_stride);
532 if (!rgba) {
533 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
534 goto done_unmap;
535 }
536 }
537
538 /* Convert to RGBA now */
539 _mesa_format_convert(rgba, rgba_format, rgba_stride,
540 map, rb_format, rb_stride,
541 width, height,
542 needs_rebase ? rebase_swizzle : NULL);
543
544 /* Handle transfer ops if necessary */
545 if (transferOps)
546 _mesa_apply_rgba_transfer_ops(ctx, transferOps, width * height, rgba);
547
548 /* If we had to rebase, we have already taken care of that */
549 needs_rebase = false;
550
551 /* If we were lucky and our RGBA conversion matches the dst format, then
552 * we are done.
553 */
554 if (!need_convert)
555 goto done_swap;
556
557 /* Otherwise, we need to convert from RGBA to dst next */
558 src = rgba;
559 src_format = rgba_format;
560 src_stride = rgba_stride;
561 } else {
562 /* No RGBA conversion needed, convert directly to dst */
563 src = map;
564 src_format = rb_format;
565 src_stride = rb_stride;
566 }
567
568 /* Do the conversion.
569 *
570 * If the dst format is Luminance, we need to do the conversion by computing
571 * L=R+G+B values.
572 */
573 if (!convert_rgb_to_lum) {
574 _mesa_format_convert(dst, dst_format, dst_stride,
575 src, src_format, src_stride,
576 width, height,
577 needs_rebase ? rebase_swizzle : NULL);
578 } else if (!dst_is_integer) {
579 /* Compute float Luminance values from RGBA float */
580 int luminance_stride, luminance_bytes;
581 void *luminance;
582 uint32_t luminance_format;
583
584 luminance_stride = width * sizeof(GL_FLOAT);
585 if (format == GL_LUMINANCE_ALPHA)
586 luminance_stride *= 2;
587 luminance_bytes = height * luminance_stride;
588 luminance = malloc(luminance_bytes);
589 if (!luminance) {
590 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
591 free(rgba);
592 goto done_unmap;
593 }
594 _mesa_pack_luminance_from_rgba_float(width * height, src,
595 luminance, format, transferOps);
596
597 /* Convert from Luminance float to dst (this will hadle type conversion
598 * from float to the type of dst if necessary)
599 */
600 luminance_format = _mesa_format_from_format_and_type(format, GL_FLOAT);
601 _mesa_format_convert(dst, dst_format, dst_stride,
602 luminance, luminance_format, luminance_stride,
603 width, height, NULL);
604 free(luminance);
605 } else {
606 _mesa_pack_luminance_from_rgba_integer(width * height, src, !src_is_uint,
607 dst, format, type);
608 }
609
610 if (rgba)
611 free(rgba);
612
613 done_swap:
614 /* Handle byte swapping if required */
615 if (packing->SwapBytes) {
616 _mesa_swap_bytes_2d_image(format, type, packing,
617 width, height, dst, dst);
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.0F || ctx->Pixel.DepthBias != 0.0F;
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 GLboolean is_float_depth = (internalFormat == GL_DEPTH_COMPONENT32F) ||
913 (internalFormat == GL_DEPTH32F_STENCIL8);
914
915 is_unsigned_int = _mesa_is_enum_format_unsigned_int(internalFormat);
916 if (!is_unsigned_int) {
917 is_signed_int = _mesa_is_enum_format_signed_int(internalFormat);
918 }
919
920 switch (format) {
921 case GL_RGBA:
922 if (type == GL_FLOAT && data_type == GL_FLOAT)
923 return GL_NO_ERROR; /* EXT_color_buffer_float */
924 if (type == GL_UNSIGNED_BYTE && data_type == GL_UNSIGNED_NORMALIZED)
925 return GL_NO_ERROR;
926 if (internalFormat == GL_RGB10_A2 &&
927 type == GL_UNSIGNED_INT_2_10_10_10_REV)
928 return GL_NO_ERROR;
929 if (internalFormat == GL_RGB10_A2UI && type == GL_UNSIGNED_BYTE)
930 return GL_NO_ERROR;
931 break;
932 case GL_BGRA:
933 /* GL_EXT_read_format_bgra */
934 if (type == GL_UNSIGNED_BYTE ||
935 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
936 type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
937 return GL_NO_ERROR;
938 break;
939 case GL_RGBA_INTEGER:
940 if ((is_signed_int && type == GL_INT) ||
941 (is_unsigned_int && type == GL_UNSIGNED_INT))
942 return GL_NO_ERROR;
943 break;
944 case GL_DEPTH_STENCIL:
945 switch (type) {
946 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
947 if (is_float_depth)
948 return GL_NO_ERROR;
949 break;
950 case GL_UNSIGNED_INT_24_8:
951 if (!is_float_depth)
952 return GL_NO_ERROR;
953 break;
954 default:
955 return GL_INVALID_ENUM;
956 }
957 break;
958 case GL_DEPTH_COMPONENT:
959 switch (type) {
960 case GL_FLOAT:
961 if (is_float_depth)
962 return GL_NO_ERROR;
963 break;
964 case GL_UNSIGNED_SHORT:
965 case GL_UNSIGNED_INT_24_8:
966 if (!is_float_depth)
967 return GL_NO_ERROR;
968 break;
969 default:
970 return GL_INVALID_ENUM;
971 }
972 break;
973 case GL_STENCIL_INDEX:
974 switch (type) {
975 case GL_UNSIGNED_BYTE:
976 return GL_NO_ERROR;
977 default:
978 return GL_INVALID_ENUM;
979 }
980 break;
981 }
982
983 return GL_INVALID_OPERATION;
984 }
985
986
987 void GLAPIENTRY
988 _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
989 GLenum format, GLenum type, GLsizei bufSize,
990 GLvoid *pixels )
991 {
992 GLenum err = GL_NO_ERROR;
993 struct gl_renderbuffer *rb;
994
995 GET_CURRENT_CONTEXT(ctx);
996
997 FLUSH_VERTICES(ctx, 0);
998 FLUSH_CURRENT(ctx, 0);
999
1000 if (MESA_VERBOSE & VERBOSE_API)
1001 _mesa_debug(ctx, "glReadPixels(%d, %d, %s, %s, %p)\n",
1002 width, height,
1003 _mesa_enum_to_string(format),
1004 _mesa_enum_to_string(type),
1005 pixels);
1006
1007 if (width < 0 || height < 0) {
1008 _mesa_error( ctx, GL_INVALID_VALUE,
1009 "glReadPixels(width=%d height=%d)", width, height );
1010 return;
1011 }
1012
1013 if (ctx->NewState)
1014 _mesa_update_state(ctx);
1015
1016 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
1017 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
1018 "glReadPixels(incomplete framebuffer)" );
1019 return;
1020 }
1021
1022 rb = _mesa_get_read_renderbuffer_for_format(ctx, format);
1023 if (rb == NULL) {
1024 _mesa_error(ctx, GL_INVALID_OPERATION,
1025 "glReadPixels(read buffer)");
1026 return;
1027 }
1028
1029 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
1030 * combinations of format and type that can be used.
1031 *
1032 * Technically, only two combinations are actually allowed:
1033 * GL_RGBA/GL_UNSIGNED_BYTE, and some implementation-specific internal
1034 * preferred combination. This code doesn't know what that preferred
1035 * combination is, and Mesa can handle anything valid. Just work instead.
1036 */
1037 if (_mesa_is_gles(ctx)) {
1038 if (ctx->API == API_OPENGLES2 &&
1039 _mesa_is_color_format(format) &&
1040 _mesa_get_color_read_format(ctx) == format &&
1041 _mesa_get_color_read_type(ctx) == type) {
1042 err = GL_NO_ERROR;
1043 } else if (ctx->Version < 30) {
1044 err = _mesa_es_error_check_format_and_type(format, type, 2);
1045 if (err == GL_NO_ERROR) {
1046 if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) {
1047 err = GL_INVALID_OPERATION;
1048 }
1049 }
1050 } else {
1051 err = read_pixels_es3_error_check(format, type, rb);
1052 }
1053
1054 if (err != GL_NO_ERROR) {
1055 _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
1056 _mesa_enum_to_string(format),
1057 _mesa_enum_to_string(type));
1058 return;
1059 }
1060 }
1061
1062 err = _mesa_error_check_format_and_type(ctx, format, type);
1063 if (err != GL_NO_ERROR) {
1064 _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
1065 _mesa_enum_to_string(format),
1066 _mesa_enum_to_string(type));
1067 return;
1068 }
1069
1070 if (_mesa_is_user_fbo(ctx->ReadBuffer) &&
1071 ctx->ReadBuffer->Visual.samples > 0) {
1072 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)");
1073 return;
1074 }
1075
1076 if (!_mesa_source_buffer_exists(ctx, format)) {
1077 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)");
1078 return;
1079 }
1080
1081 /* Check that the destination format and source buffer are both
1082 * integer-valued or both non-integer-valued.
1083 */
1084 if (ctx->Extensions.EXT_texture_integer && _mesa_is_color_format(format)) {
1085 const struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
1086 const GLboolean srcInteger = _mesa_is_format_integer_color(rb->Format);
1087 const GLboolean dstInteger = _mesa_is_enum_format_integer(format);
1088 if (dstInteger != srcInteger) {
1089 _mesa_error(ctx, GL_INVALID_OPERATION,
1090 "glReadPixels(integer / non-integer format mismatch");
1091 return;
1092 }
1093 }
1094
1095 if (width == 0 || height == 0)
1096 return; /* nothing to do */
1097
1098 if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
1099 format, type, bufSize, pixels)) {
1100 if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
1101 _mesa_error(ctx, GL_INVALID_OPERATION,
1102 "glReadPixels(out of bounds PBO access)");
1103 } else {
1104 _mesa_error(ctx, GL_INVALID_OPERATION,
1105 "glReadnPixelsARB(out of bounds access:"
1106 " bufSize (%d) is too small)", bufSize);
1107 }
1108 return;
1109 }
1110
1111 if (_mesa_is_bufferobj(ctx->Pack.BufferObj) &&
1112 _mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
1113 /* buffer is mapped - that's an error */
1114 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
1115 return;
1116 }
1117
1118 ctx->Driver.ReadPixels(ctx, x, y, width, height,
1119 format, type, &ctx->Pack, pixels);
1120 }
1121
1122 void GLAPIENTRY
1123 _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
1124 GLenum format, GLenum type, GLvoid *pixels )
1125 {
1126 _mesa_ReadnPixelsARB(x, y, width, height, format, type, INT_MAX, pixels);
1127 }