From f2c69e6a2beca9fd5bbdf24690fc2dacd17de8bb Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 20 Sep 2024 10:30:28 -0400 Subject: [PATCH] mesa: fix sample count handling for MSRTT this extension specifies error checking (which was not implemented) and also sample count clamping needs to be done since the samples specified are just min samples and not an exact param cc: mesa-stable Part-of: (cherry picked from commit 894b37e06099c60f371e9b181e3f84cfc29c49bb) --- .pick_status.json | 2 +- src/mesa/main/fbobject.c | 22 ++++++++++++++++++++++ src/mesa/main/renderbuffer.c | 25 +++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 65c10523e8d..8037d530d2d 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -4294,7 +4294,7 @@ "description": "mesa: fix sample count handling for MSRTT", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 8a7d9d876a4..8eae28e7cd9 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -3966,6 +3966,28 @@ _mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb, { FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0); + /* EXT_multisampled_render_to_texture: + + If samples is greater than the + value of MAX_SAMPLES_EXT, then the error INVALID_VALUE is generated. + An INVALID_OPERATION error is generated if samples is greater than + the maximum number of samples supported for target and its + internalformat. If samples is zero, then TEXTURE_SAMPLES_EXT is set + to zero, and FramebufferTexture2DMultisampleEXT behaves like + FramebufferTexture2D. + */ + if (samples > ctx->Const.MaxSamples) { + _mesa_error(ctx, GL_INVALID_VALUE, "invalid sample count %u", + samples); + return; + } + if (samples > ctx->Const.MaxFramebufferSamples) { + _mesa_error(ctx, GL_INVALID_OPERATION, "invalid sample count %u", + samples); + return; + } + + simple_mtx_lock(&fb->Mutex); if (texObj) { if (attachment == GL_DEPTH_ATTACHMENT && diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c index dd3d7da4af6..31d85337b71 100644 --- a/src/mesa/main/renderbuffer.c +++ b/src/mesa/main/renderbuffer.c @@ -627,6 +627,27 @@ _mesa_update_renderbuffer_surface(struct gl_context *ctx, last_layer); } + int nr_samples = rb->rtt_nr_samples; + if (rb->rtt_nr_samples && rb->rtt_nr_samples != resource->nr_samples) { + assert(!resource->nr_samples); + /* EXT_multisampled_render_to_texture: + + Otherwise samples represents a request for a desired minimum number + of samples. Since different implementations may support different + sample counts for multisampled rendering, the actual number of samples + allocated for the image is implementation-dependent. However, the + resulting value for TEXTURE_SAMPLES_EXT is guaranteed to be greater + than or equal to samples and no more than the next larger sample count + supported by the implementation. + */ + for (unsigned i = rb->rtt_nr_samples + 1; i <= ctx->Const.MaxFramebufferSamples; i++) { + if (!ctx->st->screen->is_format_supported(ctx->st->screen, format, resource->target, i, i, resource->bind)) + continue; + nr_samples = i; + break; + } + } + struct pipe_surface **psurf = enable_srgb ? &rb->surface_srgb : &rb->surface_linear; struct pipe_surface *surf = *psurf; @@ -638,7 +659,7 @@ _mesa_update_renderbuffer_surface(struct gl_context *ctx, surf->texture != resource || surf->width != rtt_width || surf->height != rtt_height || - surf->nr_samples != rb->rtt_nr_samples || + surf->nr_samples != nr_samples || surf->u.tex.level != level || surf->u.tex.first_layer != first_layer || surf->u.tex.last_layer != last_layer) { @@ -646,7 +667,7 @@ _mesa_update_renderbuffer_surface(struct gl_context *ctx, struct pipe_surface surf_tmpl; memset(&surf_tmpl, 0, sizeof(surf_tmpl)); surf_tmpl.format = format; - surf_tmpl.nr_samples = rb->rtt_nr_samples; + surf_tmpl.nr_samples = nr_samples; surf_tmpl.u.tex.level = level; surf_tmpl.u.tex.first_layer = first_layer; surf_tmpl.u.tex.last_layer = last_layer;