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 *
find_attachment(const struct gl_framebuffer * fb,const struct gl_renderbuffer * rb)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
_mesa_regions_overlap(int srcX0,int srcY0,int srcX1,int srcY1,int dstX0,int dstY0,int dstX1,int dstY1)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
compatible_color_datatypes(mesa_format srcFormat,mesa_format dstFormat)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
compatible_resolve_formats(const struct gl_renderbuffer * readRb,const struct gl_renderbuffer * drawRb)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
is_valid_blit_filter(const struct gl_context * ctx,GLenum filter)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
_mesa_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,const char * func)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
_mesa_BlitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)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
_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)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