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 "image.h"
40 #include "mtypes.h"
41 #include "macros.h"
42 #include "readpix.h"
43 #include "renderbuffer.h"
44 #include "state.h"
45 #include "api_exec_decl.h"
46
47 #include "state_tracker/st_cb_bitmap.h"
48 #include "state_tracker/st_cb_texture.h"
49 #include "state_tracker/st_manager.h"
50 #include "state_tracker/st_context.h"
51 #include "state_tracker/st_scissor.h"
52 #include "state_tracker/st_texture.h"
53 #include "state_tracker/st_util.h"
54
55 /** Set this to 1 to debug/log glBlitFramebuffer() calls */
56 #define DEBUG_BLIT 0
57
58
59
60 static const struct gl_renderbuffer_attachment *
find_attachment(const struct gl_framebuffer * fb,const struct gl_renderbuffer * rb)61 find_attachment(const struct gl_framebuffer *fb,
62 const struct gl_renderbuffer *rb)
63 {
64 GLuint i;
65 for (i = 0; i < ARRAY_SIZE(fb->Attachment); i++) {
66 if (fb->Attachment[i].Renderbuffer == rb)
67 return &fb->Attachment[i];
68 }
69 return NULL;
70 }
71
72
73 /**
74 * \return true if two regions overlap, false otherwise
75 */
76 bool
_mesa_regions_overlap(int srcX0,int srcY0,int srcX1,int srcY1,int dstX0,int dstY0,int dstX1,int dstY1)77 _mesa_regions_overlap(int srcX0, int srcY0,
78 int srcX1, int srcY1,
79 int dstX0, int dstY0,
80 int dstX1, int dstY1)
81 {
82 if (MAX2(srcX0, srcX1) <= MIN2(dstX0, dstX1))
83 return false; /* dst completely right of src */
84
85 if (MAX2(dstX0, dstX1) <= MIN2(srcX0, srcX1))
86 return false; /* dst completely left of src */
87
88 if (MAX2(srcY0, srcY1) <= MIN2(dstY0, dstY1))
89 return false; /* dst completely above src */
90
91 if (MAX2(dstY0, dstY1) <= MIN2(srcY0, srcY1))
92 return false; /* dst completely below src */
93
94 return true; /* some overlap */
95 }
96
97
98 /**
99 * Helper function for checking if the datatypes of color buffers are
100 * compatible for glBlitFramebuffer. From the 3.1 spec, page 198:
101 *
102 * "GL_INVALID_OPERATION is generated if mask contains GL_COLOR_BUFFER_BIT
103 * and any of the following conditions hold:
104 * - The read buffer contains fixed-point or floating-point values and any
105 * draw buffer contains neither fixed-point nor floating-point values.
106 * - The read buffer contains unsigned integer values and any draw buffer
107 * does not contain unsigned integer values.
108 * - The read buffer contains signed integer values and any draw buffer
109 * does not contain signed integer values."
110 */
111 static GLboolean
compatible_color_datatypes(mesa_format srcFormat,mesa_format dstFormat)112 compatible_color_datatypes(mesa_format srcFormat, mesa_format dstFormat)
113 {
114 GLenum srcType = _mesa_get_format_datatype(srcFormat);
115 GLenum dstType = _mesa_get_format_datatype(dstFormat);
116
117 if (srcType != GL_INT && srcType != GL_UNSIGNED_INT) {
118 assert(srcType == GL_UNSIGNED_NORMALIZED ||
119 srcType == GL_SIGNED_NORMALIZED ||
120 srcType == GL_FLOAT);
121 /* Boil any of those types down to GL_FLOAT */
122 srcType = GL_FLOAT;
123 }
124
125 if (dstType != GL_INT && dstType != GL_UNSIGNED_INT) {
126 assert(dstType == GL_UNSIGNED_NORMALIZED ||
127 dstType == GL_SIGNED_NORMALIZED ||
128 dstType == GL_FLOAT);
129 /* Boil any of those types down to GL_FLOAT */
130 dstType = GL_FLOAT;
131 }
132
133 return srcType == dstType;
134 }
135
136
137 static GLboolean
compatible_resolve_formats(const struct gl_renderbuffer * readRb,const struct gl_renderbuffer * drawRb)138 compatible_resolve_formats(const struct gl_renderbuffer *readRb,
139 const struct gl_renderbuffer *drawRb)
140 {
141 GLenum readFormat, drawFormat;
142
143 /* This checks whether the internal formats are compatible rather than the
144 * Mesa format for two reasons:
145 *
146 * • Under some circumstances, the user may request e.g. two GL_RGBA8
147 * textures and get two entirely different Mesa formats like RGBA8888 and
148 * ARGB8888. Drivers behaving like that should be able to cope with
149 * non-matching formats by themselves, because it's not the user's fault.
150 *
151 * • Picking two different internal formats can end up with the same Mesa
152 * format. For example the driver might be simulating GL_RGB textures
153 * with GL_RGBA internally and in that case both internal formats would
154 * end up with RGBA8888.
155 *
156 * This function is used to generate a GL error according to the spec so in
157 * both cases we want to be looking at the application-level format, which
158 * is InternalFormat.
159 *
160 * Blits between linear and sRGB formats are also allowed.
161 */
162 readFormat = _mesa_get_nongeneric_internalformat(readRb->InternalFormat);
163 drawFormat = _mesa_get_nongeneric_internalformat(drawRb->InternalFormat);
164 readFormat = _mesa_get_linear_internalformat(readFormat);
165 drawFormat = _mesa_get_linear_internalformat(drawFormat);
166
167 if (readFormat == drawFormat) {
168 return GL_TRUE;
169 }
170
171 return GL_FALSE;
172 }
173
174
175 static GLboolean
is_valid_blit_filter(const struct gl_context * ctx,GLenum filter)176 is_valid_blit_filter(const struct gl_context *ctx, GLenum filter)
177 {
178 switch (filter) {
179 case GL_NEAREST:
180 case GL_LINEAR:
181 return true;
182 case GL_SCALED_RESOLVE_FASTEST_EXT:
183 case GL_SCALED_RESOLVE_NICEST_EXT:
184 return ctx->Extensions.EXT_framebuffer_multisample_blit_scaled;
185 default:
186 return false;
187 }
188 }
189
190
191 static bool
validate_color_buffer(struct gl_context * ctx,struct gl_framebuffer * readFb,struct gl_framebuffer * drawFb,GLenum filter,const char * func)192 validate_color_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb,
193 struct gl_framebuffer *drawFb, GLenum filter,
194 const char *func)
195 {
196 const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
197 const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
198 const struct gl_renderbuffer *colorDrawRb = NULL;
199 GLuint i;
200
201 for (i = 0; i < numColorDrawBuffers; i++) {
202 colorDrawRb = drawFb->_ColorDrawBuffers[i];
203 if (!colorDrawRb)
204 continue;
205
206 /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL
207 * ES 3.0.1 spec says:
208 *
209 * "If the source and destination buffers are identical, an
210 * INVALID_OPERATION error is generated. Different mipmap levels of a
211 * texture, different layers of a three- dimensional texture or
212 * two-dimensional array texture, and different faces of a cube map
213 * texture do not constitute identical buffers."
214 */
215 if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) {
216 _mesa_error(ctx, GL_INVALID_OPERATION,
217 "%s(source and destination color buffer cannot be the "
218 "same)", func);
219 return false;
220 }
221
222 if (!compatible_color_datatypes(colorReadRb->Format,
223 colorDrawRb->Format)) {
224 _mesa_error(ctx, GL_INVALID_OPERATION,
225 "%s(color buffer datatypes mismatch)", func);
226 return false;
227 }
228
229 /* extra checks for multisample copies... */
230 if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) {
231 /* color formats must match on GLES. This isn't checked on desktop GL
232 * because the GL 4.4 spec was changed to allow it. In the section
233 * entitled “Changes in the released
234 * Specification of July 22, 2013” it says:
235 *
236 * “Relax BlitFramebuffer in section 18.3.1 so that format conversion
237 * can take place during multisample blits, since drivers already
238 * allow this and some apps depend on it.”
239 */
240 if (_mesa_is_gles(ctx) &&
241 !compatible_resolve_formats(colorReadRb, colorDrawRb)) {
242 _mesa_error(ctx, GL_INVALID_OPERATION,
243 "%s(bad src/dst multisample pixel formats)", func);
244 return false;
245 }
246 }
247
248 }
249
250 if (filter != GL_NEAREST) {
251 /* From EXT_framebuffer_multisample_blit_scaled specification:
252 * "Calling BlitFramebuffer will result in an INVALID_OPERATION error if
253 * filter is not NEAREST and read buffer contains integer data."
254 */
255 GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
256 if (type == GL_INT || type == GL_UNSIGNED_INT) {
257 _mesa_error(ctx, GL_INVALID_OPERATION,
258 "%s(integer color type)", func);
259 return false;
260 }
261 }
262 return true;
263 }
264
265
266 static bool
validate_stencil_buffer(struct gl_context * ctx,struct gl_framebuffer * readFb,struct gl_framebuffer * drawFb,const char * func)267 validate_stencil_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb,
268 struct gl_framebuffer *drawFb, const char *func)
269 {
270 struct gl_renderbuffer *readRb =
271 readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
272 struct gl_renderbuffer *drawRb =
273 drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;
274 int read_z_bits, draw_z_bits;
275
276 if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
277 _mesa_error(ctx, GL_INVALID_OPERATION,
278 "%s(source and destination stencil buffer cannot be the "
279 "same)", func);
280 return false;
281 }
282
283 if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
284 _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
285 /* There is no need to check the stencil datatype here, because
286 * there is only one: GL_UNSIGNED_INT.
287 */
288 _mesa_error(ctx, GL_INVALID_OPERATION,
289 "%s(stencil attachment format mismatch)", func);
290 return false;
291 }
292
293 read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS);
294 draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS);
295
296 /* If both buffers also have depth data, the depth formats must match
297 * as well. If one doesn't have depth, it's not blitted, so we should
298 * ignore the depth format check.
299 */
300 if (read_z_bits > 0 && draw_z_bits > 0 &&
301 (read_z_bits != draw_z_bits ||
302 _mesa_get_format_datatype(readRb->Format) !=
303 _mesa_get_format_datatype(drawRb->Format))) {
304 _mesa_error(ctx, GL_INVALID_OPERATION,
305 "%s(stencil attachment depth format mismatch)", func);
306 return false;
307 }
308 return true;
309 }
310
311
312 static bool
validate_depth_buffer(struct gl_context * ctx,struct gl_framebuffer * readFb,struct gl_framebuffer * drawFb,const char * func)313 validate_depth_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb,
314 struct gl_framebuffer *drawFb, const char *func)
315 {
316 struct gl_renderbuffer *readRb =
317 readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
318 struct gl_renderbuffer *drawRb =
319 drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
320 int read_s_bit, draw_s_bit;
321
322 if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
323 _mesa_error(ctx, GL_INVALID_OPERATION,
324 "%s(source and destination depth buffer cannot be the same)",
325 func);
326 return false;
327 }
328
329 if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
330 _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) ||
331 (_mesa_get_format_datatype(readRb->Format) !=
332 _mesa_get_format_datatype(drawRb->Format))) {
333 _mesa_error(ctx, GL_INVALID_OPERATION,
334 "%s(depth attachment format mismatch)", func);
335 return false;
336 }
337
338 read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS);
339 draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS);
340
341 /* If both buffers also have stencil data, the stencil formats must match as
342 * well. If one doesn't have stencil, it's not blitted, so we should ignore
343 * the stencil format check.
344 */
345 if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) {
346 _mesa_error(ctx, GL_INVALID_OPERATION,
347 "%s(depth attachment stencil bits mismatch)", func);
348 return false;
349 }
350 return true;
351 }
352
353
354 static void
do_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)355 do_blit_framebuffer(struct gl_context *ctx,
356 struct gl_framebuffer *readFB,
357 struct gl_framebuffer *drawFB,
358 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
359 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
360 GLbitfield mask, GLenum filter)
361 {
362 struct st_context *st = st_context(ctx);
363 const GLbitfield depthStencil = (GL_DEPTH_BUFFER_BIT |
364 GL_STENCIL_BUFFER_BIT);
365 const uint pFilter = ((filter == GL_NEAREST)
366 ? PIPE_TEX_FILTER_NEAREST
367 : PIPE_TEX_FILTER_LINEAR);
368 struct {
369 GLint srcX0, srcY0, srcX1, srcY1;
370 GLint dstX0, dstY0, dstX1, dstY1;
371 } clip;
372 struct pipe_blit_info blit;
373
374 st_manager_validate_framebuffers(st);
375
376 /* Make sure bitmap rendering has landed in the framebuffers */
377 st_flush_bitmap_cache(st);
378 st_invalidate_readpix_cache(st);
379
380 clip.srcX0 = srcX0;
381 clip.srcY0 = srcY0;
382 clip.srcX1 = srcX1;
383 clip.srcY1 = srcY1;
384 clip.dstX0 = dstX0;
385 clip.dstY0 = dstY0;
386 clip.dstX1 = dstX1;
387 clip.dstY1 = dstY1;
388
389 /* NOTE: If the src and dst dimensions don't match, we cannot simply adjust
390 * the integer coordinates to account for clipping (or scissors) because that
391 * would make us cut off fractional parts, affecting the result of the blit.
392 *
393 * XXX: This should depend on mask !
394 */
395 if (!_mesa_clip_blit(ctx, readFB, drawFB,
396 &clip.srcX0, &clip.srcY0, &clip.srcX1, &clip.srcY1,
397 &clip.dstX0, &clip.dstY0, &clip.dstX1, &clip.dstY1)) {
398 return; /* nothing to draw/blit */
399 }
400 memset(&blit, 0, sizeof(struct pipe_blit_info));
401 blit.scissor_enable =
402 (dstX0 != clip.dstX0) ||
403 (dstY0 != clip.dstY0) ||
404 (dstX1 != clip.dstX1) ||
405 (dstY1 != clip.dstY1);
406
407 if (_mesa_fb_orientation(drawFB) == Y_0_TOP) {
408 /* invert Y for dest */
409 dstY0 = drawFB->Height - dstY0;
410 dstY1 = drawFB->Height - dstY1;
411 /* invert Y for clip */
412 clip.dstY0 = drawFB->Height - clip.dstY0;
413 clip.dstY1 = drawFB->Height - clip.dstY1;
414 }
415 if (blit.scissor_enable) {
416 blit.scissor.minx = MIN2(clip.dstX0, clip.dstX1);
417 blit.scissor.miny = MIN2(clip.dstY0, clip.dstY1);
418 blit.scissor.maxx = MAX2(clip.dstX0, clip.dstX1);
419 blit.scissor.maxy = MAX2(clip.dstY0, clip.dstY1);
420 #if 0
421 debug_printf("scissor = (%i,%i)-(%i,%i)\n",
422 blit.scissor.minx,blit.scissor.miny,
423 blit.scissor.maxx,blit.scissor.maxy);
424 #endif
425 }
426
427 if (_mesa_fb_orientation(readFB) == Y_0_TOP) {
428 /* invert Y for src */
429 srcY0 = readFB->Height - srcY0;
430 srcY1 = readFB->Height - srcY1;
431 }
432
433 if (srcY0 > srcY1 && dstY0 > dstY1) {
434 /* Both src and dst are upside down. Swap Y to make it
435 * right-side up to increase odds of using a fast path.
436 * Recall that all Gallium raster coords have Y=0=top.
437 */
438 GLint tmp;
439 tmp = srcY0;
440 srcY0 = srcY1;
441 srcY1 = tmp;
442 tmp = dstY0;
443 dstY0 = dstY1;
444 dstY1 = tmp;
445 }
446
447 blit.src.box.depth = 1;
448 blit.dst.box.depth = 1;
449
450 /* Destination dimensions have to be positive: */
451 if (dstX0 < dstX1) {
452 blit.dst.box.x = dstX0;
453 blit.src.box.x = srcX0;
454 blit.dst.box.width = dstX1 - dstX0;
455 blit.src.box.width = srcX1 - srcX0;
456 } else {
457 blit.dst.box.x = dstX1;
458 blit.src.box.x = srcX1;
459 blit.dst.box.width = dstX0 - dstX1;
460 blit.src.box.width = srcX0 - srcX1;
461 }
462 if (dstY0 < dstY1) {
463 blit.dst.box.y = dstY0;
464 blit.src.box.y = srcY0;
465 blit.dst.box.height = dstY1 - dstY0;
466 blit.src.box.height = srcY1 - srcY0;
467 } else {
468 blit.dst.box.y = dstY1;
469 blit.src.box.y = srcY1;
470 blit.dst.box.height = dstY0 - dstY1;
471 blit.src.box.height = srcY0 - srcY1;
472 }
473
474 if (drawFB != ctx->WinSysDrawBuffer)
475 st_window_rectangles_to_blit(ctx, &blit);
476
477 blit.filter = pFilter;
478 blit.render_condition_enable = st->has_conditional_render;
479 blit.alpha_blend = false;
480
481 if (mask & GL_COLOR_BUFFER_BIT) {
482 struct gl_renderbuffer_attachment *srcAtt =
483 &readFB->Attachment[readFB->_ColorReadBufferIndex];
484 GLuint i;
485
486 blit.mask = PIPE_MASK_RGBA;
487
488 if (srcAtt->Type == GL_TEXTURE) {
489 /* Make sure that the st_texture_object->pt is the current storage for
490 * our miplevel. The finalize would happen at some point anyway, might
491 * as well be now.
492 */
493 st_finalize_texture(ctx, ctx->pipe, srcAtt->Texture, srcAtt->CubeMapFace);
494
495 struct gl_texture_object *srcObj = srcAtt->Texture;
496
497 if (!srcObj || !srcObj->pt) {
498 return;
499 }
500
501 blit.src.resource = srcObj->pt;
502 blit.src.level = srcAtt->TextureLevel;
503 blit.src.box.z = srcAtt->Zoffset + srcAtt->CubeMapFace;
504 blit.src.format = srcObj->surface_based ? srcObj->surface_format : srcObj->pt->format;
505
506 if (!ctx->Color.sRGBEnabled)
507 blit.src.format = util_format_linear(blit.src.format);
508 }
509 else {
510 struct gl_renderbuffer *srcRb = readFB->_ColorReadBuffer;
511 struct pipe_surface *srcSurf;
512
513 if (!srcRb)
514 return;
515
516 _mesa_update_renderbuffer_surface(ctx, srcRb);
517
518 if (!srcRb->surface)
519 return;
520
521 srcSurf = srcRb->surface;
522
523 blit.src.resource = srcSurf->texture;
524 blit.src.level = srcSurf->u.tex.level;
525 blit.src.box.z = srcSurf->u.tex.first_layer;
526 blit.src.format = srcSurf->format;
527 }
528
529 for (i = 0; i < drawFB->_NumColorDrawBuffers; i++) {
530 struct gl_renderbuffer *dstRb = drawFB->_ColorDrawBuffers[i];
531
532 if (dstRb) {
533 struct pipe_surface *dstSurf;
534
535 _mesa_update_renderbuffer_surface(ctx, dstRb);
536
537 dstSurf = dstRb->surface;
538
539 if (dstSurf) {
540 blit.dst.resource = dstSurf->texture;
541 blit.dst.level = dstSurf->u.tex.level;
542 blit.dst.box.z = dstSurf->u.tex.first_layer;
543 blit.dst.format = dstSurf->format;
544
545 ctx->pipe->blit(ctx->pipe, &blit);
546 dstRb->defined = true; /* front buffer tracking */
547 }
548 }
549 }
550 }
551
552 if (mask & depthStencil) {
553 /* depth and/or stencil blit */
554
555 /* get src/dst depth surfaces */
556 struct gl_renderbuffer *srcDepthRb =
557 readFB->Attachment[BUFFER_DEPTH].Renderbuffer;
558 struct gl_renderbuffer *dstDepthRb =
559 drawFB->Attachment[BUFFER_DEPTH].Renderbuffer;
560 struct pipe_surface *dstDepthSurf =
561 dstDepthRb ? dstDepthRb->surface : NULL;
562
563 struct gl_renderbuffer *srcStencilRb =
564 readFB->Attachment[BUFFER_STENCIL].Renderbuffer;
565 struct gl_renderbuffer *dstStencilRb =
566 drawFB->Attachment[BUFFER_STENCIL].Renderbuffer;
567 struct pipe_surface *dstStencilSurf =
568 dstStencilRb ? dstStencilRb->surface : NULL;
569
570 if (_mesa_has_depthstencil_combined(readFB) &&
571 _mesa_has_depthstencil_combined(drawFB)) {
572 blit.mask = 0;
573 if (mask & GL_DEPTH_BUFFER_BIT)
574 blit.mask |= PIPE_MASK_Z;
575 if (mask & GL_STENCIL_BUFFER_BIT)
576 blit.mask |= PIPE_MASK_S;
577
578 blit.dst.resource = dstDepthSurf->texture;
579 blit.dst.level = dstDepthSurf->u.tex.level;
580 blit.dst.box.z = dstDepthSurf->u.tex.first_layer;
581 blit.dst.format = dstDepthSurf->format;
582
583 blit.src.resource = srcDepthRb->texture;
584 blit.src.level = srcDepthRb->surface->u.tex.level;
585 blit.src.box.z = srcDepthRb->surface->u.tex.first_layer;
586 blit.src.format = srcDepthRb->surface->format;
587
588 ctx->pipe->blit(ctx->pipe, &blit);
589 }
590 else {
591 /* blitting depth and stencil separately */
592
593 if (mask & GL_DEPTH_BUFFER_BIT) {
594 blit.mask = PIPE_MASK_Z;
595
596 blit.dst.resource = dstDepthSurf->texture;
597 blit.dst.level = dstDepthSurf->u.tex.level;
598 blit.dst.box.z = dstDepthSurf->u.tex.first_layer;
599 blit.dst.format = dstDepthSurf->format;
600
601 blit.src.resource = srcDepthRb->texture;
602 blit.src.level = srcDepthRb->surface->u.tex.level;
603 blit.src.box.z = srcDepthRb->surface->u.tex.first_layer;
604 blit.src.format = srcDepthRb->surface->format;
605
606 ctx->pipe->blit(ctx->pipe, &blit);
607 }
608
609 if (mask & GL_STENCIL_BUFFER_BIT) {
610 blit.mask = PIPE_MASK_S;
611
612 blit.dst.resource = dstStencilSurf->texture;
613 blit.dst.level = dstStencilSurf->u.tex.level;
614 blit.dst.box.z = dstStencilSurf->u.tex.first_layer;
615 blit.dst.format = dstStencilSurf->format;
616
617 blit.src.resource = srcStencilRb->texture;
618 blit.src.level = srcStencilRb->surface->u.tex.level;
619 blit.src.box.z = srcStencilRb->surface->u.tex.first_layer;
620 blit.src.format = srcStencilRb->surface->format;
621
622 ctx->pipe->blit(ctx->pipe, &blit);
623 }
624 }
625 }
626 }
627
628 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)629 blit_framebuffer(struct gl_context *ctx,
630 struct gl_framebuffer *readFb, struct gl_framebuffer *drawFb,
631 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
632 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
633 GLbitfield mask, GLenum filter, bool no_error, const char *func)
634 {
635 FLUSH_VERTICES(ctx, 0, 0);
636
637 if (!readFb || !drawFb) {
638 /* This will normally never happen but someday we may want to
639 * support MakeCurrent() with no drawables.
640 */
641 return;
642 }
643
644 /* Update completeness status of readFb and drawFb. */
645 _mesa_update_framebuffer(ctx, readFb, drawFb);
646
647 /* Make sure drawFb has an initialized bounding box. */
648 _mesa_update_draw_buffer_bounds(ctx, drawFb);
649
650 if (!no_error) {
651 const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
652 GL_DEPTH_BUFFER_BIT |
653 GL_STENCIL_BUFFER_BIT);
654
655 /* check for complete framebuffers */
656 if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
657 readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
658 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
659 "%s(incomplete draw/read buffers)", func);
660 return;
661 }
662
663 if (!is_valid_blit_filter(ctx, filter)) {
664 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid filter %s)", func,
665 _mesa_enum_to_string(filter));
666 return;
667 }
668
669 if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
670 filter == GL_SCALED_RESOLVE_NICEST_EXT) &&
671 (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) {
672 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s: invalid samples)", func,
673 _mesa_enum_to_string(filter));
674 return;
675 }
676
677 if (mask & ~legalMaskBits) {
678 _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid mask bits set)", func);
679 return;
680 }
681
682 /* depth/stencil must be blitted with nearest filtering */
683 if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
684 && filter != GL_NEAREST) {
685 _mesa_error(ctx, GL_INVALID_OPERATION,
686 "%s(depth/stencil requires GL_NEAREST filter)", func);
687 return;
688 }
689
690 if (_mesa_is_gles3(ctx)) {
691 /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
692 * 3.0.1 spec says:
693 *
694 * "If SAMPLE_BUFFERS for the draw framebuffer is greater than
695 * zero, an INVALID_OPERATION error is generated."
696 */
697 if (drawFb->Visual.samples > 0) {
698 _mesa_error(ctx, GL_INVALID_OPERATION,
699 "%s(destination samples must be 0)", func);
700 return;
701 }
702
703 /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
704 * 3.0.1 spec says:
705 *
706 * "If SAMPLE_BUFFERS for the read framebuffer is greater than
707 * zero, no copy is performed and an INVALID_OPERATION error is
708 * generated if the formats of the read and draw framebuffers are
709 * not identical or if the source and destination rectangles are
710 * not defined with the same (X0, Y0) and (X1, Y1) bounds."
711 *
712 * The format check was made above because desktop OpenGL has the same
713 * requirement.
714 */
715 if (readFb->Visual.samples > 0
716 && (srcX0 != dstX0 || srcY0 != dstY0
717 || srcX1 != dstX1 || srcY1 != dstY1)) {
718 _mesa_error(ctx, GL_INVALID_OPERATION,
719 "%s(bad src/dst multisample region)", func);
720 return;
721 }
722 } else {
723 if (readFb->Visual.samples > 0 &&
724 drawFb->Visual.samples > 0 &&
725 readFb->Visual.samples != drawFb->Visual.samples) {
726 _mesa_error(ctx, GL_INVALID_OPERATION,
727 "%s(mismatched samples)", func);
728 return;
729 }
730
731 /* extra checks for multisample copies... */
732 if ((readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) &&
733 (filter == GL_NEAREST || filter == GL_LINEAR)) {
734 /* src and dest region sizes must be the same */
735 if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) ||
736 abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) {
737 _mesa_error(ctx, GL_INVALID_OPERATION,
738 "%s(bad src/dst multisample region sizes)", func);
739 return;
740 }
741 }
742 }
743 }
744
745 /* get color read/draw renderbuffers */
746 if (mask & GL_COLOR_BUFFER_BIT) {
747 const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
748 const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
749
750 /* From the EXT_framebuffer_object spec:
751 *
752 * "If a buffer is specified in <mask> and does not exist in both
753 * the read and draw framebuffers, the corresponding bit is silently
754 * ignored."
755 */
756 if (!colorReadRb || numColorDrawBuffers == 0) {
757 mask &= ~GL_COLOR_BUFFER_BIT;
758 } else if (!no_error) {
759 if (!validate_color_buffer(ctx, readFb, drawFb, filter, func))
760 return;
761 }
762 }
763
764 if (mask & GL_STENCIL_BUFFER_BIT) {
765 struct gl_renderbuffer *readRb =
766 readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
767 struct gl_renderbuffer *drawRb =
768 drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;
769
770 /* From the EXT_framebuffer_object spec:
771 *
772 * "If a buffer is specified in <mask> and does not exist in both
773 * the read and draw framebuffers, the corresponding bit is silently
774 * ignored."
775 */
776 if ((readRb == NULL) || (drawRb == NULL)) {
777 mask &= ~GL_STENCIL_BUFFER_BIT;
778 } else if (!no_error) {
779 if (!validate_stencil_buffer(ctx, readFb, drawFb, func))
780 return;
781 }
782 }
783
784 if (mask & GL_DEPTH_BUFFER_BIT) {
785 struct gl_renderbuffer *readRb =
786 readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
787 struct gl_renderbuffer *drawRb =
788 drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
789
790 /* From the EXT_framebuffer_object spec:
791 *
792 * "If a buffer is specified in <mask> and does not exist in both
793 * the read and draw framebuffers, the corresponding bit is silently
794 * ignored."
795 */
796 if ((readRb == NULL) || (drawRb == NULL)) {
797 mask &= ~GL_DEPTH_BUFFER_BIT;
798 } else if (!no_error) {
799 if (!validate_depth_buffer(ctx, readFb, drawFb, func))
800 return;
801 }
802 }
803
804 /* Debug code */
805 if (DEBUG_BLIT) {
806 const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
807 const struct gl_renderbuffer *colorDrawRb = NULL;
808 GLuint i = 0;
809
810 printf("%s(%d, %d, %d, %d, %d, %d, %d, %d,"
811 " 0x%x, 0x%x)\n", func,
812 srcX0, srcY0, srcX1, srcY1,
813 dstX0, dstY0, dstX1, dstY1,
814 mask, filter);
815
816 if (colorReadRb) {
817 const struct gl_renderbuffer_attachment *att;
818
819 att = find_attachment(readFb, colorReadRb);
820 printf(" Src FBO %u RB %u (%dx%d) ",
821 readFb->Name, colorReadRb->Name,
822 colorReadRb->Width, colorReadRb->Height);
823 if (att && att->Texture) {
824 printf("Tex %u tgt 0x%x level %u face %u",
825 att->Texture->Name,
826 att->Texture->Target,
827 att->TextureLevel,
828 att->CubeMapFace);
829 }
830 printf("\n");
831
832 /* Print all active color render buffers */
833 for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) {
834 colorDrawRb = drawFb->_ColorDrawBuffers[i];
835 if (!colorDrawRb)
836 continue;
837
838 att = find_attachment(drawFb, colorDrawRb);
839 printf(" Dst FBO %u RB %u (%dx%d) ",
840 drawFb->Name, colorDrawRb->Name,
841 colorDrawRb->Width, colorDrawRb->Height);
842 if (att && att->Texture) {
843 printf("Tex %u tgt 0x%x level %u face %u",
844 att->Texture->Name,
845 att->Texture->Target,
846 att->TextureLevel,
847 att->CubeMapFace);
848 }
849 printf("\n");
850 }
851 }
852 }
853
854 if (!mask ||
855 (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 ||
856 (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) {
857 return;
858 }
859
860 do_blit_framebuffer(ctx, readFb, drawFb,
861 srcX0, srcY0, srcX1, srcY1,
862 dstX0, dstY0, dstX1, dstY1,
863 mask, filter);
864 }
865
866
867 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)868 blit_framebuffer_err(struct gl_context *ctx,
869 struct gl_framebuffer *readFb,
870 struct gl_framebuffer *drawFb,
871 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
872 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
873 GLbitfield mask, GLenum filter, const char *func)
874 {
875 /* We are wrapping the err variant of the always inlined
876 * blit_framebuffer() to avoid inlining it in every caller.
877 */
878 blit_framebuffer(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1,
879 dstX0, dstY0, dstX1, dstY1, mask, filter, false, func);
880 }
881
882
883 /**
884 * Blit rectangular region, optionally from one framebuffer to another.
885 *
886 * Note, if the src buffer is multisampled and the dest is not, this is
887 * when the samples must be resolved to a single color.
888 */
889 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)890 _mesa_BlitFramebuffer_no_error(GLint srcX0, GLint srcY0, GLint srcX1,
891 GLint srcY1, GLint dstX0, GLint dstY0,
892 GLint dstX1, GLint dstY1,
893 GLbitfield mask, GLenum filter)
894 {
895 GET_CURRENT_CONTEXT(ctx);
896
897 blit_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
898 srcX0, srcY0, srcX1, srcY1,
899 dstX0, dstY0, dstX1, dstY1,
900 mask, filter, true, "glBlitFramebuffer");
901 }
902
903
904 void GLAPIENTRY
_mesa_BlitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)905 _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
906 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
907 GLbitfield mask, GLenum filter)
908 {
909 GET_CURRENT_CONTEXT(ctx);
910
911 if (MESA_VERBOSE & VERBOSE_API)
912 _mesa_debug(ctx,
913 "glBlitFramebuffer(%d, %d, %d, %d, "
914 " %d, %d, %d, %d, 0x%x, %s)\n",
915 srcX0, srcY0, srcX1, srcY1,
916 dstX0, dstY0, dstX1, dstY1,
917 mask, _mesa_enum_to_string(filter));
918
919 blit_framebuffer_err(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
920 srcX0, srcY0, srcX1, srcY1,
921 dstX0, dstY0, dstX1, dstY1,
922 mask, filter, "glBlitFramebuffer");
923 }
924
925
926 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)927 blit_named_framebuffer(struct gl_context *ctx,
928 GLuint readFramebuffer, GLuint drawFramebuffer,
929 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
930 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
931 GLbitfield mask, GLenum filter, bool no_error)
932 {
933 struct gl_framebuffer *readFb, *drawFb;
934
935 /*
936 * According to PDF page 533 of the OpenGL 4.5 core spec (30.10.2014,
937 * Section 18.3 Copying Pixels):
938 * "... if readFramebuffer or drawFramebuffer is zero (for
939 * BlitNamedFramebuffer), then the default read or draw framebuffer is
940 * used as the corresponding source or destination framebuffer,
941 * respectively."
942 */
943 if (readFramebuffer) {
944 if (no_error) {
945 readFb = _mesa_lookup_framebuffer(ctx, readFramebuffer);
946 } else {
947 readFb = _mesa_lookup_framebuffer_err(ctx, readFramebuffer,
948 "glBlitNamedFramebuffer");
949 if (!readFb)
950 return;
951 }
952 } else {
953 readFb = ctx->WinSysReadBuffer;
954 }
955
956 if (drawFramebuffer) {
957 if (no_error) {
958 drawFb = _mesa_lookup_framebuffer(ctx, drawFramebuffer);
959 } else {
960 drawFb = _mesa_lookup_framebuffer_err(ctx, drawFramebuffer,
961 "glBlitNamedFramebuffer");
962 if (!drawFb)
963 return;
964 }
965 } else {
966 drawFb = ctx->WinSysDrawBuffer;
967 }
968
969 blit_framebuffer(ctx, readFb, drawFb,
970 srcX0, srcY0, srcX1, srcY1,
971 dstX0, dstY0, dstX1, dstY1,
972 mask, filter, no_error, "glBlitNamedFramebuffer");
973 }
974
975
976 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)977 _mesa_BlitNamedFramebuffer_no_error(GLuint readFramebuffer,
978 GLuint drawFramebuffer,
979 GLint srcX0, GLint srcY0,
980 GLint srcX1, GLint srcY1,
981 GLint dstX0, GLint dstY0,
982 GLint dstX1, GLint dstY1,
983 GLbitfield mask, GLenum filter)
984 {
985 GET_CURRENT_CONTEXT(ctx);
986
987 blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer,
988 srcX0, srcY0, srcX1, srcY1,
989 dstX0, dstY0, dstX1, dstY1,
990 mask, filter, true);
991 }
992
993
994 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)995 _mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer,
996 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
997 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
998 GLbitfield mask, GLenum filter)
999 {
1000 GET_CURRENT_CONTEXT(ctx);
1001
1002 if (MESA_VERBOSE & VERBOSE_API)
1003 _mesa_debug(ctx,
1004 "glBlitNamedFramebuffer(%u %u %d, %d, %d, %d, "
1005 " %d, %d, %d, %d, 0x%x, %s)\n",
1006 readFramebuffer, drawFramebuffer,
1007 srcX0, srcY0, srcX1, srcY1,
1008 dstX0, dstY0, dstX1, dstY1,
1009 mask, _mesa_enum_to_string(filter));
1010
1011 blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer,
1012 srcX0, srcY0, srcX1, srcY1,
1013 dstX0, dstY0, dstX1, dstY1,
1014 mask, filter, false);
1015 }
1016