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 <italonicola@collabora.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10747>
This commit is contained in:
Italo Nicola
2023-02-21 16:32:03 +00:00
committed by Marge Bot
parent 4d1a07c1a0
commit d7b9da2673
4 changed files with 57 additions and 2 deletions

View 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

View 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);

View 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;
}

View 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;