1 /* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 #include "glheader.h" 26 #include "imports.h" 27 #include "blend.h" 28 #include "bufferobj.h" 29 #include "context.h" 30 #include "enums.h" 31 #include "readpix.h" 32 #include "framebuffer.h" 33 #include "formats.h" 34 #include "format_unpack.h" 35 #include "image.h" 36 #include "mtypes.h" 37 #include "pack.h" 38 #include "pbo.h" 39 #include "state.h" 40 #include "glformats.h" 41 #include "fbobject.h" 42 #include "format_utils.h" 43 #include "pixeltransfer.h" 44 45 46 /** 47 * Return true if the conversion L=R+G+B is needed. 48 */ 49 GLboolean 50 _mesa_need_rgb_to_luminance_conversion(GLenum srcBaseFormat, 51 GLenum dstBaseFormat) 52 { 53 return (srcBaseFormat == GL_RG || 54 srcBaseFormat == GL_RGB || 55 srcBaseFormat == GL_RGBA) && 56 (dstBaseFormat == GL_LUMINANCE || 57 dstBaseFormat == GL_LUMINANCE_ALPHA); 58 } 59 60 /** 61 * Return true if the conversion L,I to RGB conversion is needed. 62 */ 63 GLboolean 64 _mesa_need_luminance_to_rgb_conversion(GLenum srcBaseFormat, 65 GLenum dstBaseFormat) 66 { 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); 77 } 78 79 /** 80 * Return transfer op flags for this ReadPixels operation. 81 */ 82 GLbitfield 83 _mesa_get_readpixels_transfer_ops(const struct gl_context *ctx, 84 mesa_format texFormat, 85 GLenum format, GLenum type, 86 GLboolean uses_blit) 87 { 88 GLbitfield transferOps = ctx->_ImageTransferState; 89 GLenum srcBaseFormat = _mesa_get_format_base_format(texFormat); 90 GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format); 91 92 if (format == GL_DEPTH_COMPONENT || 93 format == GL_DEPTH_STENCIL || 94 format == GL_STENCIL_INDEX) { 95 return 0; 96 } 97 98 /* Pixel transfer ops (scale, bias, table lookup) do not apply 99 * to integer formats. 100 */ 101 if (_mesa_is_enum_format_integer(format)) { 102 return 0; 103 } 104 105 if (uses_blit) { 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 transferOps |= IMAGE_CLAMP_BIT; 111 } 112 } 113 else { 114 /* For CPU-based ReadPixels packing, the clamping must always be done 115 * for non-float types, */ 116 if (_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) || 117 (type != GL_FLOAT && type != GL_HALF_FLOAT)) { 118 transferOps |= IMAGE_CLAMP_BIT; 119 } 120 } 121 122 /* If the format is unsigned normalized, we can ignore clamping 123 * because the values are already in the range [0,1] so it won't 124 * have any effect anyway. 125 */ 126 if (_mesa_get_format_datatype(texFormat) == GL_UNSIGNED_NORMALIZED && 127 !_mesa_need_rgb_to_luminance_conversion(srcBaseFormat, dstBaseFormat)) { 128 transferOps &= ~IMAGE_CLAMP_BIT; 129 } 130 131 return transferOps; 132 } 133 134 135 /** 136 * Return true if memcpy cannot be used for ReadPixels. 137 * 138 * If uses_blit is true, the function returns true if a simple 3D engine blit 139 * cannot be used for ReadPixels packing. 140 * 141 * NOTE: This doesn't take swizzling and format conversions between 142 * the readbuffer and the pixel pack buffer into account. 143 */ 144 GLboolean 145 _mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format, 146 GLenum type, GLboolean uses_blit) 147 { 148 struct gl_renderbuffer *rb = 149 _mesa_get_read_renderbuffer_for_format(ctx, format); 150 GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format); 151 152 assert(rb); 153 154 /* There are different rules depending on the base format. */ 155 switch (format) { 156 case GL_DEPTH_STENCIL: 157 return !_mesa_has_depthstencil_combined(ctx->ReadBuffer) || 158 ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f || 159 ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset || 160 ctx->Pixel.MapStencilFlag; 161 162 case GL_DEPTH_COMPONENT: 163 return ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f; 164 165 case GL_STENCIL_INDEX: 166 return ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset || 167 ctx->Pixel.MapStencilFlag; 168 169 default: 170 /* Color formats. */ 171 if (_mesa_need_rgb_to_luminance_conversion(rb->_BaseFormat, 172 dstBaseFormat)) { 173 return GL_TRUE; 174 } 175 176 /* And finally, see if there are any transfer ops. */ 177 return _mesa_get_readpixels_transfer_ops(ctx, rb->Format, format, type, 178 uses_blit) != 0; 179 } 180 return GL_FALSE; 181 } 182 183 184 static GLboolean 185 readpixels_can_use_memcpy(const struct gl_context *ctx, GLenum format, GLenum type, 186 const struct gl_pixelstore_attrib *packing) 187 { 188 struct gl_renderbuffer *rb = 189 _mesa_get_read_renderbuffer_for_format(ctx, format); 190 191 assert(rb); 192 193 if (_mesa_readpixels_needs_slow_path(ctx, format, type, GL_FALSE)) { 194 return GL_FALSE; 195 } 196 197 /* The base internal format and the base Mesa format must match. */ 198 if (rb->_BaseFormat != _mesa_get_format_base_format(rb->Format)) { 199 return GL_FALSE; 200 } 201 202 /* The Mesa format must match the input format and type. */ 203 if (!_mesa_format_matches_format_and_type(rb->Format, format, type, 204 packing->SwapBytes, NULL)) { 205 return GL_FALSE; 206 } 207 208 return GL_TRUE; 209 } 210 211 212 static GLboolean 213 readpixels_memcpy(struct gl_context *ctx, 214 GLint x, GLint y, 215 GLsizei width, GLsizei height, 216 GLenum format, GLenum type, 217 GLvoid *pixels, 218 const struct gl_pixelstore_attrib *packing) 219 { 220 struct gl_renderbuffer *rb = 221 _mesa_get_read_renderbuffer_for_format(ctx, format); 222 GLubyte *dst, *map; 223 int dstStride, stride, j, texelBytes; 224 225 /* Fail if memcpy cannot be used. */ 226 if (!readpixels_can_use_memcpy(ctx, format, type, packing)) { 227 return GL_FALSE; 228 } 229 230 dstStride = _mesa_image_row_stride(packing, width, format, type); 231 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, 232 format, type, 0, 0); 233 234 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, 235 &map, &stride); 236 if (!map) { 237 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 238 return GL_TRUE; /* don't bother trying the slow path */ 239 } 240 241 texelBytes = _mesa_get_format_bytes(rb->Format); 242 243 /* memcpy*/ 244 for (j = 0; j < height; j++) { 245 memcpy(dst, map, width * texelBytes); 246 dst += dstStride; 247 map += stride; 248 } 249 250 ctx->Driver.UnmapRenderbuffer(ctx, rb); 251 return GL_TRUE; 252 } 253 254 255 /** 256 * Optimized path for conversion of depth values to GL_DEPTH_COMPONENT, 257 * GL_UNSIGNED_INT. 258 */ 259 static GLboolean 260 read_uint_depth_pixels( struct gl_context *ctx, 261 GLint x, GLint y, 262 GLsizei width, GLsizei height, 263 GLenum type, GLvoid *pixels, 264 const struct gl_pixelstore_attrib *packing ) 265 { 266 struct gl_framebuffer *fb = ctx->ReadBuffer; 267 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; 268 GLubyte *map, *dst; 269 int stride, dstStride, j; 270 271 if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F) 272 return GL_FALSE; 273 274 if (packing->SwapBytes) 275 return GL_FALSE; 276 277 if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED) 278 return GL_FALSE; 279 280 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, 281 &map, &stride); 282 283 if (!map) { 284 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 285 return GL_TRUE; /* don't bother trying the slow path */ 286 } 287 288 dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type); 289 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, 290 GL_DEPTH_COMPONENT, type, 0, 0); 291 292 for (j = 0; j < height; j++) { 293 _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst); 294 295 map += stride; 296 dst += dstStride; 297 } 298 ctx->Driver.UnmapRenderbuffer(ctx, rb); 299 300 return GL_TRUE; 301 } 302 303 /** 304 * Read pixels for format=GL_DEPTH_COMPONENT. 305 */ 306 static void 307 read_depth_pixels( struct gl_context *ctx, 308 GLint x, GLint y, 309 GLsizei width, GLsizei height, 310 GLenum type, GLvoid *pixels, 311 const struct gl_pixelstore_attrib *packing ) 312 { 313 struct gl_framebuffer *fb = ctx->ReadBuffer; 314 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; 315 GLint j; 316 GLubyte *dst, *map; 317 int dstStride, stride; 318 GLfloat *depthValues; 319 320 if (!rb) 321 return; 322 323 /* clipping should have been done already */ 324 assert(x >= 0); 325 assert(y >= 0); 326 assert(x + width <= (GLint) rb->Width); 327 assert(y + height <= (GLint) rb->Height); 328 329 if (type == GL_UNSIGNED_INT && 330 read_uint_depth_pixels(ctx, x, y, width, height, type, pixels, packing)) { 331 return; 332 } 333 334 dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type); 335 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, 336 GL_DEPTH_COMPONENT, type, 0, 0); 337 338 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, 339 &map, &stride); 340 if (!map) { 341 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 342 return; 343 } 344 345 depthValues = malloc(width * sizeof(GLfloat)); 346 347 if (depthValues) { 348 /* General case (slower) */ 349 for (j = 0; j < height; j++, y++) { 350 _mesa_unpack_float_z_row(rb->Format, width, map, depthValues); 351 _mesa_pack_depth_span(ctx, width, dst, type, depthValues, packing); 352 353 dst += dstStride; 354 map += stride; 355 } 356 } 357 else { 358 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 359 } 360 361 free(depthValues); 362 363 ctx->Driver.UnmapRenderbuffer(ctx, rb); 364 } 365 366 367 /** 368 * Read pixels for format=GL_STENCIL_INDEX. 369 */ 370 static void 371 read_stencil_pixels( struct gl_context *ctx, 372 GLint x, GLint y, 373 GLsizei width, GLsizei height, 374 GLenum type, GLvoid *pixels, 375 const struct gl_pixelstore_attrib *packing ) 376 { 377 struct gl_framebuffer *fb = ctx->ReadBuffer; 378 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; 379 GLint j; 380 GLubyte *map, *stencil; 381 GLint stride; 382 383 if (!rb) 384 return; 385 386 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, 387 &map, &stride); 388 if (!map) { 389 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 390 return; 391 } 392 393 stencil = malloc(width * sizeof(GLubyte)); 394 395 if (stencil) { 396 /* process image row by row */ 397 for (j = 0; j < height; j++) { 398 GLvoid *dest; 399 400 _mesa_unpack_ubyte_stencil_row(rb->Format, width, map, stencil); 401 dest = _mesa_image_address2d(packing, pixels, width, height, 402 GL_STENCIL_INDEX, type, j, 0); 403 404 _mesa_pack_stencil_span(ctx, width, type, dest, stencil, packing); 405 406 map += stride; 407 } 408 } 409 else { 410 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 411 } 412 413 free(stencil); 414 415 ctx->Driver.UnmapRenderbuffer(ctx, rb); 416 } 417 418 /* 419 * Read R, G, B, A, RGB, L, or LA pixels. 420 */ 421 static void 422 read_rgba_pixels( struct gl_context *ctx, 423 GLint x, GLint y, 424 GLsizei width, GLsizei height, 425 GLenum format, GLenum type, GLvoid *pixels, 426 const struct gl_pixelstore_attrib *packing ) 427 { 428 GLbitfield transferOps; 429 bool dst_is_integer, convert_rgb_to_lum, needs_rebase; 430 int dst_stride, src_stride, rb_stride; 431 uint32_t dst_format, src_format; 432 GLubyte *dst, *map; 433 mesa_format rb_format; 434 bool needs_rgba; 435 void *rgba, *src; 436 bool src_is_uint = false; 437 uint8_t rebase_swizzle[4]; 438 struct gl_framebuffer *fb = ctx->ReadBuffer; 439 struct gl_renderbuffer *rb = fb->_ColorReadBuffer; 440 GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format); 441 442 if (!rb) 443 return; 444 445 transferOps = _mesa_get_readpixels_transfer_ops(ctx, rb->Format, format, 446 type, GL_FALSE); 447 /* Describe the dst format */ 448 dst_is_integer = _mesa_is_enum_format_integer(format); 449 dst_stride = _mesa_image_row_stride(packing, width, format, type); 450 dst_format = _mesa_format_from_format_and_type(format, type); 451 convert_rgb_to_lum = 452 _mesa_need_rgb_to_luminance_conversion(rb->_BaseFormat, dstBaseFormat); 453 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, 454 format, type, 0, 0); 455 456 /* Map the source render buffer */ 457 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, 458 &map, &rb_stride); 459 if (!map) { 460 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 461 return; 462 } 463 rb_format = _mesa_get_srgb_format_linear(rb->Format); 464 465 /* 466 * Depending on the base formats involved in the conversion we might need to 467 * rebase some values, so for these formats we compute a rebase swizzle. 468 */ 469 if (rb->_BaseFormat == GL_LUMINANCE || rb->_BaseFormat == GL_INTENSITY) { 470 needs_rebase = true; 471 rebase_swizzle[0] = MESA_FORMAT_SWIZZLE_X; 472 rebase_swizzle[1] = MESA_FORMAT_SWIZZLE_ZERO; 473 rebase_swizzle[2] = MESA_FORMAT_SWIZZLE_ZERO; 474 rebase_swizzle[3] = MESA_FORMAT_SWIZZLE_ONE; 475 } else if (rb->_BaseFormat == GL_LUMINANCE_ALPHA) { 476 needs_rebase = true; 477 rebase_swizzle[0] = MESA_FORMAT_SWIZZLE_X; 478 rebase_swizzle[1] = MESA_FORMAT_SWIZZLE_ZERO; 479 rebase_swizzle[2] = MESA_FORMAT_SWIZZLE_ZERO; 480 rebase_swizzle[3] = MESA_FORMAT_SWIZZLE_W; 481 } else if (_mesa_get_format_base_format(rb_format) != rb->_BaseFormat) { 482 needs_rebase = 483 _mesa_compute_rgba2base2rgba_component_mapping(rb->_BaseFormat, 484 rebase_swizzle); 485 } else { 486 needs_rebase = false; 487 } 488 489 /* Since _mesa_format_convert does not handle transferOps we need to handle 490 * them before we call the function. This requires to convert to RGBA float 491 * first so we can call _mesa_apply_rgba_transfer_ops. If the dst format is 492 * integer transferOps do not apply. 493 * 494 * Converting to luminance also requires converting to RGBA first, so we can 495 * then compute luminance values as L=R+G+B. Notice that this is different 496 * from GetTexImage, where we compute L=R. 497 */ 498 assert(!transferOps || (transferOps && !dst_is_integer)); 499 500 needs_rgba = transferOps || convert_rgb_to_lum; 501 rgba = NULL; 502 if (needs_rgba) { 503 uint32_t rgba_format; 504 int rgba_stride; 505 bool need_convert; 506 507 /* Convert to RGBA float or int/uint depending on the type of the src */ 508 if (dst_is_integer) { 509 src_is_uint = _mesa_is_format_unsigned(rb_format); 510 if (src_is_uint) { 511 rgba_format = RGBA32_UINT; 512 rgba_stride = width * 4 * sizeof(GLuint); 513 } else { 514 rgba_format = RGBA32_INT; 515 rgba_stride = width * 4 * sizeof(GLint); 516 } 517 } else { 518 rgba_format = RGBA32_FLOAT; 519 rgba_stride = width * 4 * sizeof(GLfloat); 520 } 521 522 /* If we are lucky and the dst format matches the RGBA format we need to 523 * convert to, then we can convert directly into the dst buffer and avoid 524 * the final conversion/copy from the rgba buffer to the dst buffer. 525 */ 526 if (dst_format == rgba_format && 527 dst_stride == rgba_stride) { 528 need_convert = false; 529 rgba = dst; 530 } else { 531 need_convert = true; 532 rgba = malloc(height * rgba_stride); 533 if (!rgba) { 534 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 535 goto done_unmap; 536 } 537 } 538 539 /* Convert to RGBA now */ 540 _mesa_format_convert(rgba, rgba_format, rgba_stride, 541 map, rb_format, rb_stride, 542 width, height, 543 needs_rebase ? rebase_swizzle : NULL); 544 545 /* Handle transfer ops if necessary */ 546 if (transferOps) 547 _mesa_apply_rgba_transfer_ops(ctx, transferOps, width * height, rgba); 548 549 /* If we had to rebase, we have already taken care of that */ 550 needs_rebase = false; 551 552 /* If we were lucky and our RGBA conversion matches the dst format, then 553 * we are done. 554 */ 555 if (!need_convert) 556 goto done_swap; 557 558 /* Otherwise, we need to convert from RGBA to dst next */ 559 src = rgba; 560 src_format = rgba_format; 561 src_stride = rgba_stride; 562 } else { 563 /* No RGBA conversion needed, convert directly to dst */ 564 src = map; 565 src_format = rb_format; 566 src_stride = rb_stride; 567 } 568 569 /* Do the conversion. 570 * 571 * If the dst format is Luminance, we need to do the conversion by computing 572 * L=R+G+B values. 573 */ 574 if (!convert_rgb_to_lum) { 575 _mesa_format_convert(dst, dst_format, dst_stride, 576 src, src_format, src_stride, 577 width, height, 578 needs_rebase ? rebase_swizzle : NULL); 579 } else if (!dst_is_integer) { 580 /* Compute float Luminance values from RGBA float */ 581 int luminance_stride, luminance_bytes; 582 void *luminance; 583 uint32_t luminance_format; 584 585 luminance_stride = width * sizeof(GLfloat); 586 if (format == GL_LUMINANCE_ALPHA) 587 luminance_stride *= 2; 588 luminance_bytes = height * luminance_stride; 589 luminance = malloc(luminance_bytes); 590 if (!luminance) { 591 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 592 free(rgba); 593 goto done_unmap; 594 } 595 _mesa_pack_luminance_from_rgba_float(width * height, src, 596 luminance, format, transferOps); 597 598 /* Convert from Luminance float to dst (this will hadle type conversion 599 * from float to the type of dst if necessary) 600 */ 601 luminance_format = _mesa_format_from_format_and_type(format, GL_FLOAT); 602 _mesa_format_convert(dst, dst_format, dst_stride, 603 luminance, luminance_format, luminance_stride, 604 width, height, NULL); 605 free(luminance); 606 } else { 607 _mesa_pack_luminance_from_rgba_integer(width * height, src, !src_is_uint, 608 dst, format, type); 609 } 610 611 free(rgba); 612 613 done_swap: 614 /* Handle byte swapping if required */ 615 if (packing->SwapBytes) { 616 _mesa_swap_bytes_2d_image(format, type, packing, 617 width, height, dst, dst); 618 } 619 620 done_unmap: 621 ctx->Driver.UnmapRenderbuffer(ctx, rb); 622 } 623 624 /** 625 * For a packed depth/stencil buffer being read as depth/stencil, just memcpy the 626 * data (possibly swapping 8/24 vs 24/8 as we go). 627 */ 628 static GLboolean 629 fast_read_depth_stencil_pixels(struct gl_context *ctx, 630 GLint x, GLint y, 631 GLsizei width, GLsizei height, 632 GLubyte *dst, int dstStride) 633 { 634 struct gl_framebuffer *fb = ctx->ReadBuffer; 635 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; 636 struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; 637 GLubyte *map; 638 int stride, i; 639 640 if (rb != stencilRb) 641 return GL_FALSE; 642 643 if (rb->Format != MESA_FORMAT_S8_UINT_Z24_UNORM && 644 rb->Format != MESA_FORMAT_Z24_UNORM_S8_UINT) 645 return GL_FALSE; 646 647 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, 648 &map, &stride); 649 if (!map) { 650 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 651 return GL_TRUE; /* don't bother trying the slow path */ 652 } 653 654 for (i = 0; i < height; i++) { 655 _mesa_unpack_uint_24_8_depth_stencil_row(rb->Format, width, 656 map, (GLuint *)dst); 657 map += stride; 658 dst += dstStride; 659 } 660 661 ctx->Driver.UnmapRenderbuffer(ctx, rb); 662 663 return GL_TRUE; 664 } 665 666 667 /** 668 * For non-float-depth and stencil buffers being read as 24/8 depth/stencil, 669 * copy the integer data directly instead of converting depth to float and 670 * re-packing. 671 */ 672 static GLboolean 673 fast_read_depth_stencil_pixels_separate(struct gl_context *ctx, 674 GLint x, GLint y, 675 GLsizei width, GLsizei height, 676 uint32_t *dst, int dstStride) 677 { 678 struct gl_framebuffer *fb = ctx->ReadBuffer; 679 struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; 680 struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; 681 GLubyte *depthMap, *stencilMap, *stencilVals; 682 int depthStride, stencilStride, i, j; 683 684 if (_mesa_get_format_datatype(depthRb->Format) != GL_UNSIGNED_NORMALIZED) 685 return GL_FALSE; 686 687 ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height, 688 GL_MAP_READ_BIT, &depthMap, &depthStride); 689 if (!depthMap) { 690 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 691 return GL_TRUE; /* don't bother trying the slow path */ 692 } 693 694 ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height, 695 GL_MAP_READ_BIT, &stencilMap, &stencilStride); 696 if (!stencilMap) { 697 ctx->Driver.UnmapRenderbuffer(ctx, depthRb); 698 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 699 return GL_TRUE; /* don't bother trying the slow path */ 700 } 701 702 stencilVals = malloc(width * sizeof(GLubyte)); 703 704 if (stencilVals) { 705 for (j = 0; j < height; j++) { 706 _mesa_unpack_uint_z_row(depthRb->Format, width, depthMap, dst); 707 _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width, 708 stencilMap, stencilVals); 709 710 for (i = 0; i < width; i++) { 711 dst[i] = (dst[i] & 0xffffff00) | stencilVals[i]; 712 } 713 714 depthMap += depthStride; 715 stencilMap += stencilStride; 716 dst += dstStride / 4; 717 } 718 } 719 else { 720 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 721 } 722 723 free(stencilVals); 724 725 ctx->Driver.UnmapRenderbuffer(ctx, depthRb); 726 ctx->Driver.UnmapRenderbuffer(ctx, stencilRb); 727 728 return GL_TRUE; 729 } 730 731 static void 732 slow_read_depth_stencil_pixels_separate(struct gl_context *ctx, 733 GLint x, GLint y, 734 GLsizei width, GLsizei height, 735 GLenum type, 736 const struct gl_pixelstore_attrib *packing, 737 GLubyte *dst, int dstStride) 738 { 739 struct gl_framebuffer *fb = ctx->ReadBuffer; 740 struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; 741 struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; 742 GLubyte *depthMap, *stencilMap; 743 int depthStride, stencilStride, j; 744 GLubyte *stencilVals; 745 GLfloat *depthVals; 746 747 748 /* The depth and stencil buffers might be separate, or a single buffer. 749 * If one buffer, only map it once. 750 */ 751 ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height, 752 GL_MAP_READ_BIT, &depthMap, &depthStride); 753 if (!depthMap) { 754 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 755 return; 756 } 757 758 if (stencilRb != depthRb) { 759 ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height, 760 GL_MAP_READ_BIT, &stencilMap, 761 &stencilStride); 762 if (!stencilMap) { 763 ctx->Driver.UnmapRenderbuffer(ctx, depthRb); 764 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 765 return; 766 } 767 } 768 else { 769 stencilMap = depthMap; 770 stencilStride = depthStride; 771 } 772 773 stencilVals = malloc(width * sizeof(GLubyte)); 774 depthVals = malloc(width * sizeof(GLfloat)); 775 776 if (stencilVals && depthVals) { 777 for (j = 0; j < height; j++) { 778 _mesa_unpack_float_z_row(depthRb->Format, width, depthMap, depthVals); 779 _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width, 780 stencilMap, stencilVals); 781 782 _mesa_pack_depth_stencil_span(ctx, width, type, (GLuint *)dst, 783 depthVals, stencilVals, packing); 784 785 depthMap += depthStride; 786 stencilMap += stencilStride; 787 dst += dstStride; 788 } 789 } 790 else { 791 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); 792 } 793 794 free(stencilVals); 795 free(depthVals); 796 797 ctx->Driver.UnmapRenderbuffer(ctx, depthRb); 798 if (stencilRb != depthRb) { 799 ctx->Driver.UnmapRenderbuffer(ctx, stencilRb); 800 } 801 } 802 803 804 /** 805 * Read combined depth/stencil values. 806 * We'll have already done error checking to be sure the expected 807 * depth and stencil buffers really exist. 808 */ 809 static void 810 read_depth_stencil_pixels(struct gl_context *ctx, 811 GLint x, GLint y, 812 GLsizei width, GLsizei height, 813 GLenum type, GLvoid *pixels, 814 const struct gl_pixelstore_attrib *packing ) 815 { 816 const GLboolean scaleOrBias 817 = ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F; 818 const GLboolean stencilTransfer = ctx->Pixel.IndexShift 819 || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag; 820 GLubyte *dst; 821 int dstStride; 822 823 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, 824 width, height, 825 GL_DEPTH_STENCIL_EXT, 826 type, 0, 0); 827 dstStride = _mesa_image_row_stride(packing, width, 828 GL_DEPTH_STENCIL_EXT, type); 829 830 /* Fast 24/8 reads. */ 831 if (type == GL_UNSIGNED_INT_24_8 && 832 !scaleOrBias && !stencilTransfer && !packing->SwapBytes) { 833 if (fast_read_depth_stencil_pixels(ctx, x, y, width, height, 834 dst, dstStride)) 835 return; 836 837 if (fast_read_depth_stencil_pixels_separate(ctx, x, y, width, height, 838 (uint32_t *)dst, dstStride)) 839 return; 840 } 841 842 slow_read_depth_stencil_pixels_separate(ctx, x, y, width, height, 843 type, packing, 844 dst, dstStride); 845 } 846 847 848 849 /** 850 * Software fallback routine for ctx->Driver.ReadPixels(). 851 * By time we get here, all error checking will have been done. 852 */ 853 void 854 _mesa_readpixels(struct gl_context *ctx, 855 GLint x, GLint y, GLsizei width, GLsizei height, 856 GLenum format, GLenum type, 857 const struct gl_pixelstore_attrib *packing, 858 GLvoid *pixels) 859 { 860 if (ctx->NewState) 861 _mesa_update_state(ctx); 862 863 pixels = _mesa_map_pbo_dest(ctx, packing, pixels); 864 865 if (pixels) { 866 /* Try memcpy first. */ 867 if (readpixels_memcpy(ctx, x, y, width, height, format, type, 868 pixels, packing)) { 869 _mesa_unmap_pbo_dest(ctx, packing); 870 return; 871 } 872 873 /* Otherwise take the slow path. */ 874 switch (format) { 875 case GL_STENCIL_INDEX: 876 read_stencil_pixels(ctx, x, y, width, height, type, pixels, 877 packing); 878 break; 879 case GL_DEPTH_COMPONENT: 880 read_depth_pixels(ctx, x, y, width, height, type, pixels, 881 packing); 882 break; 883 case GL_DEPTH_STENCIL_EXT: 884 read_depth_stencil_pixels(ctx, x, y, width, height, type, pixels, 885 packing); 886 break; 887 default: 888 /* all other formats should be color formats */ 889 read_rgba_pixels(ctx, x, y, width, height, format, type, pixels, 890 packing); 891 } 892 893 _mesa_unmap_pbo_dest(ctx, packing); 894 } 895 } 896 897 898 static GLenum 899 read_pixels_es3_error_check(GLenum format, GLenum type, 900 const struct gl_renderbuffer *rb) 901 { 902 const GLenum internalFormat = rb->InternalFormat; 903 const GLenum data_type = _mesa_get_format_datatype(rb->Format); 904 GLboolean is_unsigned_int = GL_FALSE; 905 GLboolean is_signed_int = GL_FALSE; 906 GLboolean is_float_depth = (internalFormat == GL_DEPTH_COMPONENT32F) || 907 (internalFormat == GL_DEPTH32F_STENCIL8); 908 909 is_unsigned_int = _mesa_is_enum_format_unsigned_int(internalFormat); 910 if (!is_unsigned_int) { 911 is_signed_int = _mesa_is_enum_format_signed_int(internalFormat); 912 } 913 914 switch (format) { 915 case GL_RGBA: 916 if (type == GL_FLOAT && data_type == GL_FLOAT) 917 return GL_NO_ERROR; /* EXT_color_buffer_float */ 918 if (type == GL_UNSIGNED_BYTE && data_type == GL_UNSIGNED_NORMALIZED) 919 return GL_NO_ERROR; 920 if (internalFormat == GL_RGB10_A2 && 921 type == GL_UNSIGNED_INT_2_10_10_10_REV) 922 return GL_NO_ERROR; 923 if (internalFormat == GL_RGB10_A2UI && type == GL_UNSIGNED_BYTE) 924 return GL_NO_ERROR; 925 break; 926 case GL_BGRA: 927 /* GL_EXT_read_format_bgra */ 928 if (type == GL_UNSIGNED_BYTE || 929 type == GL_UNSIGNED_SHORT_4_4_4_4_REV || 930 type == GL_UNSIGNED_SHORT_1_5_5_5_REV) 931 return GL_NO_ERROR; 932 break; 933 case GL_RGBA_INTEGER: 934 if ((is_signed_int && type == GL_INT) || 935 (is_unsigned_int && type == GL_UNSIGNED_INT)) 936 return GL_NO_ERROR; 937 break; 938 case GL_DEPTH_STENCIL: 939 switch (type) { 940 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 941 if (is_float_depth) 942 return GL_NO_ERROR; 943 break; 944 case GL_UNSIGNED_INT_24_8: 945 if (!is_float_depth) 946 return GL_NO_ERROR; 947 break; 948 default: 949 return GL_INVALID_ENUM; 950 } 951 break; 952 case GL_DEPTH_COMPONENT: 953 switch (type) { 954 case GL_FLOAT: 955 if (is_float_depth) 956 return GL_NO_ERROR; 957 break; 958 case GL_UNSIGNED_SHORT: 959 case GL_UNSIGNED_INT: 960 case GL_UNSIGNED_INT_24_8: 961 if (!is_float_depth) 962 return GL_NO_ERROR; 963 break; 964 default: 965 return GL_INVALID_ENUM; 966 } 967 break; 968 case GL_STENCIL_INDEX: 969 switch (type) { 970 case GL_UNSIGNED_BYTE: 971 return GL_NO_ERROR; 972 default: 973 return GL_INVALID_ENUM; 974 } 975 break; 976 } 977 978 return GL_INVALID_OPERATION; 979 } 980 981 982 void GLAPIENTRY 983 _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height, 984 GLenum format, GLenum type, GLsizei bufSize, 985 GLvoid *pixels ) 986 { 987 GLenum err = GL_NO_ERROR; 988 struct gl_renderbuffer *rb; 989 struct gl_pixelstore_attrib clippedPacking; 990 991 GET_CURRENT_CONTEXT(ctx); 992 993 FLUSH_VERTICES(ctx, 0); 994 FLUSH_CURRENT(ctx, 0); 995 996 if (MESA_VERBOSE & VERBOSE_API) 997 _mesa_debug(ctx, "glReadPixels(%d, %d, %s, %s, %p)\n", 998 width, height, 999 _mesa_enum_to_string(format), 1000 _mesa_enum_to_string(type), 1001 pixels); 1002 1003 if (width < 0 || height < 0) { 1004 _mesa_error( ctx, GL_INVALID_VALUE, 1005 "glReadPixels(width=%d height=%d)", width, height ); 1006 return; 1007 } 1008 1009 if (ctx->NewState) 1010 _mesa_update_state(ctx); 1011 1012 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 1013 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 1014 "glReadPixels(incomplete framebuffer)" ); 1015 return; 1016 } 1017 1018 rb = _mesa_get_read_renderbuffer_for_format(ctx, format); 1019 if (rb == NULL) { 1020 _mesa_error(ctx, GL_INVALID_OPERATION, 1021 "glReadPixels(read buffer)"); 1022 return; 1023 } 1024 1025 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the 1026 * combinations of format and type that can be used. 1027 * 1028 * Technically, only two combinations are actually allowed: 1029 * GL_RGBA/GL_UNSIGNED_BYTE, and some implementation-specific internal 1030 * preferred combination. This code doesn't know what that preferred 1031 * combination is, and Mesa can handle anything valid. Just work instead. 1032 */ 1033 if (_mesa_is_gles(ctx)) { 1034 if (ctx->API == API_OPENGLES2 && 1035 _mesa_is_color_format(format) && 1036 _mesa_get_color_read_format(ctx) == format && 1037 _mesa_get_color_read_type(ctx) == type) { 1038 err = GL_NO_ERROR; 1039 } else if (ctx->Version < 30) { 1040 err = _mesa_es_error_check_format_and_type(ctx, format, type, 2); 1041 if (err == GL_NO_ERROR) { 1042 if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) { 1043 err = GL_INVALID_OPERATION; 1044 } 1045 } 1046 } else { 1047 err = read_pixels_es3_error_check(format, type, rb); 1048 } 1049 1050 if (err != GL_NO_ERROR) { 1051 _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)", 1052 _mesa_enum_to_string(format), 1053 _mesa_enum_to_string(type)); 1054 return; 1055 } 1056 } 1057 1058 err = _mesa_error_check_format_and_type(ctx, format, type); 1059 if (err != GL_NO_ERROR) { 1060 _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)", 1061 _mesa_enum_to_string(format), 1062 _mesa_enum_to_string(type)); 1063 return; 1064 } 1065 1066 if (_mesa_is_user_fbo(ctx->ReadBuffer) && 1067 ctx->ReadBuffer->Visual.samples > 0) { 1068 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)"); 1069 return; 1070 } 1071 1072 if (!_mesa_source_buffer_exists(ctx, format)) { 1073 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)"); 1074 return; 1075 } 1076 1077 /* Check that the destination format and source buffer are both 1078 * integer-valued or both non-integer-valued. 1079 */ 1080 if (ctx->Extensions.EXT_texture_integer && _mesa_is_color_format(format)) { 1081 const struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; 1082 const GLboolean srcInteger = _mesa_is_format_integer_color(rb->Format); 1083 const GLboolean dstInteger = _mesa_is_enum_format_integer(format); 1084 if (dstInteger != srcInteger) { 1085 _mesa_error(ctx, GL_INVALID_OPERATION, 1086 "glReadPixels(integer / non-integer format mismatch"); 1087 return; 1088 } 1089 } 1090 1091 /* Do all needed clipping here, so that we can forget about it later */ 1092 clippedPacking = ctx->Pack; 1093 if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) 1094 return; /* nothing to do */ 1095 1096 if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1, 1097 format, type, bufSize, pixels)) { 1098 if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 1099 _mesa_error(ctx, GL_INVALID_OPERATION, 1100 "glReadPixels(out of bounds PBO access)"); 1101 } else { 1102 _mesa_error(ctx, GL_INVALID_OPERATION, 1103 "glReadnPixelsARB(out of bounds access:" 1104 " bufSize (%d) is too small)", bufSize); 1105 } 1106 return; 1107 } 1108 1109 if (_mesa_is_bufferobj(ctx->Pack.BufferObj) && 1110 _mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) { 1111 /* buffer is mapped - that's an error */ 1112 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)"); 1113 return; 1114 } 1115 1116 ctx->Driver.ReadPixels(ctx, x, y, width, height, 1117 format, type, &clippedPacking, pixels); 1118 } 1119 1120 void GLAPIENTRY 1121 _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, 1122 GLenum format, GLenum type, GLvoid *pixels ) 1123 { 1124 _mesa_ReadnPixelsARB(x, y, width, height, format, type, INT_MAX, pixels); 1125 } 1126