readpix.c revision 848b8605
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 43 44/** 45 * Return true if the conversion L=R+G+B is needed. 46 */ 47static GLboolean 48need_rgb_to_luminance_conversion(mesa_format texFormat, GLenum format) 49{ 50 GLenum baseTexFormat = _mesa_get_format_base_format(texFormat); 51 52 return (baseTexFormat == GL_RG || 53 baseTexFormat == GL_RGB || 54 baseTexFormat == GL_RGBA) && 55 (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA); 56} 57 58 59/** 60 * Return transfer op flags for this ReadPixels operation. 61 */ 62static GLbitfield 63get_readpixels_transfer_ops(const struct gl_context *ctx, mesa_format texFormat, 64 GLenum format, GLenum type, GLboolean uses_blit) 65{ 66 GLbitfield transferOps = ctx->_ImageTransferState; 67 68 if (format == GL_DEPTH_COMPONENT || 69 format == GL_DEPTH_STENCIL || 70 format == GL_STENCIL_INDEX) { 71 return 0; 72 } 73 74 /* Pixel transfer ops (scale, bias, table lookup) do not apply 75 * to integer formats. 76 */ 77 if (_mesa_is_enum_format_integer(format)) { 78 return 0; 79 } 80 81 if (uses_blit) { 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; 87 } 88 } 89 else { 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; 95 } 96 } 97 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. 101 */ 102 if (_mesa_get_format_datatype(texFormat) == GL_UNSIGNED_NORMALIZED && 103 !need_rgb_to_luminance_conversion(texFormat, format)) { 104 transferOps &= ~IMAGE_CLAMP_BIT; 105 } 106 107 return transferOps; 108} 109 110 111/** 112 * Return true if memcpy cannot be used for ReadPixels. 113 * 114 * If uses_blit is true, the function returns true if a simple 3D engine blit 115 * cannot be used for ReadPixels packing. 116 * 117 * NOTE: This doesn't take swizzling and format conversions between 118 * the readbuffer and the pixel pack buffer into account. 119 */ 120GLboolean 121_mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format, 122 GLenum type, GLboolean uses_blit) 123{ 124 struct gl_renderbuffer *rb = 125 _mesa_get_read_renderbuffer_for_format(ctx, format); 126 GLenum srcType; 127 128 ASSERT(rb); 129 130 /* There are different rules depending on the base format. */ 131 switch (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; 137 138 case GL_DEPTH_COMPONENT: 139 return ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f; 140 141 case GL_STENCIL_INDEX: 142 return ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset || 143 ctx->Pixel.MapStencilFlag; 144 145 default: 146 /* Color formats. */ 147 if (need_rgb_to_luminance_conversion(rb->Format, format)) { 148 return GL_TRUE; 149 } 150 151 /* Conversion between signed and unsigned integers needs masking 152 * (it isn't just memcpy). */ 153 srcType = _mesa_get_format_datatype(rb->Format); 154 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 && 160 (type == GL_INT || 161 type == GL_SHORT || 162 type == GL_BYTE))) { 163 return GL_TRUE; 164 } 165 166 /* And finally, see if there are any transfer ops. */ 167 return get_readpixels_transfer_ops(ctx, rb->Format, format, type, 168 uses_blit) != 0; 169 } 170 return GL_FALSE; 171} 172 173 174static GLboolean 175readpixels_can_use_memcpy(const struct gl_context *ctx, GLenum format, GLenum type, 176 const struct gl_pixelstore_attrib *packing) 177{ 178 struct gl_renderbuffer *rb = 179 _mesa_get_read_renderbuffer_for_format(ctx, format); 180 181 ASSERT(rb); 182 183 if (_mesa_readpixels_needs_slow_path(ctx, format, type, GL_FALSE)) { 184 return GL_FALSE; 185 } 186 187 /* The base internal format and the base Mesa format must match. */ 188 if (rb->_BaseFormat != _mesa_get_format_base_format(rb->Format)) { 189 return GL_FALSE; 190 } 191 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)) { 195 return GL_FALSE; 196 } 197 198 return GL_TRUE; 199} 200 201 202static GLboolean 203readpixels_memcpy(struct gl_context *ctx, 204 GLint x, GLint y, 205 GLsizei width, GLsizei height, 206 GLenum format, GLenum type, 207 GLvoid *pixels, 208 const struct gl_pixelstore_attrib *packing) 209{ 210 struct gl_renderbuffer *rb = 211 _mesa_get_read_renderbuffer_for_format(ctx, format); 212 GLubyte *dst, *map; 213 int dstStride, stride, j, texelBytes; 214 215 /* Fail if memcpy cannot be used. */ 216 if (!readpixels_can_use_memcpy(ctx, format, type, packing)) { 217 return GL_FALSE; 218 } 219 220 dstStride = _mesa_image_row_stride(packing, width, format, type); 221 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, 222 format, type, 0, 0); 223 224 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, 225 &map, &stride); 226 if (!map) { 227 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 228 return GL_TRUE; /* don't bother trying the slow path */ 229 } 230 231 texelBytes = _mesa_get_format_bytes(rb->Format); 232 233 /* memcpy*/ 234 for (j = 0; j < height; j++) { 235 memcpy(dst, map, width * texelBytes); 236 dst += dstStride; 237 map += stride; 238 } 239 240 ctx->Driver.UnmapRenderbuffer(ctx, rb); 241 return GL_TRUE; 242} 243 244 245/** 246 * Optimized path for conversion of depth values to GL_DEPTH_COMPONENT, 247 * GL_UNSIGNED_INT. 248 */ 249static GLboolean 250read_uint_depth_pixels( struct gl_context *ctx, 251 GLint x, GLint y, 252 GLsizei width, GLsizei height, 253 GLenum type, GLvoid *pixels, 254 const struct gl_pixelstore_attrib *packing ) 255{ 256 struct gl_framebuffer *fb = ctx->ReadBuffer; 257 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; 258 GLubyte *map, *dst; 259 int stride, dstStride, j; 260 261 if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) 262 return GL_FALSE; 263 264 if (packing->SwapBytes) 265 return GL_FALSE; 266 267 if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED) 268 return GL_FALSE; 269 270 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, 271 &map, &stride); 272 273 if (!map) { 274 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 275 return GL_TRUE; /* don't bother trying the slow path */ 276 } 277 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); 281 282 for (j = 0; j < height; j++) { 283 _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst); 284 285 map += stride; 286 dst += dstStride; 287 } 288 ctx->Driver.UnmapRenderbuffer(ctx, rb); 289 290 return GL_TRUE; 291} 292 293/** 294 * Read pixels for format=GL_DEPTH_COMPONENT. 295 */ 296static void 297read_depth_pixels( struct gl_context *ctx, 298 GLint x, GLint y, 299 GLsizei width, GLsizei height, 300 GLenum type, GLvoid *pixels, 301 const struct gl_pixelstore_attrib *packing ) 302{ 303 struct gl_framebuffer *fb = ctx->ReadBuffer; 304 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; 305 GLint j; 306 GLubyte *dst, *map; 307 int dstStride, stride; 308 GLfloat *depthValues; 309 310 if (!rb) 311 return; 312 313 /* clipping should have been done already */ 314 ASSERT(x >= 0); 315 ASSERT(y >= 0); 316 ASSERT(x + width <= (GLint) rb->Width); 317 ASSERT(y + height <= (GLint) rb->Height); 318 319 if (type == GL_UNSIGNED_INT && 320 read_uint_depth_pixels(ctx, x, y, width, height, type, pixels, packing)) { 321 return; 322 } 323 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); 327 328 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, 329 &map, &stride); 330 if (!map) { 331 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 332 return; 333 } 334 335 depthValues = malloc(width * sizeof(GLfloat)); 336 337 if (depthValues) { 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); 342 343 dst += dstStride; 344 map += stride; 345 } 346 } 347 else { 348 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 349 } 350 351 free(depthValues); 352 353 ctx->Driver.UnmapRenderbuffer(ctx, rb); 354} 355 356 357/** 358 * Read pixels for format=GL_STENCIL_INDEX. 359 */ 360static void 361read_stencil_pixels( struct gl_context *ctx, 362 GLint x, GLint y, 363 GLsizei width, GLsizei height, 364 GLenum type, GLvoid *pixels, 365 const struct gl_pixelstore_attrib *packing ) 366{ 367 struct gl_framebuffer *fb = ctx->ReadBuffer; 368 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; 369 GLint j; 370 GLubyte *map, *stencil; 371 GLint stride; 372 373 if (!rb) 374 return; 375 376 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, 377 &map, &stride); 378 if (!map) { 379 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 380 return; 381 } 382 383 stencil = malloc(width * sizeof(GLubyte)); 384 385 if (stencil) { 386 /* process image row by row */ 387 for (j = 0; j < height; j++) { 388 GLvoid *dest; 389 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); 393 394 _mesa_pack_stencil_span(ctx, width, type, dest, stencil, packing); 395 396 map += stride; 397 } 398 } 399 else { 400 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 401 } 402 403 free(stencil); 404 405 ctx->Driver.UnmapRenderbuffer(ctx, rb); 406} 407 408 409/** 410 * Try to do glReadPixels of RGBA data using swizzle. 411 * \return GL_TRUE if successful, GL_FALSE otherwise (use the slow path) 412 */ 413static GLboolean 414read_rgba_pixels_swizzle(struct gl_context *ctx, 415 GLint x, GLint y, 416 GLsizei width, GLsizei height, 417 GLenum format, GLenum type, 418 GLvoid *pixels, 419 const struct gl_pixelstore_attrib *packing) 420{ 421 struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; 422 GLubyte *dst, *map; 423 int dstStride, stride, j; 424 GLboolean swizzle_rb = GL_FALSE, copy_xrgb = GL_FALSE; 425 426 /* XXX we could check for other swizzle/special cases here as needed */ 427 if (rb->Format == MESA_FORMAT_R8G8B8A8_UNORM && 428 format == GL_BGRA && 429 type == GL_UNSIGNED_INT_8_8_8_8_REV && 430 !ctx->Pack.SwapBytes) { 431 swizzle_rb = GL_TRUE; 432 } 433 else if (rb->Format == MESA_FORMAT_B8G8R8X8_UNORM && 434 format == GL_BGRA && 435 type == GL_UNSIGNED_INT_8_8_8_8_REV && 436 !ctx->Pack.SwapBytes) { 437 copy_xrgb = GL_TRUE; 438 } 439 else { 440 return GL_FALSE; 441 } 442 443 dstStride = _mesa_image_row_stride(packing, width, format, type); 444 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, 445 format, type, 0, 0); 446 447 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, 448 &map, &stride); 449 if (!map) { 450 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 451 return GL_TRUE; /* don't bother trying the slow path */ 452 } 453 454 if (swizzle_rb) { 455 /* swap R/B */ 456 for (j = 0; j < height; j++) { 457 int i; 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); 464 } 465 dst += dstStride; 466 map += stride; 467 } 468 } else if (copy_xrgb) { 469 /* convert xrgb -> argb */ 470 for (j = 0; j < height; j++) { 471 GLuint *dst4 = (GLuint *) dst, *map4 = (GLuint *) map; 472 int i; 473 for (i = 0; i < width; i++) { 474 dst4[i] = map4[i] | 0xff000000; /* set A=0xff */ 475 } 476 dst += dstStride; 477 map += stride; 478 } 479 } 480 481 ctx->Driver.UnmapRenderbuffer(ctx, rb); 482 483 return GL_TRUE; 484} 485 486static void 487slow_read_rgba_pixels( struct gl_context *ctx, 488 GLint x, GLint y, 489 GLsizei width, GLsizei height, 490 GLenum format, GLenum type, 491 GLvoid *pixels, 492 const struct gl_pixelstore_attrib *packing, 493 GLbitfield transferOps ) 494{ 495 struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; 496 const mesa_format rbFormat = _mesa_get_srgb_format_linear(rb->Format); 497 void *rgba; 498 GLubyte *dst, *map; 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); 502 503 dstStride = _mesa_image_row_stride(packing, width, format, type); 504 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, 505 format, type, 0, 0); 506 507 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, 508 &map, &stride); 509 if (!map) { 510 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 511 return; 512 } 513 514 rgba = malloc(width * MAX_PIXEL_BYTES); 515 if (!rgba) 516 goto done; 517 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, 522 rb->_BaseFormat); 523 if (dst_is_uint) { 524 _mesa_pack_rgba_span_from_uints(ctx, width, (GLuint (*)[4]) rgba, format, 525 type, dst); 526 } else { 527 _mesa_pack_rgba_span_from_ints(ctx, width, (GLint (*)[4]) rgba, format, 528 type, dst); 529 } 530 } else { 531 _mesa_unpack_rgba_row(rbFormat, width, map, (GLfloat (*)[4]) rgba); 532 _mesa_rebase_rgba_float(width, (GLfloat (*)[4]) rgba, 533 rb->_BaseFormat); 534 _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, 535 type, dst, packing, transferOps); 536 } 537 dst += dstStride; 538 map += stride; 539 } 540 541 free(rgba); 542 543done: 544 ctx->Driver.UnmapRenderbuffer(ctx, rb); 545} 546 547/* 548 * Read R, G, B, A, RGB, L, or LA pixels. 549 */ 550static void 551read_rgba_pixels( struct gl_context *ctx, 552 GLint x, GLint y, 553 GLsizei width, GLsizei height, 554 GLenum format, GLenum type, GLvoid *pixels, 555 const struct gl_pixelstore_attrib *packing ) 556{ 557 GLbitfield transferOps; 558 struct gl_framebuffer *fb = ctx->ReadBuffer; 559 struct gl_renderbuffer *rb = fb->_ColorReadBuffer; 560 561 if (!rb) 562 return; 563 564 transferOps = get_readpixels_transfer_ops(ctx, rb->Format, format, type, 565 GL_FALSE); 566 567 /* Try the optimized paths first. */ 568 if (!transferOps && 569 read_rgba_pixels_swizzle(ctx, x, y, width, height, 570 format, type, pixels, packing)) { 571 return; 572 } 573 574 slow_read_rgba_pixels(ctx, x, y, width, height, 575 format, type, pixels, packing, transferOps); 576} 577 578/** 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). 581 */ 582static GLboolean 583fast_read_depth_stencil_pixels(struct gl_context *ctx, 584 GLint x, GLint y, 585 GLsizei width, GLsizei height, 586 GLubyte *dst, int dstStride) 587{ 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; 591 GLubyte *map; 592 int stride, i; 593 594 if (rb != stencilRb) 595 return GL_FALSE; 596 597 if (rb->Format != MESA_FORMAT_S8_UINT_Z24_UNORM && 598 rb->Format != MESA_FORMAT_Z24_UNORM_S8_UINT) 599 return GL_FALSE; 600 601 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, 602 &map, &stride); 603 if (!map) { 604 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 605 return GL_TRUE; /* don't bother trying the slow path */ 606 } 607 608 for (i = 0; i < height; i++) { 609 _mesa_unpack_uint_24_8_depth_stencil_row(rb->Format, width, 610 map, (GLuint *)dst); 611 map += stride; 612 dst += dstStride; 613 } 614 615 ctx->Driver.UnmapRenderbuffer(ctx, rb); 616 617 return GL_TRUE; 618} 619 620 621/** 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 624 * re-packing. 625 */ 626static GLboolean 627fast_read_depth_stencil_pixels_separate(struct gl_context *ctx, 628 GLint x, GLint y, 629 GLsizei width, GLsizei height, 630 uint32_t *dst, int dstStride) 631{ 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; 637 638 if (_mesa_get_format_datatype(depthRb->Format) != GL_UNSIGNED_NORMALIZED) 639 return GL_FALSE; 640 641 ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height, 642 GL_MAP_READ_BIT, &depthMap, &depthStride); 643 if (!depthMap) { 644 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 645 return GL_TRUE; /* don't bother trying the slow path */ 646 } 647 648 ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height, 649 GL_MAP_READ_BIT, &stencilMap, &stencilStride); 650 if (!stencilMap) { 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 */ 654 } 655 656 stencilVals = malloc(width * sizeof(GLubyte)); 657 658 if (stencilVals) { 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); 663 664 for (i = 0; i < width; i++) { 665 dst[i] = (dst[i] & 0xffffff00) | stencilVals[i]; 666 } 667 668 depthMap += depthStride; 669 stencilMap += stencilStride; 670 dst += dstStride / 4; 671 } 672 } 673 else { 674 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 675 } 676 677 free(stencilVals); 678 679 ctx->Driver.UnmapRenderbuffer(ctx, depthRb); 680 ctx->Driver.UnmapRenderbuffer(ctx, stencilRb); 681 682 return GL_TRUE; 683} 684 685static void 686slow_read_depth_stencil_pixels_separate(struct gl_context *ctx, 687 GLint x, GLint y, 688 GLsizei width, GLsizei height, 689 GLenum type, 690 const struct gl_pixelstore_attrib *packing, 691 GLubyte *dst, int dstStride) 692{ 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; 699 GLfloat *depthVals; 700 701 702 /* The depth and stencil buffers might be separate, or a single buffer. 703 * If one buffer, only map it once. 704 */ 705 ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height, 706 GL_MAP_READ_BIT, &depthMap, &depthStride); 707 if (!depthMap) { 708 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 709 return; 710 } 711 712 if (stencilRb != depthRb) { 713 ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height, 714 GL_MAP_READ_BIT, &stencilMap, 715 &stencilStride); 716 if (!stencilMap) { 717 ctx->Driver.UnmapRenderbuffer(ctx, depthRb); 718 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 719 return; 720 } 721 } 722 else { 723 stencilMap = depthMap; 724 stencilStride = depthStride; 725 } 726 727 stencilVals = malloc(width * sizeof(GLubyte)); 728 depthVals = malloc(width * sizeof(GLfloat)); 729 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); 735 736 _mesa_pack_depth_stencil_span(ctx, width, type, (GLuint *)dst, 737 depthVals, stencilVals, packing); 738 739 depthMap += depthStride; 740 stencilMap += stencilStride; 741 dst += dstStride; 742 } 743 } 744 else { 745 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 746 } 747 748 free(stencilVals); 749 free(depthVals); 750 751 ctx->Driver.UnmapRenderbuffer(ctx, depthRb); 752 if (stencilRb != depthRb) { 753 ctx->Driver.UnmapRenderbuffer(ctx, stencilRb); 754 } 755} 756 757 758/** 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. 762 */ 763static void 764read_depth_stencil_pixels(struct gl_context *ctx, 765 GLint x, GLint y, 766 GLsizei width, GLsizei height, 767 GLenum type, GLvoid *pixels, 768 const struct gl_pixelstore_attrib *packing ) 769{ 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; 774 GLubyte *dst; 775 int dstStride; 776 777 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, 778 width, height, 779 GL_DEPTH_STENCIL_EXT, 780 type, 0, 0); 781 dstStride = _mesa_image_row_stride(packing, width, 782 GL_DEPTH_STENCIL_EXT, type); 783 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, 788 dst, dstStride)) 789 return; 790 791 if (fast_read_depth_stencil_pixels_separate(ctx, x, y, width, height, 792 (uint32_t *)dst, dstStride)) 793 return; 794 } 795 796 slow_read_depth_stencil_pixels_separate(ctx, x, y, width, height, 797 type, packing, 798 dst, dstStride); 799} 800 801 802 803/** 804 * Software fallback routine for ctx->Driver.ReadPixels(). 805 * By time we get here, all error checking will have been done. 806 */ 807void 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, 812 GLvoid *pixels) 813{ 814 struct gl_pixelstore_attrib clippedPacking = *packing; 815 816 if (ctx->NewState) 817 _mesa_update_state(ctx); 818 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)) { 821 822 pixels = _mesa_map_pbo_dest(ctx, &clippedPacking, pixels); 823 824 if (pixels) { 825 /* Try memcpy first. */ 826 if (readpixels_memcpy(ctx, x, y, width, height, format, type, 827 pixels, packing)) { 828 _mesa_unmap_pbo_dest(ctx, &clippedPacking); 829 return; 830 } 831 832 /* Otherwise take the slow path. */ 833 switch (format) { 834 case GL_STENCIL_INDEX: 835 read_stencil_pixels(ctx, x, y, width, height, type, pixels, 836 &clippedPacking); 837 break; 838 case GL_DEPTH_COMPONENT: 839 read_depth_pixels(ctx, x, y, width, height, type, pixels, 840 &clippedPacking); 841 break; 842 case GL_DEPTH_STENCIL_EXT: 843 read_depth_stencil_pixels(ctx, x, y, width, height, type, pixels, 844 &clippedPacking); 845 break; 846 default: 847 /* all other formats should be color formats */ 848 read_rgba_pixels(ctx, x, y, width, height, format, type, pixels, 849 &clippedPacking); 850 } 851 852 _mesa_unmap_pbo_dest(ctx, &clippedPacking); 853 } 854 } 855} 856 857 858static GLenum 859read_pixels_es3_error_check(GLenum format, GLenum type, 860 const struct gl_renderbuffer *rb) 861{ 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; 866 867 if (!_mesa_is_color_format(internalFormat)) { 868 return GL_INVALID_OPERATION; 869 } 870 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); 874 } 875 876 switch (format) { 877 case GL_RGBA: 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) 881 return GL_NO_ERROR; 882 if (internalFormat == GL_RGB10_A2 && 883 type == GL_UNSIGNED_INT_2_10_10_10_REV) 884 return GL_NO_ERROR; 885 if (internalFormat == GL_RGB10_A2UI && type == GL_UNSIGNED_BYTE) 886 return GL_NO_ERROR; 887 break; 888 case GL_BGRA: 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) 893 return GL_NO_ERROR; 894 break; 895 case GL_RGBA_INTEGER: 896 if ((is_signed_int && type == GL_INT) || 897 (is_unsigned_int && type == GL_UNSIGNED_INT)) 898 return GL_NO_ERROR; 899 break; 900 } 901 902 return GL_INVALID_OPERATION; 903} 904 905 906void GLAPIENTRY 907_mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height, 908 GLenum format, GLenum type, GLsizei bufSize, 909 GLvoid *pixels ) 910{ 911 GLenum err = GL_NO_ERROR; 912 struct gl_renderbuffer *rb; 913 914 GET_CURRENT_CONTEXT(ctx); 915 916 FLUSH_VERTICES(ctx, 0); 917 FLUSH_CURRENT(ctx, 0); 918 919 if (MESA_VERBOSE & VERBOSE_API) 920 _mesa_debug(ctx, "glReadPixels(%d, %d, %s, %s, %p)\n", 921 width, height, 922 _mesa_lookup_enum_by_nr(format), 923 _mesa_lookup_enum_by_nr(type), 924 pixels); 925 926 if (width < 0 || height < 0) { 927 _mesa_error( ctx, GL_INVALID_VALUE, 928 "glReadPixels(width=%d height=%d)", width, height ); 929 return; 930 } 931 932 if (ctx->NewState) 933 _mesa_update_state(ctx); 934 935 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 936 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 937 "glReadPixels(incomplete framebuffer)" ); 938 return; 939 } 940 941 rb = _mesa_get_read_renderbuffer_for_format(ctx, format); 942 if (rb == NULL) { 943 _mesa_error(ctx, GL_INVALID_OPERATION, 944 "glReadPixels(read buffer)"); 945 return; 946 } 947 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. 950 * 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. 955 */ 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) { 961 err = GL_NO_ERROR; 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; 967 } 968 } 969 } else { 970 err = read_pixels_es3_error_check(format, type, rb); 971 } 972 973 if (err == GL_NO_ERROR && (format == GL_DEPTH_COMPONENT 974 || format == GL_DEPTH_STENCIL)) { 975 err = GL_INVALID_ENUM; 976 } 977 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)); 982 return; 983 } 984 } 985 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)); 991 return; 992 } 993 994 if (_mesa_is_user_fbo(ctx->ReadBuffer) && 995 ctx->ReadBuffer->Visual.samples > 0) { 996 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)"); 997 return; 998 } 999 1000 if (!_mesa_source_buffer_exists(ctx, format)) { 1001 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)"); 1002 return; 1003 } 1004 1005 /* Check that the destination format and source buffer are both 1006 * integer-valued or both non-integer-valued. 1007 */ 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"); 1015 return; 1016 } 1017 } 1018 1019 if (width == 0 || height == 0) 1020 return; /* nothing to do */ 1021 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)"); 1027 } else { 1028 _mesa_error(ctx, GL_INVALID_OPERATION, 1029 "glReadnPixelsARB(out of bounds access:" 1030 " bufSize (%d) is too small)", bufSize); 1031 } 1032 return; 1033 } 1034 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)"); 1039 return; 1040 } 1041 1042 ctx->Driver.ReadPixels(ctx, x, y, width, height, 1043 format, type, &ctx->Pack, pixels); 1044} 1045 1046void GLAPIENTRY 1047_mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, 1048 GLenum format, GLenum type, GLvoid *pixels ) 1049{ 1050 _mesa_ReadnPixelsARB(x, y, width, height, format, type, INT_MAX, pixels); 1051} 1052