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"
45 * Return true if the conversion L=R+G+B is needed.
48 need_rgb_to_luminance_conversion(mesa_format texFormat
, GLenum format
)
50 GLenum baseTexFormat
= _mesa_get_format_base_format(texFormat
);
52 return (baseTexFormat
== GL_RG
||
53 baseTexFormat
== GL_RGB
||
54 baseTexFormat
== GL_RGBA
) &&
55 (format
== GL_LUMINANCE
|| format
== GL_LUMINANCE_ALPHA
);
60 * Return transfer op flags for this ReadPixels operation.
63 get_readpixels_transfer_ops(const struct gl_context
*ctx
, mesa_format texFormat
,
64 GLenum format
, GLenum type
, GLboolean uses_blit
)
66 GLbitfield transferOps
= ctx
->_ImageTransferState
;
68 if (format
== GL_DEPTH_COMPONENT
||
69 format
== GL_DEPTH_STENCIL
||
70 format
== GL_STENCIL_INDEX
) {
74 /* Pixel transfer ops (scale, bias, table lookup) do not apply
77 if (_mesa_is_enum_format_integer(format
)) {
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
;
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
;
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.
102 if (_mesa_get_format_datatype(texFormat
) == GL_UNSIGNED_NORMALIZED
&&
103 !need_rgb_to_luminance_conversion(texFormat
, format
)) {
104 transferOps
&= ~IMAGE_CLAMP_BIT
;
112 * Return true if memcpy cannot be used for ReadPixels.
114 * If uses_blit is true, the function returns true if a simple 3D engine blit
115 * cannot be used for ReadPixels packing.
117 * NOTE: This doesn't take swizzling and format conversions between
118 * the readbuffer and the pixel pack buffer into account.
121 _mesa_readpixels_needs_slow_path(const struct gl_context
*ctx
, GLenum format
,
122 GLenum type
, GLboolean uses_blit
)
124 struct gl_renderbuffer
*rb
=
125 _mesa_get_read_renderbuffer_for_format(ctx
, format
);
130 /* There are different rules depending on the base 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
;
138 case GL_DEPTH_COMPONENT
:
139 return ctx
->Pixel
.DepthScale
!= 1.0f
|| ctx
->Pixel
.DepthBias
!= 0.0f
;
141 case GL_STENCIL_INDEX
:
142 return ctx
->Pixel
.IndexShift
|| ctx
->Pixel
.IndexOffset
||
143 ctx
->Pixel
.MapStencilFlag
;
147 if (need_rgb_to_luminance_conversion(rb
->Format
, format
)) {
151 /* Conversion between signed and unsigned integers needs masking
152 * (it isn't just memcpy). */
153 srcType
= _mesa_get_format_datatype(rb
->Format
);
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
&&
166 /* And finally, see if there are any transfer ops. */
167 return get_readpixels_transfer_ops(ctx
, rb
->Format
, format
, type
,
175 readpixels_can_use_memcpy(const struct gl_context
*ctx
, GLenum format
, GLenum type
,
176 const struct gl_pixelstore_attrib
*packing
)
178 struct gl_renderbuffer
*rb
=
179 _mesa_get_read_renderbuffer_for_format(ctx
, format
);
183 if (_mesa_readpixels_needs_slow_path(ctx
, format
, type
, GL_FALSE
)) {
187 /* The base internal format and the base Mesa format must match. */
188 if (rb
->_BaseFormat
!= _mesa_get_format_base_format(rb
->Format
)) {
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
)) {
203 readpixels_memcpy(struct gl_context
*ctx
,
205 GLsizei width
, GLsizei height
,
206 GLenum format
, GLenum type
,
208 const struct gl_pixelstore_attrib
*packing
)
210 struct gl_renderbuffer
*rb
=
211 _mesa_get_read_renderbuffer_for_format(ctx
, format
);
213 int dstStride
, stride
, j
, texelBytes
;
215 /* Fail if memcpy cannot be used. */
216 if (!readpixels_can_use_memcpy(ctx
, format
, type
, packing
)) {
220 dstStride
= _mesa_image_row_stride(packing
, width
, format
, type
);
221 dst
= (GLubyte
*) _mesa_image_address2d(packing
, pixels
, width
, height
,
224 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
227 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
228 return GL_TRUE
; /* don't bother trying the slow path */
231 texelBytes
= _mesa_get_format_bytes(rb
->Format
);
234 for (j
= 0; j
< height
; j
++) {
235 memcpy(dst
, map
, width
* texelBytes
);
240 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
246 * Optimized path for conversion of depth values to GL_DEPTH_COMPONENT,
250 read_uint_depth_pixels( struct gl_context
*ctx
,
252 GLsizei width
, GLsizei height
,
253 GLenum type
, GLvoid
*pixels
,
254 const struct gl_pixelstore_attrib
*packing
)
256 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
257 struct gl_renderbuffer
*rb
= fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
259 int stride
, dstStride
, j
;
261 if (ctx
->Pixel
.DepthScale
!= 1.0 || ctx
->Pixel
.DepthBias
!= 0.0)
264 if (packing
->SwapBytes
)
267 if (_mesa_get_format_datatype(rb
->Format
) != GL_UNSIGNED_NORMALIZED
)
270 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
274 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
275 return GL_TRUE
; /* don't bother trying the slow path */
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);
282 for (j
= 0; j
< height
; j
++) {
283 _mesa_unpack_uint_z_row(rb
->Format
, width
, map
, (GLuint
*)dst
);
288 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
294 * Read pixels for format=GL_DEPTH_COMPONENT.
297 read_depth_pixels( struct gl_context
*ctx
,
299 GLsizei width
, GLsizei height
,
300 GLenum type
, GLvoid
*pixels
,
301 const struct gl_pixelstore_attrib
*packing
)
303 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
304 struct gl_renderbuffer
*rb
= fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
307 int dstStride
, stride
;
308 GLfloat
*depthValues
;
313 /* clipping should have been done already */
316 ASSERT(x
+ width
<= (GLint
) rb
->Width
);
317 ASSERT(y
+ height
<= (GLint
) rb
->Height
);
319 if (type
== GL_UNSIGNED_INT
&&
320 read_uint_depth_pixels(ctx
, x
, y
, width
, height
, type
, pixels
, packing
)) {
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);
328 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
331 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
335 depthValues
= malloc(width
* sizeof(GLfloat
));
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
);
348 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
353 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
358 * Read pixels for format=GL_STENCIL_INDEX.
361 read_stencil_pixels( struct gl_context
*ctx
,
363 GLsizei width
, GLsizei height
,
364 GLenum type
, GLvoid
*pixels
,
365 const struct gl_pixelstore_attrib
*packing
)
367 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
368 struct gl_renderbuffer
*rb
= fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
;
370 GLubyte
*map
, *stencil
;
376 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
379 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
383 stencil
= malloc(width
* sizeof(GLubyte
));
386 /* process image row by row */
387 for (j
= 0; j
< height
; j
++) {
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);
394 _mesa_pack_stencil_span(ctx
, width
, type
, dest
, stencil
, packing
);
400 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
405 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
410 * Try to do glReadPixels of RGBA data using swizzle.
411 * \return GL_TRUE if successful, GL_FALSE otherwise (use the slow path)
414 read_rgba_pixels_swizzle(struct gl_context
*ctx
,
416 GLsizei width
, GLsizei height
,
417 GLenum format
, GLenum type
,
419 const struct gl_pixelstore_attrib
*packing
)
421 struct gl_renderbuffer
*rb
= ctx
->ReadBuffer
->_ColorReadBuffer
;
423 int dstStride
, stride
, j
;
424 GLboolean swizzle_rb
= GL_FALSE
, copy_xrgb
= GL_FALSE
;
426 /* XXX we could check for other swizzle/special cases here as needed */
427 if (rb
->Format
== MESA_FORMAT_R8G8B8A8_UNORM
&&
429 type
== GL_UNSIGNED_INT_8_8_8_8_REV
&&
430 !ctx
->Pack
.SwapBytes
) {
431 swizzle_rb
= GL_TRUE
;
433 else if (rb
->Format
== MESA_FORMAT_B8G8R8X8_UNORM
&&
435 type
== GL_UNSIGNED_INT_8_8_8_8_REV
&&
436 !ctx
->Pack
.SwapBytes
) {
443 dstStride
= _mesa_image_row_stride(packing
, width
, format
, type
);
444 dst
= (GLubyte
*) _mesa_image_address2d(packing
, pixels
, width
, height
,
447 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
450 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
451 return GL_TRUE
; /* don't bother trying the slow path */
456 for (j
= 0; j
< height
; j
++) {
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);
468 } else if (copy_xrgb
) {
469 /* convert xrgb -> argb */
470 for (j
= 0; j
< height
; j
++) {
471 GLuint
*dst4
= (GLuint
*) dst
, *map4
= (GLuint
*) map
;
473 for (i
= 0; i
< width
; i
++) {
474 dst4
[i
] = map4
[i
] | 0xff000000; /* set A=0xff */
481 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
487 slow_read_rgba_pixels( struct gl_context
*ctx
,
489 GLsizei width
, GLsizei height
,
490 GLenum format
, GLenum type
,
492 const struct gl_pixelstore_attrib
*packing
,
493 GLbitfield transferOps
)
495 struct gl_renderbuffer
*rb
= ctx
->ReadBuffer
->_ColorReadBuffer
;
496 const mesa_format rbFormat
= _mesa_get_srgb_format_linear(rb
->Format
);
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
);
503 dstStride
= _mesa_image_row_stride(packing
, width
, format
, type
);
504 dst
= (GLubyte
*) _mesa_image_address2d(packing
, pixels
, width
, height
,
507 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
510 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
514 rgba
= malloc(width
* MAX_PIXEL_BYTES
);
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
,
524 _mesa_pack_rgba_span_from_uints(ctx
, width
, (GLuint (*)[4]) rgba
, format
,
527 _mesa_pack_rgba_span_from_ints(ctx
, width
, (GLint (*)[4]) rgba
, format
,
531 _mesa_unpack_rgba_row(rbFormat
, width
, map
, (GLfloat (*)[4]) rgba
);
532 _mesa_rebase_rgba_float(width
, (GLfloat (*)[4]) rgba
,
534 _mesa_pack_rgba_span_float(ctx
, width
, (GLfloat (*)[4]) rgba
, format
,
535 type
, dst
, packing
, transferOps
);
544 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
548 * Read R, G, B, A, RGB, L, or LA pixels.
551 read_rgba_pixels( struct gl_context
*ctx
,
553 GLsizei width
, GLsizei height
,
554 GLenum format
, GLenum type
, GLvoid
*pixels
,
555 const struct gl_pixelstore_attrib
*packing
)
557 GLbitfield transferOps
;
558 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
559 struct gl_renderbuffer
*rb
= fb
->_ColorReadBuffer
;
564 transferOps
= get_readpixels_transfer_ops(ctx
, rb
->Format
, format
, type
,
567 /* Try the optimized paths first. */
569 read_rgba_pixels_swizzle(ctx
, x
, y
, width
, height
,
570 format
, type
, pixels
, packing
)) {
574 slow_read_rgba_pixels(ctx
, x
, y
, width
, height
,
575 format
, type
, pixels
, packing
, transferOps
);
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).
583 fast_read_depth_stencil_pixels(struct gl_context
*ctx
,
585 GLsizei width
, GLsizei height
,
586 GLubyte
*dst
, int dstStride
)
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
;
597 if (rb
->Format
!= MESA_FORMAT_S8_UINT_Z24_UNORM
&&
598 rb
->Format
!= MESA_FORMAT_Z24_UNORM_S8_UINT
)
601 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
604 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
605 return GL_TRUE
; /* don't bother trying the slow path */
608 for (i
= 0; i
< height
; i
++) {
609 _mesa_unpack_uint_24_8_depth_stencil_row(rb
->Format
, width
,
615 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
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
627 fast_read_depth_stencil_pixels_separate(struct gl_context
*ctx
,
629 GLsizei width
, GLsizei height
,
630 uint32_t *dst
, int dstStride
)
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
;
638 if (_mesa_get_format_datatype(depthRb
->Format
) != GL_UNSIGNED_NORMALIZED
)
641 ctx
->Driver
.MapRenderbuffer(ctx
, depthRb
, x
, y
, width
, height
,
642 GL_MAP_READ_BIT
, &depthMap
, &depthStride
);
644 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
645 return GL_TRUE
; /* don't bother trying the slow path */
648 ctx
->Driver
.MapRenderbuffer(ctx
, stencilRb
, x
, y
, width
, height
,
649 GL_MAP_READ_BIT
, &stencilMap
, &stencilStride
);
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 */
656 stencilVals
= malloc(width
* sizeof(GLubyte
));
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
);
664 for (i
= 0; i
< width
; i
++) {
665 dst
[i
] = (dst
[i
] & 0xffffff00) | stencilVals
[i
];
668 depthMap
+= depthStride
;
669 stencilMap
+= stencilStride
;
670 dst
+= dstStride
/ 4;
674 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
679 ctx
->Driver
.UnmapRenderbuffer(ctx
, depthRb
);
680 ctx
->Driver
.UnmapRenderbuffer(ctx
, stencilRb
);
686 slow_read_depth_stencil_pixels_separate(struct gl_context
*ctx
,
688 GLsizei width
, GLsizei height
,
690 const struct gl_pixelstore_attrib
*packing
,
691 GLubyte
*dst
, int dstStride
)
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
;
702 /* The depth and stencil buffers might be separate, or a single buffer.
703 * If one buffer, only map it once.
705 ctx
->Driver
.MapRenderbuffer(ctx
, depthRb
, x
, y
, width
, height
,
706 GL_MAP_READ_BIT
, &depthMap
, &depthStride
);
708 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
712 if (stencilRb
!= depthRb
) {
713 ctx
->Driver
.MapRenderbuffer(ctx
, stencilRb
, x
, y
, width
, height
,
714 GL_MAP_READ_BIT
, &stencilMap
,
717 ctx
->Driver
.UnmapRenderbuffer(ctx
, depthRb
);
718 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
723 stencilMap
= depthMap
;
724 stencilStride
= depthStride
;
727 stencilVals
= malloc(width
* sizeof(GLubyte
));
728 depthVals
= malloc(width
* sizeof(GLfloat
));
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
);
736 _mesa_pack_depth_stencil_span(ctx
, width
, type
, (GLuint
*)dst
,
737 depthVals
, stencilVals
, packing
);
739 depthMap
+= depthStride
;
740 stencilMap
+= stencilStride
;
745 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
751 ctx
->Driver
.UnmapRenderbuffer(ctx
, depthRb
);
752 if (stencilRb
!= depthRb
) {
753 ctx
->Driver
.UnmapRenderbuffer(ctx
, stencilRb
);
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.
764 read_depth_stencil_pixels(struct gl_context
*ctx
,
766 GLsizei width
, GLsizei height
,
767 GLenum type
, GLvoid
*pixels
,
768 const struct gl_pixelstore_attrib
*packing
)
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
;
777 dst
= (GLubyte
*) _mesa_image_address2d(packing
, pixels
,
779 GL_DEPTH_STENCIL_EXT
,
781 dstStride
= _mesa_image_row_stride(packing
, width
,
782 GL_DEPTH_STENCIL_EXT
, type
);
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
,
791 if (fast_read_depth_stencil_pixels_separate(ctx
, x
, y
, width
, height
,
792 (uint32_t *)dst
, dstStride
))
796 slow_read_depth_stencil_pixels_separate(ctx
, x
, y
, width
, height
,
804 * Software fallback routine for ctx->Driver.ReadPixels().
805 * By time we get here, all error checking will have been done.
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
,
814 struct gl_pixelstore_attrib clippedPacking
= *packing
;
817 _mesa_update_state(ctx
);
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
)) {
822 pixels
= _mesa_map_pbo_dest(ctx
, &clippedPacking
, pixels
);
825 /* Try memcpy first. */
826 if (readpixels_memcpy(ctx
, x
, y
, width
, height
, format
, type
,
828 _mesa_unmap_pbo_dest(ctx
, &clippedPacking
);
832 /* Otherwise take the slow path. */
834 case GL_STENCIL_INDEX
:
835 read_stencil_pixels(ctx
, x
, y
, width
, height
, type
, pixels
,
838 case GL_DEPTH_COMPONENT
:
839 read_depth_pixels(ctx
, x
, y
, width
, height
, type
, pixels
,
842 case GL_DEPTH_STENCIL_EXT
:
843 read_depth_stencil_pixels(ctx
, x
, y
, width
, height
, type
, pixels
,
847 /* all other formats should be color formats */
848 read_rgba_pixels(ctx
, x
, y
, width
, height
, format
, type
, pixels
,
852 _mesa_unmap_pbo_dest(ctx
, &clippedPacking
);
859 read_pixels_es3_error_check(GLenum format
, GLenum type
,
860 const struct gl_renderbuffer
*rb
)
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
;
867 if (!_mesa_is_color_format(internalFormat
)) {
868 return GL_INVALID_OPERATION
;
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
);
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
)
882 if (internalFormat
== GL_RGB10_A2
&&
883 type
== GL_UNSIGNED_INT_2_10_10_10_REV
)
885 if (internalFormat
== GL_RGB10_A2UI
&& type
== GL_UNSIGNED_BYTE
)
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
)
895 case GL_RGBA_INTEGER
:
896 if ((is_signed_int
&& type
== GL_INT
) ||
897 (is_unsigned_int
&& type
== GL_UNSIGNED_INT
))
902 return GL_INVALID_OPERATION
;
907 _mesa_ReadnPixelsARB( GLint x
, GLint y
, GLsizei width
, GLsizei height
,
908 GLenum format
, GLenum type
, GLsizei bufSize
,
911 GLenum err
= GL_NO_ERROR
;
912 struct gl_renderbuffer
*rb
;
914 GET_CURRENT_CONTEXT(ctx
);
916 FLUSH_VERTICES(ctx
, 0);
917 FLUSH_CURRENT(ctx
, 0);
919 if (MESA_VERBOSE
& VERBOSE_API
)
920 _mesa_debug(ctx
, "glReadPixels(%d, %d, %s, %s, %p)\n",
922 _mesa_lookup_enum_by_nr(format
),
923 _mesa_lookup_enum_by_nr(type
),
926 if (width
< 0 || height
< 0) {
927 _mesa_error( ctx
, GL_INVALID_VALUE
,
928 "glReadPixels(width=%d height=%d)", width
, height
);
933 _mesa_update_state(ctx
);
935 if (ctx
->ReadBuffer
->_Status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
936 _mesa_error(ctx
, GL_INVALID_FRAMEBUFFER_OPERATION_EXT
,
937 "glReadPixels(incomplete framebuffer)" );
941 rb
= _mesa_get_read_renderbuffer_for_format(ctx
, format
);
943 _mesa_error(ctx
, GL_INVALID_OPERATION
,
944 "glReadPixels(read buffer)");
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.
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.
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
) {
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
;
970 err
= read_pixels_es3_error_check(format
, type
, rb
);
973 if (err
== GL_NO_ERROR
&& (format
== GL_DEPTH_COMPONENT
974 || format
== GL_DEPTH_STENCIL
)) {
975 err
= GL_INVALID_ENUM
;
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
));
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
));
994 if (_mesa_is_user_fbo(ctx
->ReadBuffer
) &&
995 ctx
->ReadBuffer
->Visual
.samples
> 0) {
996 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glReadPixels(multisample FBO)");
1000 if (!_mesa_source_buffer_exists(ctx
, format
)) {
1001 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glReadPixels(no readbuffer)");
1005 /* Check that the destination format and source buffer are both
1006 * integer-valued or both non-integer-valued.
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");
1019 if (width
== 0 || height
== 0)
1020 return; /* nothing to do */
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)");
1028 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1029 "glReadnPixelsARB(out of bounds access:"
1030 " bufSize (%d) is too small)", bufSize
);
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)");
1042 ctx
->Driver
.ReadPixels(ctx
, x
, y
, width
, height
,
1043 format
, type
, &ctx
->Pack
, pixels
);
1047 _mesa_ReadPixels( GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1048 GLenum format
, GLenum type
, GLvoid
*pixels
)
1050 _mesa_ReadnPixelsARB(x
, y
, width
, height
, format
, type
, INT_MAX
, pixels
);