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