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