1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5 * Copyright (C) 1999-2013 VMware, Inc. All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26/* 27 * glBlitFramebuffer functions. 28 */ 29 30#include <stdbool.h> 31#include <stdio.h> 32 33#include "context.h" 34#include "enums.h" 35#include "blit.h" 36#include "fbobject.h" 37#include "framebuffer.h" 38#include "glformats.h" 39#include "mtypes.h" 40#include "macros.h" 41#include "state.h" 42 43 44/** Set this to 1 to debug/log glBlitFramebuffer() calls */ 45#define DEBUG_BLIT 0 46 47 48 49static const struct gl_renderbuffer_attachment * 50find_attachment(const struct gl_framebuffer *fb, 51 const struct gl_renderbuffer *rb) 52{ 53 GLuint i; 54 for (i = 0; i < ARRAY_SIZE(fb->Attachment); i++) { 55 if (fb->Attachment[i].Renderbuffer == rb) 56 return &fb->Attachment[i]; 57 } 58 return NULL; 59} 60 61 62/** 63 * \return true if two regions overlap, false otherwise 64 */ 65bool 66_mesa_regions_overlap(int srcX0, int srcY0, 67 int srcX1, int srcY1, 68 int dstX0, int dstY0, 69 int dstX1, int dstY1) 70{ 71 if (MAX2(srcX0, srcX1) <= MIN2(dstX0, dstX1)) 72 return false; /* dst completely right of src */ 73 74 if (MAX2(dstX0, dstX1) <= MIN2(srcX0, srcX1)) 75 return false; /* dst completely left of src */ 76 77 if (MAX2(srcY0, srcY1) <= MIN2(dstY0, dstY1)) 78 return false; /* dst completely above src */ 79 80 if (MAX2(dstY0, dstY1) <= MIN2(srcY0, srcY1)) 81 return false; /* dst completely below src */ 82 83 return true; /* some overlap */ 84} 85 86 87/** 88 * Helper function for checking if the datatypes of color buffers are 89 * compatible for glBlitFramebuffer. From the 3.1 spec, page 198: 90 * 91 * "GL_INVALID_OPERATION is generated if mask contains GL_COLOR_BUFFER_BIT 92 * and any of the following conditions hold: 93 * - The read buffer contains fixed-point or floating-point values and any 94 * draw buffer contains neither fixed-point nor floating-point values. 95 * - The read buffer contains unsigned integer values and any draw buffer 96 * does not contain unsigned integer values. 97 * - The read buffer contains signed integer values and any draw buffer 98 * does not contain signed integer values." 99 */ 100static GLboolean 101compatible_color_datatypes(mesa_format srcFormat, mesa_format dstFormat) 102{ 103 GLenum srcType = _mesa_get_format_datatype(srcFormat); 104 GLenum dstType = _mesa_get_format_datatype(dstFormat); 105 106 if (srcType != GL_INT && srcType != GL_UNSIGNED_INT) { 107 assert(srcType == GL_UNSIGNED_NORMALIZED || 108 srcType == GL_SIGNED_NORMALIZED || 109 srcType == GL_FLOAT); 110 /* Boil any of those types down to GL_FLOAT */ 111 srcType = GL_FLOAT; 112 } 113 114 if (dstType != GL_INT && dstType != GL_UNSIGNED_INT) { 115 assert(dstType == GL_UNSIGNED_NORMALIZED || 116 dstType == GL_SIGNED_NORMALIZED || 117 dstType == GL_FLOAT); 118 /* Boil any of those types down to GL_FLOAT */ 119 dstType = GL_FLOAT; 120 } 121 122 return srcType == dstType; 123} 124 125 126static GLboolean 127compatible_resolve_formats(const struct gl_renderbuffer *readRb, 128 const struct gl_renderbuffer *drawRb) 129{ 130 GLenum readFormat, drawFormat; 131 132 /* This checks whether the internal formats are compatible rather than the 133 * Mesa format for two reasons: 134 * 135 * • Under some circumstances, the user may request e.g. two GL_RGBA8 136 * textures and get two entirely different Mesa formats like RGBA8888 and 137 * ARGB8888. Drivers behaving like that should be able to cope with 138 * non-matching formats by themselves, because it's not the user's fault. 139 * 140 * • Picking two different internal formats can end up with the same Mesa 141 * format. For example the driver might be simulating GL_RGB textures 142 * with GL_RGBA internally and in that case both internal formats would 143 * end up with RGBA8888. 144 * 145 * This function is used to generate a GL error according to the spec so in 146 * both cases we want to be looking at the application-level format, which 147 * is InternalFormat. 148 * 149 * Blits between linear and sRGB formats are also allowed. 150 */ 151 readFormat = _mesa_get_nongeneric_internalformat(readRb->InternalFormat); 152 drawFormat = _mesa_get_nongeneric_internalformat(drawRb->InternalFormat); 153 readFormat = _mesa_get_linear_internalformat(readFormat); 154 drawFormat = _mesa_get_linear_internalformat(drawFormat); 155 156 if (readFormat == drawFormat) { 157 return GL_TRUE; 158 } 159 160 return GL_FALSE; 161} 162 163 164static GLboolean 165is_valid_blit_filter(const struct gl_context *ctx, GLenum filter) 166{ 167 switch (filter) { 168 case GL_NEAREST: 169 case GL_LINEAR: 170 return true; 171 case GL_SCALED_RESOLVE_FASTEST_EXT: 172 case GL_SCALED_RESOLVE_NICEST_EXT: 173 return ctx->Extensions.EXT_framebuffer_multisample_blit_scaled; 174 default: 175 return false; 176 } 177} 178 179 180static bool 181validate_color_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb, 182 struct gl_framebuffer *drawFb, GLenum filter, 183 const char *func) 184{ 185 const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers; 186 const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer; 187 const struct gl_renderbuffer *colorDrawRb = NULL; 188 GLuint i; 189 190 for (i = 0; i < numColorDrawBuffers; i++) { 191 colorDrawRb = drawFb->_ColorDrawBuffers[i]; 192 if (!colorDrawRb) 193 continue; 194 195 /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL 196 * ES 3.0.1 spec says: 197 * 198 * "If the source and destination buffers are identical, an 199 * INVALID_OPERATION error is generated. Different mipmap levels of a 200 * texture, different layers of a three- dimensional texture or 201 * two-dimensional array texture, and different faces of a cube map 202 * texture do not constitute identical buffers." 203 */ 204 if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) { 205 _mesa_error(ctx, GL_INVALID_OPERATION, 206 "%s(source and destination color buffer cannot be the " 207 "same)", func); 208 return false; 209 } 210 211 if (!compatible_color_datatypes(colorReadRb->Format, 212 colorDrawRb->Format)) { 213 _mesa_error(ctx, GL_INVALID_OPERATION, 214 "%s(color buffer datatypes mismatch)", func); 215 return false; 216 } 217 218 /* extra checks for multisample copies... */ 219 if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) { 220 /* color formats must match on GLES. This isn't checked on desktop GL 221 * because the GL 4.4 spec was changed to allow it. In the section 222 * entitled “Changes in the released 223 * Specification of July 22, 2013” it says: 224 * 225 * “Relax BlitFramebuffer in section 18.3.1 so that format conversion 226 * can take place during multisample blits, since drivers already 227 * allow this and some apps depend on it.” 228 */ 229 if (_mesa_is_gles(ctx) && 230 !compatible_resolve_formats(colorReadRb, colorDrawRb)) { 231 _mesa_error(ctx, GL_INVALID_OPERATION, 232 "%s(bad src/dst multisample pixel formats)", func); 233 return false; 234 } 235 } 236 237 } 238 239 if (filter != GL_NEAREST) { 240 /* From EXT_framebuffer_multisample_blit_scaled specification: 241 * "Calling BlitFramebuffer will result in an INVALID_OPERATION error if 242 * filter is not NEAREST and read buffer contains integer data." 243 */ 244 GLenum type = _mesa_get_format_datatype(colorReadRb->Format); 245 if (type == GL_INT || type == GL_UNSIGNED_INT) { 246 _mesa_error(ctx, GL_INVALID_OPERATION, 247 "%s(integer color type)", func); 248 return false; 249 } 250 } 251 return true; 252} 253 254 255static bool 256validate_stencil_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb, 257 struct gl_framebuffer *drawFb, const char *func) 258{ 259 struct gl_renderbuffer *readRb = 260 readFb->Attachment[BUFFER_STENCIL].Renderbuffer; 261 struct gl_renderbuffer *drawRb = 262 drawFb->Attachment[BUFFER_STENCIL].Renderbuffer; 263 int read_z_bits, draw_z_bits; 264 265 if (_mesa_is_gles3(ctx) && (drawRb == readRb)) { 266 _mesa_error(ctx, GL_INVALID_OPERATION, 267 "%s(source and destination stencil buffer cannot be the " 268 "same)", func); 269 return false; 270 } 271 272 if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) != 273 _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) { 274 /* There is no need to check the stencil datatype here, because 275 * there is only one: GL_UNSIGNED_INT. 276 */ 277 _mesa_error(ctx, GL_INVALID_OPERATION, 278 "%s(stencil attachment format mismatch)", func); 279 return false; 280 } 281 282 read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS); 283 draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS); 284 285 /* If both buffers also have depth data, the depth formats must match 286 * as well. If one doesn't have depth, it's not blitted, so we should 287 * ignore the depth format check. 288 */ 289 if (read_z_bits > 0 && draw_z_bits > 0 && 290 (read_z_bits != draw_z_bits || 291 _mesa_get_format_datatype(readRb->Format) != 292 _mesa_get_format_datatype(drawRb->Format))) { 293 _mesa_error(ctx, GL_INVALID_OPERATION, 294 "%s(stencil attachment depth format mismatch)", func); 295 return false; 296 } 297 return true; 298} 299 300 301static bool 302validate_depth_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb, 303 struct gl_framebuffer *drawFb, const char *func) 304{ 305 struct gl_renderbuffer *readRb = 306 readFb->Attachment[BUFFER_DEPTH].Renderbuffer; 307 struct gl_renderbuffer *drawRb = 308 drawFb->Attachment[BUFFER_DEPTH].Renderbuffer; 309 int read_s_bit, draw_s_bit; 310 311 if (_mesa_is_gles3(ctx) && (drawRb == readRb)) { 312 _mesa_error(ctx, GL_INVALID_OPERATION, 313 "%s(source and destination depth buffer cannot be the same)", 314 func); 315 return false; 316 } 317 318 if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) != 319 _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) || 320 (_mesa_get_format_datatype(readRb->Format) != 321 _mesa_get_format_datatype(drawRb->Format))) { 322 _mesa_error(ctx, GL_INVALID_OPERATION, 323 "%s(depth attachment format mismatch)", func); 324 return false; 325 } 326 327 read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS); 328 draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS); 329 330 /* If both buffers also have stencil data, the stencil formats must match as 331 * well. If one doesn't have stencil, it's not blitted, so we should ignore 332 * the stencil format check. 333 */ 334 if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) { 335 _mesa_error(ctx, GL_INVALID_OPERATION, 336 "%s(depth attachment stencil bits mismatch)", func); 337 return false; 338 } 339 return true; 340} 341 342 343static ALWAYS_INLINE void 344blit_framebuffer(struct gl_context *ctx, 345 struct gl_framebuffer *readFb, struct gl_framebuffer *drawFb, 346 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 347 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 348 GLbitfield mask, GLenum filter, bool no_error, const char *func) 349{ 350 FLUSH_VERTICES(ctx, 0, 0); 351 352 if (!readFb || !drawFb) { 353 /* This will normally never happen but someday we may want to 354 * support MakeCurrent() with no drawables. 355 */ 356 return; 357 } 358 359 /* Update completeness status of readFb and drawFb. */ 360 _mesa_update_framebuffer(ctx, readFb, drawFb); 361 362 /* Make sure drawFb has an initialized bounding box. */ 363 _mesa_update_draw_buffer_bounds(ctx, drawFb); 364 365 if (!no_error) { 366 const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT | 367 GL_DEPTH_BUFFER_BIT | 368 GL_STENCIL_BUFFER_BIT); 369 370 /* check for complete framebuffers */ 371 if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT || 372 readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 373 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 374 "%s(incomplete draw/read buffers)", func); 375 return; 376 } 377 378 if (!is_valid_blit_filter(ctx, filter)) { 379 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid filter %s)", func, 380 _mesa_enum_to_string(filter)); 381 return; 382 } 383 384 if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT || 385 filter == GL_SCALED_RESOLVE_NICEST_EXT) && 386 (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) { 387 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s: invalid samples)", func, 388 _mesa_enum_to_string(filter)); 389 return; 390 } 391 392 if (mask & ~legalMaskBits) { 393 _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid mask bits set)", func); 394 return; 395 } 396 397 /* depth/stencil must be blitted with nearest filtering */ 398 if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) 399 && filter != GL_NEAREST) { 400 _mesa_error(ctx, GL_INVALID_OPERATION, 401 "%s(depth/stencil requires GL_NEAREST filter)", func); 402 return; 403 } 404 405 if (_mesa_is_gles3(ctx)) { 406 /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES 407 * 3.0.1 spec says: 408 * 409 * "If SAMPLE_BUFFERS for the draw framebuffer is greater than 410 * zero, an INVALID_OPERATION error is generated." 411 */ 412 if (drawFb->Visual.samples > 0) { 413 _mesa_error(ctx, GL_INVALID_OPERATION, 414 "%s(destination samples must be 0)", func); 415 return; 416 } 417 418 /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES 419 * 3.0.1 spec says: 420 * 421 * "If SAMPLE_BUFFERS for the read framebuffer is greater than 422 * zero, no copy is performed and an INVALID_OPERATION error is 423 * generated if the formats of the read and draw framebuffers are 424 * not identical or if the source and destination rectangles are 425 * not defined with the same (X0, Y0) and (X1, Y1) bounds." 426 * 427 * The format check was made above because desktop OpenGL has the same 428 * requirement. 429 */ 430 if (readFb->Visual.samples > 0 431 && (srcX0 != dstX0 || srcY0 != dstY0 432 || srcX1 != dstX1 || srcY1 != dstY1)) { 433 _mesa_error(ctx, GL_INVALID_OPERATION, 434 "%s(bad src/dst multisample region)", func); 435 return; 436 } 437 } else { 438 if (readFb->Visual.samples > 0 && 439 drawFb->Visual.samples > 0 && 440 readFb->Visual.samples != drawFb->Visual.samples) { 441 _mesa_error(ctx, GL_INVALID_OPERATION, 442 "%s(mismatched samples)", func); 443 return; 444 } 445 446 /* extra checks for multisample copies... */ 447 if ((readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) && 448 (filter == GL_NEAREST || filter == GL_LINEAR)) { 449 /* src and dest region sizes must be the same */ 450 if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) || 451 abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) { 452 _mesa_error(ctx, GL_INVALID_OPERATION, 453 "%s(bad src/dst multisample region sizes)", func); 454 return; 455 } 456 } 457 } 458 } 459 460 /* get color read/draw renderbuffers */ 461 if (mask & GL_COLOR_BUFFER_BIT) { 462 const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers; 463 const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer; 464 465 /* From the EXT_framebuffer_object spec: 466 * 467 * "If a buffer is specified in <mask> and does not exist in both 468 * the read and draw framebuffers, the corresponding bit is silently 469 * ignored." 470 */ 471 if (!colorReadRb || numColorDrawBuffers == 0) { 472 mask &= ~GL_COLOR_BUFFER_BIT; 473 } else if (!no_error) { 474 if (!validate_color_buffer(ctx, readFb, drawFb, filter, func)) 475 return; 476 } 477 } 478 479 if (mask & GL_STENCIL_BUFFER_BIT) { 480 struct gl_renderbuffer *readRb = 481 readFb->Attachment[BUFFER_STENCIL].Renderbuffer; 482 struct gl_renderbuffer *drawRb = 483 drawFb->Attachment[BUFFER_STENCIL].Renderbuffer; 484 485 /* From the EXT_framebuffer_object spec: 486 * 487 * "If a buffer is specified in <mask> and does not exist in both 488 * the read and draw framebuffers, the corresponding bit is silently 489 * ignored." 490 */ 491 if ((readRb == NULL) || (drawRb == NULL)) { 492 mask &= ~GL_STENCIL_BUFFER_BIT; 493 } else if (!no_error) { 494 if (!validate_stencil_buffer(ctx, readFb, drawFb, func)) 495 return; 496 } 497 } 498 499 if (mask & GL_DEPTH_BUFFER_BIT) { 500 struct gl_renderbuffer *readRb = 501 readFb->Attachment[BUFFER_DEPTH].Renderbuffer; 502 struct gl_renderbuffer *drawRb = 503 drawFb->Attachment[BUFFER_DEPTH].Renderbuffer; 504 505 /* From the EXT_framebuffer_object spec: 506 * 507 * "If a buffer is specified in <mask> and does not exist in both 508 * the read and draw framebuffers, the corresponding bit is silently 509 * ignored." 510 */ 511 if ((readRb == NULL) || (drawRb == NULL)) { 512 mask &= ~GL_DEPTH_BUFFER_BIT; 513 } else if (!no_error) { 514 if (!validate_depth_buffer(ctx, readFb, drawFb, func)) 515 return; 516 } 517 } 518 519 /* Debug code */ 520 if (DEBUG_BLIT) { 521 const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer; 522 const struct gl_renderbuffer *colorDrawRb = NULL; 523 GLuint i = 0; 524 525 printf("%s(%d, %d, %d, %d, %d, %d, %d, %d," 526 " 0x%x, 0x%x)\n", func, 527 srcX0, srcY0, srcX1, srcY1, 528 dstX0, dstY0, dstX1, dstY1, 529 mask, filter); 530 531 if (colorReadRb) { 532 const struct gl_renderbuffer_attachment *att; 533 534 att = find_attachment(readFb, colorReadRb); 535 printf(" Src FBO %u RB %u (%dx%d) ", 536 readFb->Name, colorReadRb->Name, 537 colorReadRb->Width, colorReadRb->Height); 538 if (att && att->Texture) { 539 printf("Tex %u tgt 0x%x level %u face %u", 540 att->Texture->Name, 541 att->Texture->Target, 542 att->TextureLevel, 543 att->CubeMapFace); 544 } 545 printf("\n"); 546 547 /* Print all active color render buffers */ 548 for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) { 549 colorDrawRb = drawFb->_ColorDrawBuffers[i]; 550 if (!colorDrawRb) 551 continue; 552 553 att = find_attachment(drawFb, colorDrawRb); 554 printf(" Dst FBO %u RB %u (%dx%d) ", 555 drawFb->Name, colorDrawRb->Name, 556 colorDrawRb->Width, colorDrawRb->Height); 557 if (att && att->Texture) { 558 printf("Tex %u tgt 0x%x level %u face %u", 559 att->Texture->Name, 560 att->Texture->Target, 561 att->TextureLevel, 562 att->CubeMapFace); 563 } 564 printf("\n"); 565 } 566 } 567 } 568 569 if (!mask || 570 (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 || 571 (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) { 572 return; 573 } 574 575 assert(ctx->Driver.BlitFramebuffer); 576 ctx->Driver.BlitFramebuffer(ctx, readFb, drawFb, 577 srcX0, srcY0, srcX1, srcY1, 578 dstX0, dstY0, dstX1, dstY1, 579 mask, filter); 580} 581 582 583static void 584blit_framebuffer_err(struct gl_context *ctx, 585 struct gl_framebuffer *readFb, 586 struct gl_framebuffer *drawFb, 587 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 588 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 589 GLbitfield mask, GLenum filter, const char *func) 590{ 591 /* We are wrapping the err variant of the always inlined 592 * blit_framebuffer() to avoid inlining it in every caller. 593 */ 594 blit_framebuffer(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1, 595 dstX0, dstY0, dstX1, dstY1, mask, filter, false, func); 596} 597 598 599/** 600 * Blit rectangular region, optionally from one framebuffer to another. 601 * 602 * Note, if the src buffer is multisampled and the dest is not, this is 603 * when the samples must be resolved to a single color. 604 */ 605void GLAPIENTRY 606_mesa_BlitFramebuffer_no_error(GLint srcX0, GLint srcY0, GLint srcX1, 607 GLint srcY1, GLint dstX0, GLint dstY0, 608 GLint dstX1, GLint dstY1, 609 GLbitfield mask, GLenum filter) 610{ 611 GET_CURRENT_CONTEXT(ctx); 612 613 blit_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, 614 srcX0, srcY0, srcX1, srcY1, 615 dstX0, dstY0, dstX1, dstY1, 616 mask, filter, true, "glBlitFramebuffer"); 617} 618 619 620void GLAPIENTRY 621_mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 622 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 623 GLbitfield mask, GLenum filter) 624{ 625 GET_CURRENT_CONTEXT(ctx); 626 627 if (MESA_VERBOSE & VERBOSE_API) 628 _mesa_debug(ctx, 629 "glBlitFramebuffer(%d, %d, %d, %d, " 630 " %d, %d, %d, %d, 0x%x, %s)\n", 631 srcX0, srcY0, srcX1, srcY1, 632 dstX0, dstY0, dstX1, dstY1, 633 mask, _mesa_enum_to_string(filter)); 634 635 blit_framebuffer_err(ctx, ctx->ReadBuffer, ctx->DrawBuffer, 636 srcX0, srcY0, srcX1, srcY1, 637 dstX0, dstY0, dstX1, dstY1, 638 mask, filter, "glBlitFramebuffer"); 639} 640 641 642static ALWAYS_INLINE void 643blit_named_framebuffer(struct gl_context *ctx, 644 GLuint readFramebuffer, GLuint drawFramebuffer, 645 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 646 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 647 GLbitfield mask, GLenum filter, bool no_error) 648{ 649 struct gl_framebuffer *readFb, *drawFb; 650 651 /* 652 * According to PDF page 533 of the OpenGL 4.5 core spec (30.10.2014, 653 * Section 18.3 Copying Pixels): 654 * "... if readFramebuffer or drawFramebuffer is zero (for 655 * BlitNamedFramebuffer), then the default read or draw framebuffer is 656 * used as the corresponding source or destination framebuffer, 657 * respectively." 658 */ 659 if (readFramebuffer) { 660 if (no_error) { 661 readFb = _mesa_lookup_framebuffer(ctx, readFramebuffer); 662 } else { 663 readFb = _mesa_lookup_framebuffer_err(ctx, readFramebuffer, 664 "glBlitNamedFramebuffer"); 665 if (!readFb) 666 return; 667 } 668 } else { 669 readFb = ctx->WinSysReadBuffer; 670 } 671 672 if (drawFramebuffer) { 673 if (no_error) { 674 drawFb = _mesa_lookup_framebuffer(ctx, drawFramebuffer); 675 } else { 676 drawFb = _mesa_lookup_framebuffer_err(ctx, drawFramebuffer, 677 "glBlitNamedFramebuffer"); 678 if (!drawFb) 679 return; 680 } 681 } else { 682 drawFb = ctx->WinSysDrawBuffer; 683 } 684 685 blit_framebuffer(ctx, readFb, drawFb, 686 srcX0, srcY0, srcX1, srcY1, 687 dstX0, dstY0, dstX1, dstY1, 688 mask, filter, no_error, "glBlitNamedFramebuffer"); 689} 690 691 692void GLAPIENTRY 693_mesa_BlitNamedFramebuffer_no_error(GLuint readFramebuffer, 694 GLuint drawFramebuffer, 695 GLint srcX0, GLint srcY0, 696 GLint srcX1, GLint srcY1, 697 GLint dstX0, GLint dstY0, 698 GLint dstX1, GLint dstY1, 699 GLbitfield mask, GLenum filter) 700{ 701 GET_CURRENT_CONTEXT(ctx); 702 703 blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer, 704 srcX0, srcY0, srcX1, srcY1, 705 dstX0, dstY0, dstX1, dstY1, 706 mask, filter, true); 707} 708 709 710void GLAPIENTRY 711_mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer, 712 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 713 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 714 GLbitfield mask, GLenum filter) 715{ 716 GET_CURRENT_CONTEXT(ctx); 717 718 if (MESA_VERBOSE & VERBOSE_API) 719 _mesa_debug(ctx, 720 "glBlitNamedFramebuffer(%u %u %d, %d, %d, %d, " 721 " %d, %d, %d, %d, 0x%x, %s)\n", 722 readFramebuffer, drawFramebuffer, 723 srcX0, srcY0, srcX1, srcY1, 724 dstX0, dstY0, dstX1, dstY1, 725 mask, _mesa_enum_to_string(filter)); 726 727 blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer, 728 srcX0, srcY0, srcX1, srcY1, 729 dstX0, dstY0, dstX1, dstY1, 730 mask, filter, false); 731} 732