+static bool
+validate_color_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb,
+ struct gl_framebuffer *drawFb, GLenum filter,
+ const char *func)
+{
+ const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
+ const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
+ const struct gl_renderbuffer *colorDrawRb = NULL;
+ GLuint i;
+
+ for (i = 0; i < numColorDrawBuffers; i++) {
+ colorDrawRb = drawFb->_ColorDrawBuffers[i];
+ if (!colorDrawRb)
+ continue;
+
+ /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL
+ * ES 3.0.1 spec says:
+ *
+ * "If the source and destination buffers are identical, an
+ * INVALID_OPERATION error is generated. Different mipmap levels of a
+ * texture, different layers of a three- dimensional texture or
+ * two-dimensional array texture, and different faces of a cube map
+ * texture do not constitute identical buffers."
+ */
+ if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(source and destination color buffer cannot be the "
+ "same)", func);
+ return false;
+ }
+
+ if (!compatible_color_datatypes(colorReadRb->Format,
+ colorDrawRb->Format)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(color buffer datatypes mismatch)", func);
+ return false;
+ }
+
+ /* extra checks for multisample copies... */
+ if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) {
+ /* color formats must match on GLES. This isn't checked on desktop GL
+ * because the GL 4.4 spec was changed to allow it. In the section
+ * entitled “Changes in the released
+ * Specification of July 22, 2013” it says:
+ *
+ * “Relax BlitFramebuffer in section 18.3.1 so that format conversion
+ * can take place during multisample blits, since drivers already
+ * allow this and some apps depend on it.”
+ */
+ if (_mesa_is_gles(ctx) &&
+ !compatible_resolve_formats(colorReadRb, colorDrawRb)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(bad src/dst multisample pixel formats)", func);
+ return false;
+ }
+ }
+
+ }
+
+ if (filter != GL_NEAREST) {
+ /* From EXT_framebuffer_multisample_blit_scaled specification:
+ * "Calling BlitFramebuffer will result in an INVALID_OPERATION error if
+ * filter is not NEAREST and read buffer contains integer data."
+ */
+ GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
+ if (type == GL_INT || type == GL_UNSIGNED_INT) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(integer color type)", func);
+ return false;
+ }
+ }
+ return true;
+}
+
+
+static bool
+validate_stencil_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb,
+ struct gl_framebuffer *drawFb, const char *func)
+{
+ struct gl_renderbuffer *readRb =
+ readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
+ struct gl_renderbuffer *drawRb =
+ drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;
+ int read_z_bits, draw_z_bits;
+
+ if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(source and destination stencil buffer cannot be the "
+ "same)", func);
+ return false;
+ }
+
+ if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
+ _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
+ /* There is no need to check the stencil datatype here, because
+ * there is only one: GL_UNSIGNED_INT.
+ */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(stencil attachment format mismatch)", func);
+ return false;
+ }
+
+ read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS);
+ draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS);
+
+ /* If both buffers also have depth data, the depth formats must match
+ * as well. If one doesn't have depth, it's not blitted, so we should
+ * ignore the depth format check.
+ */
+ if (read_z_bits > 0 && draw_z_bits > 0 &&
+ (read_z_bits != draw_z_bits ||
+ _mesa_get_format_datatype(readRb->Format) !=
+ _mesa_get_format_datatype(drawRb->Format))) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(stencil attachment depth format mismatch)", func);
+ return false;
+ }
+ return true;
+}
+
+
+static bool
+validate_depth_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb,
+ struct gl_framebuffer *drawFb, const char *func)
+{
+ struct gl_renderbuffer *readRb =
+ readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ struct gl_renderbuffer *drawRb =
+ drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ int read_s_bit, draw_s_bit;
+
+ if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(source and destination depth buffer cannot be the same)",
+ func);
+ return false;
+ }
+
+ if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
+ _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) ||
+ (_mesa_get_format_datatype(readRb->Format) !=
+ _mesa_get_format_datatype(drawRb->Format))) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(depth attachment format mismatch)", func);
+ return false;
+ }
+
+ read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS);
+ draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS);
+
+ /* If both buffers also have stencil data, the stencil formats must match as
+ * well. If one doesn't have stencil, it's not blitted, so we should ignore
+ * the stencil format check.
+ */
+ if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(depth attachment stencil bits mismatch)", func);
+ return false;
+ }
+ return true;
+}
+
+