diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index 5d2c0044e85..962cd7c5334 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -828,6 +828,22 @@ _mesa_dest_buffer_exists(struct gl_context *ctx, GLenum format) return renderbuffer_exists(ctx, ctx->DrawBuffer, format, GL_FALSE); } +extern bool +_mesa_has_rtt_samples(const struct gl_framebuffer *fb) +{ + /* If there are multiple attachments, all of them are guaranteed + * to have the same sample count. */ + if (fb->_ColorReadBufferIndex) { + assert(fb->Attachment[fb->_ColorReadBufferIndex].Type != GL_NONE); + return fb->Attachment[fb->_ColorReadBufferIndex].NumSamples > 0; + } else if (fb->Attachment[BUFFER_DEPTH].Type != GL_NONE) { + return fb->Attachment[BUFFER_DEPTH].NumSamples > 0; + } else if (fb->Attachment[BUFFER_STENCIL].Type != GL_NONE) { + return fb->Attachment[BUFFER_STENCIL].NumSamples > 0; + } + + return true; +} /** * Used to answer the GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES queries (using diff --git a/src/mesa/main/framebuffer.h b/src/mesa/main/framebuffer.h index 8891e4e4164..60c53e6af21 100644 --- a/src/mesa/main/framebuffer.h +++ b/src/mesa/main/framebuffer.h @@ -161,6 +161,9 @@ extern struct gl_renderbuffer * _mesa_get_read_renderbuffer_for_format(const struct gl_context *ctx, GLenum format); +extern bool +_mesa_has_rtt_samples(const struct gl_framebuffer *fb); + extern void _mesa_print_framebuffer(const struct gl_framebuffer *fb); diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c index e7ab5f681d0..99788846058 100644 --- a/src/mesa/main/readpix.c +++ b/src/mesa/main/readpix.c @@ -1119,8 +1119,25 @@ read_pixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, return; } + /** + * From the GL_EXT_multisampled_render_to_texture spec: + * + * Similarly, for ReadPixels: + * "An INVALID_OPERATION error is generated if the value of READ_- + * FRAMEBUFFER_BINDING (see section 9) is non-zero, the read framebuffer + * is framebuffer complete, and the value of SAMPLE_BUFFERS for the read + * framebuffer is one." + * + * These errors do not apply to textures and renderbuffers that have + * associated multisample data specified by the mechanisms described in + * this extension, i.e., the above operations are allowed even when + * SAMPLE_BUFFERS is non-zero for renderbuffers created via Renderbuffer- + * StorageMultisampleEXT or textures attached via FramebufferTexture2D- + * MultisampleEXT. + */ if (_mesa_is_user_fbo(ctx->ReadBuffer) && - ctx->ReadBuffer->Visual.samples > 0) { + ctx->ReadBuffer->Visual.samples > 0 && + !_mesa_has_rtt_samples(ctx->ReadBuffer)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)"); return; } diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index a8fd97d9f63..412fce4d8c7 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -2692,8 +2692,27 @@ copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions, return GL_TRUE; } + /** + * From the GL_EXT_multisampled_render_to_texture spec: + * + * "An INVALID_OPERATION error is generated by CopyTexSubImage3D, + * CopyTexImage2D, or CopyTexSubImage2D if [...] the value of + * READ_FRAMEBUFFER_BINDING is non-zero, and: + * - the read buffer selects an attachment that has no image attached, + * or + * - the value of SAMPLE_BUFFERS for the read framebuffer is one." + * + * [...] + * These errors do not apply to textures and renderbuffers that have + * associated multisample data specified by the mechanisms described in + * this extension, i.e., the above operations are allowed even when + * SAMPLE_BUFFERS is non-zero for renderbuffers created via Renderbuffer- + * StorageMultisampleEXT or textures attached via FramebufferTexture2D- + * MultisampleEXT. + */ if (!ctx->st_opts->allow_multisampled_copyteximage && - ctx->ReadBuffer->Visual.samples > 0) { + ctx->ReadBuffer->Visual.samples > 0 && + !_mesa_has_rtt_samples(ctx->ReadBuffer)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(multisample FBO)", caller); return GL_TRUE;