mesa/main: allow readpix/teximage to read from implicitly multisampled fbos
authorItalo Nicola <italonicola@collabora.com>
Tue, 21 Feb 2023 16:32:03 +0000 (16:32 +0000)
committerMarge Bot <emma+marge@anholt.net>
Tue, 1 Aug 2023 21:22:28 +0000 (21:22 +0000)
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 <italonicola@collabora.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10747>

src/mesa/main/framebuffer.c
src/mesa/main/framebuffer.h
src/mesa/main/readpix.c
src/mesa/main/teximage.c

index 5d2c004..962cd7c 100644 (file)
@@ -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
index 8891e4e..60c53e6 100644 (file)
@@ -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);
 
index e7ab5f6..9978884 100644 (file)
@@ -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;
       }
index a8fd97d..412fce4 100644 (file)
@@ -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;