1af69d88dSmrg/*
2af69d88dSmrg * Mesa 3-D graphics library
3af69d88dSmrg *
4af69d88dSmrg * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5af69d88dSmrg * Copyright (C) 1999-2013  VMware, Inc.  All Rights Reserved.
6af69d88dSmrg *
7af69d88dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
8af69d88dSmrg * copy of this software and associated documentation files (the "Software"),
9af69d88dSmrg * to deal in the Software without restriction, including without limitation
10af69d88dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11af69d88dSmrg * and/or sell copies of the Software, and to permit persons to whom the
12af69d88dSmrg * Software is furnished to do so, subject to the following conditions:
13af69d88dSmrg *
14af69d88dSmrg * The above copyright notice and this permission notice shall be included
15af69d88dSmrg * in all copies or substantial portions of the Software.
16af69d88dSmrg *
17af69d88dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18af69d88dSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19af69d88dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE.
24af69d88dSmrg */
25af69d88dSmrg
26af69d88dSmrg/*
27af69d88dSmrg * glBlitFramebuffer functions.
28af69d88dSmrg */
29af69d88dSmrg
30af69d88dSmrg#include <stdbool.h>
3101e04c3fSmrg#include <stdio.h>
32af69d88dSmrg
33af69d88dSmrg#include "context.h"
34af69d88dSmrg#include "enums.h"
35af69d88dSmrg#include "blit.h"
36af69d88dSmrg#include "fbobject.h"
3701e04c3fSmrg#include "framebuffer.h"
38af69d88dSmrg#include "glformats.h"
39af69d88dSmrg#include "mtypes.h"
4001e04c3fSmrg#include "macros.h"
41af69d88dSmrg#include "state.h"
42af69d88dSmrg
43af69d88dSmrg
44af69d88dSmrg/** Set this to 1 to debug/log glBlitFramebuffer() calls */
45af69d88dSmrg#define DEBUG_BLIT 0
46af69d88dSmrg
47af69d88dSmrg
48af69d88dSmrg
49af69d88dSmrgstatic const struct gl_renderbuffer_attachment *
50af69d88dSmrgfind_attachment(const struct gl_framebuffer *fb,
51af69d88dSmrg                const struct gl_renderbuffer *rb)
52af69d88dSmrg{
53af69d88dSmrg   GLuint i;
5401e04c3fSmrg   for (i = 0; i < ARRAY_SIZE(fb->Attachment); i++) {
55af69d88dSmrg      if (fb->Attachment[i].Renderbuffer == rb)
56af69d88dSmrg         return &fb->Attachment[i];
57af69d88dSmrg   }
58af69d88dSmrg   return NULL;
59af69d88dSmrg}
60af69d88dSmrg
61af69d88dSmrg
6201e04c3fSmrg/**
6301e04c3fSmrg * \return true if two regions overlap, false otherwise
6401e04c3fSmrg */
6501e04c3fSmrgbool
6601e04c3fSmrg_mesa_regions_overlap(int srcX0, int srcY0,
6701e04c3fSmrg                      int srcX1, int srcY1,
6801e04c3fSmrg                      int dstX0, int dstY0,
6901e04c3fSmrg                      int dstX1, int dstY1)
7001e04c3fSmrg{
7101e04c3fSmrg   if (MAX2(srcX0, srcX1) <= MIN2(dstX0, dstX1))
7201e04c3fSmrg      return false; /* dst completely right of src */
7301e04c3fSmrg
7401e04c3fSmrg   if (MAX2(dstX0, dstX1) <= MIN2(srcX0, srcX1))
7501e04c3fSmrg      return false; /* dst completely left of src */
7601e04c3fSmrg
7701e04c3fSmrg   if (MAX2(srcY0, srcY1) <= MIN2(dstY0, dstY1))
7801e04c3fSmrg      return false; /* dst completely above src */
7901e04c3fSmrg
8001e04c3fSmrg   if (MAX2(dstY0, dstY1) <= MIN2(srcY0, srcY1))
8101e04c3fSmrg      return false; /* dst completely below src */
8201e04c3fSmrg
8301e04c3fSmrg   return true; /* some overlap */
8401e04c3fSmrg}
8501e04c3fSmrg
8601e04c3fSmrg
87af69d88dSmrg/**
88af69d88dSmrg * Helper function for checking if the datatypes of color buffers are
89af69d88dSmrg * compatible for glBlitFramebuffer.  From the 3.1 spec, page 198:
90af69d88dSmrg *
91af69d88dSmrg * "GL_INVALID_OPERATION is generated if mask contains GL_COLOR_BUFFER_BIT
92af69d88dSmrg *  and any of the following conditions hold:
93af69d88dSmrg *   - The read buffer contains fixed-point or floating-point values and any
94af69d88dSmrg *     draw buffer contains neither fixed-point nor floating-point values.
95af69d88dSmrg *   - The read buffer contains unsigned integer values and any draw buffer
96af69d88dSmrg *     does not contain unsigned integer values.
97af69d88dSmrg *   - The read buffer contains signed integer values and any draw buffer
98af69d88dSmrg *     does not contain signed integer values."
99af69d88dSmrg */
100af69d88dSmrgstatic GLboolean
101af69d88dSmrgcompatible_color_datatypes(mesa_format srcFormat, mesa_format dstFormat)
102af69d88dSmrg{
103af69d88dSmrg   GLenum srcType = _mesa_get_format_datatype(srcFormat);
104af69d88dSmrg   GLenum dstType = _mesa_get_format_datatype(dstFormat);
105af69d88dSmrg
106af69d88dSmrg   if (srcType != GL_INT && srcType != GL_UNSIGNED_INT) {
107af69d88dSmrg      assert(srcType == GL_UNSIGNED_NORMALIZED ||
108af69d88dSmrg             srcType == GL_SIGNED_NORMALIZED ||
109af69d88dSmrg             srcType == GL_FLOAT);
110af69d88dSmrg      /* Boil any of those types down to GL_FLOAT */
111af69d88dSmrg      srcType = GL_FLOAT;
112af69d88dSmrg   }
113af69d88dSmrg
114af69d88dSmrg   if (dstType != GL_INT && dstType != GL_UNSIGNED_INT) {
115af69d88dSmrg      assert(dstType == GL_UNSIGNED_NORMALIZED ||
116af69d88dSmrg             dstType == GL_SIGNED_NORMALIZED ||
117af69d88dSmrg             dstType == GL_FLOAT);
118af69d88dSmrg      /* Boil any of those types down to GL_FLOAT */
119af69d88dSmrg      dstType = GL_FLOAT;
120af69d88dSmrg   }
121af69d88dSmrg
122af69d88dSmrg   return srcType == dstType;
123af69d88dSmrg}
124af69d88dSmrg
125af69d88dSmrg
126af69d88dSmrgstatic GLboolean
127af69d88dSmrgcompatible_resolve_formats(const struct gl_renderbuffer *readRb,
128af69d88dSmrg                           const struct gl_renderbuffer *drawRb)
129af69d88dSmrg{
130af69d88dSmrg   GLenum readFormat, drawFormat;
131af69d88dSmrg
13201e04c3fSmrg   /* This checks whether the internal formats are compatible rather than the
13301e04c3fSmrg    * Mesa format for two reasons:
13401e04c3fSmrg    *
13501e04c3fSmrg    * • Under some circumstances, the user may request e.g. two GL_RGBA8
13601e04c3fSmrg    *   textures and get two entirely different Mesa formats like RGBA8888 and
13701e04c3fSmrg    *   ARGB8888. Drivers behaving like that should be able to cope with
13801e04c3fSmrg    *   non-matching formats by themselves, because it's not the user's fault.
139af69d88dSmrg    *
14001e04c3fSmrg    * • Picking two different internal formats can end up with the same Mesa
14101e04c3fSmrg    *   format. For example the driver might be simulating GL_RGB textures
14201e04c3fSmrg    *   with GL_RGBA internally and in that case both internal formats would
14301e04c3fSmrg    *   end up with RGBA8888.
14401e04c3fSmrg    *
14501e04c3fSmrg    * This function is used to generate a GL error according to the spec so in
14601e04c3fSmrg    * both cases we want to be looking at the application-level format, which
14701e04c3fSmrg    * is InternalFormat.
148af69d88dSmrg    *
149af69d88dSmrg    * Blits between linear and sRGB formats are also allowed.
150af69d88dSmrg    */
151af69d88dSmrg   readFormat = _mesa_get_nongeneric_internalformat(readRb->InternalFormat);
152af69d88dSmrg   drawFormat = _mesa_get_nongeneric_internalformat(drawRb->InternalFormat);
153af69d88dSmrg   readFormat = _mesa_get_linear_internalformat(readFormat);
154af69d88dSmrg   drawFormat = _mesa_get_linear_internalformat(drawFormat);
155af69d88dSmrg
156af69d88dSmrg   if (readFormat == drawFormat) {
157af69d88dSmrg      return GL_TRUE;
158af69d88dSmrg   }
159af69d88dSmrg
160af69d88dSmrg   return GL_FALSE;
161af69d88dSmrg}
162af69d88dSmrg
163af69d88dSmrg
164af69d88dSmrgstatic GLboolean
165af69d88dSmrgis_valid_blit_filter(const struct gl_context *ctx, GLenum filter)
166af69d88dSmrg{
167af69d88dSmrg   switch (filter) {
168af69d88dSmrg   case GL_NEAREST:
169af69d88dSmrg   case GL_LINEAR:
170af69d88dSmrg      return true;
171af69d88dSmrg   case GL_SCALED_RESOLVE_FASTEST_EXT:
172af69d88dSmrg   case GL_SCALED_RESOLVE_NICEST_EXT:
173af69d88dSmrg      return ctx->Extensions.EXT_framebuffer_multisample_blit_scaled;
174af69d88dSmrg   default:
175af69d88dSmrg      return false;
176af69d88dSmrg   }
177af69d88dSmrg}
178af69d88dSmrg
179af69d88dSmrg
18001e04c3fSmrgstatic bool
18101e04c3fSmrgvalidate_color_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb,
18201e04c3fSmrg                      struct gl_framebuffer *drawFb, GLenum filter,
18301e04c3fSmrg                      const char *func)
184af69d88dSmrg{
18501e04c3fSmrg   const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
18601e04c3fSmrg   const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
18701e04c3fSmrg   const struct gl_renderbuffer *colorDrawRb = NULL;
18801e04c3fSmrg   GLuint i;
189af69d88dSmrg
19001e04c3fSmrg   for (i = 0; i < numColorDrawBuffers; i++) {
19101e04c3fSmrg      colorDrawRb = drawFb->_ColorDrawBuffers[i];
19201e04c3fSmrg      if (!colorDrawRb)
19301e04c3fSmrg         continue;
194af69d88dSmrg
19501e04c3fSmrg      /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL
19601e04c3fSmrg       * ES 3.0.1 spec says:
19701e04c3fSmrg       *
19801e04c3fSmrg       *     "If the source and destination buffers are identical, an
19901e04c3fSmrg       *     INVALID_OPERATION error is generated. Different mipmap levels of a
20001e04c3fSmrg       *     texture, different layers of a three- dimensional texture or
20101e04c3fSmrg       *     two-dimensional array texture, and different faces of a cube map
20201e04c3fSmrg       *     texture do not constitute identical buffers."
20301e04c3fSmrg       */
20401e04c3fSmrg      if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) {
20501e04c3fSmrg         _mesa_error(ctx, GL_INVALID_OPERATION,
20601e04c3fSmrg                     "%s(source and destination color buffer cannot be the "
20701e04c3fSmrg                     "same)", func);
20801e04c3fSmrg         return false;
20901e04c3fSmrg      }
210af69d88dSmrg
21101e04c3fSmrg      if (!compatible_color_datatypes(colorReadRb->Format,
21201e04c3fSmrg                                      colorDrawRb->Format)) {
21301e04c3fSmrg         _mesa_error(ctx, GL_INVALID_OPERATION,
21401e04c3fSmrg                     "%s(color buffer datatypes mismatch)", func);
21501e04c3fSmrg         return false;
21601e04c3fSmrg      }
217af69d88dSmrg
21801e04c3fSmrg      /* extra checks for multisample copies... */
21901e04c3fSmrg      if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) {
22001e04c3fSmrg         /* color formats must match on GLES. This isn't checked on desktop GL
22101e04c3fSmrg          * because the GL 4.4 spec was changed to allow it.  In the section
22201e04c3fSmrg          * entitled “Changes in the released
22301e04c3fSmrg          * Specification of July 22, 2013” it says:
22401e04c3fSmrg          *
22501e04c3fSmrg          * “Relax BlitFramebuffer in section 18.3.1 so that format conversion
22601e04c3fSmrg          * can take place during multisample blits, since drivers already
22701e04c3fSmrg          * allow this and some apps depend on it.”
22801e04c3fSmrg          */
22901e04c3fSmrg         if (_mesa_is_gles(ctx) &&
23001e04c3fSmrg             !compatible_resolve_formats(colorReadRb, colorDrawRb)) {
23101e04c3fSmrg            _mesa_error(ctx, GL_INVALID_OPERATION,
23201e04c3fSmrg                        "%s(bad src/dst multisample pixel formats)", func);
23301e04c3fSmrg            return false;
23401e04c3fSmrg         }
23501e04c3fSmrg      }
236af69d88dSmrg
23701e04c3fSmrg   }
23801e04c3fSmrg
23901e04c3fSmrg   if (filter != GL_NEAREST) {
24001e04c3fSmrg      /* From EXT_framebuffer_multisample_blit_scaled specification:
24101e04c3fSmrg       * "Calling BlitFramebuffer will result in an INVALID_OPERATION error if
24201e04c3fSmrg       * filter is not NEAREST and read buffer contains integer data."
243af69d88dSmrg       */
24401e04c3fSmrg      GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
24501e04c3fSmrg      if (type == GL_INT || type == GL_UNSIGNED_INT) {
24601e04c3fSmrg         _mesa_error(ctx, GL_INVALID_OPERATION,
24701e04c3fSmrg                     "%s(integer color type)", func);
24801e04c3fSmrg         return false;
24901e04c3fSmrg      }
250af69d88dSmrg   }
25101e04c3fSmrg   return true;
25201e04c3fSmrg}
253af69d88dSmrg
25401e04c3fSmrg
25501e04c3fSmrgstatic bool
25601e04c3fSmrgvalidate_stencil_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb,
25701e04c3fSmrg                        struct gl_framebuffer *drawFb, const char *func)
25801e04c3fSmrg{
25901e04c3fSmrg   struct gl_renderbuffer *readRb =
26001e04c3fSmrg      readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
26101e04c3fSmrg   struct gl_renderbuffer *drawRb =
26201e04c3fSmrg      drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;
26301e04c3fSmrg   int read_z_bits, draw_z_bits;
26401e04c3fSmrg
26501e04c3fSmrg   if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
26601e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
26701e04c3fSmrg                  "%s(source and destination stencil buffer cannot be the "
26801e04c3fSmrg                  "same)", func);
26901e04c3fSmrg      return false;
270af69d88dSmrg   }
271af69d88dSmrg
27201e04c3fSmrg   if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
27301e04c3fSmrg       _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
27401e04c3fSmrg      /* There is no need to check the stencil datatype here, because
27501e04c3fSmrg       * there is only one: GL_UNSIGNED_INT.
27601e04c3fSmrg       */
27701e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
27801e04c3fSmrg                  "%s(stencil attachment format mismatch)", func);
27901e04c3fSmrg      return false;
280af69d88dSmrg   }
281af69d88dSmrg
28201e04c3fSmrg   read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS);
28301e04c3fSmrg   draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS);
28401e04c3fSmrg
28501e04c3fSmrg   /* If both buffers also have depth data, the depth formats must match
28601e04c3fSmrg    * as well.  If one doesn't have depth, it's not blitted, so we should
28701e04c3fSmrg    * ignore the depth format check.
28801e04c3fSmrg    */
28901e04c3fSmrg   if (read_z_bits > 0 && draw_z_bits > 0 &&
29001e04c3fSmrg       (read_z_bits != draw_z_bits ||
29101e04c3fSmrg        _mesa_get_format_datatype(readRb->Format) !=
29201e04c3fSmrg        _mesa_get_format_datatype(drawRb->Format))) {
29301e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
29401e04c3fSmrg                  "%s(stencil attachment depth format mismatch)", func);
29501e04c3fSmrg      return false;
296af69d88dSmrg   }
29701e04c3fSmrg   return true;
29801e04c3fSmrg}
299af69d88dSmrg
30001e04c3fSmrg
30101e04c3fSmrgstatic bool
30201e04c3fSmrgvalidate_depth_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb,
30301e04c3fSmrg                      struct gl_framebuffer *drawFb, const char *func)
30401e04c3fSmrg{
30501e04c3fSmrg   struct gl_renderbuffer *readRb =
30601e04c3fSmrg      readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
30701e04c3fSmrg   struct gl_renderbuffer *drawRb =
30801e04c3fSmrg      drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
30901e04c3fSmrg   int read_s_bit, draw_s_bit;
31001e04c3fSmrg
31101e04c3fSmrg   if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
31201e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
31301e04c3fSmrg                  "%s(source and destination depth buffer cannot be the same)",
31401e04c3fSmrg                  func);
31501e04c3fSmrg      return false;
316af69d88dSmrg   }
317af69d88dSmrg
31801e04c3fSmrg   if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
31901e04c3fSmrg        _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) ||
32001e04c3fSmrg       (_mesa_get_format_datatype(readRb->Format) !=
32101e04c3fSmrg        _mesa_get_format_datatype(drawRb->Format))) {
322af69d88dSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
32301e04c3fSmrg                  "%s(depth attachment format mismatch)", func);
32401e04c3fSmrg      return false;
32501e04c3fSmrg   }
32601e04c3fSmrg
32701e04c3fSmrg   read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS);
32801e04c3fSmrg   draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS);
32901e04c3fSmrg
33001e04c3fSmrg   /* If both buffers also have stencil data, the stencil formats must match as
33101e04c3fSmrg    * well.  If one doesn't have stencil, it's not blitted, so we should ignore
33201e04c3fSmrg    * the stencil format check.
33301e04c3fSmrg    */
33401e04c3fSmrg   if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) {
33501e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
33601e04c3fSmrg                  "%s(depth attachment stencil bits mismatch)", func);
33701e04c3fSmrg      return false;
33801e04c3fSmrg   }
33901e04c3fSmrg   return true;
34001e04c3fSmrg}
34101e04c3fSmrg
34201e04c3fSmrg
34301e04c3fSmrgstatic ALWAYS_INLINE void
34401e04c3fSmrgblit_framebuffer(struct gl_context *ctx,
34501e04c3fSmrg                 struct gl_framebuffer *readFb, struct gl_framebuffer *drawFb,
34601e04c3fSmrg                 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
34701e04c3fSmrg                 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
34801e04c3fSmrg                 GLbitfield mask, GLenum filter, bool no_error, const char *func)
34901e04c3fSmrg{
3507ec681f3Smrg   FLUSH_VERTICES(ctx, 0, 0);
35101e04c3fSmrg
35201e04c3fSmrg   if (!readFb || !drawFb) {
35301e04c3fSmrg      /* This will normally never happen but someday we may want to
35401e04c3fSmrg       * support MakeCurrent() with no drawables.
35501e04c3fSmrg       */
356af69d88dSmrg      return;
357af69d88dSmrg   }
358af69d88dSmrg
35901e04c3fSmrg   /* Update completeness status of readFb and drawFb. */
36001e04c3fSmrg   _mesa_update_framebuffer(ctx, readFb, drawFb);
36101e04c3fSmrg
36201e04c3fSmrg   /* Make sure drawFb has an initialized bounding box. */
36301e04c3fSmrg   _mesa_update_draw_buffer_bounds(ctx, drawFb);
36401e04c3fSmrg
36501e04c3fSmrg   if (!no_error) {
36601e04c3fSmrg      const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
36701e04c3fSmrg                                        GL_DEPTH_BUFFER_BIT |
36801e04c3fSmrg                                        GL_STENCIL_BUFFER_BIT);
36901e04c3fSmrg
37001e04c3fSmrg      /* check for complete framebuffers */
37101e04c3fSmrg      if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
37201e04c3fSmrg          readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
37301e04c3fSmrg         _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
37401e04c3fSmrg                     "%s(incomplete draw/read buffers)", func);
37501e04c3fSmrg         return;
37601e04c3fSmrg      }
37701e04c3fSmrg
37801e04c3fSmrg      if (!is_valid_blit_filter(ctx, filter)) {
37901e04c3fSmrg         _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid filter %s)", func,
38001e04c3fSmrg                     _mesa_enum_to_string(filter));
38101e04c3fSmrg         return;
38201e04c3fSmrg      }
38301e04c3fSmrg
38401e04c3fSmrg      if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
38501e04c3fSmrg           filter == GL_SCALED_RESOLVE_NICEST_EXT) &&
38601e04c3fSmrg           (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) {
38701e04c3fSmrg         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s: invalid samples)", func,
38801e04c3fSmrg                     _mesa_enum_to_string(filter));
38901e04c3fSmrg         return;
39001e04c3fSmrg      }
39101e04c3fSmrg
39201e04c3fSmrg      if (mask & ~legalMaskBits) {
39301e04c3fSmrg         _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid mask bits set)", func);
39401e04c3fSmrg         return;
39501e04c3fSmrg      }
39601e04c3fSmrg
39701e04c3fSmrg      /* depth/stencil must be blitted with nearest filtering */
39801e04c3fSmrg      if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
39901e04c3fSmrg           && filter != GL_NEAREST) {
40001e04c3fSmrg         _mesa_error(ctx, GL_INVALID_OPERATION,
40101e04c3fSmrg                "%s(depth/stencil requires GL_NEAREST filter)", func);
40201e04c3fSmrg         return;
40301e04c3fSmrg      }
40401e04c3fSmrg
40501e04c3fSmrg      if (_mesa_is_gles3(ctx)) {
40601e04c3fSmrg         /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
40701e04c3fSmrg          * 3.0.1 spec says:
40801e04c3fSmrg          *
40901e04c3fSmrg          *     "If SAMPLE_BUFFERS for the draw framebuffer is greater than
41001e04c3fSmrg          *     zero, an INVALID_OPERATION error is generated."
41101e04c3fSmrg          */
41201e04c3fSmrg         if (drawFb->Visual.samples > 0) {
41301e04c3fSmrg            _mesa_error(ctx, GL_INVALID_OPERATION,
41401e04c3fSmrg                        "%s(destination samples must be 0)", func);
41501e04c3fSmrg            return;
41601e04c3fSmrg         }
41701e04c3fSmrg
41801e04c3fSmrg         /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
41901e04c3fSmrg          * 3.0.1 spec says:
42001e04c3fSmrg          *
42101e04c3fSmrg          *     "If SAMPLE_BUFFERS for the read framebuffer is greater than
42201e04c3fSmrg          *     zero, no copy is performed and an INVALID_OPERATION error is
42301e04c3fSmrg          *     generated if the formats of the read and draw framebuffers are
42401e04c3fSmrg          *     not identical or if the source and destination rectangles are
42501e04c3fSmrg          *     not defined with the same (X0, Y0) and (X1, Y1) bounds."
42601e04c3fSmrg          *
42701e04c3fSmrg          * The format check was made above because desktop OpenGL has the same
42801e04c3fSmrg          * requirement.
42901e04c3fSmrg          */
43001e04c3fSmrg         if (readFb->Visual.samples > 0
43101e04c3fSmrg             && (srcX0 != dstX0 || srcY0 != dstY0
43201e04c3fSmrg                 || srcX1 != dstX1 || srcY1 != dstY1)) {
43301e04c3fSmrg            _mesa_error(ctx, GL_INVALID_OPERATION,
43401e04c3fSmrg                        "%s(bad src/dst multisample region)", func);
43501e04c3fSmrg            return;
43601e04c3fSmrg         }
43701e04c3fSmrg      } else {
43801e04c3fSmrg         if (readFb->Visual.samples > 0 &&
43901e04c3fSmrg             drawFb->Visual.samples > 0 &&
44001e04c3fSmrg             readFb->Visual.samples != drawFb->Visual.samples) {
44101e04c3fSmrg            _mesa_error(ctx, GL_INVALID_OPERATION,
44201e04c3fSmrg                        "%s(mismatched samples)", func);
44301e04c3fSmrg            return;
44401e04c3fSmrg         }
44501e04c3fSmrg
44601e04c3fSmrg         /* extra checks for multisample copies... */
44701e04c3fSmrg         if ((readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) &&
44801e04c3fSmrg             (filter == GL_NEAREST || filter == GL_LINEAR)) {
44901e04c3fSmrg            /* src and dest region sizes must be the same */
45001e04c3fSmrg            if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) ||
45101e04c3fSmrg                abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) {
45201e04c3fSmrg               _mesa_error(ctx, GL_INVALID_OPERATION,
45301e04c3fSmrg                           "%s(bad src/dst multisample region sizes)", func);
45401e04c3fSmrg               return;
45501e04c3fSmrg            }
45601e04c3fSmrg         }
45701e04c3fSmrg      }
45801e04c3fSmrg   }
45901e04c3fSmrg
460af69d88dSmrg   /* get color read/draw renderbuffers */
461af69d88dSmrg   if (mask & GL_COLOR_BUFFER_BIT) {
46201e04c3fSmrg      const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
463af69d88dSmrg      const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
464af69d88dSmrg
465af69d88dSmrg      /* From the EXT_framebuffer_object spec:
466af69d88dSmrg       *
467af69d88dSmrg       *     "If a buffer is specified in <mask> and does not exist in both
468af69d88dSmrg       *     the read and draw framebuffers, the corresponding bit is silently
469af69d88dSmrg       *     ignored."
470af69d88dSmrg       */
471af69d88dSmrg      if (!colorReadRb || numColorDrawBuffers == 0) {
472af69d88dSmrg         mask &= ~GL_COLOR_BUFFER_BIT;
47301e04c3fSmrg      } else if (!no_error) {
47401e04c3fSmrg         if (!validate_color_buffer(ctx, readFb, drawFb, filter, func))
47501e04c3fSmrg            return;
476af69d88dSmrg      }
477af69d88dSmrg   }
478af69d88dSmrg
479af69d88dSmrg   if (mask & GL_STENCIL_BUFFER_BIT) {
480af69d88dSmrg      struct gl_renderbuffer *readRb =
481af69d88dSmrg         readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
482af69d88dSmrg      struct gl_renderbuffer *drawRb =
483af69d88dSmrg         drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;
484af69d88dSmrg
485af69d88dSmrg      /* From the EXT_framebuffer_object spec:
486af69d88dSmrg       *
487af69d88dSmrg       *     "If a buffer is specified in <mask> and does not exist in both
488af69d88dSmrg       *     the read and draw framebuffers, the corresponding bit is silently
489af69d88dSmrg       *     ignored."
490af69d88dSmrg       */
491af69d88dSmrg      if ((readRb == NULL) || (drawRb == NULL)) {
49201e04c3fSmrg         mask &= ~GL_STENCIL_BUFFER_BIT;
49301e04c3fSmrg      } else if (!no_error) {
49401e04c3fSmrg         if (!validate_stencil_buffer(ctx, readFb, drawFb, func))
495af69d88dSmrg            return;
496af69d88dSmrg      }
497af69d88dSmrg   }
498af69d88dSmrg
499af69d88dSmrg   if (mask & GL_DEPTH_BUFFER_BIT) {
500af69d88dSmrg      struct gl_renderbuffer *readRb =
501af69d88dSmrg         readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
502af69d88dSmrg      struct gl_renderbuffer *drawRb =
503af69d88dSmrg         drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
504af69d88dSmrg
505af69d88dSmrg      /* From the EXT_framebuffer_object spec:
506af69d88dSmrg       *
507af69d88dSmrg       *     "If a buffer is specified in <mask> and does not exist in both
508af69d88dSmrg       *     the read and draw framebuffers, the corresponding bit is silently
509af69d88dSmrg       *     ignored."
510af69d88dSmrg       */
511af69d88dSmrg      if ((readRb == NULL) || (drawRb == NULL)) {
51201e04c3fSmrg         mask &= ~GL_DEPTH_BUFFER_BIT;
51301e04c3fSmrg      } else if (!no_error) {
51401e04c3fSmrg         if (!validate_depth_buffer(ctx, readFb, drawFb, func))
515af69d88dSmrg            return;
516af69d88dSmrg      }
517af69d88dSmrg   }
518af69d88dSmrg
519af69d88dSmrg   /* Debug code */
520af69d88dSmrg   if (DEBUG_BLIT) {
521af69d88dSmrg      const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
522af69d88dSmrg      const struct gl_renderbuffer *colorDrawRb = NULL;
523af69d88dSmrg      GLuint i = 0;
524af69d88dSmrg
52501e04c3fSmrg      printf("%s(%d, %d, %d, %d,  %d, %d, %d, %d,"
52601e04c3fSmrg             " 0x%x, 0x%x)\n", func,
52701e04c3fSmrg             srcX0, srcY0, srcX1, srcY1,
52801e04c3fSmrg             dstX0, dstY0, dstX1, dstY1,
52901e04c3fSmrg             mask, filter);
53001e04c3fSmrg
531af69d88dSmrg      if (colorReadRb) {
532af69d88dSmrg         const struct gl_renderbuffer_attachment *att;
533af69d88dSmrg
534af69d88dSmrg         att = find_attachment(readFb, colorReadRb);
535af69d88dSmrg         printf("  Src FBO %u  RB %u (%dx%d)  ",
53601e04c3fSmrg                readFb->Name, colorReadRb->Name,
53701e04c3fSmrg                colorReadRb->Width, colorReadRb->Height);
538af69d88dSmrg         if (att && att->Texture) {
539af69d88dSmrg            printf("Tex %u  tgt 0x%x  level %u  face %u",
54001e04c3fSmrg                   att->Texture->Name,
54101e04c3fSmrg                   att->Texture->Target,
54201e04c3fSmrg                   att->TextureLevel,
54301e04c3fSmrg                   att->CubeMapFace);
544af69d88dSmrg         }
545af69d88dSmrg         printf("\n");
546af69d88dSmrg
547af69d88dSmrg         /* Print all active color render buffers */
54801e04c3fSmrg         for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) {
54901e04c3fSmrg            colorDrawRb = drawFb->_ColorDrawBuffers[i];
550af69d88dSmrg            if (!colorDrawRb)
551af69d88dSmrg               continue;
552af69d88dSmrg
553af69d88dSmrg            att = find_attachment(drawFb, colorDrawRb);
554af69d88dSmrg            printf("  Dst FBO %u  RB %u (%dx%d)  ",
55501e04c3fSmrg                   drawFb->Name, colorDrawRb->Name,
55601e04c3fSmrg                   colorDrawRb->Width, colorDrawRb->Height);
557af69d88dSmrg            if (att && att->Texture) {
558af69d88dSmrg               printf("Tex %u  tgt 0x%x  level %u  face %u",
55901e04c3fSmrg                      att->Texture->Name,
56001e04c3fSmrg                      att->Texture->Target,
56101e04c3fSmrg                      att->TextureLevel,
56201e04c3fSmrg                      att->CubeMapFace);
563af69d88dSmrg            }
564af69d88dSmrg            printf("\n");
565af69d88dSmrg         }
566af69d88dSmrg      }
567af69d88dSmrg   }
568af69d88dSmrg
569af69d88dSmrg   if (!mask ||
570af69d88dSmrg       (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 ||
571af69d88dSmrg       (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) {
572af69d88dSmrg      return;
573af69d88dSmrg   }
574af69d88dSmrg
57501e04c3fSmrg   assert(ctx->Driver.BlitFramebuffer);
57601e04c3fSmrg   ctx->Driver.BlitFramebuffer(ctx, readFb, drawFb,
577af69d88dSmrg                               srcX0, srcY0, srcX1, srcY1,
578af69d88dSmrg                               dstX0, dstY0, dstX1, dstY1,
579af69d88dSmrg                               mask, filter);
580af69d88dSmrg}
58101e04c3fSmrg
58201e04c3fSmrg
58301e04c3fSmrgstatic void
58401e04c3fSmrgblit_framebuffer_err(struct gl_context *ctx,
58501e04c3fSmrg                     struct gl_framebuffer *readFb,
58601e04c3fSmrg                     struct gl_framebuffer *drawFb,
58701e04c3fSmrg                     GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
58801e04c3fSmrg                     GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
58901e04c3fSmrg                     GLbitfield mask, GLenum filter, const char *func)
59001e04c3fSmrg{
59101e04c3fSmrg   /* We are wrapping the err variant of the always inlined
59201e04c3fSmrg    * blit_framebuffer() to avoid inlining it in every caller.
59301e04c3fSmrg    */
59401e04c3fSmrg   blit_framebuffer(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1,
59501e04c3fSmrg                    dstX0, dstY0, dstX1, dstY1, mask, filter, false, func);
59601e04c3fSmrg}
59701e04c3fSmrg
59801e04c3fSmrg
59901e04c3fSmrg/**
60001e04c3fSmrg * Blit rectangular region, optionally from one framebuffer to another.
60101e04c3fSmrg *
60201e04c3fSmrg * Note, if the src buffer is multisampled and the dest is not, this is
60301e04c3fSmrg * when the samples must be resolved to a single color.
60401e04c3fSmrg */
60501e04c3fSmrgvoid GLAPIENTRY
60601e04c3fSmrg_mesa_BlitFramebuffer_no_error(GLint srcX0, GLint srcY0, GLint srcX1,
60701e04c3fSmrg                               GLint srcY1, GLint dstX0, GLint dstY0,
60801e04c3fSmrg                               GLint dstX1, GLint dstY1,
60901e04c3fSmrg                               GLbitfield mask, GLenum filter)
61001e04c3fSmrg{
61101e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
61201e04c3fSmrg
61301e04c3fSmrg   blit_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
61401e04c3fSmrg                    srcX0, srcY0, srcX1, srcY1,
61501e04c3fSmrg                    dstX0, dstY0, dstX1, dstY1,
61601e04c3fSmrg                    mask, filter, true, "glBlitFramebuffer");
61701e04c3fSmrg}
61801e04c3fSmrg
61901e04c3fSmrg
62001e04c3fSmrgvoid GLAPIENTRY
62101e04c3fSmrg_mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
62201e04c3fSmrg                      GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
62301e04c3fSmrg                      GLbitfield mask, GLenum filter)
62401e04c3fSmrg{
62501e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
62601e04c3fSmrg
62701e04c3fSmrg   if (MESA_VERBOSE & VERBOSE_API)
62801e04c3fSmrg      _mesa_debug(ctx,
62901e04c3fSmrg                  "glBlitFramebuffer(%d, %d, %d, %d, "
63001e04c3fSmrg                  " %d, %d, %d, %d, 0x%x, %s)\n",
63101e04c3fSmrg                  srcX0, srcY0, srcX1, srcY1,
63201e04c3fSmrg                  dstX0, dstY0, dstX1, dstY1,
63301e04c3fSmrg                  mask, _mesa_enum_to_string(filter));
63401e04c3fSmrg
63501e04c3fSmrg   blit_framebuffer_err(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
63601e04c3fSmrg                        srcX0, srcY0, srcX1, srcY1,
63701e04c3fSmrg                        dstX0, dstY0, dstX1, dstY1,
63801e04c3fSmrg                        mask, filter, "glBlitFramebuffer");
63901e04c3fSmrg}
64001e04c3fSmrg
64101e04c3fSmrg
64201e04c3fSmrgstatic ALWAYS_INLINE void
64301e04c3fSmrgblit_named_framebuffer(struct gl_context *ctx,
64401e04c3fSmrg                       GLuint readFramebuffer, GLuint drawFramebuffer,
64501e04c3fSmrg                       GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
64601e04c3fSmrg                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
64701e04c3fSmrg                       GLbitfield mask, GLenum filter, bool no_error)
64801e04c3fSmrg{
64901e04c3fSmrg   struct gl_framebuffer *readFb, *drawFb;
65001e04c3fSmrg
65101e04c3fSmrg   /*
65201e04c3fSmrg    * According to PDF page 533 of the OpenGL 4.5 core spec (30.10.2014,
65301e04c3fSmrg    * Section 18.3 Copying Pixels):
65401e04c3fSmrg    *   "... if readFramebuffer or drawFramebuffer is zero (for
65501e04c3fSmrg    *   BlitNamedFramebuffer), then the default read or draw framebuffer is
65601e04c3fSmrg    *   used as the corresponding source or destination framebuffer,
65701e04c3fSmrg    *   respectively."
65801e04c3fSmrg    */
65901e04c3fSmrg   if (readFramebuffer) {
66001e04c3fSmrg      if (no_error) {
66101e04c3fSmrg         readFb = _mesa_lookup_framebuffer(ctx, readFramebuffer);
66201e04c3fSmrg      } else {
66301e04c3fSmrg         readFb = _mesa_lookup_framebuffer_err(ctx, readFramebuffer,
66401e04c3fSmrg                                               "glBlitNamedFramebuffer");
66501e04c3fSmrg         if (!readFb)
66601e04c3fSmrg            return;
66701e04c3fSmrg      }
66801e04c3fSmrg   } else {
66901e04c3fSmrg      readFb = ctx->WinSysReadBuffer;
67001e04c3fSmrg   }
67101e04c3fSmrg
67201e04c3fSmrg   if (drawFramebuffer) {
67301e04c3fSmrg      if (no_error) {
67401e04c3fSmrg         drawFb = _mesa_lookup_framebuffer(ctx, drawFramebuffer);
67501e04c3fSmrg      } else {
67601e04c3fSmrg         drawFb = _mesa_lookup_framebuffer_err(ctx, drawFramebuffer,
67701e04c3fSmrg                                               "glBlitNamedFramebuffer");
67801e04c3fSmrg         if (!drawFb)
67901e04c3fSmrg            return;
68001e04c3fSmrg      }
68101e04c3fSmrg   } else {
68201e04c3fSmrg      drawFb = ctx->WinSysDrawBuffer;
68301e04c3fSmrg   }
68401e04c3fSmrg
68501e04c3fSmrg   blit_framebuffer(ctx, readFb, drawFb,
68601e04c3fSmrg                    srcX0, srcY0, srcX1, srcY1,
68701e04c3fSmrg                    dstX0, dstY0, dstX1, dstY1,
68801e04c3fSmrg                    mask, filter, no_error, "glBlitNamedFramebuffer");
68901e04c3fSmrg}
69001e04c3fSmrg
69101e04c3fSmrg
69201e04c3fSmrgvoid GLAPIENTRY
69301e04c3fSmrg_mesa_BlitNamedFramebuffer_no_error(GLuint readFramebuffer,
69401e04c3fSmrg                                    GLuint drawFramebuffer,
69501e04c3fSmrg                                    GLint srcX0, GLint srcY0,
69601e04c3fSmrg                                    GLint srcX1, GLint srcY1,
69701e04c3fSmrg                                    GLint dstX0, GLint dstY0,
69801e04c3fSmrg                                    GLint dstX1, GLint dstY1,
69901e04c3fSmrg                                    GLbitfield mask, GLenum filter)
70001e04c3fSmrg{
70101e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
70201e04c3fSmrg
70301e04c3fSmrg   blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer,
70401e04c3fSmrg                          srcX0, srcY0, srcX1, srcY1,
70501e04c3fSmrg                          dstX0, dstY0, dstX1, dstY1,
70601e04c3fSmrg                          mask, filter, true);
70701e04c3fSmrg}
70801e04c3fSmrg
70901e04c3fSmrg
71001e04c3fSmrgvoid GLAPIENTRY
71101e04c3fSmrg_mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer,
71201e04c3fSmrg                           GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
71301e04c3fSmrg                           GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
71401e04c3fSmrg                           GLbitfield mask, GLenum filter)
71501e04c3fSmrg{
71601e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
71701e04c3fSmrg
71801e04c3fSmrg   if (MESA_VERBOSE & VERBOSE_API)
71901e04c3fSmrg      _mesa_debug(ctx,
72001e04c3fSmrg                  "glBlitNamedFramebuffer(%u %u %d, %d, %d, %d, "
72101e04c3fSmrg                  " %d, %d, %d, %d, 0x%x, %s)\n",
72201e04c3fSmrg                  readFramebuffer, drawFramebuffer,
72301e04c3fSmrg                  srcX0, srcY0, srcX1, srcY1,
72401e04c3fSmrg                  dstX0, dstY0, dstX1, dstY1,
72501e04c3fSmrg                  mask, _mesa_enum_to_string(filter));
72601e04c3fSmrg
72701e04c3fSmrg   blit_named_framebuffer(ctx, readFramebuffer, drawFramebuffer,
72801e04c3fSmrg                          srcX0, srcY0, srcX1, srcY1,
72901e04c3fSmrg                          dstX0, dstY0, dstX1, dstY1,
73001e04c3fSmrg                          mask, filter, false);
73101e04c3fSmrg}
732