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