Home | History | Annotate | Download | only in main
      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 
     49 static const struct gl_renderbuffer_attachment *
     50 find_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  */
     65 bool
     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  */
    100 static GLboolean
    101 compatible_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 
    126 static GLboolean
    127 compatible_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 
    164 static GLboolean
    165 is_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 
    180 void
    181 _mesa_blit_framebuffer(struct gl_context *ctx,
    182                        struct gl_framebuffer *readFb,
    183                        struct gl_framebuffer *drawFb,
    184                        GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
    185                        GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
    186                        GLbitfield mask, GLenum filter, const char *func)
    187 {
    188    const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
    189                                      GL_DEPTH_BUFFER_BIT |
    190                                      GL_STENCIL_BUFFER_BIT);
    191 
    192    FLUSH_VERTICES(ctx, 0);
    193 
    194    /* Update completeness status of readFb and drawFb. */
    195    _mesa_update_framebuffer(ctx, readFb, drawFb);
    196 
    197    /* Make sure drawFb has an initialized bounding box. */
    198    _mesa_update_draw_buffer_bounds(ctx, drawFb);
    199 
    200    if (!readFb || !drawFb) {
    201       /* This will normally never happen but someday we may want to
    202        * support MakeCurrent() with no drawables.
    203        */
    204       return;
    205    }
    206 
    207    /* check for complete framebuffers */
    208    if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
    209        readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
    210       _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
    211                   "%s(incomplete draw/read buffers)", func);
    212       return;
    213    }
    214 
    215    if (!is_valid_blit_filter(ctx, filter)) {
    216       _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid filter %s)", func,
    217                   _mesa_enum_to_string(filter));
    218       return;
    219    }
    220 
    221    if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
    222         filter == GL_SCALED_RESOLVE_NICEST_EXT) &&
    223         (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) {
    224       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s: invalid samples)", func,
    225                   _mesa_enum_to_string(filter));
    226       return;
    227    }
    228 
    229    if (mask & ~legalMaskBits) {
    230       _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid mask bits set)", func);
    231       return;
    232    }
    233 
    234    /* depth/stencil must be blitted with nearest filtering */
    235    if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
    236         && filter != GL_NEAREST) {
    237       _mesa_error(ctx, GL_INVALID_OPERATION,
    238              "%s(depth/stencil requires GL_NEAREST filter)", func);
    239       return;
    240    }
    241 
    242    /* get color read/draw renderbuffers */
    243    if (mask & GL_COLOR_BUFFER_BIT) {
    244       const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
    245       const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
    246       const struct gl_renderbuffer *colorDrawRb = NULL;
    247       GLuint i;
    248 
    249       /* From the EXT_framebuffer_object spec:
    250        *
    251        *     "If a buffer is specified in <mask> and does not exist in both
    252        *     the read and draw framebuffers, the corresponding bit is silently
    253        *     ignored."
    254        */
    255       if (!colorReadRb || numColorDrawBuffers == 0) {
    256          mask &= ~GL_COLOR_BUFFER_BIT;
    257       }
    258       else {
    259          for (i = 0; i < numColorDrawBuffers; i++) {
    260             colorDrawRb = drawFb->_ColorDrawBuffers[i];
    261             if (!colorDrawRb)
    262                continue;
    263 
    264             /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL
    265              * ES 3.0.1 spec says:
    266              *
    267              *     "If the source and destination buffers are identical, an
    268              *     INVALID_OPERATION error is generated. Different mipmap
    269              *     levels of a texture, different layers of a three-
    270              *     dimensional texture or two-dimensional array texture, and
    271              *     different faces of a cube map texture do not constitute
    272              *     identical buffers."
    273              */
    274             if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) {
    275                _mesa_error(ctx, GL_INVALID_OPERATION,
    276                            "%s(source and destination color "
    277                            "buffer cannot be the same)", func);
    278                return;
    279             }
    280 
    281             if (!compatible_color_datatypes(colorReadRb->Format,
    282                                             colorDrawRb->Format)) {
    283                _mesa_error(ctx, GL_INVALID_OPERATION,
    284                            "%s(color buffer datatypes mismatch)", func);
    285                return;
    286             }
    287             /* extra checks for multisample copies... */
    288             if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) {
    289                /* color formats must match on GLES. This isn't checked on
    290                 * desktop GL because the GL 4.4 spec was changed to allow it.
    291                 * In the section entitled Changes in the released
    292                 * Specification of July 22, 2013 it says:
    293                 *
    294                 * Relax BlitFramebuffer in section 18.3.1 so that format
    295                 *  conversion can take place during multisample blits, since
    296                 *  drivers already allow this and some apps depend on it.
    297                 */
    298                if (_mesa_is_gles(ctx) &&
    299                    !compatible_resolve_formats(colorReadRb, colorDrawRb)) {
    300                   _mesa_error(ctx, GL_INVALID_OPERATION,
    301                          "%s(bad src/dst multisample pixel formats)", func);
    302                   return;
    303                }
    304             }
    305          }
    306          if (filter != GL_NEAREST) {
    307             /* From EXT_framebuffer_multisample_blit_scaled specification:
    308              * "Calling BlitFramebuffer will result in an INVALID_OPERATION error
    309              * if filter is not NEAREST and read buffer contains integer data."
    310              */
    311             GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
    312             if (type == GL_INT || type == GL_UNSIGNED_INT) {
    313                _mesa_error(ctx, GL_INVALID_OPERATION,
    314                            "%s(integer color type)", func);
    315                return;
    316             }
    317          }
    318       }
    319    }
    320 
    321    if (mask & GL_STENCIL_BUFFER_BIT) {
    322       struct gl_renderbuffer *readRb =
    323          readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
    324       struct gl_renderbuffer *drawRb =
    325          drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;
    326 
    327       /* From the EXT_framebuffer_object spec:
    328        *
    329        *     "If a buffer is specified in <mask> and does not exist in both
    330        *     the read and draw framebuffers, the corresponding bit is silently
    331        *     ignored."
    332        */
    333       if ((readRb == NULL) || (drawRb == NULL)) {
    334          mask &= ~GL_STENCIL_BUFFER_BIT;
    335       }
    336       else {
    337          int read_z_bits, draw_z_bits;
    338 
    339          if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
    340             _mesa_error(ctx, GL_INVALID_OPERATION,
    341                         "%s(source and destination stencil "
    342                         "buffer cannot be the same)", func);
    343             return;
    344          }
    345 
    346          if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
    347              _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
    348             /* There is no need to check the stencil datatype here, because
    349              * there is only one: GL_UNSIGNED_INT.
    350              */
    351             _mesa_error(ctx, GL_INVALID_OPERATION,
    352                         "%s(stencil attachment format mismatch)", func);
    353             return;
    354          }
    355 
    356          read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS);
    357          draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS);
    358 
    359          /* If both buffers also have depth data, the depth formats must match
    360           * as well.  If one doesn't have depth, it's not blitted, so we should
    361           * ignore the depth format check.
    362           */
    363          if (read_z_bits > 0 && draw_z_bits > 0 &&
    364              (read_z_bits != draw_z_bits ||
    365               _mesa_get_format_datatype(readRb->Format) !=
    366               _mesa_get_format_datatype(drawRb->Format))) {
    367 
    368             _mesa_error(ctx, GL_INVALID_OPERATION,
    369                         "%s(stencil attachment depth format mismatch)", func);
    370             return;
    371          }
    372       }
    373    }
    374 
    375    if (mask & GL_DEPTH_BUFFER_BIT) {
    376       struct gl_renderbuffer *readRb =
    377          readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
    378       struct gl_renderbuffer *drawRb =
    379          drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
    380 
    381       /* From the EXT_framebuffer_object spec:
    382        *
    383        *     "If a buffer is specified in <mask> and does not exist in both
    384        *     the read and draw framebuffers, the corresponding bit is silently
    385        *     ignored."
    386        */
    387       if ((readRb == NULL) || (drawRb == NULL)) {
    388          mask &= ~GL_DEPTH_BUFFER_BIT;
    389       }
    390       else {
    391          int read_s_bit, draw_s_bit;
    392 
    393          if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
    394             _mesa_error(ctx, GL_INVALID_OPERATION,
    395                         "%s(source and destination depth "
    396                         "buffer cannot be the same)", func);
    397             return;
    398          }
    399 
    400          if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
    401               _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) ||
    402              (_mesa_get_format_datatype(readRb->Format) !=
    403               _mesa_get_format_datatype(drawRb->Format))) {
    404             _mesa_error(ctx, GL_INVALID_OPERATION,
    405                         "%s(depth attachment format mismatch)", func);
    406             return;
    407          }
    408 
    409          read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS);
    410          draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS);
    411 
    412          /* If both buffers also have stencil data, the stencil formats must
    413           * match as well.  If one doesn't have stencil, it's not blitted, so
    414           * we should ignore the stencil format check.
    415           */
    416          if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) {
    417             _mesa_error(ctx, GL_INVALID_OPERATION,
    418                         "%s(depth attachment stencil bits mismatch)", func);
    419             return;
    420          }
    421       }
    422    }
    423 
    424 
    425    if (_mesa_is_gles3(ctx)) {
    426       /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
    427        * 3.0.1 spec says:
    428        *
    429        *     "If SAMPLE_BUFFERS for the draw framebuffer is greater than zero,
    430        *     an INVALID_OPERATION error is generated."
    431        */
    432       if (drawFb->Visual.samples > 0) {
    433          _mesa_error(ctx, GL_INVALID_OPERATION,
    434                      "%s(destination samples must be 0)", func);
    435          return;
    436       }
    437 
    438       /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
    439        * 3.0.1 spec says:
    440        *
    441        *     "If SAMPLE_BUFFERS for the read framebuffer is greater than zero,
    442        *     no copy is performed and an INVALID_OPERATION error is generated
    443        *     if the formats of the read and draw framebuffers are not
    444        *     identical or if the source and destination rectangles are not
    445        *     defined with the same (X0, Y0) and (X1, Y1) bounds."
    446        *
    447        * The format check was made above because desktop OpenGL has the same
    448        * requirement.
    449        */
    450       if (readFb->Visual.samples > 0
    451           && (srcX0 != dstX0 || srcY0 != dstY0
    452               || srcX1 != dstX1 || srcY1 != dstY1)) {
    453          _mesa_error(ctx, GL_INVALID_OPERATION,
    454                      "%s(bad src/dst multisample region)", func);
    455          return;
    456       }
    457    } else {
    458       if (readFb->Visual.samples > 0 &&
    459           drawFb->Visual.samples > 0 &&
    460           readFb->Visual.samples != drawFb->Visual.samples) {
    461          _mesa_error(ctx, GL_INVALID_OPERATION,
    462                      "%s(mismatched samples)", func);
    463          return;
    464       }
    465 
    466       /* extra checks for multisample copies... */
    467       if ((readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) &&
    468           (filter == GL_NEAREST || filter == GL_LINEAR)) {
    469          /* src and dest region sizes must be the same */
    470          if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) ||
    471              abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) {
    472             _mesa_error(ctx, GL_INVALID_OPERATION,
    473                         "%s(bad src/dst multisample region sizes)", func);
    474             return;
    475          }
    476       }
    477    }
    478 
    479    /* Debug code */
    480    if (DEBUG_BLIT) {
    481       const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
    482       const struct gl_renderbuffer *colorDrawRb = NULL;
    483       GLuint i = 0;
    484 
    485       printf("%s(%d, %d, %d, %d,  %d, %d, %d, %d,"
    486              " 0x%x, 0x%x)\n", func,
    487              srcX0, srcY0, srcX1, srcY1,
    488              dstX0, dstY0, dstX1, dstY1,
    489              mask, filter);
    490 
    491       if (colorReadRb) {
    492          const struct gl_renderbuffer_attachment *att;
    493 
    494          att = find_attachment(readFb, colorReadRb);
    495          printf("  Src FBO %u  RB %u (%dx%d)  ",
    496                 readFb->Name, colorReadRb->Name,
    497                 colorReadRb->Width, colorReadRb->Height);
    498          if (att && att->Texture) {
    499             printf("Tex %u  tgt 0x%x  level %u  face %u",
    500                    att->Texture->Name,
    501                    att->Texture->Target,
    502                    att->TextureLevel,
    503                    att->CubeMapFace);
    504          }
    505          printf("\n");
    506 
    507          /* Print all active color render buffers */
    508          for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) {
    509             colorDrawRb = drawFb->_ColorDrawBuffers[i];
    510             if (!colorDrawRb)
    511                continue;
    512 
    513             att = find_attachment(drawFb, colorDrawRb);
    514             printf("  Dst FBO %u  RB %u (%dx%d)  ",
    515                    drawFb->Name, colorDrawRb->Name,
    516                    colorDrawRb->Width, colorDrawRb->Height);
    517             if (att && att->Texture) {
    518                printf("Tex %u  tgt 0x%x  level %u  face %u",
    519                       att->Texture->Name,
    520                       att->Texture->Target,
    521                       att->TextureLevel,
    522                       att->CubeMapFace);
    523             }
    524             printf("\n");
    525          }
    526       }
    527    }
    528 
    529    if (!mask ||
    530        (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 ||
    531        (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) {
    532       return;
    533    }
    534 
    535    assert(ctx->Driver.BlitFramebuffer);
    536    ctx->Driver.BlitFramebuffer(ctx, readFb, drawFb,
    537                                srcX0, srcY0, srcX1, srcY1,
    538                                dstX0, dstY0, dstX1, dstY1,
    539                                mask, filter);
    540 }
    541 
    542 
    543 /**
    544  * Blit rectangular region, optionally from one framebuffer to another.
    545  *
    546  * Note, if the src buffer is multisampled and the dest is not, this is
    547  * when the samples must be resolved to a single color.
    548  */
    549 void GLAPIENTRY
    550 _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
    551                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
    552                       GLbitfield mask, GLenum filter)
    553 {
    554    GET_CURRENT_CONTEXT(ctx);
    555 
    556    if (MESA_VERBOSE & VERBOSE_API)
    557       _mesa_debug(ctx,
    558                   "glBlitFramebuffer(%d, %d, %d, %d, "
    559                   " %d, %d, %d, %d, 0x%x, %s)\n",
    560                   srcX0, srcY0, srcX1, srcY1,
    561                   dstX0, dstY0, dstX1, dstY1,
    562                   mask, _mesa_enum_to_string(filter));
    563 
    564    _mesa_blit_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
    565                           srcX0, srcY0, srcX1, srcY1,
    566                           dstX0, dstY0, dstX1, dstY1,
    567                           mask, filter, "glBlitFramebuffer");
    568 }
    569 
    570 
    571 void GLAPIENTRY
    572 _mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer,
    573                            GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
    574                            GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
    575                            GLbitfield mask, GLenum filter)
    576 {
    577    GET_CURRENT_CONTEXT(ctx);
    578    struct gl_framebuffer *readFb, *drawFb;
    579 
    580    if (MESA_VERBOSE & VERBOSE_API)
    581       _mesa_debug(ctx,
    582                   "glBlitNamedFramebuffer(%u %u %d, %d, %d, %d, "
    583                   " %d, %d, %d, %d, 0x%x, %s)\n",
    584                   readFramebuffer, drawFramebuffer,
    585                   srcX0, srcY0, srcX1, srcY1,
    586                   dstX0, dstY0, dstX1, dstY1,
    587                   mask, _mesa_enum_to_string(filter));
    588 
    589    /*
    590     * According to PDF page 533 of the OpenGL 4.5 core spec (30.10.2014,
    591     * Section 18.3 Copying Pixels):
    592     *   "... if readFramebuffer or drawFramebuffer is zero (for
    593     *   BlitNamedFramebuffer), then the default read or draw framebuffer is
    594     *   used as the corresponding source or destination framebuffer,
    595     *   respectively."
    596     */
    597    if (readFramebuffer) {
    598       readFb = _mesa_lookup_framebuffer_err(ctx, readFramebuffer,
    599                                             "glBlitNamedFramebuffer");
    600       if (!readFb)
    601          return;
    602    }
    603    else
    604       readFb = ctx->WinSysReadBuffer;
    605 
    606    if (drawFramebuffer) {
    607       drawFb = _mesa_lookup_framebuffer_err(ctx, drawFramebuffer,
    608                                             "glBlitNamedFramebuffer");
    609       if (!drawFb)
    610          return;
    611    }
    612    else
    613       drawFb = ctx->WinSysDrawBuffer;
    614 
    615    _mesa_blit_framebuffer(ctx, readFb, drawFb,
    616                           srcX0, srcY0, srcX1, srcY1,
    617                           dstX0, dstY0, dstX1, dstY1,
    618                           mask, filter, "glBlitNamedFramebuffer");
    619 }
    620