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;