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