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