2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
27 #include "bufferobj.h"
31 #include "framebuffer.h"
33 #include "format_unpack.h"
42 * Tries to implement glReadPixels() of GL_DEPTH_COMPONENT using memcpy of the
46 fast_read_depth_pixels( struct gl_context
*ctx
,
48 GLsizei width
, GLsizei height
,
49 GLenum type
, GLvoid
*pixels
,
50 const struct gl_pixelstore_attrib
*packing
)
52 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
53 struct gl_renderbuffer
*rb
= fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
55 int stride
, dstStride
, j
;
57 if (ctx
->Pixel
.DepthScale
!= 1.0 || ctx
->Pixel
.DepthBias
!= 0.0)
60 if (packing
->SwapBytes
)
63 if (_mesa_get_format_datatype(rb
->Format
) != GL_UNSIGNED_NORMALIZED
)
66 if (!((type
== GL_UNSIGNED_SHORT
&& rb
->Format
== MESA_FORMAT_Z16
) ||
67 type
== GL_UNSIGNED_INT
))
70 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
74 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
75 return GL_TRUE
; /* don't bother trying the slow path */
78 dstStride
= _mesa_image_row_stride(packing
, width
, GL_DEPTH_COMPONENT
, type
);
79 dst
= (GLubyte
*) _mesa_image_address2d(packing
, pixels
, width
, height
,
80 GL_DEPTH_COMPONENT
, type
, 0, 0);
82 for (j
= 0; j
< height
; j
++) {
83 if (type
== GL_UNSIGNED_INT
) {
84 _mesa_unpack_uint_z_row(rb
->Format
, width
, map
, (GLuint
*)dst
);
86 ASSERT(type
== GL_UNSIGNED_SHORT
&& rb
->Format
== MESA_FORMAT_Z16
);
87 memcpy(dst
, map
, width
* 2);
93 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
99 * Read pixels for format=GL_DEPTH_COMPONENT.
102 read_depth_pixels( struct gl_context
*ctx
,
104 GLsizei width
, GLsizei height
,
105 GLenum type
, GLvoid
*pixels
,
106 const struct gl_pixelstore_attrib
*packing
)
108 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
109 struct gl_renderbuffer
*rb
= fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
112 int dstStride
, stride
;
113 GLfloat
*depthValues
;
118 /* clipping should have been done already */
121 ASSERT(x
+ width
<= (GLint
) rb
->Width
);
122 ASSERT(y
+ height
<= (GLint
) rb
->Height
);
124 if (fast_read_depth_pixels(ctx
, x
, y
, width
, height
, type
, pixels
, packing
))
127 dstStride
= _mesa_image_row_stride(packing
, width
, GL_DEPTH_COMPONENT
, type
);
128 dst
= (GLubyte
*) _mesa_image_address2d(packing
, pixels
, width
, height
,
129 GL_DEPTH_COMPONENT
, type
, 0, 0);
131 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
134 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
138 depthValues
= (GLfloat
*) malloc(width
* sizeof(GLfloat
));
141 /* General case (slower) */
142 for (j
= 0; j
< height
; j
++, y
++) {
143 _mesa_unpack_float_z_row(rb
->Format
, width
, map
, depthValues
);
144 _mesa_pack_depth_span(ctx
, width
, dst
, type
, depthValues
, packing
);
151 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
156 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
161 * Read pixels for format=GL_STENCIL_INDEX.
164 read_stencil_pixels( struct gl_context
*ctx
,
166 GLsizei width
, GLsizei height
,
167 GLenum type
, GLvoid
*pixels
,
168 const struct gl_pixelstore_attrib
*packing
)
170 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
171 struct gl_renderbuffer
*rb
= fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
;
173 GLubyte
*map
, *stencil
;
179 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
182 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
186 stencil
= (GLubyte
*) malloc(width
* sizeof(GLubyte
));
189 /* process image row by row */
190 for (j
= 0; j
< height
; j
++) {
193 _mesa_unpack_ubyte_stencil_row(rb
->Format
, width
, map
, stencil
);
194 dest
= _mesa_image_address2d(packing
, pixels
, width
, height
,
195 GL_STENCIL_INDEX
, type
, j
, 0);
197 _mesa_pack_stencil_span(ctx
, width
, type
, dest
, stencil
, packing
);
203 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
208 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
212 fast_read_rgba_pixels_memcpy( struct gl_context
*ctx
,
214 GLsizei width
, GLsizei height
,
215 GLenum format
, GLenum type
,
217 const struct gl_pixelstore_attrib
*packing
,
218 GLbitfield transferOps
)
220 struct gl_renderbuffer
*rb
= ctx
->ReadBuffer
->_ColorReadBuffer
;
222 int dstStride
, stride
, j
, texelBytes
;
224 if (!_mesa_format_matches_format_and_type(rb
->Format
, format
, type
,
225 ctx
->Pack
.SwapBytes
))
228 /* If the format is unsigned normalized then we can ignore clamping
229 * because the values are already in the range [0,1] so it won't
230 * have any effect anyway.
232 if (_mesa_get_format_datatype(rb
->Format
) == GL_UNSIGNED_NORMALIZED
)
233 transferOps
&= ~IMAGE_CLAMP_BIT
;
238 dstStride
= _mesa_image_row_stride(packing
, width
, format
, type
);
239 dst
= (GLubyte
*) _mesa_image_address2d(packing
, pixels
, width
, height
,
242 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
245 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
246 return GL_TRUE
; /* don't bother trying the slow path */
249 texelBytes
= _mesa_get_format_bytes(rb
->Format
);
250 for (j
= 0; j
< height
; j
++) {
251 memcpy(dst
, map
, width
* texelBytes
);
256 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
262 slow_read_rgba_pixels( struct gl_context
*ctx
,
264 GLsizei width
, GLsizei height
,
265 GLenum format
, GLenum type
,
267 const struct gl_pixelstore_attrib
*packing
,
268 GLbitfield transferOps
)
270 struct gl_renderbuffer
*rb
= ctx
->ReadBuffer
->_ColorReadBuffer
;
271 const gl_format rbFormat
= _mesa_get_srgb_format_linear(rb
->Format
);
274 int dstStride
, stride
, j
;
276 dstStride
= _mesa_image_row_stride(packing
, width
, format
, type
);
277 dst
= (GLubyte
*) _mesa_image_address2d(packing
, pixels
, width
, height
,
280 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
283 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
287 rgba
= malloc(width
* MAX_PIXEL_BYTES
);
291 for (j
= 0; j
< height
; j
++) {
292 if (_mesa_is_integer_format(format
)) {
293 _mesa_unpack_uint_rgba_row(rbFormat
, width
, map
, (GLuint (*)[4]) rgba
);
294 _mesa_rebase_rgba_uint(width
, (GLuint (*)[4]) rgba
,
296 _mesa_pack_rgba_span_int(ctx
, width
, (GLuint (*)[4]) rgba
, format
,
299 _mesa_unpack_rgba_row(rbFormat
, width
, map
, (GLfloat (*)[4]) rgba
);
300 _mesa_rebase_rgba_float(width
, (GLfloat (*)[4]) rgba
,
302 _mesa_pack_rgba_span_float(ctx
, width
, (GLfloat (*)[4]) rgba
, format
,
303 type
, dst
, packing
, transferOps
);
312 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
316 * Read R, G, B, A, RGB, L, or LA pixels.
319 read_rgba_pixels( struct gl_context
*ctx
,
321 GLsizei width
, GLsizei height
,
322 GLenum format
, GLenum type
, GLvoid
*pixels
,
323 const struct gl_pixelstore_attrib
*packing
)
325 GLbitfield transferOps
= ctx
->_ImageTransferState
;
326 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
327 struct gl_renderbuffer
*rb
= fb
->_ColorReadBuffer
;
332 if ((ctx
->Color
._ClampReadColor
== GL_TRUE
|| type
!= GL_FLOAT
) &&
333 !_mesa_is_integer_format(format
)) {
334 transferOps
|= IMAGE_CLAMP_BIT
;
337 /* Try the optimized paths first. */
338 if (fast_read_rgba_pixels_memcpy(ctx
, x
, y
, width
, height
,
339 format
, type
, pixels
, packing
,
344 slow_read_rgba_pixels(ctx
, x
, y
, width
, height
,
345 format
, type
, pixels
, packing
, transferOps
);
349 * For a packed depth/stencil buffer being read as depth/stencil, just memcpy the
350 * data (possibly swapping 8/24 vs 24/8 as we go).
353 fast_read_depth_stencil_pixels(struct gl_context
*ctx
,
355 GLsizei width
, GLsizei height
,
356 GLubyte
*dst
, int dstStride
)
358 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
359 struct gl_renderbuffer
*rb
= fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
360 struct gl_renderbuffer
*stencilRb
= fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
;
367 if (rb
->Format
!= MESA_FORMAT_Z24_S8
&&
368 rb
->Format
!= MESA_FORMAT_S8_Z24
)
371 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
, GL_MAP_READ_BIT
,
374 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
375 return GL_TRUE
; /* don't bother trying the slow path */
378 for (i
= 0; i
< height
; i
++) {
379 _mesa_unpack_uint_24_8_depth_stencil_row(rb
->Format
, width
,
385 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
392 * For non-float-depth and stencil buffers being read as 24/8 depth/stencil,
393 * copy the integer data directly instead of converting depth to float and
397 fast_read_depth_stencil_pixels_separate(struct gl_context
*ctx
,
399 GLsizei width
, GLsizei height
,
400 uint32_t *dst
, int dstStride
)
402 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
403 struct gl_renderbuffer
*depthRb
= fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
404 struct gl_renderbuffer
*stencilRb
= fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
;
405 GLubyte
*depthMap
, *stencilMap
, *stencilVals
;
406 int depthStride
, stencilStride
, i
, j
;
408 if (_mesa_get_format_datatype(depthRb
->Format
) != GL_UNSIGNED_NORMALIZED
)
411 ctx
->Driver
.MapRenderbuffer(ctx
, depthRb
, x
, y
, width
, height
,
412 GL_MAP_READ_BIT
, &depthMap
, &depthStride
);
414 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
415 return GL_TRUE
; /* don't bother trying the slow path */
418 ctx
->Driver
.MapRenderbuffer(ctx
, stencilRb
, x
, y
, width
, height
,
419 GL_MAP_READ_BIT
, &stencilMap
, &stencilStride
);
421 ctx
->Driver
.UnmapRenderbuffer(ctx
, depthRb
);
422 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
423 return GL_TRUE
; /* don't bother trying the slow path */
426 stencilVals
= (GLubyte
*) malloc(width
* sizeof(GLubyte
));
429 for (j
= 0; j
< height
; j
++) {
430 _mesa_unpack_uint_z_row(depthRb
->Format
, width
, depthMap
, dst
);
431 _mesa_unpack_ubyte_stencil_row(stencilRb
->Format
, width
,
432 stencilMap
, stencilVals
);
434 for (i
= 0; i
< width
; i
++) {
435 dst
[i
] = (dst
[i
] & 0xffffff00) | stencilVals
[i
];
438 depthMap
+= depthStride
;
439 stencilMap
+= stencilStride
;
440 dst
+= dstStride
/ 4;
444 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
449 ctx
->Driver
.UnmapRenderbuffer(ctx
, depthRb
);
450 ctx
->Driver
.UnmapRenderbuffer(ctx
, stencilRb
);
456 slow_read_depth_stencil_pixels_separate(struct gl_context
*ctx
,
458 GLsizei width
, GLsizei height
,
460 const struct gl_pixelstore_attrib
*packing
,
461 GLubyte
*dst
, int dstStride
)
463 struct gl_framebuffer
*fb
= ctx
->ReadBuffer
;
464 struct gl_renderbuffer
*depthRb
= fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
465 struct gl_renderbuffer
*stencilRb
= fb
->Attachment
[BUFFER_STENCIL
].Renderbuffer
;
466 GLubyte
*depthMap
, *stencilMap
;
467 int depthStride
, stencilStride
, j
;
468 GLubyte
*stencilVals
;
472 /* The depth and stencil buffers might be separate, or a single buffer.
473 * If one buffer, only map it once.
475 ctx
->Driver
.MapRenderbuffer(ctx
, depthRb
, x
, y
, width
, height
,
476 GL_MAP_READ_BIT
, &depthMap
, &depthStride
);
478 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
482 if (stencilRb
!= depthRb
) {
483 ctx
->Driver
.MapRenderbuffer(ctx
, stencilRb
, x
, y
, width
, height
,
484 GL_MAP_READ_BIT
, &stencilMap
,
487 ctx
->Driver
.UnmapRenderbuffer(ctx
, depthRb
);
488 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
493 stencilMap
= depthMap
;
494 stencilStride
= depthStride
;
497 stencilVals
= (GLubyte
*) malloc(width
* sizeof(GLubyte
));
498 depthVals
= (GLfloat
*) malloc(width
* sizeof(GLfloat
));
500 if (stencilVals
&& depthVals
) {
501 for (j
= 0; j
< height
; j
++) {
502 _mesa_unpack_float_z_row(depthRb
->Format
, width
, depthMap
, depthVals
);
503 _mesa_unpack_ubyte_stencil_row(stencilRb
->Format
, width
,
504 stencilMap
, stencilVals
);
506 _mesa_pack_depth_stencil_span(ctx
, width
, type
, (GLuint
*)dst
,
507 depthVals
, stencilVals
, packing
);
509 depthMap
+= depthStride
;
510 stencilMap
+= stencilStride
;
515 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glReadPixels");
521 ctx
->Driver
.UnmapRenderbuffer(ctx
, depthRb
);
522 if (stencilRb
!= depthRb
) {
523 ctx
->Driver
.UnmapRenderbuffer(ctx
, stencilRb
);
529 * Read combined depth/stencil values.
530 * We'll have already done error checking to be sure the expected
531 * depth and stencil buffers really exist.
534 read_depth_stencil_pixels(struct gl_context
*ctx
,
536 GLsizei width
, GLsizei height
,
537 GLenum type
, GLvoid
*pixels
,
538 const struct gl_pixelstore_attrib
*packing
)
540 const GLboolean scaleOrBias
541 = ctx
->Pixel
.DepthScale
!= 1.0 || ctx
->Pixel
.DepthBias
!= 0.0;
542 const GLboolean stencilTransfer
= ctx
->Pixel
.IndexShift
543 || ctx
->Pixel
.IndexOffset
|| ctx
->Pixel
.MapStencilFlag
;
547 dst
= (GLubyte
*) _mesa_image_address2d(packing
, pixels
,
549 GL_DEPTH_STENCIL_EXT
,
551 dstStride
= _mesa_image_row_stride(packing
, width
,
552 GL_DEPTH_STENCIL_EXT
, type
);
554 /* Fast 24/8 reads. */
555 if (type
== GL_UNSIGNED_INT_24_8
&&
556 !scaleOrBias
&& !stencilTransfer
&& !packing
->SwapBytes
) {
557 if (fast_read_depth_stencil_pixels(ctx
, x
, y
, width
, height
,
561 if (fast_read_depth_stencil_pixels_separate(ctx
, x
, y
, width
, height
,
562 (uint32_t *)dst
, dstStride
))
566 slow_read_depth_stencil_pixels_separate(ctx
, x
, y
, width
, height
,
574 * Software fallback routine for ctx->Driver.ReadPixels().
575 * By time we get here, all error checking will have been done.
578 _mesa_readpixels(struct gl_context
*ctx
,
579 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
580 GLenum format
, GLenum type
,
581 const struct gl_pixelstore_attrib
*packing
,
584 struct gl_pixelstore_attrib clippedPacking
= *packing
;
587 _mesa_update_state(ctx
);
589 /* Do all needed clipping here, so that we can forget about it later */
590 if (_mesa_clip_readpixels(ctx
, &x
, &y
, &width
, &height
, &clippedPacking
)) {
592 pixels
= _mesa_map_pbo_dest(ctx
, &clippedPacking
, pixels
);
596 case GL_STENCIL_INDEX
:
597 read_stencil_pixels(ctx
, x
, y
, width
, height
, type
, pixels
,
600 case GL_DEPTH_COMPONENT
:
601 read_depth_pixels(ctx
, x
, y
, width
, height
, type
, pixels
,
604 case GL_DEPTH_STENCIL_EXT
:
605 read_depth_stencil_pixels(ctx
, x
, y
, width
, height
, type
, pixels
,
609 /* all other formats should be color formats */
610 read_rgba_pixels(ctx
, x
, y
, width
, height
, format
, type
, pixels
,
614 _mesa_unmap_pbo_dest(ctx
, &clippedPacking
);
621 _mesa_ReadnPixelsARB( GLint x
, GLint y
, GLsizei width
, GLsizei height
,
622 GLenum format
, GLenum type
, GLsizei bufSize
,
627 GET_CURRENT_CONTEXT(ctx
);
628 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
630 FLUSH_CURRENT(ctx
, 0);
632 if (MESA_VERBOSE
& VERBOSE_API
)
633 _mesa_debug(ctx
, "glReadPixels(%d, %d, %s, %s, %p)\n",
635 _mesa_lookup_enum_by_nr(format
),
636 _mesa_lookup_enum_by_nr(type
),
639 if (width
< 0 || height
< 0) {
640 _mesa_error( ctx
, GL_INVALID_VALUE
,
641 "glReadPixels(width=%d height=%d)", width
, height
);
646 _mesa_update_state(ctx
);
648 err
= _mesa_error_check_format_and_type(ctx
, format
, type
);
649 if (err
!= GL_NO_ERROR
) {
650 _mesa_error(ctx
, err
, "glReadPixels(invalid format %s and/or type %s)",
651 _mesa_lookup_enum_by_nr(format
),
652 _mesa_lookup_enum_by_nr(type
));
656 /* Check that the destination format and source buffer are both
657 * integer-valued or both non-integer-valued.
659 if (ctx
->Extensions
.EXT_texture_integer
&& _mesa_is_color_format(format
)) {
660 const struct gl_renderbuffer
*rb
= ctx
->ReadBuffer
->_ColorReadBuffer
;
661 const GLboolean srcInteger
= _mesa_is_format_integer_color(rb
->Format
);
662 const GLboolean dstInteger
= _mesa_is_integer_format(format
);
663 if (dstInteger
!= srcInteger
) {
664 _mesa_error(ctx
, GL_INVALID_OPERATION
,
665 "glReadPixels(integer / non-integer format mismatch");
670 if (ctx
->ReadBuffer
->_Status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
671 _mesa_error(ctx
, GL_INVALID_FRAMEBUFFER_OPERATION_EXT
,
672 "glReadPixels(incomplete framebuffer)" );
676 if (ctx
->ReadBuffer
->Name
!= 0 && ctx
->ReadBuffer
->Visual
.samples
> 0) {
677 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glReadPixels(multisample FBO)");
681 if (!_mesa_source_buffer_exists(ctx
, format
)) {
682 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glReadPixels(no readbuffer)");
686 if (width
== 0 || height
== 0)
687 return; /* nothing to do */
689 if (!_mesa_validate_pbo_access(2, &ctx
->Pack
, width
, height
, 1,
690 format
, type
, bufSize
, pixels
)) {
691 if (_mesa_is_bufferobj(ctx
->Pack
.BufferObj
)) {
692 _mesa_error(ctx
, GL_INVALID_OPERATION
,
693 "glReadPixels(out of bounds PBO access)");
695 _mesa_error(ctx
, GL_INVALID_OPERATION
,
696 "glReadnPixelsARB(out of bounds access:"
697 " bufSize (%d) is too small)", bufSize
);
702 if (_mesa_is_bufferobj(ctx
->Pack
.BufferObj
) &&
703 _mesa_bufferobj_mapped(ctx
->Pack
.BufferObj
)) {
704 /* buffer is mapped - that's an error */
705 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glReadPixels(PBO is mapped)");
709 ctx
->Driver
.ReadPixels(ctx
, x
, y
, width
, height
,
710 format
, type
, &ctx
->Pack
, pixels
);
714 _mesa_ReadPixels( GLint x
, GLint y
, GLsizei width
, GLsizei height
,
715 GLenum format
, GLenum type
, GLvoid
*pixels
)
717 _mesa_ReadnPixelsARB(x
, y
, width
, height
, format
, type
, INT_MAX
, pixels
);