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