From 894b37e06099c60f371e9b181e3f84cfc29c49bb 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: --- src/mesa/main/fbobject.c | 19 +++++++++++++++++++ src/mesa/main/renderbuffer.c | 25 +++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index fef538a8c14..2d242135a42 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -4290,6 +4290,25 @@ frame_buffer_texture(GLuint framebuffer, GLenum target, } if (!no_error) { + /* 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, "%s(invalid sample count %u)", + func, samples); + } + if (samples > ctx->Const.MaxFramebufferSamples) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid sample count %u)", + func, samples); + } + if (!check_layered) { if (!check_texture_target(ctx, texObj->Target, func)) return; diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c index af15081fe1c..3b11c5c3e07 100644 --- a/src/mesa/main/renderbuffer.c +++ b/src/mesa/main/renderbuffer.c @@ -630,6 +630,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; @@ -641,7 +662,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) { @@ -649,7 +670,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;