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