From d7b9da2673a8aef49f83dc043aae6ff4fcb212a3 Mon Sep 17 00:00:00 2001 From: Italo Nicola Date: Tue, 21 Feb 2023 16:32:03 +0000 Subject: [PATCH] mesa/main: allow readpix/teximage to read from implicitly multisampled fbos The GL_EXT_multisampled_render_to_texture spec explicitly allow reading from these FBOs. "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." Signed-off-by: Italo Nicola Reviewed-by: Emma Anholt Part-of: --- src/mesa/main/framebuffer.c | 16 ++++++++++++++++ src/mesa/main/framebuffer.h | 3 +++ src/mesa/main/readpix.c | 19 ++++++++++++++++++- src/mesa/main/teximage.c | 21 ++++++++++++++++++++- 4 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index 5d2c004..962cd7c 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 8891e4e..60c53e6 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 e7ab5f6..99788846 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 a8fd97d..412fce4 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; -- 2.7.4