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