Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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 "state.h"
  41.  
  42.  
  43. /** Set this to 1 to debug/log glBlitFramebuffer() calls */
  44. #define DEBUG_BLIT 0
  45.  
  46.  
  47.  
  48. static const struct gl_renderbuffer_attachment *
  49. find_attachment(const struct gl_framebuffer *fb,
  50.                 const struct gl_renderbuffer *rb)
  51. {
  52.    GLuint i;
  53.    for (i = 0; i < ARRAY_SIZE(fb->Attachment); i++) {
  54.       if (fb->Attachment[i].Renderbuffer == rb)
  55.          return &fb->Attachment[i];
  56.    }
  57.    return NULL;
  58. }
  59.  
  60.  
  61. /**
  62.  * Helper function for checking if the datatypes of color buffers are
  63.  * compatible for glBlitFramebuffer.  From the 3.1 spec, page 198:
  64.  *
  65.  * "GL_INVALID_OPERATION is generated if mask contains GL_COLOR_BUFFER_BIT
  66.  *  and any of the following conditions hold:
  67.  *   - The read buffer contains fixed-point or floating-point values and any
  68.  *     draw buffer contains neither fixed-point nor floating-point values.
  69.  *   - The read buffer contains unsigned integer values and any draw buffer
  70.  *     does not contain unsigned integer values.
  71.  *   - The read buffer contains signed integer values and any draw buffer
  72.  *     does not contain signed integer values."
  73.  */
  74. static GLboolean
  75. compatible_color_datatypes(mesa_format srcFormat, mesa_format dstFormat)
  76. {
  77.    GLenum srcType = _mesa_get_format_datatype(srcFormat);
  78.    GLenum dstType = _mesa_get_format_datatype(dstFormat);
  79.  
  80.    if (srcType != GL_INT && srcType != GL_UNSIGNED_INT) {
  81.       assert(srcType == GL_UNSIGNED_NORMALIZED ||
  82.              srcType == GL_SIGNED_NORMALIZED ||
  83.              srcType == GL_FLOAT);
  84.       /* Boil any of those types down to GL_FLOAT */
  85.       srcType = GL_FLOAT;
  86.    }
  87.  
  88.    if (dstType != GL_INT && dstType != GL_UNSIGNED_INT) {
  89.       assert(dstType == GL_UNSIGNED_NORMALIZED ||
  90.              dstType == GL_SIGNED_NORMALIZED ||
  91.              dstType == GL_FLOAT);
  92.       /* Boil any of those types down to GL_FLOAT */
  93.       dstType = GL_FLOAT;
  94.    }
  95.  
  96.    return srcType == dstType;
  97. }
  98.  
  99.  
  100. static GLboolean
  101. compatible_resolve_formats(const struct gl_renderbuffer *readRb,
  102.                            const struct gl_renderbuffer *drawRb)
  103. {
  104.    GLenum readFormat, drawFormat;
  105.  
  106.    /* The simple case where we know the backing Mesa formats are the same.
  107.     */
  108.    if (_mesa_get_srgb_format_linear(readRb->Format) ==
  109.        _mesa_get_srgb_format_linear(drawRb->Format)) {
  110.       return GL_TRUE;
  111.    }
  112.  
  113.    /* The Mesa formats are different, so we must check whether the internal
  114.     * formats are compatible.
  115.     *
  116.     * Under some circumstances, the user may request e.g. two GL_RGBA8
  117.     * textures and get two entirely different Mesa formats like RGBA8888 and
  118.     * ARGB8888. Drivers behaving like that should be able to cope with
  119.     * non-matching formats by themselves, because it's not the user's fault.
  120.     *
  121.     * Blits between linear and sRGB formats are also allowed.
  122.     */
  123.    readFormat = _mesa_get_nongeneric_internalformat(readRb->InternalFormat);
  124.    drawFormat = _mesa_get_nongeneric_internalformat(drawRb->InternalFormat);
  125.    readFormat = _mesa_get_linear_internalformat(readFormat);
  126.    drawFormat = _mesa_get_linear_internalformat(drawFormat);
  127.  
  128.    if (readFormat == drawFormat) {
  129.       return GL_TRUE;
  130.    }
  131.  
  132.    return GL_FALSE;
  133. }
  134.  
  135.  
  136. static GLboolean
  137. is_valid_blit_filter(const struct gl_context *ctx, GLenum filter)
  138. {
  139.    switch (filter) {
  140.    case GL_NEAREST:
  141.    case GL_LINEAR:
  142.       return true;
  143.    case GL_SCALED_RESOLVE_FASTEST_EXT:
  144.    case GL_SCALED_RESOLVE_NICEST_EXT:
  145.       return ctx->Extensions.EXT_framebuffer_multisample_blit_scaled;
  146.    default:
  147.       return false;
  148.    }
  149. }
  150.  
  151.  
  152. void
  153. _mesa_blit_framebuffer(struct gl_context *ctx,
  154.                        struct gl_framebuffer *readFb,
  155.                        struct gl_framebuffer *drawFb,
  156.                        GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
  157.                        GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
  158.                        GLbitfield mask, GLenum filter, const char *func)
  159. {
  160.    const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
  161.                                      GL_DEPTH_BUFFER_BIT |
  162.                                      GL_STENCIL_BUFFER_BIT);
  163.  
  164.    FLUSH_VERTICES(ctx, 0);
  165.  
  166.    /* Update completeness status of readFb and drawFb. */
  167.    _mesa_update_framebuffer(ctx, readFb, drawFb);
  168.  
  169.    /* Make sure drawFb has an initialized bounding box. */
  170.    _mesa_update_draw_buffer_bounds(ctx, drawFb);
  171.  
  172.    if (!readFb || !drawFb) {
  173.       /* This will normally never happen but someday we may want to
  174.        * support MakeCurrent() with no drawables.
  175.        */
  176.       return;
  177.    }
  178.  
  179.    /* check for complete framebuffers */
  180.    if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
  181.        readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
  182.       _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
  183.                   "%s(incomplete draw/read buffers)", func);
  184.       return;
  185.    }
  186.  
  187.    if (!is_valid_blit_filter(ctx, filter)) {
  188.       _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid filter %s)", func,
  189.                   _mesa_lookup_enum_by_nr(filter));
  190.       return;
  191.    }
  192.  
  193.    if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
  194.         filter == GL_SCALED_RESOLVE_NICEST_EXT) &&
  195.         (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) {
  196.       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s: invalid samples)", func,
  197.                   _mesa_lookup_enum_by_nr(filter));
  198.       return;
  199.    }
  200.  
  201.    if (mask & ~legalMaskBits) {
  202.       _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid mask bits set)", func);
  203.       return;
  204.    }
  205.  
  206.    /* depth/stencil must be blitted with nearest filtering */
  207.    if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
  208.         && filter != GL_NEAREST) {
  209.       _mesa_error(ctx, GL_INVALID_OPERATION,
  210.              "%s(depth/stencil requires GL_NEAREST filter)", func);
  211.       return;
  212.    }
  213.  
  214.    /* get color read/draw renderbuffers */
  215.    if (mask & GL_COLOR_BUFFER_BIT) {
  216.       const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
  217.       const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
  218.       const struct gl_renderbuffer *colorDrawRb = NULL;
  219.       GLuint i;
  220.  
  221.       /* From the EXT_framebuffer_object spec:
  222.        *
  223.        *     "If a buffer is specified in <mask> and does not exist in both
  224.        *     the read and draw framebuffers, the corresponding bit is silently
  225.        *     ignored."
  226.        */
  227.       if (!colorReadRb || numColorDrawBuffers == 0) {
  228.          mask &= ~GL_COLOR_BUFFER_BIT;
  229.       }
  230.       else {
  231.          for (i = 0; i < numColorDrawBuffers; i++) {
  232.             colorDrawRb = drawFb->_ColorDrawBuffers[i];
  233.             if (!colorDrawRb)
  234.                continue;
  235.  
  236.             /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL
  237.              * ES 3.0.1 spec says:
  238.              *
  239.              *     "If the source and destination buffers are identical, an
  240.              *     INVALID_OPERATION error is generated. Different mipmap
  241.              *     levels of a texture, different layers of a three-
  242.              *     dimensional texture or two-dimensional array texture, and
  243.              *     different faces of a cube map texture do not constitute
  244.              *     identical buffers."
  245.              */
  246.             if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) {
  247.                _mesa_error(ctx, GL_INVALID_OPERATION,
  248.                            "%s(source and destination color "
  249.                            "buffer cannot be the same)", func);
  250.                return;
  251.             }
  252.  
  253.             if (!compatible_color_datatypes(colorReadRb->Format,
  254.                                             colorDrawRb->Format)) {
  255.                _mesa_error(ctx, GL_INVALID_OPERATION,
  256.                            "%s(color buffer datatypes mismatch)", func);
  257.                return;
  258.             }
  259.             /* extra checks for multisample copies... */
  260.             if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) {
  261.                /* color formats must match */
  262.                if (!compatible_resolve_formats(colorReadRb, colorDrawRb)) {
  263.                   _mesa_error(ctx, GL_INVALID_OPERATION,
  264.                          "%s(bad src/dst multisample pixel formats)", func);
  265.                   return;
  266.                }
  267.             }
  268.          }
  269.          if (filter != GL_NEAREST) {
  270.             /* From EXT_framebuffer_multisample_blit_scaled specification:
  271.              * "Calling BlitFramebuffer will result in an INVALID_OPERATION error
  272.              * if filter is not NEAREST and read buffer contains integer data."
  273.              */
  274.             GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
  275.             if (type == GL_INT || type == GL_UNSIGNED_INT) {
  276.                _mesa_error(ctx, GL_INVALID_OPERATION,
  277.                            "%s(integer color type)", func);
  278.                return;
  279.             }
  280.          }
  281.       }
  282.    }
  283.  
  284.    if (mask & GL_STENCIL_BUFFER_BIT) {
  285.       struct gl_renderbuffer *readRb =
  286.          readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
  287.       struct gl_renderbuffer *drawRb =
  288.          drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;
  289.  
  290.       /* From the EXT_framebuffer_object spec:
  291.        *
  292.        *     "If a buffer is specified in <mask> and does not exist in both
  293.        *     the read and draw framebuffers, the corresponding bit is silently
  294.        *     ignored."
  295.        */
  296.       if ((readRb == NULL) || (drawRb == NULL)) {
  297.          mask &= ~GL_STENCIL_BUFFER_BIT;
  298.       }
  299.       else {
  300.          int read_z_bits, draw_z_bits;
  301.  
  302.          if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
  303.             _mesa_error(ctx, GL_INVALID_OPERATION,
  304.                         "%s(source and destination stencil "
  305.                         "buffer cannot be the same)", func);
  306.             return;
  307.          }
  308.  
  309.          if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
  310.              _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
  311.             /* There is no need to check the stencil datatype here, because
  312.              * there is only one: GL_UNSIGNED_INT.
  313.              */
  314.             _mesa_error(ctx, GL_INVALID_OPERATION,
  315.                         "%s(stencil attachment format mismatch)", func);
  316.             return;
  317.          }
  318.  
  319.          read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS);
  320.          draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS);
  321.  
  322.          /* If both buffers also have depth data, the depth formats must match
  323.           * as well.  If one doesn't have depth, it's not blitted, so we should
  324.           * ignore the depth format check.
  325.           */
  326.          if (read_z_bits > 0 && draw_z_bits > 0 &&
  327.              (read_z_bits != draw_z_bits ||
  328.               _mesa_get_format_datatype(readRb->Format) !=
  329.               _mesa_get_format_datatype(drawRb->Format))) {
  330.  
  331.             _mesa_error(ctx, GL_INVALID_OPERATION,
  332.                         "%s(stencil attachment depth format mismatch)", func);
  333.             return;
  334.          }
  335.       }
  336.    }
  337.  
  338.    if (mask & GL_DEPTH_BUFFER_BIT) {
  339.       struct gl_renderbuffer *readRb =
  340.          readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
  341.       struct gl_renderbuffer *drawRb =
  342.          drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
  343.  
  344.       /* From the EXT_framebuffer_object spec:
  345.        *
  346.        *     "If a buffer is specified in <mask> and does not exist in both
  347.        *     the read and draw framebuffers, the corresponding bit is silently
  348.        *     ignored."
  349.        */
  350.       if ((readRb == NULL) || (drawRb == NULL)) {
  351.          mask &= ~GL_DEPTH_BUFFER_BIT;
  352.       }
  353.       else {
  354.          int read_s_bit, draw_s_bit;
  355.  
  356.          if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
  357.             _mesa_error(ctx, GL_INVALID_OPERATION,
  358.                         "%s(source and destination depth "
  359.                         "buffer cannot be the same)", func);
  360.             return;
  361.          }
  362.  
  363.          if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
  364.               _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) ||
  365.              (_mesa_get_format_datatype(readRb->Format) !=
  366.               _mesa_get_format_datatype(drawRb->Format))) {
  367.             _mesa_error(ctx, GL_INVALID_OPERATION,
  368.                         "%s(depth attachment format mismatch)", func);
  369.             return;
  370.          }
  371.  
  372.          read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS);
  373.          draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS);
  374.  
  375.          /* If both buffers also have stencil data, the stencil formats must
  376.           * match as well.  If one doesn't have stencil, it's not blitted, so
  377.           * we should ignore the stencil format check.
  378.           */
  379.          if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) {
  380.             _mesa_error(ctx, GL_INVALID_OPERATION,
  381.                         "%s(depth attachment stencil bits mismatch)", func);
  382.             return;
  383.          }
  384.       }
  385.    }
  386.  
  387.  
  388.    if (_mesa_is_gles3(ctx)) {
  389.       /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
  390.        * 3.0.1 spec says:
  391.        *
  392.        *     "If SAMPLE_BUFFERS for the draw framebuffer is greater than zero,
  393.        *     an INVALID_OPERATION error is generated."
  394.        */
  395.       if (drawFb->Visual.samples > 0) {
  396.          _mesa_error(ctx, GL_INVALID_OPERATION,
  397.                      "%s(destination samples must be 0)", func);
  398.          return;
  399.       }
  400.  
  401.       /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
  402.        * 3.0.1 spec says:
  403.        *
  404.        *     "If SAMPLE_BUFFERS for the read framebuffer is greater than zero,
  405.        *     no copy is performed and an INVALID_OPERATION error is generated
  406.        *     if the formats of the read and draw framebuffers are not
  407.        *     identical or if the source and destination rectangles are not
  408.        *     defined with the same (X0, Y0) and (X1, Y1) bounds."
  409.        *
  410.        * The format check was made above because desktop OpenGL has the same
  411.        * requirement.
  412.        */
  413.       if (readFb->Visual.samples > 0
  414.           && (srcX0 != dstX0 || srcY0 != dstY0
  415.               || srcX1 != dstX1 || srcY1 != dstY1)) {
  416.          _mesa_error(ctx, GL_INVALID_OPERATION,
  417.                      "%s(bad src/dst multisample region)", func);
  418.          return;
  419.       }
  420.    } else {
  421.       if (readFb->Visual.samples > 0 &&
  422.           drawFb->Visual.samples > 0 &&
  423.           readFb->Visual.samples != drawFb->Visual.samples) {
  424.          _mesa_error(ctx, GL_INVALID_OPERATION,
  425.                      "%s(mismatched samples)", func);
  426.          return;
  427.       }
  428.  
  429.       /* extra checks for multisample copies... */
  430.       if ((readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) &&
  431.           (filter == GL_NEAREST || filter == GL_LINEAR)) {
  432.          /* src and dest region sizes must be the same */
  433.          if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) ||
  434.              abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) {
  435.             _mesa_error(ctx, GL_INVALID_OPERATION,
  436.                         "%s(bad src/dst multisample region sizes)", func);
  437.             return;
  438.          }
  439.       }
  440.    }
  441.  
  442.    /* Debug code */
  443.    if (DEBUG_BLIT) {
  444.       const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
  445.       const struct gl_renderbuffer *colorDrawRb = NULL;
  446.       GLuint i = 0;
  447.  
  448.       printf("%s(%d, %d, %d, %d,  %d, %d, %d, %d,"
  449.              " 0x%x, 0x%x)\n", func,
  450.              srcX0, srcY0, srcX1, srcY1,
  451.              dstX0, dstY0, dstX1, dstY1,
  452.              mask, filter);
  453.  
  454.       if (colorReadRb) {
  455.          const struct gl_renderbuffer_attachment *att;
  456.  
  457.          att = find_attachment(readFb, colorReadRb);
  458.          printf("  Src FBO %u  RB %u (%dx%d)  ",
  459.                 readFb->Name, colorReadRb->Name,
  460.                 colorReadRb->Width, colorReadRb->Height);
  461.          if (att && att->Texture) {
  462.             printf("Tex %u  tgt 0x%x  level %u  face %u",
  463.                    att->Texture->Name,
  464.                    att->Texture->Target,
  465.                    att->TextureLevel,
  466.                    att->CubeMapFace);
  467.          }
  468.          printf("\n");
  469.  
  470.          /* Print all active color render buffers */
  471.          for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) {
  472.             colorDrawRb = drawFb->_ColorDrawBuffers[i];
  473.             if (!colorDrawRb)
  474.                continue;
  475.  
  476.             att = find_attachment(drawFb, colorDrawRb);
  477.             printf("  Dst FBO %u  RB %u (%dx%d)  ",
  478.                    drawFb->Name, colorDrawRb->Name,
  479.                    colorDrawRb->Width, colorDrawRb->Height);
  480.             if (att && att->Texture) {
  481.                printf("Tex %u  tgt 0x%x  level %u  face %u",
  482.                       att->Texture->Name,
  483.                       att->Texture->Target,
  484.                       att->TextureLevel,
  485.                       att->CubeMapFace);
  486.             }
  487.             printf("\n");
  488.          }
  489.       }
  490.    }
  491.  
  492.    if (!mask ||
  493.        (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 ||
  494.        (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) {
  495.       return;
  496.    }
  497.  
  498.    assert(ctx->Driver.BlitFramebuffer);
  499.    ctx->Driver.BlitFramebuffer(ctx, readFb, drawFb,
  500.                                srcX0, srcY0, srcX1, srcY1,
  501.                                dstX0, dstY0, dstX1, dstY1,
  502.                                mask, filter);
  503. }
  504.  
  505.  
  506. /**
  507.  * Blit rectangular region, optionally from one framebuffer to another.
  508.  *
  509.  * Note, if the src buffer is multisampled and the dest is not, this is
  510.  * when the samples must be resolved to a single color.
  511.  */
  512. void GLAPIENTRY
  513. _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
  514.                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
  515.                       GLbitfield mask, GLenum filter)
  516. {
  517.    GET_CURRENT_CONTEXT(ctx);
  518.  
  519.    if (MESA_VERBOSE & VERBOSE_API)
  520.       _mesa_debug(ctx,
  521.                   "glBlitFramebuffer(%d, %d, %d, %d, "
  522.                   " %d, %d, %d, %d, 0x%x, %s)\n",
  523.                   srcX0, srcY0, srcX1, srcY1,
  524.                   dstX0, dstY0, dstX1, dstY1,
  525.                   mask, _mesa_lookup_enum_by_nr(filter));
  526.  
  527.    _mesa_blit_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
  528.                           srcX0, srcY0, srcX1, srcY1,
  529.                           dstX0, dstY0, dstX1, dstY1,
  530.                           mask, filter, "glBlitFramebuffer");
  531. }
  532.  
  533.  
  534. void GLAPIENTRY
  535. _mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer,
  536.                            GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
  537.                            GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
  538.                            GLbitfield mask, GLenum filter)
  539. {
  540.    GET_CURRENT_CONTEXT(ctx);
  541.    struct gl_framebuffer *readFb, *drawFb;
  542.  
  543.    if (!ctx->Extensions.ARB_direct_state_access) {
  544.       _mesa_error(ctx, GL_INVALID_OPERATION,
  545.                   "glBlitNamedFramebuffer(GL_ARB_direct_state_access "
  546.                   "is not supported)");
  547.       return;
  548.    }
  549.  
  550.    if (MESA_VERBOSE & VERBOSE_API)
  551.       _mesa_debug(ctx,
  552.                   "glBlitNamedFramebuffer(%u %u %d, %d, %d, %d, "
  553.                   " %d, %d, %d, %d, 0x%x, %s)\n",
  554.                   readFramebuffer, drawFramebuffer,
  555.                   srcX0, srcY0, srcX1, srcY1,
  556.                   dstX0, dstY0, dstX1, dstY1,
  557.                   mask, _mesa_lookup_enum_by_nr(filter));
  558.  
  559.    /*
  560.     * According to PDF page 533 of the OpenGL 4.5 core spec (30.10.2014,
  561.     * Section 18.3 Copying Pixels):
  562.     *   "... if readFramebuffer or drawFramebuffer is zero (for
  563.     *   BlitNamedFramebuffer), then the default read or draw framebuffer is
  564.     *   used as the corresponding source or destination framebuffer,
  565.     *   respectively."
  566.     */
  567.    if (readFramebuffer) {
  568.       readFb = _mesa_lookup_framebuffer_err(ctx, readFramebuffer,
  569.                                             "glBlitNamedFramebuffer");
  570.       if (!readFb)
  571.          return;
  572.    }
  573.    else
  574.       readFb = ctx->WinSysReadBuffer;
  575.  
  576.    if (drawFramebuffer) {
  577.       drawFb = _mesa_lookup_framebuffer_err(ctx, drawFramebuffer,
  578.                                             "glBlitNamedFramebuffer");
  579.       if (!drawFb)
  580.          return;
  581.    }
  582.    else
  583.       drawFb = ctx->WinSysDrawBuffer;
  584.  
  585.    _mesa_blit_framebuffer(ctx, readFb, drawFb,
  586.                           srcX0, srcY0, srcX1, srcY1,
  587.                           dstX0, dstY0, dstX1, dstY1,
  588.                           mask, filter, "glBlitNamedFramebuffer");
  589. }
  590.