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