• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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