2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
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:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
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.
28 #include "bufferobj.h"
32 #include "framebuffer.h"
34 #include "format_unpack.h"
40 #include "glformats.h"
42 #include "format_utils.h"
43 #include "pixeltransfer.h"
47 * Return true if the conversion L=R+G+B is needed.
50 _mesa_need_rgb_to_luminance_conversion(GLenum srcBaseFormat
,
53 return (srcBaseFormat
== GL_RG
||
54 srcBaseFormat
== GL_RGB
||
55 srcBaseFormat
== GL_RGBA
) &&
56 (dstBaseFormat
== GL_LUMINANCE
||
57 dstBaseFormat
== GL_LUMINANCE_ALPHA
);
61 * Return true if the conversion L,I to RGB conversion is needed.
64 _mesa_need_luminance_to_rgb_conversion(GLenum srcBaseFormat
,
67 return (srcBaseFormat
== GL_LUMINANCE
||
68 srcBaseFormat
== GL_LUMINANCE_ALPHA
||
69 srcBaseFormat
== GL_INTENSITY
) &&
70 (dstBaseFormat
== GL_GREEN
||
71 dstBaseFormat
== GL_BLUE
||
72 dstBaseFormat
== GL_RG
||
73 dstBaseFormat
== GL_RGB
||
74 dstBaseFormat
== GL_BGR
||
75 dstBaseFormat
== GL_RGBA
||
76 dstBaseFormat
== GL_BGRA
);
80 * Return transfer op flags for this ReadPixels operation.
83 _mesa_get_readpixels_transfer_ops(const struct gl_context
*ctx
,
84 mesa_format texFormat
,
85 GLenum format
, GLenum type
,
88 GLbitfield transferOps
= ctx
->_ImageTransferState
;
89 GLenum srcBaseFormat
= _mesa_get_format_base_format(texFormat
);
90 GLenum dstBaseFormat
= _mesa_unpack_format_to_base_format(format
);
92 if (format
== GL_DEPTH_COMPONENT
||
93 format
== GL_DEPTH_STENCIL
||
94 format
== GL_STENCIL_INDEX
) {
98 /* Pixel transfer ops (scale, bias, table lookup) do not apply
101 if (_mesa_is_enum_format_integer(format
)) {
106 /* For blit-based ReadPixels packing, the clamping is done automatically
107 * unless the type is float. */
108 if (_mesa_get_clamp_read_color(ctx
, ctx
->ReadBuffer
) &&
109 (type
== GL_FLOAT
|| type
== GL_HALF_FLOAT
||
110 type
== GL_UNSIGNED_INT_10F_11F_11F_REV
)) {
111 transferOps
|= IMAGE_CLAMP_BIT
;
115 /* For CPU-based ReadPixels packing, the clamping must always be done
116 * for non-float types, */
117 if (_mesa_get_clamp_read_color(ctx
, ctx
->ReadBuffer
) ||
118 (type
!= GL_FLOAT
&& type
!= GL_HALF_FLOAT
&&
119 type
!= GL_UNSIGNED_INT_10F_11F_11F_REV
)) {
120 transferOps
|= IMAGE_CLAMP_BIT
;
124 /* If the format is unsigned normalized, we can ignore clamping
125 * because the values are already in the range [0,1] so it won't
126 * have any effect anyway.
128 if (_mesa_get_format_datatype(texFormat
) == GL_UNSIGNED_NORMALIZED
&&
129 !_mesa_need_rgb_to_luminance_conversion(srcBaseFormat
, dstBaseFormat
)) {
130 transferOps
&= ~IMAGE_CLAMP_BIT
;
138 * Return true if memcpy cannot be used for ReadPixels.
140 * If uses_blit is true, the function returns true if a simple 3D engine blit
141 * cannot be used for ReadPixels packing.
143 * NOTE: This doesn't take swizzling and format conversions between
144 * the readbuffer and the pixel pack buffer into account.
147 _mesa_readpixels_needs_slow_path(const struct gl_context
*ctx
, GLenum format
,
148 GLenum type
, GLboolean uses_blit
)
150 struct gl_renderbuffer
*rb
=
151 _mesa_get_read_renderbuffer_for_format(ctx
, format
);
152 GLenum dstBaseFormat
= _mesa_unpack_format_to_base_format(format
);
156 /* There are different rules depending on the base format. */
158 case GL_DEPTH_STENCIL
:
159 return !_mesa_has_depthstencil_combined(ctx
->ReadBuffer
) ||
160 ctx
->Pixel
.DepthScale
!= 1.0f
|| ctx
->Pixel
.DepthBias
!= 0.0f
||
161 ctx
->Pixel
.IndexShift
|| ctx
->Pixel
.IndexOffset
||
162 ctx
->Pixel
.MapStencilFlag
;
164 case GL_DEPTH_COMPONENT
:
165 return ctx
->Pixel
.DepthScale
!= 1.0f
|| ctx
->Pixel
.DepthBias
!= 0.0f
;
167 case GL_STENCIL_INDEX
:
168 return ctx
->Pixel
.IndexShift
|| ctx
->Pixel
.IndexOffset
||
169 ctx
->Pixel
.MapStencilFlag
;
173 if (_mesa_need_rgb_to_luminance_conversion(rb
->_BaseFormat
,
178 /* And finally, see if there are any transfer ops. */
179 return _mesa_get_readpixels_transfer_ops(ctx
, rb
->Format
, format
, type
,
187 readpixels_can_use_memcpy(const struct gl_context
*ctx
, GLenum format
, GLenum type
,
188 const struct gl_pixelstore_attrib
*packing
)
190 struct gl_renderbuffer
*rb
=
191 _mesa_get_read_renderbuffer_for_format(ctx
, format
);
195 if (_mesa_readpixels_needs_slow_path(ctx
, format
, type
, GL_FALSE
)) {
199 /* The base internal format and the base Mesa format must match. */
200 if (rb
->_BaseFormat
!= _mesa_get_format_base_format(rb
->Format
)) {
204 /* The Mesa format must match the input format and type. */
205 if (!_mesa_format_matches_format_and_type(rb
->Format
, format
, type
,
206 packing
->SwapBytes
, NULL
)) {
215 readpixels_memcpy(struct gl_context
*ctx
,
217 GLsizei width
, GLsizei height
,
218 GLenum format
, GLenum type
,
220 const struct gl_pixelstore_attrib
*packing
)
222 struct gl_renderbuffer
*rb
=
223 _mesa_get_read_renderbuffer_for_format(ctx
, format
);
225 int dstStride
, stride
, j
, texelBytes
, bytesPerRow
;
227 /* Fail if memcpy cannot be used. */
228 if (!readpixels_can_use_memcpy(ctx
, format
, type
, packing
)) {
232 dstStride
= _mesa_image_row_stride(packing
, width
, format
, type
);
233 dst
= (GLubyte
*) _mesa_image_address2d(packing
, pixels
, width
, height
,
236 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
239 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
240 return GL_TRUE
; /* don't bother trying the slow path */
243 texelBytes
= _mesa_get_format_bytes(rb
->Format
);
244 bytesPerRow
= texelBytes
* width
;
247 if (dstStride
== stride
&& dstStride
== bytesPerRow
) {
248 memcpy(dst
, map
, bytesPerRow
* height
);
250 for (j
= 0; j
< height
; j
++) {
251 memcpy(dst
, map
, bytesPerRow
);
257 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
263 * Optimized path for conversion of depth values to GL_DEPTH_COMPONENT,
267 read_uint_depth_pixels( struct gl_context
*ctx
,
269 GLsizei width
, GLsizei height
,
270 GLenum type
, GLvoid
*pixels
,
271 const struct gl_pixelstore_attrib
*packing
)
273 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
274 struct gl_renderbuffer
*rb
= fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
276 int stride
, dstStride
, j
;
278 if (ctx
->Pixel
.DepthScale
!= 1.0F
|| ctx
->Pixel
.DepthBias
!= 0.0F
)
281 if (packing
->SwapBytes
)
284 if (_mesa_get_format_datatype(rb
->Format
) != GL_UNSIGNED_NORMALIZED
)
287 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
291 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
292 return GL_TRUE
; /* don't bother trying the slow path */
295 dstStride
= _mesa_image_row_stride(packing
, width
, GL_DEPTH_COMPONENT
, type
);
296 dst
= (GLubyte
*) _mesa_image_address2d(packing
, pixels
, width
, height
,
297 GL_DEPTH_COMPONENT
, type
, 0, 0);
299 for (j
= 0; j
< height
; j
++) {
300 _mesa_unpack_uint_z_row(rb
->Format
, width
, map
, (GLuint
*)dst
);
305 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
311 * Read pixels for format=GL_DEPTH_COMPONENT.
314 read_depth_pixels( struct gl_context
*ctx
,
316 GLsizei width
, GLsizei height
,
317 GLenum type
, GLvoid
*pixels
,
318 const struct gl_pixelstore_attrib
*packing
)
320 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
321 struct gl_renderbuffer
*rb
= fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
324 int dstStride
, stride
;
325 GLfloat
*depthValues
;
330 /* clipping should have been done already */
333 assert(x
+ width
<= (GLint
) rb
->Width
);
334 assert(y
+ height
<= (GLint
) rb
->Height
);
336 if (type
== GL_UNSIGNED_INT
&&
337 read_uint_depth_pixels(ctx
, x
, y
, width
, height
, type
, pixels
, packing
)) {
341 dstStride
= _mesa_image_row_stride(packing
, width
, GL_DEPTH_COMPONENT
, type
);
342 dst
= (GLubyte
*) _mesa_image_address2d(packing
, pixels
, width
, height
,
343 GL_DEPTH_COMPONENT
, type
, 0, 0);
345 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
348 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
352 depthValues
= malloc(width
* sizeof(GLfloat
));
355 /* General case (slower) */
356 for (j
= 0; j
< height
; j
++, y
++) {
357 _mesa_unpack_float_z_row(rb
->Format
, width
, map
, depthValues
);
358 _mesa_pack_depth_span(ctx
, width
, dst
, type
, depthValues
, packing
);
365 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
370 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
375 * Read pixels for format=GL_STENCIL_INDEX.
378 read_stencil_pixels( struct gl_context
*ctx
,
380 GLsizei width
, GLsizei height
,
381 GLenum type
, GLvoid
*pixels
,
382 const struct gl_pixelstore_attrib
*packing
)
384 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
385 struct gl_renderbuffer
*rb
= fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
;
387 GLubyte
*map
, *stencil
;
393 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
396 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
400 stencil
= malloc(width
* sizeof(GLubyte
));
403 /* process image row by row */
404 for (j
= 0; j
< height
; j
++) {
407 _mesa_unpack_ubyte_stencil_row(rb
->Format
, width
, map
, stencil
);
408 dest
= _mesa_image_address2d(packing
, pixels
, width
, height
,
409 GL_STENCIL_INDEX
, type
, j
, 0);
411 _mesa_pack_stencil_span(ctx
, width
, type
, dest
, stencil
, packing
);
417 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
422 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
426 * Read R, G, B, A, RGB, L, or LA pixels.
429 read_rgba_pixels( struct gl_context
*ctx
,
431 GLsizei width
, GLsizei height
,
432 GLenum format
, GLenum type
, GLvoid
*pixels
,
433 const struct gl_pixelstore_attrib
*packing
)
435 GLbitfield transferOps
;
436 bool dst_is_integer
, convert_rgb_to_lum
, needs_rebase
;
437 int dst_stride
, src_stride
, rb_stride
;
438 uint32_t dst_format
, src_format
;
440 mesa_format rb_format
;
443 bool src_is_uint
= false;
444 uint8_t rebase_swizzle
[4];
445 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
446 struct gl_renderbuffer
*rb
= fb
->_ColorReadBuffer
;
447 GLenum dstBaseFormat
= _mesa_unpack_format_to_base_format(format
);
452 transferOps
= _mesa_get_readpixels_transfer_ops(ctx
, rb
->Format
, format
,
454 /* Describe the dst format */
455 dst_is_integer
= _mesa_is_enum_format_integer(format
);
456 dst_stride
= _mesa_image_row_stride(packing
, width
, format
, type
);
457 dst_format
= _mesa_format_from_format_and_type(format
, type
);
459 _mesa_need_rgb_to_luminance_conversion(rb
->_BaseFormat
, dstBaseFormat
);
460 dst
= (GLubyte
*) _mesa_image_address2d(packing
, pixels
, width
, height
,
463 /* Map the source render buffer */
464 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
467 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
470 rb_format
= _mesa_get_srgb_format_linear(rb
->Format
);
473 * Depending on the base formats involved in the conversion we might need to
474 * rebase some values, so for these formats we compute a rebase swizzle.
476 if (rb
->_BaseFormat
== GL_LUMINANCE
|| rb
->_BaseFormat
== GL_INTENSITY
) {
478 rebase_swizzle
[0] = MESA_FORMAT_SWIZZLE_X
;
479 rebase_swizzle
[1] = MESA_FORMAT_SWIZZLE_ZERO
;
480 rebase_swizzle
[2] = MESA_FORMAT_SWIZZLE_ZERO
;
481 rebase_swizzle
[3] = MESA_FORMAT_SWIZZLE_ONE
;
482 } else if (rb
->_BaseFormat
== GL_LUMINANCE_ALPHA
) {
484 rebase_swizzle
[0] = MESA_FORMAT_SWIZZLE_X
;
485 rebase_swizzle
[1] = MESA_FORMAT_SWIZZLE_ZERO
;
486 rebase_swizzle
[2] = MESA_FORMAT_SWIZZLE_ZERO
;
487 rebase_swizzle
[3] = MESA_FORMAT_SWIZZLE_W
;
488 } else if (_mesa_get_format_base_format(rb_format
) != rb
->_BaseFormat
) {
490 _mesa_compute_rgba2base2rgba_component_mapping(rb
->_BaseFormat
,
493 needs_rebase
= false;
496 /* Since _mesa_format_convert does not handle transferOps we need to handle
497 * them before we call the function. This requires to convert to RGBA float
498 * first so we can call _mesa_apply_rgba_transfer_ops. If the dst format is
499 * integer transferOps do not apply.
501 * Converting to luminance also requires converting to RGBA first, so we can
502 * then compute luminance values as L=R+G+B. Notice that this is different
503 * from GetTexImage, where we compute L=R.
505 assert(!transferOps
|| (transferOps
&& !dst_is_integer
));
507 needs_rgba
= transferOps
|| convert_rgb_to_lum
;
510 uint32_t rgba_format
;
514 /* Convert to RGBA float or int/uint depending on the type of the src */
515 if (dst_is_integer
) {
516 src_is_uint
= _mesa_is_format_unsigned(rb_format
);
518 rgba_format
= RGBA32_UINT
;
519 rgba_stride
= width
* 4 * sizeof(GLuint
);
521 rgba_format
= RGBA32_INT
;
522 rgba_stride
= width
* 4 * sizeof(GLint
);
525 rgba_format
= RGBA32_FLOAT
;
526 rgba_stride
= width
* 4 * sizeof(GLfloat
);
529 /* If we are lucky and the dst format matches the RGBA format we need to
530 * convert to, then we can convert directly into the dst buffer and avoid
531 * the final conversion/copy from the rgba buffer to the dst buffer.
533 if (dst_format
== rgba_format
&&
534 dst_stride
== rgba_stride
) {
535 need_convert
= false;
539 rgba
= malloc(height
* rgba_stride
);
541 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
546 /* Convert to RGBA now */
547 _mesa_format_convert(rgba
, rgba_format
, rgba_stride
,
548 map
, rb_format
, rb_stride
,
550 needs_rebase
? rebase_swizzle
: NULL
);
552 /* Handle transfer ops if necessary */
554 _mesa_apply_rgba_transfer_ops(ctx
, transferOps
, width
* height
, rgba
);
556 /* If we had to rebase, we have already taken care of that */
557 needs_rebase
= false;
559 /* If we were lucky and our RGBA conversion matches the dst format, then
565 /* Otherwise, we need to convert from RGBA to dst next */
567 src_format
= rgba_format
;
568 src_stride
= rgba_stride
;
570 /* No RGBA conversion needed, convert directly to dst */
572 src_format
= rb_format
;
573 src_stride
= rb_stride
;
576 /* Do the conversion.
578 * If the dst format is Luminance, we need to do the conversion by computing
581 if (!convert_rgb_to_lum
) {
582 _mesa_format_convert(dst
, dst_format
, dst_stride
,
583 src
, src_format
, src_stride
,
585 needs_rebase
? rebase_swizzle
: NULL
);
586 } else if (!dst_is_integer
) {
587 /* Compute float Luminance values from RGBA float */
588 int luminance_stride
, luminance_bytes
;
590 uint32_t luminance_format
;
592 luminance_stride
= width
* sizeof(GLfloat
);
593 if (format
== GL_LUMINANCE_ALPHA
)
594 luminance_stride
*= 2;
595 luminance_bytes
= height
* luminance_stride
;
596 luminance
= malloc(luminance_bytes
);
598 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
602 _mesa_pack_luminance_from_rgba_float(width
* height
, src
,
603 luminance
, format
, transferOps
);
605 /* Convert from Luminance float to dst (this will hadle type conversion
606 * from float to the type of dst if necessary)
608 luminance_format
= _mesa_format_from_format_and_type(format
, GL_FLOAT
);
609 _mesa_format_convert(dst
, dst_format
, dst_stride
,
610 luminance
, luminance_format
, luminance_stride
,
611 width
, height
, NULL
);
614 _mesa_pack_luminance_from_rgba_integer(width
* height
, src
, !src_is_uint
,
621 /* Handle byte swapping if required */
622 if (packing
->SwapBytes
) {
623 _mesa_swap_bytes_2d_image(format
, type
, packing
,
624 width
, height
, dst
, dst
);
628 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
632 * For a packed depth/stencil buffer being read as depth/stencil, just memcpy the
633 * data (possibly swapping 8/24 vs 24/8 as we go).
636 fast_read_depth_stencil_pixels(struct gl_context
*ctx
,
638 GLsizei width
, GLsizei height
,
639 GLubyte
*dst
, int dstStride
)
641 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
642 struct gl_renderbuffer
*rb
= fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
643 struct gl_renderbuffer
*stencilRb
= fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
;
650 if (rb
->Format
!= MESA_FORMAT_S8_UINT_Z24_UNORM
&&
651 rb
->Format
!= MESA_FORMAT_Z24_UNORM_S8_UINT
)
654 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
657 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
658 return GL_TRUE
; /* don't bother trying the slow path */
661 for (i
= 0; i
< height
; i
++) {
662 _mesa_unpack_uint_24_8_depth_stencil_row(rb
->Format
, width
,
668 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
675 * For non-float-depth and stencil buffers being read as 24/8 depth/stencil,
676 * copy the integer data directly instead of converting depth to float and
680 fast_read_depth_stencil_pixels_separate(struct gl_context
*ctx
,
682 GLsizei width
, GLsizei height
,
683 uint32_t *dst
, int dstStride
)
685 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
686 struct gl_renderbuffer
*depthRb
= fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
687 struct gl_renderbuffer
*stencilRb
= fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
;
688 GLubyte
*depthMap
, *stencilMap
, *stencilVals
;
689 int depthStride
, stencilStride
, i
, j
;
691 if (_mesa_get_format_datatype(depthRb
->Format
) != GL_UNSIGNED_NORMALIZED
)
694 ctx
->Driver
.MapRenderbuffer(ctx
, depthRb
, x
, y
, width
, height
,
695 GL_MAP_READ_BIT
, &depthMap
, &depthStride
);
697 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
698 return GL_TRUE
; /* don't bother trying the slow path */
701 ctx
->Driver
.MapRenderbuffer(ctx
, stencilRb
, x
, y
, width
, height
,
702 GL_MAP_READ_BIT
, &stencilMap
, &stencilStride
);
704 ctx
->Driver
.UnmapRenderbuffer(ctx
, depthRb
);
705 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
706 return GL_TRUE
; /* don't bother trying the slow path */
709 stencilVals
= malloc(width
* sizeof(GLubyte
));
712 for (j
= 0; j
< height
; j
++) {
713 _mesa_unpack_uint_z_row(depthRb
->Format
, width
, depthMap
, dst
);
714 _mesa_unpack_ubyte_stencil_row(stencilRb
->Format
, width
,
715 stencilMap
, stencilVals
);
717 for (i
= 0; i
< width
; i
++) {
718 dst
[i
] = (dst
[i
] & 0xffffff00) | stencilVals
[i
];
721 depthMap
+= depthStride
;
722 stencilMap
+= stencilStride
;
723 dst
+= dstStride
/ 4;
727 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
732 ctx
->Driver
.UnmapRenderbuffer(ctx
, depthRb
);
733 ctx
->Driver
.UnmapRenderbuffer(ctx
, stencilRb
);
739 slow_read_depth_stencil_pixels_separate(struct gl_context
*ctx
,
741 GLsizei width
, GLsizei height
,
743 const struct gl_pixelstore_attrib
*packing
,
744 GLubyte
*dst
, int dstStride
)
746 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
747 struct gl_renderbuffer
*depthRb
= fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
748 struct gl_renderbuffer
*stencilRb
= fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
;
749 GLubyte
*depthMap
, *stencilMap
;
750 int depthStride
, stencilStride
, j
;
751 GLubyte
*stencilVals
;
755 /* The depth and stencil buffers might be separate, or a single buffer.
756 * If one buffer, only map it once.
758 ctx
->Driver
.MapRenderbuffer(ctx
, depthRb
, x
, y
, width
, height
,
759 GL_MAP_READ_BIT
, &depthMap
, &depthStride
);
761 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
765 if (stencilRb
!= depthRb
) {
766 ctx
->Driver
.MapRenderbuffer(ctx
, stencilRb
, x
, y
, width
, height
,
767 GL_MAP_READ_BIT
, &stencilMap
,
770 ctx
->Driver
.UnmapRenderbuffer(ctx
, depthRb
);
771 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
776 stencilMap
= depthMap
;
777 stencilStride
= depthStride
;
780 stencilVals
= malloc(width
* sizeof(GLubyte
));
781 depthVals
= malloc(width
* sizeof(GLfloat
));
783 if (stencilVals
&& depthVals
) {
784 for (j
= 0; j
< height
; j
++) {
785 _mesa_unpack_float_z_row(depthRb
->Format
, width
, depthMap
, depthVals
);
786 _mesa_unpack_ubyte_stencil_row(stencilRb
->Format
, width
,
787 stencilMap
, stencilVals
);
789 _mesa_pack_depth_stencil_span(ctx
, width
, type
, (GLuint
*)dst
,
790 depthVals
, stencilVals
, packing
);
792 depthMap
+= depthStride
;
793 stencilMap
+= stencilStride
;
798 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
804 ctx
->Driver
.UnmapRenderbuffer(ctx
, depthRb
);
805 if (stencilRb
!= depthRb
) {
806 ctx
->Driver
.UnmapRenderbuffer(ctx
, stencilRb
);
812 * Read combined depth/stencil values.
813 * We'll have already done error checking to be sure the expected
814 * depth and stencil buffers really exist.
817 read_depth_stencil_pixels(struct gl_context
*ctx
,
819 GLsizei width
, GLsizei height
,
820 GLenum type
, GLvoid
*pixels
,
821 const struct gl_pixelstore_attrib
*packing
)
823 const GLboolean scaleOrBias
824 = ctx
->Pixel
.DepthScale
!= 1.0F
|| ctx
->Pixel
.DepthBias
!= 0.0F
;
825 const GLboolean stencilTransfer
= ctx
->Pixel
.IndexShift
826 || ctx
->Pixel
.IndexOffset
|| ctx
->Pixel
.MapStencilFlag
;
830 dst
= (GLubyte
*) _mesa_image_address2d(packing
, pixels
,
832 GL_DEPTH_STENCIL_EXT
,
834 dstStride
= _mesa_image_row_stride(packing
, width
,
835 GL_DEPTH_STENCIL_EXT
, type
);
837 /* Fast 24/8 reads. */
838 if (type
== GL_UNSIGNED_INT_24_8
&&
839 !scaleOrBias
&& !stencilTransfer
&& !packing
->SwapBytes
) {
840 if (fast_read_depth_stencil_pixels(ctx
, x
, y
, width
, height
,
844 if (fast_read_depth_stencil_pixels_separate(ctx
, x
, y
, width
, height
,
845 (uint32_t *)dst
, dstStride
))
849 slow_read_depth_stencil_pixels_separate(ctx
, x
, y
, width
, height
,
857 * Software fallback routine for ctx->Driver.ReadPixels().
858 * By time we get here, all error checking will have been done.
861 _mesa_readpixels(struct gl_context
*ctx
,
862 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
863 GLenum format
, GLenum type
,
864 const struct gl_pixelstore_attrib
*packing
,
868 _mesa_update_state(ctx
);
870 pixels
= _mesa_map_pbo_dest(ctx
, packing
, pixels
);
873 /* Try memcpy first. */
874 if (readpixels_memcpy(ctx
, x
, y
, width
, height
, format
, type
,
876 _mesa_unmap_pbo_dest(ctx
, packing
);
880 /* Otherwise take the slow path. */
882 case GL_STENCIL_INDEX
:
883 read_stencil_pixels(ctx
, x
, y
, width
, height
, type
, pixels
,
886 case GL_DEPTH_COMPONENT
:
887 read_depth_pixels(ctx
, x
, y
, width
, height
, type
, pixels
,
890 case GL_DEPTH_STENCIL_EXT
:
891 read_depth_stencil_pixels(ctx
, x
, y
, width
, height
, type
, pixels
,
895 /* all other formats should be color formats */
896 read_rgba_pixels(ctx
, x
, y
, width
, height
, format
, type
, pixels
,
900 _mesa_unmap_pbo_dest(ctx
, packing
);
906 read_pixels_es3_error_check(struct gl_context
*ctx
, GLenum format
, GLenum type
,
907 const struct gl_renderbuffer
*rb
)
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 GLboolean is_float_depth
= (internalFormat
== GL_DEPTH_COMPONENT32F
) ||
914 (internalFormat
== GL_DEPTH32F_STENCIL8
);
916 is_unsigned_int
= _mesa_is_enum_format_unsigned_int(internalFormat
);
917 if (!is_unsigned_int
) {
918 is_signed_int
= _mesa_is_enum_format_signed_int(internalFormat
);
923 if (type
== GL_FLOAT
&& data_type
== GL_FLOAT
)
924 return GL_NO_ERROR
; /* EXT_color_buffer_float */
925 if (type
== GL_UNSIGNED_BYTE
&& data_type
== GL_UNSIGNED_NORMALIZED
)
927 if (internalFormat
== GL_RGB10_A2
&&
928 type
== GL_UNSIGNED_INT_2_10_10_10_REV
)
930 if (internalFormat
== GL_RGB10_A2UI
&& type
== GL_UNSIGNED_BYTE
)
932 if (type
== GL_UNSIGNED_SHORT
) {
933 switch (internalFormat
) {
938 if (_mesa_has_EXT_texture_norm16(ctx
))
944 /* GL_EXT_read_format_bgra */
945 if (type
== GL_UNSIGNED_BYTE
||
946 type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
||
947 type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
)
950 case GL_RGBA_INTEGER
:
951 if ((is_signed_int
&& type
== GL_INT
) ||
952 (is_unsigned_int
&& type
== GL_UNSIGNED_INT
))
955 case GL_DEPTH_STENCIL
:
957 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV
:
961 case GL_UNSIGNED_INT_24_8
:
966 return GL_INVALID_ENUM
;
969 case GL_DEPTH_COMPONENT
:
975 case GL_UNSIGNED_SHORT
:
976 case GL_UNSIGNED_INT
:
977 case GL_UNSIGNED_INT_24_8
:
982 return GL_INVALID_ENUM
;
985 case GL_STENCIL_INDEX
:
987 case GL_UNSIGNED_BYTE
:
990 return GL_INVALID_ENUM
;
995 return GL_INVALID_OPERATION
;
999 static ALWAYS_INLINE
void
1000 read_pixels(GLint x
, GLint y
, GLsizei width
, GLsizei height
, GLenum format
,
1001 GLenum type
, GLsizei bufSize
, GLvoid
*pixels
, bool no_error
)
1003 GLenum err
= GL_NO_ERROR
;
1004 struct gl_renderbuffer
*rb
;
1005 struct gl_pixelstore_attrib clippedPacking
;
1007 GET_CURRENT_CONTEXT(ctx
);
1009 FLUSH_VERTICES(ctx
, 0);
1010 FLUSH_CURRENT(ctx
, 0);
1012 if (MESA_VERBOSE
& VERBOSE_API
)
1013 _mesa_debug(ctx
, "glReadPixels(%d, %d, %s, %s, %p)\n",
1015 _mesa_enum_to_string(format
),
1016 _mesa_enum_to_string(type
),
1019 if (!no_error
&& (width
< 0 || height
< 0)) {
1020 _mesa_error( ctx
, GL_INVALID_VALUE
,
1021 "glReadPixels(width=%d height=%d)", width
, height
);
1026 _mesa_update_state(ctx
);
1028 if (!no_error
&& ctx
->ReadBuffer
->_Status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
1029 _mesa_error(ctx
, GL_INVALID_FRAMEBUFFER_OPERATION_EXT
,
1030 "glReadPixels(incomplete framebuffer)" );
1034 rb
= _mesa_get_read_renderbuffer_for_format(ctx
, format
);
1037 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1038 "glReadPixels(read buffer)");
1042 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
1043 * combinations of format and type that can be used.
1045 * Technically, only two combinations are actually allowed:
1046 * GL_RGBA/GL_UNSIGNED_BYTE, and some implementation-specific internal
1047 * preferred combination. This code doesn't know what that preferred
1048 * combination is, and Mesa can handle anything valid. Just work instead.
1050 if (_mesa_is_gles(ctx
)) {
1051 if (ctx
->API
== API_OPENGLES2
&&
1052 _mesa_is_color_format(format
) &&
1053 _mesa_get_color_read_format(ctx
, NULL
, "glReadPixels") == format
&&
1054 _mesa_get_color_read_type(ctx
, NULL
, "glReadPixels") == type
) {
1056 } else if (ctx
->Version
< 30) {
1057 err
= _mesa_es_error_check_format_and_type(ctx
, format
, type
, 2);
1058 if (err
== GL_NO_ERROR
) {
1059 if (type
== GL_FLOAT
|| type
== GL_HALF_FLOAT_OES
) {
1060 err
= GL_INVALID_OPERATION
;
1064 err
= read_pixels_es3_error_check(ctx
, format
, type
, rb
);
1067 if (err
!= GL_NO_ERROR
) {
1068 _mesa_error(ctx
, err
, "glReadPixels(invalid format %s and/or type %s)",
1069 _mesa_enum_to_string(format
),
1070 _mesa_enum_to_string(type
));
1075 err
= _mesa_error_check_format_and_type(ctx
, format
, type
);
1076 if (err
!= GL_NO_ERROR
) {
1077 _mesa_error(ctx
, err
, "glReadPixels(invalid format %s and/or type %s)",
1078 _mesa_enum_to_string(format
),
1079 _mesa_enum_to_string(type
));
1083 if (_mesa_is_user_fbo(ctx
->ReadBuffer
) &&
1084 ctx
->ReadBuffer
->Visual
.samples
> 0) {
1085 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glReadPixels(multisample FBO)");
1089 if (!_mesa_source_buffer_exists(ctx
, format
)) {
1090 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glReadPixels(no readbuffer)");
1094 /* Check that the destination format and source buffer are both
1095 * integer-valued or both non-integer-valued.
1097 if (ctx
->Extensions
.EXT_texture_integer
&& _mesa_is_color_format(format
)) {
1098 const struct gl_renderbuffer
*rb
= ctx
->ReadBuffer
->_ColorReadBuffer
;
1099 const GLboolean srcInteger
= _mesa_is_format_integer_color(rb
->Format
);
1100 const GLboolean dstInteger
= _mesa_is_enum_format_integer(format
);
1101 if (dstInteger
!= srcInteger
) {
1102 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1103 "glReadPixels(integer / non-integer format mismatch");
1109 /* Do all needed clipping here, so that we can forget about it later */
1110 clippedPacking
= ctx
->Pack
;
1111 if (!_mesa_clip_readpixels(ctx
, &x
, &y
, &width
, &height
, &clippedPacking
))
1112 return; /* nothing to do */
1115 if (!_mesa_validate_pbo_access(2, &ctx
->Pack
, width
, height
, 1,
1116 format
, type
, bufSize
, pixels
)) {
1117 if (_mesa_is_bufferobj(ctx
->Pack
.BufferObj
)) {
1118 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1119 "glReadPixels(out of bounds PBO access)");
1121 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1122 "glReadnPixelsARB(out of bounds access:"
1123 " bufSize (%d) is too small)", bufSize
);
1128 if (_mesa_is_bufferobj(ctx
->Pack
.BufferObj
) &&
1129 _mesa_check_disallowed_mapping(ctx
->Pack
.BufferObj
)) {
1130 /* buffer is mapped - that's an error */
1131 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glReadPixels(PBO is mapped)");
1136 ctx
->Driver
.ReadPixels(ctx
, x
, y
, width
, height
,
1137 format
, type
, &clippedPacking
, pixels
);
1141 _mesa_ReadnPixelsARB_no_error(GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1142 GLenum format
, GLenum type
, GLsizei bufSize
,
1145 read_pixels(x
, y
, width
, height
, format
, type
, bufSize
, pixels
, true);
1149 _mesa_ReadnPixelsARB(GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1150 GLenum format
, GLenum type
, GLsizei bufSize
,
1153 read_pixels(x
, y
, width
, height
, format
, type
, bufSize
, pixels
, false);
1157 _mesa_ReadPixels_no_error(GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1158 GLenum format
, GLenum type
, GLvoid
*pixels
)
1160 _mesa_ReadnPixelsARB_no_error(x
, y
, width
, height
, format
, type
, INT_MAX
,
1165 _mesa_ReadPixels(GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1166 GLenum format
, GLenum type
, GLvoid
*pixels
)
1168 _mesa_ReadnPixelsARB(x
, y
, width
, height
, format
, type
, INT_MAX
, pixels
);