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 GLenum src_base_fmt, dst_base_fmt;
486
487 blit.mask = PIPE_MASK_RGBA;
488
489 if (srcAtt->Type == GL_TEXTURE) {
490 /* Make sure that the st_texture_object->pt is the current storage for
491 * our miplevel. The finalize would happen at some point anyway, might
492 * as well be now.
493 */
494 st_finalize_texture(ctx, ctx->pipe, srcAtt->Texture, srcAtt->CubeMapFace);
495
496 struct gl_texture_object *srcObj = srcAtt->Texture;
497
498 if (!srcObj || !srcObj->pt) {
499 return;
500 }
501 src_base_fmt = srcObj->Image[0][0]->_BaseFormat;
502
503 blit.src.resource = srcObj->pt;
504 blit.src.level = srcAtt->TextureLevel;
505 blit.src.box.z = srcAtt->Zoffset + srcAtt->CubeMapFace;
506 blit.src.format = srcObj->surface_based ? srcObj->surface_format : srcObj->pt->format;
507
508 if (!ctx->Color.sRGBEnabled)
509 blit.src.format = util_format_linear(blit.src.format);
510 }
511 else {
512 struct gl_renderbuffer *srcRb = readFB->_ColorReadBuffer;
513 struct pipe_surface *srcSurf;
514
515 if (!srcRb)
516 return;
517
518 _mesa_update_renderbuffer_surface(ctx, srcRb);
519
520 if (!srcRb->surface)
521 return;
522
523 srcSurf = srcRb->surface;
524 src_base_fmt = srcRb->_BaseFormat;
525 blit.src.resource = srcSurf->texture;
526 blit.src.level = srcSurf->u.tex.level;
527 blit.src.box.z = srcSurf->u.tex.first_layer;
528 blit.src.format = srcSurf->format;
529 }
530
531 for (i = 0; i < drawFB->_NumColorDrawBuffers; i++) {
532 struct gl_renderbuffer *dstRb = drawFB->_ColorDrawBuffers[i];
533
534 if (dstRb) {
535 struct pipe_surface *dstSurf;
536
537 dst_base_fmt = dstRb->_BaseFormat;
538 _mesa_update_renderbuffer_surface(ctx, dstRb);
539
540 dstSurf = dstRb->surface;
541
542 if (dstSurf) {
543 blit.dst.resource = dstSurf->texture;
544 blit.dst.level = dstSurf->u.tex.level;
545 blit.dst.box.z = dstSurf->u.tex.first_layer;
546 blit.dst.format = dstSurf->format;
547
548 if (dst_base_fmt != src_base_fmt) {
549 uint8_t map[6];
550 /* we may have to add a swizzle to the blit */
551 _mesa_compute_component_mapping(src_base_fmt, dst_base_fmt, map);
552 for (int i = 0; i < 4; i++) {
553 if (map[i] > MESA_FORMAT_SWIZZLE_W) {
554 blit.swizzle_enable = true;
555 blit.swizzle[i] = map[i];
556 } else {
557 /* the swizzle has already been mostly applied,
558 so don't un-do it; we only want the 0's and 1's
559 inserted */
560 blit.swizzle[i] = i;
561 }
562 }
563 }
564 ctx->pipe->blit(ctx->pipe, &blit);
565 dstRb->defined = true; /* front buffer tracking */
566 }
567 }
568 }
569 }
570
571 if (mask & depthStencil) {
572 /* depth and/or stencil blit */
573
574 /* get src/dst depth surfaces */
575 struct gl_renderbuffer *srcDepthRb =
576 readFB->Attachment[BUFFER_DEPTH].Renderbuffer;
577 struct gl_renderbuffer *dstDepthRb =
578 drawFB->Attachment[BUFFER_DEPTH].Renderbuffer;
579 struct pipe_surface *dstDepthSurf =
580 dstDepthRb ? dstDepthRb->surface : NULL;
581
582 struct gl_renderbuffer *srcStencilRb =
583 readFB->Attachment[BUFFER_STENCIL].Renderbuffer;
584 struct gl_renderbuffer *dstStencilRb =
585 drawFB->Attachment[BUFFER_STENCIL].Renderbuffer;
586 struct pipe_surface *dstStencilSurf =
587 dstStencilRb ? dstStencilRb->surface : NULL;
588
589 if (_mesa_has_depthstencil_combined(readFB) &&
590 _mesa_has_depthstencil_combined(drawFB)) {
591 blit.mask = 0;
592 if (mask & GL_DEPTH_BUFFER_BIT)
593 blit.mask |= PIPE_MASK_Z;
594 if (mask & GL_STENCIL_BUFFER_BIT)
595 blit.mask |= PIPE_MASK_S;
596
597 blit.dst.resource = dstDepthSurf->texture;
598 blit.dst.level = dstDepthSurf->u.tex.level;
599 blit.dst.box.z = dstDepthSurf->u.tex.first_layer;
600 blit.dst.format = dstDepthSurf->format;
601
602 blit.src.resource = srcDepthRb->texture;
603 blit.src.level = srcDepthRb->surface->u.tex.level;
604 blit.src.box.z = srcDepthRb->surface->u.tex.first_layer;
605 blit.src.format = srcDepthRb->surface->format;
606
607 ctx->pipe->blit(ctx->pipe, &blit);
608 }
609 else {
610 /* blitting depth and stencil separately */
611
612 if (mask & GL_DEPTH_BUFFER_BIT) {
613 blit.mask = PIPE_MASK_Z;
614
615 blit.dst.resource = dstDepthSurf->texture;
616 blit.dst.level = dstDepthSurf->u.tex.level;
617 blit.dst.box.z = dstDepthSurf->u.tex.first_layer;
618 blit.dst.format = dstDepthSurf->format;
619
620 blit.src.resource = srcDepthRb->texture;
621 blit.src.level = srcDepthRb->surface->u.tex.level;
622 blit.src.box.z = srcDepthRb->surface->u.tex.first_layer;
623 blit.src.format = srcDepthRb->surface->format;
624
625 ctx->pipe->blit(ctx->pipe, &blit);
626 }
627
628 if (mask & GL_STENCIL_BUFFER_BIT) {
629 blit.mask = PIPE_MASK_S;
630
631 blit.dst.resource = dstStencilSurf->texture;
632 blit.dst.level = dstStencilSurf->u.tex.level;
633 blit.dst.box.z = dstStencilSurf->u.tex.first_layer;
634 blit.dst.format = dstStencilSurf->format;
635
636 blit.src.resource = srcStencilRb->texture;
637 blit.src.level = srcStencilRb->surface->u.tex.level;
638 blit.src.box.z = srcStencilRb->surface->u.tex.first_layer;
639 blit.src.format = srcStencilRb->surface->format;
640
641 ctx->pipe->blit(ctx->pipe, &blit);
642 }
643 }
644 }
645 }
646
647 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)648 blit_framebuffer(struct gl_context *ctx,
649 struct gl_framebuffer *readFb, struct gl_framebuffer *drawFb,
650 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
651 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
652 GLbitfield mask, GLenum filter, bool no_error, const char *func)
653 {
654 FLUSH_VERTICES(ctx, 0, 0);
655
656 if (!readFb || !drawFb) {
657 /* This will normally never happen but someday we may want to
658 * support MakeCurrent() with no drawables.
659 */
660 return;
661 }
662
663 /* Update completeness status of readFb and drawFb. */
664 _mesa_update_framebuffer(ctx, readFb, drawFb);
665
666 /* Make sure drawFb has an initialized bounding box. */
667 _mesa_update_draw_buffer_bounds(ctx, drawFb);
668
669 if (!no_error) {
670 const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
671 GL_DEPTH_BUFFER_BIT |
672 GL_STENCIL_BUFFER_BIT);
673
674 /* check for complete framebuffers */
675 if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
676 readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
677 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
678 "%s(incomplete draw/read buffers)", func);
679 return;
680 }
681
682 if (!is_valid_blit_filter(ctx, filter)) {
683 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid filter %s)", func,
684 _mesa_enum_to_string(filter));
685 return;
686 }
687
688 if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
689 filter == GL_SCALED_RESOLVE_NICEST_EXT) &&
690 (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) {
691 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s: invalid samples)", func,
692 _mesa_enum_to_string(filter));
693 return;
694 }
695
696 if (mask & ~legalMaskBits) {
697 _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid mask bits set)", func);
698 return;
699 }
700
701 /* depth/stencil must be blitted with nearest filtering */
702 if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
703 && filter != GL_NEAREST) {
704 _mesa_error(ctx, GL_INVALID_OPERATION,
705 "%s(depth/stencil requires GL_NEAREST filter)", func);
706 return;
707 }
708
709 if (_mesa_is_gles3(ctx)) {
710 /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
711 * 3.0.1 spec says:
712 *
713 * "If SAMPLE_BUFFERS for the draw framebuffer is greater than
714 * zero, an INVALID_OPERATION error is generated."
715 */
716 if (drawFb->Visual.samples > 0) {
717 _mesa_error(ctx, GL_INVALID_OPERATION,
718 "%s(destination samples must be 0)", func);
719 return;
720 }
721
722 /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
723 * 3.0.1 spec says:
724 *
725 * "If SAMPLE_BUFFERS for the read framebuffer is greater than
726 * zero, no copy is performed and an INVALID_OPERATION error is
727 * generated if the formats of the read and draw framebuffers are
728 * not identical or if the source and destination rectangles are
729 * not defined with the same (X0, Y0) and (X1, Y1) bounds."
730 *
731 * The format check was made above because desktop OpenGL has the same
732 * requirement.
733 */
734 if (readFb->Visual.samples > 0
735 && (srcX0 != dstX0 || srcY0 != dstY0
736 || srcX1 != dstX1 || srcY1 != dstY1)) {
737 _mesa_error(ctx, GL_INVALID_OPERATION,
738 "%s(bad src/dst multisample region)", func);
739 return;
740 }
741 } else {
742 if (readFb->Visual.samples > 0 &&
743 drawFb->Visual.samples > 0 &&
744 readFb->Visual.samples != drawFb->Visual.samples) {
745 _mesa_error(ctx, GL_INVALID_OPERATION,
746 "%s(mismatched samples)", func);
747 return;
748 }
749
750 /* extra checks for multisample copies... */
751 if ((readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) &&
752 (filter == GL_NEAREST || filter == GL_LINEAR)) {
753 /* src and dest region sizes must be the same */
754 if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) ||
755 abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) {
756 _mesa_error(ctx, GL_INVALID_OPERATION,
757 "%s(bad src/dst multisample region sizes)", func);
758 return;
759 }
760 }
761 }
762 }
763
764 /* get color read/draw renderbuffers */
765 if (mask & GL_COLOR_BUFFER_BIT) {
766 const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
767 const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
768
769 /* From the EXT_framebuffer_object spec:
770 *
771 * "If a buffer is specified in <mask> and does not exist in both
772 * the read and draw framebuffers, the corresponding bit is silently
773 * ignored."
774 */
775 if (!colorReadRb || numColorDrawBuffers == 0) {
776 mask &= ~GL_COLOR_BUFFER_BIT;
777 } else if (!no_error) {
778 if (!validate_color_buffer(ctx, readFb, drawFb, filter, func))
779 return;
780 }
781 }
782
783 if (mask & GL_STENCIL_BUFFER_BIT) {
784 struct gl_renderbuffer *readRb =
785 readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
786 struct gl_renderbuffer *drawRb =
787 drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;
788
789 /* From the EXT_framebuffer_object spec:
790 *
791 * "If a buffer is specified in <mask> and does not exist in both
792 * the read and draw framebuffers, the corresponding bit is silently
793 * ignored."
794 */
795 if ((readRb == NULL) || (drawRb == NULL)) {
796 mask &= ~GL_STENCIL_BUFFER_BIT;
797 } else if (!no_error) {
798 if (!validate_stencil_buffer(ctx, readFb, drawFb, func))
799 return;
800 }
801 }
802
803 if (mask & GL_DEPTH_BUFFER_BIT) {
804 struct gl_renderbuffer *readRb =
805 readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
806 struct gl_renderbuffer *drawRb =
807 drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
808
809 /* From the EXT_framebuffer_object spec:
810 *
811 * "If a buffer is specified in <mask> and does not exist in both
812 * the read and draw framebuffers, the corresponding bit is silently
813 * ignored."
814 */
815 if ((readRb == NULL) || (drawRb == NULL)) {
816 mask &= ~GL_DEPTH_BUFFER_BIT;
817 } else if (!no_error) {
818 if (!validate_depth_buffer(ctx, readFb, drawFb, func))
819 return;
820 }
821 }
822
823 /* Debug code */
824 if (DEBUG_BLIT) {
825 const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
826 const struct gl_renderbuffer *colorDrawRb = NULL;
827 GLuint i = 0;
828
829 printf("%s(%d, %d, %d, %d, %d, %d, %d, %d,"
830 " 0x%x, 0x%x)\n", func,
831 srcX0, srcY0, srcX1, srcY1,
832 dstX0, dstY0, dstX1, dstY1,
833 mask, filter);
834
835 if (colorReadRb) {
836 const struct gl_renderbuffer_attachment *att;
837
838 att = find_attachment(readFb, colorReadRb);
839 printf(" Src FBO %u RB %u (%dx%d) ",
840 readFb->Name, colorReadRb->Name,
841 colorReadRb->Width, colorReadRb->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 /* Print all active color render buffers */
852 for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) {
853 colorDrawRb = drawFb->_ColorDrawBuffers[i];
854 if (!colorDrawRb)
855 continue;
856
857 att = find_attachment(drawFb, colorDrawRb);
858 printf(" Dst FBO %u RB %u (%dx%d) ",
859 drawFb->Name, colorDrawRb->Name,
860 colorDrawRb->Width, colorDrawRb->Height);
861 if (att && att->Texture) {
862 printf("Tex %u tgt 0x%x level %u face %u",
863 att->Texture->Name,
864 att->Texture->Target,
865 att->TextureLevel,
866 att->CubeMapFace);
867 }
868 printf("\n");
869 }
870 }
871 }
872
873 if (!mask ||
874 (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 ||
875 (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) {
876 return;
877 }
878
879 do_blit_framebuffer(ctx, readFb, drawFb,
880 srcX0, srcY0, srcX1, srcY1,
881 dstX0, dstY0, dstX1, dstY1,
882 mask, filter);
883 }
884
885
886 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)887 blit_framebuffer_err(struct gl_context *ctx,
888 struct gl_framebuffer *readFb,
889 struct gl_framebuffer *drawFb,
890 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
891 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
892 GLbitfield mask, GLenum filter, const char *func)
893 {
894 /* We are wrapping the err variant of the always inlined
895 * blit_framebuffer() to avoid inlining it in every caller.
896 */
897 blit_framebuffer(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1,
898 dstX0, dstY0, dstX1, dstY1, mask, filter, false, func);
899 }
900
901
902 /**
903 * Blit rectangular region, optionally from one framebuffer to another.
904 *
905 * Note, if the src buffer is multisampled and the dest is not, this is
906 * when the samples must be resolved to a single color.
907 */
908 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)909 _mesa_BlitFramebuffer_no_error(GLint srcX0, GLint srcY0, GLint srcX1,
910 GLint srcY1, GLint dstX0, GLint dstY0,
911 GLint dstX1, GLint dstY1,
912 GLbitfield mask, GLenum filter)
913 {
914 GET_CURRENT_CONTEXT(ctx);
915
916 blit_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
917 srcX0, srcY0, srcX1, srcY1,
918 dstX0, dstY0, dstX1, dstY1,
919 mask, filter, true, "glBlitFramebuffer");
920 }
921
922
923 void GLAPIENTRY
_mesa_BlitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)924 _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
925 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
926 GLbitfield mask, GLenum filter)
927 {
928 GET_CURRENT_CONTEXT(ctx);
929
930 if (MESA_VERBOSE & VERBOSE_API)
931 _mesa_debug(ctx,
932 "glBlitFramebuffer(%d, %d, %d, %d, "
933 " %d, %d, %d, %d, 0x%x, %s)\n",
934 srcX0, srcY0, srcX1, srcY1,
935 dstX0, dstY0, dstX1, dstY1,
936 mask, _mesa_enum_to_string(filter));
937
938 blit_framebuffer_err(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
939 srcX0, srcY0, srcX1, srcY1,
940 dstX0, dstY0, dstX1, dstY1,
941 mask, filter, "glBlitFramebuffer");
942 }
943
944
945 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)946 blit_named_framebuffer(struct gl_context *ctx,
947 GLuint readFramebuffer, GLuint drawFramebuffer,
948 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
949 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
950 GLbitfield mask, GLenum filter, bool no_error)
951 {
952 struct gl_framebuffer *readFb, *drawFb;
953
954 /*
955 * According to PDF page 533 of the OpenGL 4.5 core spec (30.10.2014,
956 * Section 18.3 Copying Pixels):
957 * "... if readFramebuffer or drawFramebuffer is zero (for
958 * BlitNamedFramebuffer), then the default read or draw framebuffer is
959 * used as the corresponding source or destination framebuffer,
960 * respectively."
961 */
962 if (readFramebuffer) {
963 if (no_error) {
964 readFb = _mesa_lookup_framebuffer(ctx, readFramebuffer);
965 } else {
966 readFb = _mesa_lookup_framebuffer_err(ctx, readFramebuffer,
967 "glBlitNamedFramebuffer");
968 if (!readFb)
969 return;
970 }
971 } else {
972 readFb = ctx->WinSysReadBuffer;
973 }
974
975 if (drawFramebuffer) {
976 if (no_error) {
977 drawFb = _mesa_lookup_framebuffer(ctx, drawFramebuffer);
978 } else {
979 drawFb = _mesa_lookup_framebuffer_err(ctx, drawFramebuffer,
980 "glBlitNamedFramebuffer");
981 if (!drawFb)
982 return;
983 }
984 } else {
985 drawFb = ctx->WinSysDrawBuffer;
986 }
987
988 blit_framebuffer(ctx, readFb, drawFb,
989 srcX0, srcY0, srcX1, srcY1,
990 dstX0, dstY0, dstX1, dstY1,
991 mask, filter, no_error, "glBlitNamedFramebuffer");
992 }
993
994
995 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)996 _mesa_BlitNamedFramebuffer_no_error(GLuint readFramebuffer,
997 GLuint drawFramebuffer,
998 GLint srcX0, GLint srcY0,
999 GLint srcX1, GLint srcY1,
1000 GLint dstX0, GLint dstY0,
1001 GLint dstX1, GLint dstY1,
1002 GLbitfield mask, GLenum filter)
1003 {
1004 GET_CURRENT_CONTEXT(ctx);
1005
1006 blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer,
1007 srcX0, srcY0, srcX1, srcY1,
1008 dstX0, dstY0, dstX1, dstY1,
1009 mask, filter, true);
1010 }
1011
1012
1013 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)1014 _mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer,
1015 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1016 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1017 GLbitfield mask, GLenum filter)
1018 {
1019 GET_CURRENT_CONTEXT(ctx);
1020
1021 if (MESA_VERBOSE & VERBOSE_API)
1022 _mesa_debug(ctx,
1023 "glBlitNamedFramebuffer(%u %u %d, %d, %d, %d, "
1024 " %d, %d, %d, %d, 0x%x, %s)\n",
1025 readFramebuffer, drawFramebuffer,
1026 srcX0, srcY0, srcX1, srcY1,
1027 dstX0, dstY0, dstX1, dstY1,
1028 mask, _mesa_enum_to_string(filter));
1029
1030 blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer,
1031 srcX0, srcY0, srcX1, srcY1,
1032 dstX0, dstY0, dstX1, dstY1,
1033 mask, filter, false);
1034 }
1035