main: Add entry point for BlitNamedFramebuffer.
[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 "glformats.h"
38 #include "mtypes.h"
39 #include "state.h"
40
41
42 /** Set this to 1 to debug/log glBlitFramebuffer() calls */
43 #define DEBUG_BLIT 0
44
45
46
47 static const struct gl_renderbuffer_attachment *
48 find_attachment(const struct gl_framebuffer *fb,
49 const struct gl_renderbuffer *rb)
50 {
51 GLuint i;
52 for (i = 0; i < ARRAY_SIZE(fb->Attachment); i++) {
53 if (fb->Attachment[i].Renderbuffer == rb)
54 return &fb->Attachment[i];
55 }
56 return NULL;
57 }
58
59
60 /**
61 * Helper function for checking if the datatypes of color buffers are
62 * compatible for glBlitFramebuffer. From the 3.1 spec, page 198:
63 *
64 * "GL_INVALID_OPERATION is generated if mask contains GL_COLOR_BUFFER_BIT
65 * and any of the following conditions hold:
66 * - The read buffer contains fixed-point or floating-point values and any
67 * draw buffer contains neither fixed-point nor floating-point values.
68 * - The read buffer contains unsigned integer values and any draw buffer
69 * does not contain unsigned integer values.
70 * - The read buffer contains signed integer values and any draw buffer
71 * does not contain signed integer values."
72 */
73 static GLboolean
74 compatible_color_datatypes(mesa_format srcFormat, mesa_format dstFormat)
75 {
76 GLenum srcType = _mesa_get_format_datatype(srcFormat);
77 GLenum dstType = _mesa_get_format_datatype(dstFormat);
78
79 if (srcType != GL_INT && srcType != GL_UNSIGNED_INT) {
80 assert(srcType == GL_UNSIGNED_NORMALIZED ||
81 srcType == GL_SIGNED_NORMALIZED ||
82 srcType == GL_FLOAT);
83 /* Boil any of those types down to GL_FLOAT */
84 srcType = GL_FLOAT;
85 }
86
87 if (dstType != GL_INT && dstType != GL_UNSIGNED_INT) {
88 assert(dstType == GL_UNSIGNED_NORMALIZED ||
89 dstType == GL_SIGNED_NORMALIZED ||
90 dstType == GL_FLOAT);
91 /* Boil any of those types down to GL_FLOAT */
92 dstType = GL_FLOAT;
93 }
94
95 return srcType == dstType;
96 }
97
98
99 static GLboolean
100 compatible_resolve_formats(const struct gl_renderbuffer *readRb,
101 const struct gl_renderbuffer *drawRb)
102 {
103 GLenum readFormat, drawFormat;
104
105 /* The simple case where we know the backing Mesa formats are the same.
106 */
107 if (_mesa_get_srgb_format_linear(readRb->Format) ==
108 _mesa_get_srgb_format_linear(drawRb->Format)) {
109 return GL_TRUE;
110 }
111
112 /* The Mesa formats are different, so we must check whether the internal
113 * formats are compatible.
114 *
115 * Under some circumstances, the user may request e.g. two GL_RGBA8
116 * textures and get two entirely different Mesa formats like RGBA8888 and
117 * ARGB8888. Drivers behaving like that should be able to cope with
118 * non-matching formats by themselves, because it's not the user's fault.
119 *
120 * Blits between linear and sRGB formats are also allowed.
121 */
122 readFormat = _mesa_get_nongeneric_internalformat(readRb->InternalFormat);
123 drawFormat = _mesa_get_nongeneric_internalformat(drawRb->InternalFormat);
124 readFormat = _mesa_get_linear_internalformat(readFormat);
125 drawFormat = _mesa_get_linear_internalformat(drawFormat);
126
127 if (readFormat == drawFormat) {
128 return GL_TRUE;
129 }
130
131 return GL_FALSE;
132 }
133
134
135 static GLboolean
136 is_valid_blit_filter(const struct gl_context *ctx, GLenum filter)
137 {
138 switch (filter) {
139 case GL_NEAREST:
140 case GL_LINEAR:
141 return true;
142 case GL_SCALED_RESOLVE_FASTEST_EXT:
143 case GL_SCALED_RESOLVE_NICEST_EXT:
144 return ctx->Extensions.EXT_framebuffer_multisample_blit_scaled;
145 default:
146 return false;
147 }
148 }
149
150
151 void
152 _mesa_blit_framebuffer(struct gl_context *ctx,
153 struct gl_framebuffer *readFb,
154 struct gl_framebuffer *drawFb,
155 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
156 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
157 GLbitfield mask, GLenum filter, const char *func)
158 {
159 const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
160 GL_DEPTH_BUFFER_BIT |
161 GL_STENCIL_BUFFER_BIT);
162
163 FLUSH_VERTICES(ctx, 0);
164
165 if (ctx->NewState) {
166 _mesa_update_state(ctx);
167 }
168
169 if (!readFb || !drawFb) {
170 /* This will normally never happen but someday we may want to
171 * support MakeCurrent() with no drawables.
172 */
173 return;
174 }
175
176 /* check for complete framebuffers */
177 if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
178 readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
179 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
180 "%s(incomplete draw/read buffers)", func);
181 return;
182 }
183
184 if (!is_valid_blit_filter(ctx, filter)) {
185 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid filter %s)", func,
186 _mesa_lookup_enum_by_nr(filter));
187 return;
188 }
189
190 if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
191 filter == GL_SCALED_RESOLVE_NICEST_EXT) &&
192 (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) {
193 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s: invalid samples)", func,
194 _mesa_lookup_enum_by_nr(filter));
195 return;
196 }
197
198 if (mask & ~legalMaskBits) {
199 _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid mask bits set)", func);
200 return;
201 }
202
203 /* depth/stencil must be blitted with nearest filtering */
204 if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
205 && filter != GL_NEAREST) {
206 _mesa_error(ctx, GL_INVALID_OPERATION,
207 "%s(depth/stencil requires GL_NEAREST filter)", func);
208 return;
209 }
210
211 /* get color read/draw renderbuffers */
212 if (mask & GL_COLOR_BUFFER_BIT) {
213 const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
214 const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
215 const struct gl_renderbuffer *colorDrawRb = NULL;
216 GLuint i;
217
218 /* From the EXT_framebuffer_object spec:
219 *
220 * "If a buffer is specified in <mask> and does not exist in both
221 * the read and draw framebuffers, the corresponding bit is silently
222 * ignored."
223 */
224 if (!colorReadRb || numColorDrawBuffers == 0) {
225 mask &= ~GL_COLOR_BUFFER_BIT;
226 }
227 else {
228 for (i = 0; i < numColorDrawBuffers; i++) {
229 colorDrawRb = drawFb->_ColorDrawBuffers[i];
230 if (!colorDrawRb)
231 continue;
232
233 /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL
234 * ES 3.0.1 spec says:
235 *
236 * "If the source and destination buffers are identical, an
237 * INVALID_OPERATION error is generated. Different mipmap
238 * levels of a texture, different layers of a three-
239 * dimensional texture or two-dimensional array texture, and
240 * different faces of a cube map texture do not constitute
241 * identical buffers."
242 */
243 if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) {
244 _mesa_error(ctx, GL_INVALID_OPERATION,
245 "%s(source and destination color "
246 "buffer cannot be the same)", func);
247 return;
248 }
249
250 if (!compatible_color_datatypes(colorReadRb->Format,
251 colorDrawRb->Format)) {
252 _mesa_error(ctx, GL_INVALID_OPERATION,
253 "%s(color buffer datatypes mismatch)", func);
254 return;
255 }
256 /* extra checks for multisample copies... */
257 if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) {
258 /* color formats must match */
259 if (!compatible_resolve_formats(colorReadRb, colorDrawRb)) {
260 _mesa_error(ctx, GL_INVALID_OPERATION,
261 "%s(bad src/dst multisample pixel formats)", func);
262 return;
263 }
264 }
265 }
266 if (filter != GL_NEAREST) {
267 /* From EXT_framebuffer_multisample_blit_scaled specification:
268 * "Calling BlitFramebuffer will result in an INVALID_OPERATION error
269 * if filter is not NEAREST and read buffer contains integer data."
270 */
271 GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
272 if (type == GL_INT || type == GL_UNSIGNED_INT) {
273 _mesa_error(ctx, GL_INVALID_OPERATION,
274 "%s(integer color type)", func);
275 return;
276 }
277 }
278 }
279 }
280
281 if (mask & GL_STENCIL_BUFFER_BIT) {
282 struct gl_renderbuffer *readRb =
283 readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
284 struct gl_renderbuffer *drawRb =
285 drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;
286
287 /* From the EXT_framebuffer_object spec:
288 *
289 * "If a buffer is specified in <mask> and does not exist in both
290 * the read and draw framebuffers, the corresponding bit is silently
291 * ignored."
292 */
293 if ((readRb == NULL) || (drawRb == NULL)) {
294 mask &= ~GL_STENCIL_BUFFER_BIT;
295 }
296 else {
297 int read_z_bits, draw_z_bits;
298
299 if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
300 _mesa_error(ctx, GL_INVALID_OPERATION,
301 "%s(source and destination stencil "
302 "buffer cannot be the same)", func);
303 return;
304 }
305
306 if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
307 _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
308 /* There is no need to check the stencil datatype here, because
309 * there is only one: GL_UNSIGNED_INT.
310 */
311 _mesa_error(ctx, GL_INVALID_OPERATION,
312 "%s(stencil attachment format mismatch)", func);
313 return;
314 }
315
316 read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS);
317 draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS);
318
319 /* If both buffers also have depth data, the depth formats must match
320 * as well. If one doesn't have depth, it's not blitted, so we should
321 * ignore the depth format check.
322 */
323 if (read_z_bits > 0 && draw_z_bits > 0 &&
324 (read_z_bits != draw_z_bits ||
325 _mesa_get_format_datatype(readRb->Format) !=
326 _mesa_get_format_datatype(drawRb->Format))) {
327
328 _mesa_error(ctx, GL_INVALID_OPERATION,
329 "%s(stencil attachment depth format mismatch)", func);
330 return;
331 }
332 }
333 }
334
335 if (mask & GL_DEPTH_BUFFER_BIT) {
336 struct gl_renderbuffer *readRb =
337 readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
338 struct gl_renderbuffer *drawRb =
339 drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
340
341 /* From the EXT_framebuffer_object spec:
342 *
343 * "If a buffer is specified in <mask> and does not exist in both
344 * the read and draw framebuffers, the corresponding bit is silently
345 * ignored."
346 */
347 if ((readRb == NULL) || (drawRb == NULL)) {
348 mask &= ~GL_DEPTH_BUFFER_BIT;
349 }
350 else {
351 int read_s_bit, draw_s_bit;
352
353 if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
354 _mesa_error(ctx, GL_INVALID_OPERATION,
355 "%s(source and destination depth "
356 "buffer cannot be the same)", func);
357 return;
358 }
359
360 if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
361 _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) ||
362 (_mesa_get_format_datatype(readRb->Format) !=
363 _mesa_get_format_datatype(drawRb->Format))) {
364 _mesa_error(ctx, GL_INVALID_OPERATION,
365 "%s(depth attachment format mismatch)", func);
366 return;
367 }
368
369 read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS);
370 draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS);
371
372 /* If both buffers also have stencil data, the stencil formats must
373 * match as well. If one doesn't have stencil, it's not blitted, so
374 * we should ignore the stencil format check.
375 */
376 if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) {
377 _mesa_error(ctx, GL_INVALID_OPERATION,
378 "%s(depth attachment stencil bits mismatch)", func);
379 return;
380 }
381 }
382 }
383
384
385 if (_mesa_is_gles3(ctx)) {
386 /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
387 * 3.0.1 spec says:
388 *
389 * "If SAMPLE_BUFFERS for the draw framebuffer is greater than zero,
390 * an INVALID_OPERATION error is generated."
391 */
392 if (drawFb->Visual.samples > 0) {
393 _mesa_error(ctx, GL_INVALID_OPERATION,
394 "%s(destination samples must be 0)", func);
395 return;
396 }
397
398 /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
399 * 3.0.1 spec says:
400 *
401 * "If SAMPLE_BUFFERS for the read framebuffer is greater than zero,
402 * no copy is performed and an INVALID_OPERATION error is generated
403 * if the formats of the read and draw framebuffers are not
404 * identical or if the source and destination rectangles are not
405 * defined with the same (X0, Y0) and (X1, Y1) bounds."
406 *
407 * The format check was made above because desktop OpenGL has the same
408 * requirement.
409 */
410 if (readFb->Visual.samples > 0
411 && (srcX0 != dstX0 || srcY0 != dstY0
412 || srcX1 != dstX1 || srcY1 != dstY1)) {
413 _mesa_error(ctx, GL_INVALID_OPERATION,
414 "%s(bad src/dst multisample region)", func);
415 return;
416 }
417 } else {
418 if (readFb->Visual.samples > 0 &&
419 drawFb->Visual.samples > 0 &&
420 readFb->Visual.samples != drawFb->Visual.samples) {
421 _mesa_error(ctx, GL_INVALID_OPERATION,
422 "%s(mismatched samples)", func);
423 return;
424 }
425
426 /* extra checks for multisample copies... */
427 if ((readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) &&
428 (filter == GL_NEAREST || filter == GL_LINEAR)) {
429 /* src and dest region sizes must be the same */
430 if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) ||
431 abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) {
432 _mesa_error(ctx, GL_INVALID_OPERATION,
433 "%s(bad src/dst multisample region sizes)", func);
434 return;
435 }
436 }
437 }
438
439 /* Debug code */
440 if (DEBUG_BLIT) {
441 const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
442 const struct gl_renderbuffer *colorDrawRb = NULL;
443 GLuint i = 0;
444
445 printf("%s(%d, %d, %d, %d, %d, %d, %d, %d,"
446 " 0x%x, 0x%x)\n", func,
447 srcX0, srcY0, srcX1, srcY1,
448 dstX0, dstY0, dstX1, dstY1,
449 mask, filter);
450
451 if (colorReadRb) {
452 const struct gl_renderbuffer_attachment *att;
453
454 att = find_attachment(readFb, colorReadRb);
455 printf(" Src FBO %u RB %u (%dx%d) ",
456 readFb->Name, colorReadRb->Name,
457 colorReadRb->Width, colorReadRb->Height);
458 if (att && att->Texture) {
459 printf("Tex %u tgt 0x%x level %u face %u",
460 att->Texture->Name,
461 att->Texture->Target,
462 att->TextureLevel,
463 att->CubeMapFace);
464 }
465 printf("\n");
466
467 /* Print all active color render buffers */
468 for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) {
469 colorDrawRb = drawFb->_ColorDrawBuffers[i];
470 if (!colorDrawRb)
471 continue;
472
473 att = find_attachment(drawFb, colorDrawRb);
474 printf(" Dst FBO %u RB %u (%dx%d) ",
475 drawFb->Name, colorDrawRb->Name,
476 colorDrawRb->Width, colorDrawRb->Height);
477 if (att && att->Texture) {
478 printf("Tex %u tgt 0x%x level %u face %u",
479 att->Texture->Name,
480 att->Texture->Target,
481 att->TextureLevel,
482 att->CubeMapFace);
483 }
484 printf("\n");
485 }
486 }
487 }
488
489 if (!mask ||
490 (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 ||
491 (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) {
492 return;
493 }
494
495 assert(ctx->Driver.BlitFramebuffer);
496 ctx->Driver.BlitFramebuffer(ctx, readFb, drawFb,
497 srcX0, srcY0, srcX1, srcY1,
498 dstX0, dstY0, dstX1, dstY1,
499 mask, filter);
500 }
501
502
503 /**
504 * Blit rectangular region, optionally from one framebuffer to another.
505 *
506 * Note, if the src buffer is multisampled and the dest is not, this is
507 * when the samples must be resolved to a single color.
508 */
509 void GLAPIENTRY
510 _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
511 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
512 GLbitfield mask, GLenum filter)
513 {
514 GET_CURRENT_CONTEXT(ctx);
515
516 if (MESA_VERBOSE & VERBOSE_API)
517 _mesa_debug(ctx,
518 "glBlitFramebuffer(%d, %d, %d, %d, "
519 " %d, %d, %d, %d, 0x%x, %s)\n",
520 srcX0, srcY0, srcX1, srcY1,
521 dstX0, dstY0, dstX1, dstY1,
522 mask, _mesa_lookup_enum_by_nr(filter));
523
524 _mesa_blit_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
525 srcX0, srcY0, srcX1, srcY1,
526 dstX0, dstY0, dstX1, dstY1,
527 mask, filter, "glBlitFramebuffer");
528 }
529
530
531 void GLAPIENTRY
532 _mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer,
533 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
534 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
535 GLbitfield mask, GLenum filter)
536 {
537 GET_CURRENT_CONTEXT(ctx);
538 struct gl_framebuffer *readFb, *drawFb;
539
540 if (MESA_VERBOSE & VERBOSE_API)
541 _mesa_debug(ctx,
542 "glBlitNamedFramebuffer(%u %u %d, %d, %d, %d, "
543 " %d, %d, %d, %d, 0x%x, %s)\n",
544 readFramebuffer, drawFramebuffer,
545 srcX0, srcY0, srcX1, srcY1,
546 dstX0, dstY0, dstX1, dstY1,
547 mask, _mesa_lookup_enum_by_nr(filter));
548
549 /*
550 * According to PDF page 533 of the OpenGL 4.5 core spec (30.10.2014,
551 * Section 18.3 Copying Pixels):
552 * "... if readFramebuffer or drawFramebuffer is zero (for
553 * BlitNamedFramebuffer), then the default read or draw framebuffer is
554 * used as the corresponding source or destination framebuffer,
555 * respectively."
556 */
557 if (readFramebuffer) {
558 readFb = _mesa_lookup_framebuffer_err(ctx, readFramebuffer,
559 "glBlitNamedFramebuffer");
560 if (!readFb)
561 return;
562 }
563 else
564 readFb = ctx->WinSysReadBuffer;
565
566 if (drawFramebuffer) {
567 drawFb = _mesa_lookup_framebuffer_err(ctx, drawFramebuffer,
568 "glBlitNamedFramebuffer");
569 if (!drawFb)
570 return;
571 }
572 else
573 drawFb = ctx->WinSysDrawBuffer;
574
575 _mesa_blit_framebuffer(ctx, readFb, drawFb,
576 srcX0, srcY0, srcX1, srcY1,
577 dstX0, dstY0, dstX1, dstY1,
578 mask, filter, "glBlitNamedFramebuffer");
579 }