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