Merge remote-tracking branch 'mesa-public/master' into vulkan
[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 GLint swapSize = _mesa_sizeof_packed_type(type);
617 if (swapSize == 2 || swapSize == 4) {
618 int swapsPerPixel = _mesa_bytes_per_pixel(format, type) / swapSize;
619 assert(_mesa_bytes_per_pixel(format, type) % swapSize == 0);
620 if (swapSize == 2)
621 _mesa_swap2((GLushort *) dst, width * height * swapsPerPixel);
622 else if (swapSize == 4)
623 _mesa_swap4((GLuint *) dst, width * height * swapsPerPixel);
624 }
625 }
626
627 done_unmap:
628 ctx->Driver.UnmapRenderbuffer(ctx, rb);
629 }
630
631 /**
632 * For a packed depth/stencil buffer being read as depth/stencil, just memcpy the
633 * data (possibly swapping 8/24 vs 24/8 as we go).
634 */
635 static GLboolean
636 fast_read_depth_stencil_pixels(struct gl_context *ctx,
637 GLint x, GLint y,
638 GLsizei width, GLsizei height,
639 GLubyte *dst, int dstStride)
640 {
641 struct gl_framebuffer *fb = ctx->ReadBuffer;
642 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
643 struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
644 GLubyte *map;
645 int stride, i;
646
647 if (rb != stencilRb)
648 return GL_FALSE;
649
650 if (rb->Format != MESA_FORMAT_S8_UINT_Z24_UNORM &&
651 rb->Format != MESA_FORMAT_Z24_UNORM_S8_UINT)
652 return GL_FALSE;
653
654 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
655 &map, &stride);
656 if (!map) {
657 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
658 return GL_TRUE; /* don't bother trying the slow path */
659 }
660
661 for (i = 0; i < height; i++) {
662 _mesa_unpack_uint_24_8_depth_stencil_row(rb->Format, width,
663 map, (GLuint *)dst);
664 map += stride;
665 dst += dstStride;
666 }
667
668 ctx->Driver.UnmapRenderbuffer(ctx, rb);
669
670 return GL_TRUE;
671 }
672
673
674 /**
675 * For non-float-depth and stencil buffers being read as 24/8 depth/stencil,
676 * copy the integer data directly instead of converting depth to float and
677 * re-packing.
678 */
679 static GLboolean
680 fast_read_depth_stencil_pixels_separate(struct gl_context *ctx,
681 GLint x, GLint y,
682 GLsizei width, GLsizei height,
683 uint32_t *dst, int dstStride)
684 {
685 struct gl_framebuffer *fb = ctx->ReadBuffer;
686 struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
687 struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
688 GLubyte *depthMap, *stencilMap, *stencilVals;
689 int depthStride, stencilStride, i, j;
690
691 if (_mesa_get_format_datatype(depthRb->Format) != GL_UNSIGNED_NORMALIZED)
692 return GL_FALSE;
693
694 ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
695 GL_MAP_READ_BIT, &depthMap, &depthStride);
696 if (!depthMap) {
697 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
698 return GL_TRUE; /* don't bother trying the slow path */
699 }
700
701 ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
702 GL_MAP_READ_BIT, &stencilMap, &stencilStride);
703 if (!stencilMap) {
704 ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
705 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
706 return GL_TRUE; /* don't bother trying the slow path */
707 }
708
709 stencilVals = malloc(width * sizeof(GLubyte));
710
711 if (stencilVals) {
712 for (j = 0; j < height; j++) {
713 _mesa_unpack_uint_z_row(depthRb->Format, width, depthMap, dst);
714 _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
715 stencilMap, stencilVals);
716
717 for (i = 0; i < width; i++) {
718 dst[i] = (dst[i] & 0xffffff00) | stencilVals[i];
719 }
720
721 depthMap += depthStride;
722 stencilMap += stencilStride;
723 dst += dstStride / 4;
724 }
725 }
726 else {
727 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
728 }
729
730 free(stencilVals);
731
732 ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
733 ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
734
735 return GL_TRUE;
736 }
737
738 static void
739 slow_read_depth_stencil_pixels_separate(struct gl_context *ctx,
740 GLint x, GLint y,
741 GLsizei width, GLsizei height,
742 GLenum type,
743 const struct gl_pixelstore_attrib *packing,
744 GLubyte *dst, int dstStride)
745 {
746 struct gl_framebuffer *fb = ctx->ReadBuffer;
747 struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
748 struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
749 GLubyte *depthMap, *stencilMap;
750 int depthStride, stencilStride, j;
751 GLubyte *stencilVals;
752 GLfloat *depthVals;
753
754
755 /* The depth and stencil buffers might be separate, or a single buffer.
756 * If one buffer, only map it once.
757 */
758 ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
759 GL_MAP_READ_BIT, &depthMap, &depthStride);
760 if (!depthMap) {
761 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
762 return;
763 }
764
765 if (stencilRb != depthRb) {
766 ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
767 GL_MAP_READ_BIT, &stencilMap,
768 &stencilStride);
769 if (!stencilMap) {
770 ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
771 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
772 return;
773 }
774 }
775 else {
776 stencilMap = depthMap;
777 stencilStride = depthStride;
778 }
779
780 stencilVals = malloc(width * sizeof(GLubyte));
781 depthVals = malloc(width * sizeof(GLfloat));
782
783 if (stencilVals && depthVals) {
784 for (j = 0; j < height; j++) {
785 _mesa_unpack_float_z_row(depthRb->Format, width, depthMap, depthVals);
786 _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
787 stencilMap, stencilVals);
788
789 _mesa_pack_depth_stencil_span(ctx, width, type, (GLuint *)dst,
790 depthVals, stencilVals, packing);
791
792 depthMap += depthStride;
793 stencilMap += stencilStride;
794 dst += dstStride;
795 }
796 }
797 else {
798 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
799 }
800
801 free(stencilVals);
802 free(depthVals);
803
804 ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
805 if (stencilRb != depthRb) {
806 ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
807 }
808 }
809
810
811 /**
812 * Read combined depth/stencil values.
813 * We'll have already done error checking to be sure the expected
814 * depth and stencil buffers really exist.
815 */
816 static void
817 read_depth_stencil_pixels(struct gl_context *ctx,
818 GLint x, GLint y,
819 GLsizei width, GLsizei height,
820 GLenum type, GLvoid *pixels,
821 const struct gl_pixelstore_attrib *packing )
822 {
823 const GLboolean scaleOrBias
824 = ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F;
825 const GLboolean stencilTransfer = ctx->Pixel.IndexShift
826 || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag;
827 GLubyte *dst;
828 int dstStride;
829
830 dst = (GLubyte *) _mesa_image_address2d(packing, pixels,
831 width, height,
832 GL_DEPTH_STENCIL_EXT,
833 type, 0, 0);
834 dstStride = _mesa_image_row_stride(packing, width,
835 GL_DEPTH_STENCIL_EXT, type);
836
837 /* Fast 24/8 reads. */
838 if (type == GL_UNSIGNED_INT_24_8 &&
839 !scaleOrBias && !stencilTransfer && !packing->SwapBytes) {
840 if (fast_read_depth_stencil_pixels(ctx, x, y, width, height,
841 dst, dstStride))
842 return;
843
844 if (fast_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
845 (uint32_t *)dst, dstStride))
846 return;
847 }
848
849 slow_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
850 type, packing,
851 dst, dstStride);
852 }
853
854
855
856 /**
857 * Software fallback routine for ctx->Driver.ReadPixels().
858 * By time we get here, all error checking will have been done.
859 */
860 void
861 _mesa_readpixels(struct gl_context *ctx,
862 GLint x, GLint y, GLsizei width, GLsizei height,
863 GLenum format, GLenum type,
864 const struct gl_pixelstore_attrib *packing,
865 GLvoid *pixels)
866 {
867 struct gl_pixelstore_attrib clippedPacking = *packing;
868
869 if (ctx->NewState)
870 _mesa_update_state(ctx);
871
872 /* Do all needed clipping here, so that we can forget about it later */
873 if (_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) {
874
875 pixels = _mesa_map_pbo_dest(ctx, &clippedPacking, pixels);
876
877 if (pixels) {
878 /* Try memcpy first. */
879 if (readpixels_memcpy(ctx, x, y, width, height, format, type,
880 pixels, packing)) {
881 _mesa_unmap_pbo_dest(ctx, &clippedPacking);
882 return;
883 }
884
885 /* Otherwise take the slow path. */
886 switch (format) {
887 case GL_STENCIL_INDEX:
888 read_stencil_pixels(ctx, x, y, width, height, type, pixels,
889 &clippedPacking);
890 break;
891 case GL_DEPTH_COMPONENT:
892 read_depth_pixels(ctx, x, y, width, height, type, pixels,
893 &clippedPacking);
894 break;
895 case GL_DEPTH_STENCIL_EXT:
896 read_depth_stencil_pixels(ctx, x, y, width, height, type, pixels,
897 &clippedPacking);
898 break;
899 default:
900 /* all other formats should be color formats */
901 read_rgba_pixels(ctx, x, y, width, height, format, type, pixels,
902 &clippedPacking);
903 }
904
905 _mesa_unmap_pbo_dest(ctx, &clippedPacking);
906 }
907 }
908 }
909
910
911 static GLenum
912 read_pixels_es3_error_check(GLenum format, GLenum type,
913 const struct gl_renderbuffer *rb)
914 {
915 const GLenum internalFormat = rb->InternalFormat;
916 const GLenum data_type = _mesa_get_format_datatype(rb->Format);
917 GLboolean is_unsigned_int = GL_FALSE;
918 GLboolean is_signed_int = GL_FALSE;
919 GLboolean is_float_depth = (internalFormat == GL_DEPTH_COMPONENT32F) ||
920 (internalFormat == GL_DEPTH32F_STENCIL8);
921
922 is_unsigned_int = _mesa_is_enum_format_unsigned_int(internalFormat);
923 if (!is_unsigned_int) {
924 is_signed_int = _mesa_is_enum_format_signed_int(internalFormat);
925 }
926
927 switch (format) {
928 case GL_RGBA:
929 if (type == GL_FLOAT && data_type == GL_FLOAT)
930 return GL_NO_ERROR; /* EXT_color_buffer_float */
931 if (type == GL_UNSIGNED_BYTE && data_type == GL_UNSIGNED_NORMALIZED)
932 return GL_NO_ERROR;
933 if (internalFormat == GL_RGB10_A2 &&
934 type == GL_UNSIGNED_INT_2_10_10_10_REV)
935 return GL_NO_ERROR;
936 if (internalFormat == GL_RGB10_A2UI && type == GL_UNSIGNED_BYTE)
937 return GL_NO_ERROR;
938 break;
939 case GL_BGRA:
940 /* GL_EXT_read_format_bgra */
941 if (type == GL_UNSIGNED_BYTE ||
942 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
943 type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
944 return GL_NO_ERROR;
945 break;
946 case GL_RGBA_INTEGER:
947 if ((is_signed_int && type == GL_INT) ||
948 (is_unsigned_int && type == GL_UNSIGNED_INT))
949 return GL_NO_ERROR;
950 break;
951 case GL_DEPTH_STENCIL:
952 switch (type) {
953 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
954 if (is_float_depth)
955 return GL_NO_ERROR;
956 break;
957 case GL_UNSIGNED_INT_24_8:
958 if (!is_float_depth)
959 return GL_NO_ERROR;
960 break;
961 default:
962 return GL_INVALID_ENUM;
963 }
964 break;
965 case GL_DEPTH_COMPONENT:
966 switch (type) {
967 case GL_FLOAT:
968 if (is_float_depth)
969 return GL_NO_ERROR;
970 break;
971 case GL_UNSIGNED_SHORT:
972 case GL_UNSIGNED_INT_24_8:
973 if (!is_float_depth)
974 return GL_NO_ERROR;
975 break;
976 default:
977 return GL_INVALID_ENUM;
978 }
979 break;
980 case GL_STENCIL_INDEX:
981 switch (type) {
982 case GL_UNSIGNED_BYTE:
983 return GL_NO_ERROR;
984 default:
985 return GL_INVALID_ENUM;
986 }
987 break;
988 }
989
990 return GL_INVALID_OPERATION;
991 }
992
993
994 void GLAPIENTRY
995 _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
996 GLenum format, GLenum type, GLsizei bufSize,
997 GLvoid *pixels )
998 {
999 GLenum err = GL_NO_ERROR;
1000 struct gl_renderbuffer *rb;
1001
1002 GET_CURRENT_CONTEXT(ctx);
1003
1004 FLUSH_VERTICES(ctx, 0);
1005 FLUSH_CURRENT(ctx, 0);
1006
1007 if (MESA_VERBOSE & VERBOSE_API)
1008 _mesa_debug(ctx, "glReadPixels(%d, %d, %s, %s, %p)\n",
1009 width, height,
1010 _mesa_enum_to_string(format),
1011 _mesa_enum_to_string(type),
1012 pixels);
1013
1014 if (width < 0 || height < 0) {
1015 _mesa_error( ctx, GL_INVALID_VALUE,
1016 "glReadPixels(width=%d height=%d)", width, height );
1017 return;
1018 }
1019
1020 if (ctx->NewState)
1021 _mesa_update_state(ctx);
1022
1023 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
1024 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
1025 "glReadPixels(incomplete framebuffer)" );
1026 return;
1027 }
1028
1029 rb = _mesa_get_read_renderbuffer_for_format(ctx, format);
1030 if (rb == NULL) {
1031 _mesa_error(ctx, GL_INVALID_OPERATION,
1032 "glReadPixels(read buffer)");
1033 return;
1034 }
1035
1036 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
1037 * combinations of format and type that can be used.
1038 *
1039 * Technically, only two combinations are actually allowed:
1040 * GL_RGBA/GL_UNSIGNED_BYTE, and some implementation-specific internal
1041 * preferred combination. This code doesn't know what that preferred
1042 * combination is, and Mesa can handle anything valid. Just work instead.
1043 */
1044 if (_mesa_is_gles(ctx)) {
1045 if (ctx->API == API_OPENGLES2 &&
1046 _mesa_is_color_format(format) &&
1047 _mesa_get_color_read_format(ctx) == format &&
1048 _mesa_get_color_read_type(ctx) == type) {
1049 err = GL_NO_ERROR;
1050 } else if (ctx->Version < 30) {
1051 err = _mesa_es_error_check_format_and_type(format, type, 2);
1052 if (err == GL_NO_ERROR) {
1053 if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) {
1054 err = GL_INVALID_OPERATION;
1055 }
1056 }
1057 } else {
1058 err = read_pixels_es3_error_check(format, type, rb);
1059 }
1060
1061 if (err != GL_NO_ERROR) {
1062 _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
1063 _mesa_enum_to_string(format),
1064 _mesa_enum_to_string(type));
1065 return;
1066 }
1067 }
1068
1069 err = _mesa_error_check_format_and_type(ctx, format, type);
1070 if (err != GL_NO_ERROR) {
1071 _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
1072 _mesa_enum_to_string(format),
1073 _mesa_enum_to_string(type));
1074 return;
1075 }
1076
1077 if (_mesa_is_user_fbo(ctx->ReadBuffer) &&
1078 ctx->ReadBuffer->Visual.samples > 0) {
1079 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)");
1080 return;
1081 }
1082
1083 if (!_mesa_source_buffer_exists(ctx, format)) {
1084 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)");
1085 return;
1086 }
1087
1088 /* Check that the destination format and source buffer are both
1089 * integer-valued or both non-integer-valued.
1090 */
1091 if (ctx->Extensions.EXT_texture_integer && _mesa_is_color_format(format)) {
1092 const struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
1093 const GLboolean srcInteger = _mesa_is_format_integer_color(rb->Format);
1094 const GLboolean dstInteger = _mesa_is_enum_format_integer(format);
1095 if (dstInteger != srcInteger) {
1096 _mesa_error(ctx, GL_INVALID_OPERATION,
1097 "glReadPixels(integer / non-integer format mismatch");
1098 return;
1099 }
1100 }
1101
1102 if (width == 0 || height == 0)
1103 return; /* nothing to do */
1104
1105 if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
1106 format, type, bufSize, pixels)) {
1107 if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
1108 _mesa_error(ctx, GL_INVALID_OPERATION,
1109 "glReadPixels(out of bounds PBO access)");
1110 } else {
1111 _mesa_error(ctx, GL_INVALID_OPERATION,
1112 "glReadnPixelsARB(out of bounds access:"
1113 " bufSize (%d) is too small)", bufSize);
1114 }
1115 return;
1116 }
1117
1118 if (_mesa_is_bufferobj(ctx->Pack.BufferObj) &&
1119 _mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
1120 /* buffer is mapped - that's an error */
1121 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
1122 return;
1123 }
1124
1125 ctx->Driver.ReadPixels(ctx, x, y, width, height,
1126 format, type, &ctx->Pack, pixels);
1127 }
1128
1129 void GLAPIENTRY
1130 _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
1131 GLenum format, GLenum type, GLvoid *pixels )
1132 {
1133 _mesa_ReadnPixelsARB(x, y, width, height, format, type, INT_MAX, pixels);
1134 }