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