blit.c revision 848b8605
1848b8605Smrg/*
2848b8605Smrg * Mesa 3-D graphics library
3848b8605Smrg *
4848b8605Smrg * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5848b8605Smrg * Copyright (C) 1999-2013  VMware, Inc.  All Rights Reserved.
6848b8605Smrg *
7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
8848b8605Smrg * copy of this software and associated documentation files (the "Software"),
9848b8605Smrg * to deal in the Software without restriction, including without limitation
10848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
12848b8605Smrg * Software is furnished to do so, subject to the following conditions:
13848b8605Smrg *
14848b8605Smrg * The above copyright notice and this permission notice shall be included
15848b8605Smrg * in all copies or substantial portions of the Software.
16848b8605Smrg *
17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE.
24848b8605Smrg */
25848b8605Smrg
26848b8605Smrg/*
27848b8605Smrg * glBlitFramebuffer functions.
28848b8605Smrg */
29848b8605Smrg
30848b8605Smrg#include <stdbool.h>
31848b8605Smrg
32848b8605Smrg#include "context.h"
33848b8605Smrg#include "enums.h"
34848b8605Smrg#include "blit.h"
35848b8605Smrg#include "fbobject.h"
36848b8605Smrg#include "glformats.h"
37848b8605Smrg#include "mtypes.h"
38848b8605Smrg#include "state.h"
39848b8605Smrg
40848b8605Smrg
41848b8605Smrg/** Set this to 1 to debug/log glBlitFramebuffer() calls */
42848b8605Smrg#define DEBUG_BLIT 0
43848b8605Smrg
44848b8605Smrg
45848b8605Smrg
46848b8605Smrgstatic const struct gl_renderbuffer_attachment *
47848b8605Smrgfind_attachment(const struct gl_framebuffer *fb,
48848b8605Smrg                const struct gl_renderbuffer *rb)
49848b8605Smrg{
50848b8605Smrg   GLuint i;
51848b8605Smrg   for (i = 0; i < Elements(fb->Attachment); i++) {
52848b8605Smrg      if (fb->Attachment[i].Renderbuffer == rb)
53848b8605Smrg         return &fb->Attachment[i];
54848b8605Smrg   }
55848b8605Smrg   return NULL;
56848b8605Smrg}
57848b8605Smrg
58848b8605Smrg
59848b8605Smrg/**
60848b8605Smrg * Helper function for checking if the datatypes of color buffers are
61848b8605Smrg * compatible for glBlitFramebuffer.  From the 3.1 spec, page 198:
62848b8605Smrg *
63848b8605Smrg * "GL_INVALID_OPERATION is generated if mask contains GL_COLOR_BUFFER_BIT
64848b8605Smrg *  and any of the following conditions hold:
65848b8605Smrg *   - The read buffer contains fixed-point or floating-point values and any
66848b8605Smrg *     draw buffer contains neither fixed-point nor floating-point values.
67848b8605Smrg *   - The read buffer contains unsigned integer values and any draw buffer
68848b8605Smrg *     does not contain unsigned integer values.
69848b8605Smrg *   - The read buffer contains signed integer values and any draw buffer
70848b8605Smrg *     does not contain signed integer values."
71848b8605Smrg */
72848b8605Smrgstatic GLboolean
73848b8605Smrgcompatible_color_datatypes(mesa_format srcFormat, mesa_format dstFormat)
74848b8605Smrg{
75848b8605Smrg   GLenum srcType = _mesa_get_format_datatype(srcFormat);
76848b8605Smrg   GLenum dstType = _mesa_get_format_datatype(dstFormat);
77848b8605Smrg
78848b8605Smrg   if (srcType != GL_INT && srcType != GL_UNSIGNED_INT) {
79848b8605Smrg      assert(srcType == GL_UNSIGNED_NORMALIZED ||
80848b8605Smrg             srcType == GL_SIGNED_NORMALIZED ||
81848b8605Smrg             srcType == GL_FLOAT);
82848b8605Smrg      /* Boil any of those types down to GL_FLOAT */
83848b8605Smrg      srcType = GL_FLOAT;
84848b8605Smrg   }
85848b8605Smrg
86848b8605Smrg   if (dstType != GL_INT && dstType != GL_UNSIGNED_INT) {
87848b8605Smrg      assert(dstType == GL_UNSIGNED_NORMALIZED ||
88848b8605Smrg             dstType == GL_SIGNED_NORMALIZED ||
89848b8605Smrg             dstType == GL_FLOAT);
90848b8605Smrg      /* Boil any of those types down to GL_FLOAT */
91848b8605Smrg      dstType = GL_FLOAT;
92848b8605Smrg   }
93848b8605Smrg
94848b8605Smrg   return srcType == dstType;
95848b8605Smrg}
96848b8605Smrg
97848b8605Smrg
98848b8605Smrgstatic GLboolean
99848b8605Smrgcompatible_resolve_formats(const struct gl_renderbuffer *readRb,
100848b8605Smrg                           const struct gl_renderbuffer *drawRb)
101848b8605Smrg{
102848b8605Smrg   GLenum readFormat, drawFormat;
103848b8605Smrg
104848b8605Smrg   /* The simple case where we know the backing Mesa formats are the same.
105848b8605Smrg    */
106848b8605Smrg   if (_mesa_get_srgb_format_linear(readRb->Format) ==
107848b8605Smrg       _mesa_get_srgb_format_linear(drawRb->Format)) {
108848b8605Smrg      return GL_TRUE;
109848b8605Smrg   }
110848b8605Smrg
111848b8605Smrg   /* The Mesa formats are different, so we must check whether the internal
112848b8605Smrg    * formats are compatible.
113848b8605Smrg    *
114848b8605Smrg    * Under some circumstances, the user may request e.g. two GL_RGBA8
115848b8605Smrg    * textures and get two entirely different Mesa formats like RGBA8888 and
116848b8605Smrg    * ARGB8888. Drivers behaving like that should be able to cope with
117848b8605Smrg    * non-matching formats by themselves, because it's not the user's fault.
118848b8605Smrg    *
119848b8605Smrg    * Blits between linear and sRGB formats are also allowed.
120848b8605Smrg    */
121848b8605Smrg   readFormat = _mesa_get_nongeneric_internalformat(readRb->InternalFormat);
122848b8605Smrg   drawFormat = _mesa_get_nongeneric_internalformat(drawRb->InternalFormat);
123848b8605Smrg   readFormat = _mesa_get_linear_internalformat(readFormat);
124848b8605Smrg   drawFormat = _mesa_get_linear_internalformat(drawFormat);
125848b8605Smrg
126848b8605Smrg   if (readFormat == drawFormat) {
127848b8605Smrg      return GL_TRUE;
128848b8605Smrg   }
129848b8605Smrg
130848b8605Smrg   return GL_FALSE;
131848b8605Smrg}
132848b8605Smrg
133848b8605Smrg
134848b8605Smrgstatic GLboolean
135848b8605Smrgis_valid_blit_filter(const struct gl_context *ctx, GLenum filter)
136848b8605Smrg{
137848b8605Smrg   switch (filter) {
138848b8605Smrg   case GL_NEAREST:
139848b8605Smrg   case GL_LINEAR:
140848b8605Smrg      return true;
141848b8605Smrg   case GL_SCALED_RESOLVE_FASTEST_EXT:
142848b8605Smrg   case GL_SCALED_RESOLVE_NICEST_EXT:
143848b8605Smrg      return ctx->Extensions.EXT_framebuffer_multisample_blit_scaled;
144848b8605Smrg   default:
145848b8605Smrg      return false;
146848b8605Smrg   }
147848b8605Smrg}
148848b8605Smrg
149848b8605Smrg
150848b8605Smrg/**
151848b8605Smrg * Blit rectangular region, optionally from one framebuffer to another.
152848b8605Smrg *
153848b8605Smrg * Note, if the src buffer is multisampled and the dest is not, this is
154848b8605Smrg * when the samples must be resolved to a single color.
155848b8605Smrg */
156848b8605Smrgvoid GLAPIENTRY
157848b8605Smrg_mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
158848b8605Smrg                         GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
159848b8605Smrg                         GLbitfield mask, GLenum filter)
160848b8605Smrg{
161848b8605Smrg   const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
162848b8605Smrg                                     GL_DEPTH_BUFFER_BIT |
163848b8605Smrg                                     GL_STENCIL_BUFFER_BIT);
164848b8605Smrg   const struct gl_framebuffer *readFb, *drawFb;
165848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
166848b8605Smrg
167848b8605Smrg   FLUSH_VERTICES(ctx, 0);
168848b8605Smrg
169848b8605Smrg   if (MESA_VERBOSE & VERBOSE_API)
170848b8605Smrg      _mesa_debug(ctx,
171848b8605Smrg                  "glBlitFramebuffer(%d, %d, %d, %d,  %d, %d, %d, %d, 0x%x, %s)\n",
172848b8605Smrg                  srcX0, srcY0, srcX1, srcY1,
173848b8605Smrg                  dstX0, dstY0, dstX1, dstY1,
174848b8605Smrg                  mask, _mesa_lookup_enum_by_nr(filter));
175848b8605Smrg
176848b8605Smrg   if (ctx->NewState) {
177848b8605Smrg      _mesa_update_state(ctx);
178848b8605Smrg   }
179848b8605Smrg
180848b8605Smrg   readFb = ctx->ReadBuffer;
181848b8605Smrg   drawFb = ctx->DrawBuffer;
182848b8605Smrg
183848b8605Smrg   if (!readFb || !drawFb) {
184848b8605Smrg      /* This will normally never happen but someday we may want to
185848b8605Smrg       * support MakeCurrent() with no drawables.
186848b8605Smrg       */
187848b8605Smrg      return;
188848b8605Smrg   }
189848b8605Smrg
190848b8605Smrg   /* check for complete framebuffers */
191848b8605Smrg   if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
192848b8605Smrg       readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
193848b8605Smrg      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
194848b8605Smrg                  "glBlitFramebufferEXT(incomplete draw/read buffers)");
195848b8605Smrg      return;
196848b8605Smrg   }
197848b8605Smrg
198848b8605Smrg   if (!is_valid_blit_filter(ctx, filter)) {
199848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glBlitFramebufferEXT(%s)",
200848b8605Smrg                  _mesa_lookup_enum_by_nr(filter));
201848b8605Smrg      return;
202848b8605Smrg   }
203848b8605Smrg
204848b8605Smrg   if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
205848b8605Smrg        filter == GL_SCALED_RESOLVE_NICEST_EXT) &&
206848b8605Smrg        (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) {
207848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT(%s)",
208848b8605Smrg                  _mesa_lookup_enum_by_nr(filter));
209848b8605Smrg      return;
210848b8605Smrg   }
211848b8605Smrg
212848b8605Smrg   if (mask & ~legalMaskBits) {
213848b8605Smrg      _mesa_error( ctx, GL_INVALID_VALUE, "glBlitFramebufferEXT(mask)");
214848b8605Smrg      return;
215848b8605Smrg   }
216848b8605Smrg
217848b8605Smrg   /* depth/stencil must be blitted with nearest filtering */
218848b8605Smrg   if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
219848b8605Smrg        && filter != GL_NEAREST) {
220848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
221848b8605Smrg             "glBlitFramebufferEXT(depth/stencil requires GL_NEAREST filter)");
222848b8605Smrg      return;
223848b8605Smrg   }
224848b8605Smrg
225848b8605Smrg   /* get color read/draw renderbuffers */
226848b8605Smrg   if (mask & GL_COLOR_BUFFER_BIT) {
227848b8605Smrg      const GLuint numColorDrawBuffers = ctx->DrawBuffer->_NumColorDrawBuffers;
228848b8605Smrg      const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
229848b8605Smrg      const struct gl_renderbuffer *colorDrawRb = NULL;
230848b8605Smrg      GLuint i;
231848b8605Smrg
232848b8605Smrg      /* From the EXT_framebuffer_object spec:
233848b8605Smrg       *
234848b8605Smrg       *     "If a buffer is specified in <mask> and does not exist in both
235848b8605Smrg       *     the read and draw framebuffers, the corresponding bit is silently
236848b8605Smrg       *     ignored."
237848b8605Smrg       */
238848b8605Smrg      if (!colorReadRb || numColorDrawBuffers == 0) {
239848b8605Smrg         mask &= ~GL_COLOR_BUFFER_BIT;
240848b8605Smrg      }
241848b8605Smrg      else {
242848b8605Smrg         for (i = 0; i < numColorDrawBuffers; i++) {
243848b8605Smrg            colorDrawRb = ctx->DrawBuffer->_ColorDrawBuffers[i];
244848b8605Smrg            if (!colorDrawRb)
245848b8605Smrg               continue;
246848b8605Smrg
247848b8605Smrg            /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL
248848b8605Smrg             * ES 3.0.1 spec says:
249848b8605Smrg             *
250848b8605Smrg             *     "If the source and destination buffers are identical, an
251848b8605Smrg             *     INVALID_OPERATION error is generated. Different mipmap
252848b8605Smrg             *     levels of a texture, different layers of a three-
253848b8605Smrg             *     dimensional texture or two-dimensional array texture, and
254848b8605Smrg             *     different faces of a cube map texture do not constitute
255848b8605Smrg             *     identical buffers."
256848b8605Smrg             */
257848b8605Smrg            if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) {
258848b8605Smrg               _mesa_error(ctx, GL_INVALID_OPERATION,
259848b8605Smrg                           "glBlitFramebuffer(source and destination color "
260848b8605Smrg                           "buffer cannot be the same)");
261848b8605Smrg               return;
262848b8605Smrg            }
263848b8605Smrg
264848b8605Smrg            if (!compatible_color_datatypes(colorReadRb->Format,
265848b8605Smrg                                            colorDrawRb->Format)) {
266848b8605Smrg               _mesa_error(ctx, GL_INVALID_OPERATION,
267848b8605Smrg                           "glBlitFramebufferEXT(color buffer datatypes mismatch)");
268848b8605Smrg               return;
269848b8605Smrg            }
270848b8605Smrg            /* extra checks for multisample copies... */
271848b8605Smrg            if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) {
272848b8605Smrg               /* color formats must match */
273848b8605Smrg               if (!compatible_resolve_formats(colorReadRb, colorDrawRb)) {
274848b8605Smrg                  _mesa_error(ctx, GL_INVALID_OPERATION,
275848b8605Smrg                         "glBlitFramebufferEXT(bad src/dst multisample pixel formats)");
276848b8605Smrg                  return;
277848b8605Smrg               }
278848b8605Smrg            }
279848b8605Smrg         }
280848b8605Smrg         if (filter != GL_NEAREST) {
281848b8605Smrg            /* From EXT_framebuffer_multisample_blit_scaled specification:
282848b8605Smrg             * "Calling BlitFramebuffer will result in an INVALID_OPERATION error
283848b8605Smrg             * if filter is not NEAREST and read buffer contains integer data."
284848b8605Smrg             */
285848b8605Smrg            GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
286848b8605Smrg            if (type == GL_INT || type == GL_UNSIGNED_INT) {
287848b8605Smrg               _mesa_error(ctx, GL_INVALID_OPERATION,
288848b8605Smrg                           "glBlitFramebufferEXT(integer color type)");
289848b8605Smrg               return;
290848b8605Smrg            }
291848b8605Smrg         }
292848b8605Smrg      }
293848b8605Smrg   }
294848b8605Smrg
295848b8605Smrg   if (mask & GL_STENCIL_BUFFER_BIT) {
296848b8605Smrg      struct gl_renderbuffer *readRb =
297848b8605Smrg         readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
298848b8605Smrg      struct gl_renderbuffer *drawRb =
299848b8605Smrg         drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;
300848b8605Smrg
301848b8605Smrg      /* From the EXT_framebuffer_object spec:
302848b8605Smrg       *
303848b8605Smrg       *     "If a buffer is specified in <mask> and does not exist in both
304848b8605Smrg       *     the read and draw framebuffers, the corresponding bit is silently
305848b8605Smrg       *     ignored."
306848b8605Smrg       */
307848b8605Smrg      if ((readRb == NULL) || (drawRb == NULL)) {
308848b8605Smrg	 mask &= ~GL_STENCIL_BUFFER_BIT;
309848b8605Smrg      }
310848b8605Smrg      else {
311848b8605Smrg         int read_z_bits, draw_z_bits;
312848b8605Smrg
313848b8605Smrg         if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
314848b8605Smrg            _mesa_error(ctx, GL_INVALID_OPERATION,
315848b8605Smrg                        "glBlitFramebuffer(source and destination stencil "
316848b8605Smrg                        "buffer cannot be the same)");
317848b8605Smrg            return;
318848b8605Smrg         }
319848b8605Smrg
320848b8605Smrg         if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
321848b8605Smrg             _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
322848b8605Smrg            /* There is no need to check the stencil datatype here, because
323848b8605Smrg             * there is only one: GL_UNSIGNED_INT.
324848b8605Smrg             */
325848b8605Smrg            _mesa_error(ctx, GL_INVALID_OPERATION,
326848b8605Smrg                        "glBlitFramebuffer(stencil attachment format mismatch)");
327848b8605Smrg            return;
328848b8605Smrg         }
329848b8605Smrg
330848b8605Smrg         read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS);
331848b8605Smrg         draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS);
332848b8605Smrg
333848b8605Smrg         /* If both buffers also have depth data, the depth formats must match
334848b8605Smrg          * as well.  If one doesn't have depth, it's not blitted, so we should
335848b8605Smrg          * ignore the depth format check.
336848b8605Smrg          */
337848b8605Smrg         if (read_z_bits > 0 && draw_z_bits > 0 &&
338848b8605Smrg             (read_z_bits != draw_z_bits ||
339848b8605Smrg              _mesa_get_format_datatype(readRb->Format) !=
340848b8605Smrg              _mesa_get_format_datatype(drawRb->Format))) {
341848b8605Smrg
342848b8605Smrg            _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer"
343848b8605Smrg                        "(stencil attachment depth format mismatch)");
344848b8605Smrg            return;
345848b8605Smrg         }
346848b8605Smrg      }
347848b8605Smrg   }
348848b8605Smrg
349848b8605Smrg   if (mask & GL_DEPTH_BUFFER_BIT) {
350848b8605Smrg      struct gl_renderbuffer *readRb =
351848b8605Smrg         readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
352848b8605Smrg      struct gl_renderbuffer *drawRb =
353848b8605Smrg         drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
354848b8605Smrg
355848b8605Smrg      /* From the EXT_framebuffer_object spec:
356848b8605Smrg       *
357848b8605Smrg       *     "If a buffer is specified in <mask> and does not exist in both
358848b8605Smrg       *     the read and draw framebuffers, the corresponding bit is silently
359848b8605Smrg       *     ignored."
360848b8605Smrg       */
361848b8605Smrg      if ((readRb == NULL) || (drawRb == NULL)) {
362848b8605Smrg	 mask &= ~GL_DEPTH_BUFFER_BIT;
363848b8605Smrg      }
364848b8605Smrg      else {
365848b8605Smrg         int read_s_bit, draw_s_bit;
366848b8605Smrg
367848b8605Smrg         if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
368848b8605Smrg            _mesa_error(ctx, GL_INVALID_OPERATION,
369848b8605Smrg                        "glBlitFramebuffer(source and destination depth "
370848b8605Smrg                        "buffer cannot be the same)");
371848b8605Smrg            return;
372848b8605Smrg         }
373848b8605Smrg
374848b8605Smrg         if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
375848b8605Smrg              _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) ||
376848b8605Smrg             (_mesa_get_format_datatype(readRb->Format) !=
377848b8605Smrg              _mesa_get_format_datatype(drawRb->Format))) {
378848b8605Smrg            _mesa_error(ctx, GL_INVALID_OPERATION,
379848b8605Smrg                        "glBlitFramebuffer(depth attachment format mismatch)");
380848b8605Smrg            return;
381848b8605Smrg         }
382848b8605Smrg
383848b8605Smrg         read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS);
384848b8605Smrg         draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS);
385848b8605Smrg
386848b8605Smrg         /* If both buffers also have stencil data, the stencil formats must
387848b8605Smrg          * match as well.  If one doesn't have stencil, it's not blitted, so
388848b8605Smrg          * we should ignore the stencil format check.
389848b8605Smrg          */
390848b8605Smrg         if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) {
391848b8605Smrg            _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer"
392848b8605Smrg                        "(depth attachment stencil bits mismatch)");
393848b8605Smrg            return;
394848b8605Smrg         }
395848b8605Smrg      }
396848b8605Smrg   }
397848b8605Smrg
398848b8605Smrg
399848b8605Smrg   if (_mesa_is_gles3(ctx)) {
400848b8605Smrg      /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
401848b8605Smrg       * 3.0.1 spec says:
402848b8605Smrg       *
403848b8605Smrg       *     "If SAMPLE_BUFFERS for the draw framebuffer is greater than zero,
404848b8605Smrg       *     an INVALID_OPERATION error is generated."
405848b8605Smrg       */
406848b8605Smrg      if (drawFb->Visual.samples > 0) {
407848b8605Smrg         _mesa_error(ctx, GL_INVALID_OPERATION,
408848b8605Smrg                     "glBlitFramebuffer(destination samples must be 0)");
409848b8605Smrg         return;
410848b8605Smrg      }
411848b8605Smrg
412848b8605Smrg      /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
413848b8605Smrg       * 3.0.1 spec says:
414848b8605Smrg       *
415848b8605Smrg       *     "If SAMPLE_BUFFERS for the read framebuffer is greater than zero,
416848b8605Smrg       *     no copy is performed and an INVALID_OPERATION error is generated
417848b8605Smrg       *     if the formats of the read and draw framebuffers are not
418848b8605Smrg       *     identical or if the source and destination rectangles are not
419848b8605Smrg       *     defined with the same (X0, Y0) and (X1, Y1) bounds."
420848b8605Smrg       *
421848b8605Smrg       * The format check was made above because desktop OpenGL has the same
422848b8605Smrg       * requirement.
423848b8605Smrg       */
424848b8605Smrg      if (readFb->Visual.samples > 0
425848b8605Smrg          && (srcX0 != dstX0 || srcY0 != dstY0
426848b8605Smrg              || srcX1 != dstX1 || srcY1 != dstY1)) {
427848b8605Smrg         _mesa_error(ctx, GL_INVALID_OPERATION,
428848b8605Smrg                     "glBlitFramebuffer(bad src/dst multisample region)");
429848b8605Smrg         return;
430848b8605Smrg      }
431848b8605Smrg   } else {
432848b8605Smrg      if (readFb->Visual.samples > 0 &&
433848b8605Smrg          drawFb->Visual.samples > 0 &&
434848b8605Smrg          readFb->Visual.samples != drawFb->Visual.samples) {
435848b8605Smrg         _mesa_error(ctx, GL_INVALID_OPERATION,
436848b8605Smrg                     "glBlitFramebufferEXT(mismatched samples)");
437848b8605Smrg         return;
438848b8605Smrg      }
439848b8605Smrg
440848b8605Smrg      /* extra checks for multisample copies... */
441848b8605Smrg      if ((readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) &&
442848b8605Smrg          (filter == GL_NEAREST || filter == GL_LINEAR)) {
443848b8605Smrg         /* src and dest region sizes must be the same */
444848b8605Smrg         if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) ||
445848b8605Smrg             abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) {
446848b8605Smrg            _mesa_error(ctx, GL_INVALID_OPERATION,
447848b8605Smrg                        "glBlitFramebufferEXT(bad src/dst multisample region sizes)");
448848b8605Smrg            return;
449848b8605Smrg         }
450848b8605Smrg      }
451848b8605Smrg   }
452848b8605Smrg
453848b8605Smrg   /* Debug code */
454848b8605Smrg   if (DEBUG_BLIT) {
455848b8605Smrg      const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
456848b8605Smrg      const struct gl_renderbuffer *colorDrawRb = NULL;
457848b8605Smrg      GLuint i = 0;
458848b8605Smrg
459848b8605Smrg      printf("glBlitFramebuffer(%d, %d, %d, %d,  %d, %d, %d, %d,"
460848b8605Smrg	     " 0x%x, 0x%x)\n",
461848b8605Smrg	     srcX0, srcY0, srcX1, srcY1,
462848b8605Smrg	     dstX0, dstY0, dstX1, dstY1,
463848b8605Smrg	     mask, filter);
464848b8605Smrg      if (colorReadRb) {
465848b8605Smrg         const struct gl_renderbuffer_attachment *att;
466848b8605Smrg
467848b8605Smrg         att = find_attachment(readFb, colorReadRb);
468848b8605Smrg         printf("  Src FBO %u  RB %u (%dx%d)  ",
469848b8605Smrg		readFb->Name, colorReadRb->Name,
470848b8605Smrg		colorReadRb->Width, colorReadRb->Height);
471848b8605Smrg         if (att && att->Texture) {
472848b8605Smrg            printf("Tex %u  tgt 0x%x  level %u  face %u",
473848b8605Smrg		   att->Texture->Name,
474848b8605Smrg		   att->Texture->Target,
475848b8605Smrg		   att->TextureLevel,
476848b8605Smrg		   att->CubeMapFace);
477848b8605Smrg         }
478848b8605Smrg         printf("\n");
479848b8605Smrg
480848b8605Smrg         /* Print all active color render buffers */
481848b8605Smrg         for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
482848b8605Smrg            colorDrawRb = ctx->DrawBuffer->_ColorDrawBuffers[i];
483848b8605Smrg            if (!colorDrawRb)
484848b8605Smrg               continue;
485848b8605Smrg
486848b8605Smrg            att = find_attachment(drawFb, colorDrawRb);
487848b8605Smrg            printf("  Dst FBO %u  RB %u (%dx%d)  ",
488848b8605Smrg		   drawFb->Name, colorDrawRb->Name,
489848b8605Smrg		   colorDrawRb->Width, colorDrawRb->Height);
490848b8605Smrg            if (att && att->Texture) {
491848b8605Smrg               printf("Tex %u  tgt 0x%x  level %u  face %u",
492848b8605Smrg		      att->Texture->Name,
493848b8605Smrg		      att->Texture->Target,
494848b8605Smrg		      att->TextureLevel,
495848b8605Smrg		      att->CubeMapFace);
496848b8605Smrg            }
497848b8605Smrg            printf("\n");
498848b8605Smrg         }
499848b8605Smrg      }
500848b8605Smrg   }
501848b8605Smrg
502848b8605Smrg   if (!mask ||
503848b8605Smrg       (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 ||
504848b8605Smrg       (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) {
505848b8605Smrg      return;
506848b8605Smrg   }
507848b8605Smrg
508848b8605Smrg   ASSERT(ctx->Driver.BlitFramebuffer);
509848b8605Smrg   ctx->Driver.BlitFramebuffer(ctx,
510848b8605Smrg                               srcX0, srcY0, srcX1, srcY1,
511848b8605Smrg                               dstX0, dstY0, dstX1, dstY1,
512848b8605Smrg                               mask, filter);
513848b8605Smrg}
514