mesa: add blit_named_framebuffer() helper
[mesa.git] / src / mesa / main / blit.c
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 *
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
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
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
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
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
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
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
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
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 /* Update completeness status of readFb and drawFb. */
353 _mesa_update_framebuffer(ctx, readFb, drawFb);
354
355 /* Make sure drawFb has an initialized bounding box. */
356 _mesa_update_draw_buffer_bounds(ctx, drawFb);
357
358 if (!readFb || !drawFb) {
359 /* This will normally never happen but someday we may want to
360 * support MakeCurrent() with no drawables.
361 */
362 return;
363 }
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
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
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
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
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
693 _mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer,
694 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
695 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
696 GLbitfield mask, GLenum filter)
697 {
698 GET_CURRENT_CONTEXT(ctx);
699
700 if (MESA_VERBOSE & VERBOSE_API)
701 _mesa_debug(ctx,
702 "glBlitNamedFramebuffer(%u %u %d, %d, %d, %d, "
703 " %d, %d, %d, %d, 0x%x, %s)\n",
704 readFramebuffer, drawFramebuffer,
705 srcX0, srcY0, srcX1, srcY1,
706 dstX0, dstY0, dstX1, dstY1,
707 mask, _mesa_enum_to_string(filter));
708
709 blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer,
710 srcX0, srcY0, srcX1, srcY1,
711 dstX0, dstY0, dstX1, dstY1,
712 mask, filter, false);
713 }