/*
 * Mesa 3-D graphics library
 *
 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
 * Copyright (C) 1999-2013  VMware, Inc.  All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/*
 * glBlitFramebuffer functions.
 */

#include <stdbool.h>
#include <stdio.h>

#include "context.h"
#include "enums.h"
#include "blit.h"
#include "fbobject.h"
#include "framebuffer.h"
#include "glformats.h"
#include "mtypes.h"
#include "macros.h"
#include "state.h"


/** Set this to 1 to debug/log glBlitFramebuffer() calls */
#define DEBUG_BLIT 0



static const struct gl_renderbuffer_attachment *
find_attachment(const struct gl_framebuffer *fb,
                const struct gl_renderbuffer *rb)
{
   GLuint i;
   for (i = 0; i < ARRAY_SIZE(fb->Attachment); i++) {
      if (fb->Attachment[i].Renderbuffer == rb)
         return &fb->Attachment[i];
   }
   return NULL;
}


/**
 * \return true if two regions overlap, false otherwise
 */
bool
_mesa_regions_overlap(int srcX0, int srcY0,
                      int srcX1, int srcY1,
                      int dstX0, int dstY0,
                      int dstX1, int dstY1)
{
   if (MAX2(srcX0, srcX1) <= MIN2(dstX0, dstX1))
      return false; /* dst completely right of src */

   if (MAX2(dstX0, dstX1) <= MIN2(srcX0, srcX1))
      return false; /* dst completely left of src */

   if (MAX2(srcY0, srcY1) <= MIN2(dstY0, dstY1))
      return false; /* dst completely above src */

   if (MAX2(dstY0, dstY1) <= MIN2(srcY0, srcY1))
      return false; /* dst completely below src */

   return true; /* some overlap */
}


/**
 * Helper function for checking if the datatypes of color buffers are
 * compatible for glBlitFramebuffer.  From the 3.1 spec, page 198:
 *
 * "GL_INVALID_OPERATION is generated if mask contains GL_COLOR_BUFFER_BIT
 *  and any of the following conditions hold:
 *   - The read buffer contains fixed-point or floating-point values and any
 *     draw buffer contains neither fixed-point nor floating-point values.
 *   - The read buffer contains unsigned integer values and any draw buffer
 *     does not contain unsigned integer values.
 *   - The read buffer contains signed integer values and any draw buffer
 *     does not contain signed integer values."
 */
static GLboolean
compatible_color_datatypes(mesa_format srcFormat, mesa_format dstFormat)
{
   GLenum srcType = _mesa_get_format_datatype(srcFormat);
   GLenum dstType = _mesa_get_format_datatype(dstFormat);

   if (srcType != GL_INT && srcType != GL_UNSIGNED_INT) {
      assert(srcType == GL_UNSIGNED_NORMALIZED ||
             srcType == GL_SIGNED_NORMALIZED ||
             srcType == GL_FLOAT);
      /* Boil any of those types down to GL_FLOAT */
      srcType = GL_FLOAT;
   }

   if (dstType != GL_INT && dstType != GL_UNSIGNED_INT) {
      assert(dstType == GL_UNSIGNED_NORMALIZED ||
             dstType == GL_SIGNED_NORMALIZED ||
             dstType == GL_FLOAT);
      /* Boil any of those types down to GL_FLOAT */
      dstType = GL_FLOAT;
   }

   return srcType == dstType;
}


static GLboolean
compatible_resolve_formats(const struct gl_renderbuffer *readRb,
                           const struct gl_renderbuffer *drawRb)
{
   GLenum readFormat, drawFormat;

   /* This checks whether the internal formats are compatible rather than the
    * Mesa format for two reasons:
    *
    * • Under some circumstances, the user may request e.g. two GL_RGBA8
    *   textures and get two entirely different Mesa formats like RGBA8888 and
    *   ARGB8888. Drivers behaving like that should be able to cope with
    *   non-matching formats by themselves, because it's not the user's fault.
    *
    * • Picking two different internal formats can end up with the same Mesa
    *   format. For example the driver might be simulating GL_RGB textures
    *   with GL_RGBA internally and in that case both internal formats would
    *   end up with RGBA8888.
    *
    * This function is used to generate a GL error according to the spec so in
    * both cases we want to be looking at the application-level format, which
    * is InternalFormat.
    *
    * Blits between linear and sRGB formats are also allowed.
    */
   readFormat = _mesa_get_nongeneric_internalformat(readRb->InternalFormat);
   drawFormat = _mesa_get_nongeneric_internalformat(drawRb->InternalFormat);
   readFormat = _mesa_get_linear_internalformat(readFormat);
   drawFormat = _mesa_get_linear_internalformat(drawFormat);

   if (readFormat == drawFormat) {
      return GL_TRUE;
   }

   return GL_FALSE;
}


static GLboolean
is_valid_blit_filter(const struct gl_context *ctx, GLenum filter)
{
   switch (filter) {
   case GL_NEAREST:
   case GL_LINEAR:
      return true;
   case GL_SCALED_RESOLVE_FASTEST_EXT:
   case GL_SCALED_RESOLVE_NICEST_EXT:
      return ctx->Extensions.EXT_framebuffer_multisample_blit_scaled;
   default:
      return false;
   }
}


static bool
validate_color_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb,
                      struct gl_framebuffer *drawFb, GLenum filter,
                      const char *func)
{
   const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
   const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
   const struct gl_renderbuffer *colorDrawRb = NULL;
   GLuint i;

   for (i = 0; i < numColorDrawBuffers; i++) {
      colorDrawRb = drawFb->_ColorDrawBuffers[i];
      if (!colorDrawRb)
         continue;

      /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL
       * ES 3.0.1 spec says:
       *
       *     "If the source and destination buffers are identical, an
       *     INVALID_OPERATION error is generated. Different mipmap levels of a
       *     texture, different layers of a three- dimensional texture or
       *     two-dimensional array texture, and different faces of a cube map
       *     texture do not constitute identical buffers."
       */
      if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "%s(source and destination color buffer cannot be the "
                     "same)", func);
         return false;
      }

      if (!compatible_color_datatypes(colorReadRb->Format,
                                      colorDrawRb->Format)) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "%s(color buffer datatypes mismatch)", func);
         return false;
      }

      /* extra checks for multisample copies... */
      if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) {
         /* color formats must match on GLES. This isn't checked on desktop GL
          * because the GL 4.4 spec was changed to allow it.  In the section
          * entitled “Changes in the released
          * Specification of July 22, 2013” it says:
          *
          * “Relax BlitFramebuffer in section 18.3.1 so that format conversion
          * can take place during multisample blits, since drivers already
          * allow this and some apps depend on it.”
          */
         if (_mesa_is_gles(ctx) &&
             !compatible_resolve_formats(colorReadRb, colorDrawRb)) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(bad src/dst multisample pixel formats)", func);
            return false;
         }
      }

   }

   if (filter != GL_NEAREST) {
      /* From EXT_framebuffer_multisample_blit_scaled specification:
       * "Calling BlitFramebuffer will result in an INVALID_OPERATION error if
       * filter is not NEAREST and read buffer contains integer data."
       */
      GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
      if (type == GL_INT || type == GL_UNSIGNED_INT) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "%s(integer color type)", func);
         return false;
      }
   }
   return true;
}


static bool
validate_stencil_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb,
                        struct gl_framebuffer *drawFb, const char *func)
{
   struct gl_renderbuffer *readRb =
      readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
   struct gl_renderbuffer *drawRb =
      drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;
   int read_z_bits, draw_z_bits;

   if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "%s(source and destination stencil buffer cannot be the "
                  "same)", func);
      return false;
   }

   if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
       _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
      /* There is no need to check the stencil datatype here, because
       * there is only one: GL_UNSIGNED_INT.
       */
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "%s(stencil attachment format mismatch)", func);
      return false;
   }

   read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS);
   draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS);

   /* If both buffers also have depth data, the depth formats must match
    * as well.  If one doesn't have depth, it's not blitted, so we should
    * ignore the depth format check.
    */
   if (read_z_bits > 0 && draw_z_bits > 0 &&
       (read_z_bits != draw_z_bits ||
        _mesa_get_format_datatype(readRb->Format) !=
        _mesa_get_format_datatype(drawRb->Format))) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "%s(stencil attachment depth format mismatch)", func);
      return false;
   }
   return true;
}


static bool
validate_depth_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb,
                      struct gl_framebuffer *drawFb, const char *func)
{
   struct gl_renderbuffer *readRb =
      readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
   struct gl_renderbuffer *drawRb =
      drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
   int read_s_bit, draw_s_bit;

   if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "%s(source and destination depth buffer cannot be the same)",
                  func);
      return false;
   }

   if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
        _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) ||
       (_mesa_get_format_datatype(readRb->Format) !=
        _mesa_get_format_datatype(drawRb->Format))) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "%s(depth attachment format mismatch)", func);
      return false;
   }

   read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS);
   draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS);

   /* If both buffers also have stencil data, the stencil formats must match as
    * well.  If one doesn't have stencil, it's not blitted, so we should ignore
    * the stencil format check.
    */
   if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "%s(depth attachment stencil bits mismatch)", func);
      return false;
   }
   return true;
}


static ALWAYS_INLINE void
blit_framebuffer(struct gl_context *ctx,
                 struct gl_framebuffer *readFb, struct gl_framebuffer *drawFb,
                 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                 GLbitfield mask, GLenum filter, bool no_error, const char *func)
{
   FLUSH_VERTICES(ctx, 0);

   if (!readFb || !drawFb) {
      /* This will normally never happen but someday we may want to
       * support MakeCurrent() with no drawables.
       */
      return;
   }

   /* Update completeness status of readFb and drawFb. */
   _mesa_update_framebuffer(ctx, readFb, drawFb);

   /* Make sure drawFb has an initialized bounding box. */
   _mesa_update_draw_buffer_bounds(ctx, drawFb);

   if (!no_error) {
      const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
                                        GL_DEPTH_BUFFER_BIT |
                                        GL_STENCIL_BUFFER_BIT);

      /* check for complete framebuffers */
      if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
          readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
         _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
                     "%s(incomplete draw/read buffers)", func);
         return;
      }

      if (!is_valid_blit_filter(ctx, filter)) {
         _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid filter %s)", func,
                     _mesa_enum_to_string(filter));
         return;
      }

      if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
           filter == GL_SCALED_RESOLVE_NICEST_EXT) &&
           (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) {
         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s: invalid samples)", func,
                     _mesa_enum_to_string(filter));
         return;
      }

      if (mask & ~legalMaskBits) {
         _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid mask bits set)", func);
         return;
      }

      /* depth/stencil must be blitted with nearest filtering */
      if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
           && filter != GL_NEAREST) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                "%s(depth/stencil requires GL_NEAREST filter)", func);
         return;
      }

      if (_mesa_is_gles3(ctx)) {
         /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
          * 3.0.1 spec says:
          *
          *     "If SAMPLE_BUFFERS for the draw framebuffer is greater than
          *     zero, an INVALID_OPERATION error is generated."
          */
         if (drawFb->Visual.samples > 0) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(destination samples must be 0)", func);
            return;
         }

         /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
          * 3.0.1 spec says:
          *
          *     "If SAMPLE_BUFFERS for the read framebuffer is greater than
          *     zero, no copy is performed and an INVALID_OPERATION error is
          *     generated if the formats of the read and draw framebuffers are
          *     not identical or if the source and destination rectangles are
          *     not defined with the same (X0, Y0) and (X1, Y1) bounds."
          *
          * The format check was made above because desktop OpenGL has the same
          * requirement.
          */
         if (readFb->Visual.samples > 0
             && (srcX0 != dstX0 || srcY0 != dstY0
                 || srcX1 != dstX1 || srcY1 != dstY1)) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(bad src/dst multisample region)", func);
            return;
         }
      } else {
         if (readFb->Visual.samples > 0 &&
             drawFb->Visual.samples > 0 &&
             readFb->Visual.samples != drawFb->Visual.samples) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(mismatched samples)", func);
            return;
         }

         /* extra checks for multisample copies... */
         if ((readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) &&
             (filter == GL_NEAREST || filter == GL_LINEAR)) {
            /* src and dest region sizes must be the same */
            if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) ||
                abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) {
               _mesa_error(ctx, GL_INVALID_OPERATION,
                           "%s(bad src/dst multisample region sizes)", func);
               return;
            }
         }
      }
   }

   /* get color read/draw renderbuffers */
   if (mask & GL_COLOR_BUFFER_BIT) {
      const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
      const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;

      /* From the EXT_framebuffer_object spec:
       *
       *     "If a buffer is specified in <mask> and does not exist in both
       *     the read and draw framebuffers, the corresponding bit is silently
       *     ignored."
       */
      if (!colorReadRb || numColorDrawBuffers == 0) {
         mask &= ~GL_COLOR_BUFFER_BIT;
      } else if (!no_error) {
         if (!validate_color_buffer(ctx, readFb, drawFb, filter, func))
            return;
      }
   }

   if (mask & GL_STENCIL_BUFFER_BIT) {
      struct gl_renderbuffer *readRb =
         readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
      struct gl_renderbuffer *drawRb =
         drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;

      /* From the EXT_framebuffer_object spec:
       *
       *     "If a buffer is specified in <mask> and does not exist in both
       *     the read and draw framebuffers, the corresponding bit is silently
       *     ignored."
       */
      if ((readRb == NULL) || (drawRb == NULL)) {
         mask &= ~GL_STENCIL_BUFFER_BIT;
      } else if (!no_error) {
         if (!validate_stencil_buffer(ctx, readFb, drawFb, func))
            return;
      }
   }

   if (mask & GL_DEPTH_BUFFER_BIT) {
      struct gl_renderbuffer *readRb =
         readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
      struct gl_renderbuffer *drawRb =
         drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;

      /* From the EXT_framebuffer_object spec:
       *
       *     "If a buffer is specified in <mask> and does not exist in both
       *     the read and draw framebuffers, the corresponding bit is silently
       *     ignored."
       */
      if ((readRb == NULL) || (drawRb == NULL)) {
         mask &= ~GL_DEPTH_BUFFER_BIT;
      } else if (!no_error) {
         if (!validate_depth_buffer(ctx, readFb, drawFb, func))
            return;
      }
   }

   /* Debug code */
   if (DEBUG_BLIT) {
      const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
      const struct gl_renderbuffer *colorDrawRb = NULL;
      GLuint i = 0;

      printf("%s(%d, %d, %d, %d,  %d, %d, %d, %d,"
             " 0x%x, 0x%x)\n", func,
             srcX0, srcY0, srcX1, srcY1,
             dstX0, dstY0, dstX1, dstY1,
             mask, filter);

      if (colorReadRb) {
         const struct gl_renderbuffer_attachment *att;

         att = find_attachment(readFb, colorReadRb);
         printf("  Src FBO %u  RB %u (%dx%d)  ",
                readFb->Name, colorReadRb->Name,
                colorReadRb->Width, colorReadRb->Height);
         if (att && att->Texture) {
            printf("Tex %u  tgt 0x%x  level %u  face %u",
                   att->Texture->Name,
                   att->Texture->Target,
                   att->TextureLevel,
                   att->CubeMapFace);
         }
         printf("\n");

         /* Print all active color render buffers */
         for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) {
            colorDrawRb = drawFb->_ColorDrawBuffers[i];
            if (!colorDrawRb)
               continue;

            att = find_attachment(drawFb, colorDrawRb);
            printf("  Dst FBO %u  RB %u (%dx%d)  ",
                   drawFb->Name, colorDrawRb->Name,
                   colorDrawRb->Width, colorDrawRb->Height);
            if (att && att->Texture) {
               printf("Tex %u  tgt 0x%x  level %u  face %u",
                      att->Texture->Name,
                      att->Texture->Target,
                      att->TextureLevel,
                      att->CubeMapFace);
            }
            printf("\n");
         }
      }
   }

   if (!mask ||
       (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 ||
       (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) {
      return;
   }

   assert(ctx->Driver.BlitFramebuffer);
   ctx->Driver.BlitFramebuffer(ctx, readFb, drawFb,
                               srcX0, srcY0, srcX1, srcY1,
                               dstX0, dstY0, dstX1, dstY1,
                               mask, filter);
}


static void
blit_framebuffer_err(struct gl_context *ctx,
                     struct gl_framebuffer *readFb,
                     struct gl_framebuffer *drawFb,
                     GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                     GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                     GLbitfield mask, GLenum filter, const char *func)
{
   /* We are wrapping the err variant of the always inlined
    * blit_framebuffer() to avoid inlining it in every caller.
    */
   blit_framebuffer(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1,
                    dstX0, dstY0, dstX1, dstY1, mask, filter, false, func);
}


/**
 * Blit rectangular region, optionally from one framebuffer to another.
 *
 * Note, if the src buffer is multisampled and the dest is not, this is
 * when the samples must be resolved to a single color.
 */
void GLAPIENTRY
_mesa_BlitFramebuffer_no_error(GLint srcX0, GLint srcY0, GLint srcX1,
                               GLint srcY1, GLint dstX0, GLint dstY0,
                               GLint dstX1, GLint dstY1,
                               GLbitfield mask, GLenum filter)
{
   GET_CURRENT_CONTEXT(ctx);

   blit_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
                    srcX0, srcY0, srcX1, srcY1,
                    dstX0, dstY0, dstX1, dstY1,
                    mask, filter, true, "glBlitFramebuffer");
}


void GLAPIENTRY
_mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                      GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                      GLbitfield mask, GLenum filter)
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx,
                  "glBlitFramebuffer(%d, %d, %d, %d, "
                  " %d, %d, %d, %d, 0x%x, %s)\n",
                  srcX0, srcY0, srcX1, srcY1,
                  dstX0, dstY0, dstX1, dstY1,
                  mask, _mesa_enum_to_string(filter));

   blit_framebuffer_err(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
                        srcX0, srcY0, srcX1, srcY1,
                        dstX0, dstY0, dstX1, dstY1,
                        mask, filter, "glBlitFramebuffer");
}


static ALWAYS_INLINE void
blit_named_framebuffer(struct gl_context *ctx,
                       GLuint readFramebuffer, GLuint drawFramebuffer,
                       GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                       GLbitfield mask, GLenum filter, bool no_error)
{
   struct gl_framebuffer *readFb, *drawFb;

   /*
    * According to PDF page 533 of the OpenGL 4.5 core spec (30.10.2014,
    * Section 18.3 Copying Pixels):
    *   "... if readFramebuffer or drawFramebuffer is zero (for
    *   BlitNamedFramebuffer), then the default read or draw framebuffer is
    *   used as the corresponding source or destination framebuffer,
    *   respectively."
    */
   if (readFramebuffer) {
      if (no_error) {
         readFb = _mesa_lookup_framebuffer(ctx, readFramebuffer);
      } else {
         readFb = _mesa_lookup_framebuffer_err(ctx, readFramebuffer,
                                               "glBlitNamedFramebuffer");
         if (!readFb)
            return;
      }
   } else {
      readFb = ctx->WinSysReadBuffer;
   }

   if (drawFramebuffer) {
      if (no_error) {
         drawFb = _mesa_lookup_framebuffer(ctx, drawFramebuffer);
      } else {
         drawFb = _mesa_lookup_framebuffer_err(ctx, drawFramebuffer,
                                               "glBlitNamedFramebuffer");
         if (!drawFb)
            return;
      }
   } else {
      drawFb = ctx->WinSysDrawBuffer;
   }

   blit_framebuffer(ctx, readFb, drawFb,
                    srcX0, srcY0, srcX1, srcY1,
                    dstX0, dstY0, dstX1, dstY1,
                    mask, filter, no_error, "glBlitNamedFramebuffer");
}


void GLAPIENTRY
_mesa_BlitNamedFramebuffer_no_error(GLuint readFramebuffer,
                                    GLuint drawFramebuffer,
                                    GLint srcX0, GLint srcY0,
                                    GLint srcX1, GLint srcY1,
                                    GLint dstX0, GLint dstY0,
                                    GLint dstX1, GLint dstY1,
                                    GLbitfield mask, GLenum filter)
{
   GET_CURRENT_CONTEXT(ctx);

   blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer,
                          srcX0, srcY0, srcX1, srcY1,
                          dstX0, dstY0, dstX1, dstY1,
                          mask, filter, true);
}


void GLAPIENTRY
_mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer,
                           GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                           GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                           GLbitfield mask, GLenum filter)
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx,
                  "glBlitNamedFramebuffer(%u %u %d, %d, %d, %d, "
                  " %d, %d, %d, %d, 0x%x, %s)\n",
                  readFramebuffer, drawFramebuffer,
                  srcX0, srcY0, srcX1, srcY1,
                  dstX0, dstY0, dstX1, dstY1,
                  mask, _mesa_enum_to_string(filter));

   blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer,
                          srcX0, srcY0, srcX1, srcY1,
                          dstX0, dstY0, dstX1, dstY1,
                          mask, filter, false);
}
