2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 1999-2013 VMware, Inc. All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
27 * glBlitFramebuffer functions.
37 #include "framebuffer.h"
38 #include "glformats.h"
44 /** Set this to 1 to debug/log glBlitFramebuffer() calls */
49 static const struct gl_renderbuffer_attachment
*
50 find_attachment(const struct gl_framebuffer
*fb
,
51 const struct gl_renderbuffer
*rb
)
54 for (i
= 0; i
< ARRAY_SIZE(fb
->Attachment
); i
++) {
55 if (fb
->Attachment
[i
].Renderbuffer
== rb
)
56 return &fb
->Attachment
[i
];
63 * \return true if two regions overlap, false otherwise
66 _mesa_regions_overlap(int srcX0
, int srcY0
,
71 if (MAX2(srcX0
, srcX1
) <= MIN2(dstX0
, dstX1
))
72 return false; /* dst completely right of src */
74 if (MAX2(dstX0
, dstX1
) <= MIN2(srcX0
, srcX1
))
75 return false; /* dst completely left of src */
77 if (MAX2(srcY0
, srcY1
) <= MIN2(dstY0
, dstY1
))
78 return false; /* dst completely above src */
80 if (MAX2(dstY0
, dstY1
) <= MIN2(srcY0
, srcY1
))
81 return false; /* dst completely below src */
83 return true; /* some overlap */
88 * Helper function for checking if the datatypes of color buffers are
89 * compatible for glBlitFramebuffer. From the 3.1 spec, page 198:
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."
101 compatible_color_datatypes(mesa_format srcFormat
, mesa_format dstFormat
)
103 GLenum srcType
= _mesa_get_format_datatype(srcFormat
);
104 GLenum dstType
= _mesa_get_format_datatype(dstFormat
);
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 */
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 */
122 return srcType
== dstType
;
127 compatible_resolve_formats(const struct gl_renderbuffer
*readRb
,
128 const struct gl_renderbuffer
*drawRb
)
130 GLenum readFormat
, drawFormat
;
132 /* This checks whether the internal formats are compatible rather than the
133 * Mesa format for two reasons:
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.
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.
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
149 * Blits between linear and sRGB formats are also allowed.
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
);
156 if (readFormat
== drawFormat
) {
165 is_valid_blit_filter(const struct gl_context
*ctx
, GLenum filter
)
171 case GL_SCALED_RESOLVE_FASTEST_EXT
:
172 case GL_SCALED_RESOLVE_NICEST_EXT
:
173 return ctx
->Extensions
.EXT_framebuffer_multisample_blit_scaled
;
181 validate_color_buffer(struct gl_context
*ctx
, struct gl_framebuffer
*readFb
,
182 struct gl_framebuffer
*drawFb
, GLenum filter
,
185 const GLuint numColorDrawBuffers
= drawFb
->_NumColorDrawBuffers
;
186 const struct gl_renderbuffer
*colorReadRb
= readFb
->_ColorReadBuffer
;
187 const struct gl_renderbuffer
*colorDrawRb
= NULL
;
190 for (i
= 0; i
< numColorDrawBuffers
; i
++) {
191 colorDrawRb
= drawFb
->_ColorDrawBuffers
[i
];
195 /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL
196 * ES 3.0.1 spec says:
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."
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 "
211 if (!compatible_color_datatypes(colorReadRb
->Format
,
212 colorDrawRb
->Format
)) {
213 _mesa_error(ctx
, GL_INVALID_OPERATION
,
214 "%s(color buffer datatypes mismatch)", func
);
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:
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.”
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
);
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."
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
);
256 validate_stencil_buffer(struct gl_context
*ctx
, struct gl_framebuffer
*readFb
,
257 struct gl_framebuffer
*drawFb
, const char *func
)
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
;
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 "
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.
277 _mesa_error(ctx
, GL_INVALID_OPERATION
,
278 "%s(stencil attachment format mismatch)", func
);
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
);
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.
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
);
302 validate_depth_buffer(struct gl_context
*ctx
, struct gl_framebuffer
*readFb
,
303 struct gl_framebuffer
*drawFb
, const char *func
)
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
;
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)",
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
);
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
);
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.
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
);
343 static ALWAYS_INLINE
void
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
)
350 FLUSH_VERTICES(ctx
, 0);
352 if (!readFb
|| !drawFb
) {
353 /* This will normally never happen but someday we may want to
354 * support MakeCurrent() with no drawables.
359 /* Update completeness status of readFb and drawFb. */
360 _mesa_update_framebuffer(ctx
, readFb
, drawFb
);
362 /* Make sure drawFb has an initialized bounding box. */
363 _mesa_update_draw_buffer_bounds(ctx
, drawFb
);
366 const GLbitfield legalMaskBits
= (GL_COLOR_BUFFER_BIT
|
367 GL_DEPTH_BUFFER_BIT
|
368 GL_STENCIL_BUFFER_BIT
);
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
);
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
));
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
));
392 if (mask
& ~legalMaskBits
) {
393 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(invalid mask bits set)", func
);
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
);
405 if (_mesa_is_gles3(ctx
)) {
406 /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
409 * "If SAMPLE_BUFFERS for the draw framebuffer is greater than
410 * zero, an INVALID_OPERATION error is generated."
412 if (drawFb
->Visual
.samples
> 0) {
413 _mesa_error(ctx
, GL_INVALID_OPERATION
,
414 "%s(destination samples must be 0)", func
);
418 /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
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."
427 * The format check was made above because desktop OpenGL has the same
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
);
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
);
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
);
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
;
465 /* From the EXT_framebuffer_object spec:
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
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
))
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
;
485 /* From the EXT_framebuffer_object spec:
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
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
))
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
;
505 /* From the EXT_framebuffer_object spec:
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
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
))
521 const struct gl_renderbuffer
*colorReadRb
= readFb
->_ColorReadBuffer
;
522 const struct gl_renderbuffer
*colorDrawRb
= NULL
;
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
,
532 const struct gl_renderbuffer_attachment
*att
;
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",
541 att
->Texture
->Target
,
547 /* Print all active color render buffers */
548 for (i
= 0; i
< drawFb
->_NumColorDrawBuffers
; i
++) {
549 colorDrawRb
= drawFb
->_ColorDrawBuffers
[i
];
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",
560 att
->Texture
->Target
,
570 (srcX1
- srcX0
) == 0 || (srcY1
- srcY0
) == 0 ||
571 (dstX1
- dstX0
) == 0 || (dstY1
- dstY0
) == 0) {
575 assert(ctx
->Driver
.BlitFramebuffer
);
576 ctx
->Driver
.BlitFramebuffer(ctx
, readFb
, drawFb
,
577 srcX0
, srcY0
, srcX1
, srcY1
,
578 dstX0
, dstY0
, dstX1
, dstY1
,
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
)
591 /* We are wrapping the err variant of the always inlined
592 * blit_framebuffer() to avoid inlining it in every caller.
594 blit_framebuffer(ctx
, readFb
, drawFb
, srcX0
, srcY0
, srcX1
, srcY1
,
595 dstX0
, dstY0
, dstX1
, dstY1
, mask
, filter
, false, func
);
600 * Blit rectangular region, optionally from one framebuffer to another.
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.
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
)
611 GET_CURRENT_CONTEXT(ctx
);
613 blit_framebuffer(ctx
, ctx
->ReadBuffer
, ctx
->DrawBuffer
,
614 srcX0
, srcY0
, srcX1
, srcY1
,
615 dstX0
, dstY0
, dstX1
, dstY1
,
616 mask
, filter
, true, "glBlitFramebuffer");
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
)
625 GET_CURRENT_CONTEXT(ctx
);
627 if (MESA_VERBOSE
& VERBOSE_API
)
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
));
635 blit_framebuffer_err(ctx
, ctx
->ReadBuffer
, ctx
->DrawBuffer
,
636 srcX0
, srcY0
, srcX1
, srcY1
,
637 dstX0
, dstY0
, dstX1
, dstY1
,
638 mask
, filter
, "glBlitFramebuffer");
642 static ALWAYS_INLINE
void
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
)
649 struct gl_framebuffer
*readFb
, *drawFb
;
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,
659 if (readFramebuffer
) {
661 readFb
= _mesa_lookup_framebuffer(ctx
, readFramebuffer
);
663 readFb
= _mesa_lookup_framebuffer_err(ctx
, readFramebuffer
,
664 "glBlitNamedFramebuffer");
669 readFb
= ctx
->WinSysReadBuffer
;
672 if (drawFramebuffer
) {
674 drawFb
= _mesa_lookup_framebuffer(ctx
, drawFramebuffer
);
676 drawFb
= _mesa_lookup_framebuffer_err(ctx
, drawFramebuffer
,
677 "glBlitNamedFramebuffer");
682 drawFb
= ctx
->WinSysDrawBuffer
;
685 blit_framebuffer(ctx
, readFb
, drawFb
,
686 srcX0
, srcY0
, srcX1
, srcY1
,
687 dstX0
, dstY0
, dstX1
, dstY1
,
688 mask
, filter
, no_error
, "glBlitNamedFramebuffer");
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
)
701 GET_CURRENT_CONTEXT(ctx
);
703 blit_named_framebuffer(ctx
, readFramebuffer
, drawFramebuffer
,
704 srcX0
, srcY0
, srcX1
, srcY1
,
705 dstX0
, dstY0
, dstX1
, dstY1
,
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
)
716 GET_CURRENT_CONTEXT(ctx
);
718 if (MESA_VERBOSE
& VERBOSE_API
)
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
));
727 blit_named_framebuffer(ctx
, readFramebuffer
, drawFramebuffer
,
728 srcX0
, srcY0
, srcX1
, srcY1
,
729 dstX0
, dstY0
, dstX1
, dstY1
,
730 mask
, filter
, false);