From e81d6cec278f005ad052b2b68fef5b33697c093b Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 8 Jul 2022 10:49:54 -0400 Subject: [PATCH] zink: clamp color clear values based on format formats like GL_RGB10_A2UI can be cleared with out of range values, so to ensure consistent driver behavior, pre-clamp to the valid range affects: KHR-GL46.direct_state_access.renderbuffers_storage_multisample Acked-by: Dave Airlie Part-of: --- src/gallium/drivers/zink/zink_clear.c | 42 ++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/zink/zink_clear.c b/src/gallium/drivers/zink/zink_clear.c index 8f39b4ad4b0..289feee2176 100644 --- a/src/gallium/drivers/zink/zink_clear.c +++ b/src/gallium/drivers/zink/zink_clear.c @@ -207,6 +207,44 @@ get_clear_data(struct zink_context *ctx, struct zink_framebuffer_clear *fb_clear return clear; } +static void +clamp_color(const struct util_format_description *desc, union pipe_color_union *dst, const union pipe_color_union *src, unsigned i) +{ + int non_void = util_format_get_first_non_void_channel(desc->format); + switch (desc->channel[i].type) { + case UTIL_FORMAT_TYPE_VOID: + if (desc->channel[non_void].type == UTIL_FORMAT_TYPE_FLOAT) { + dst->f[i] = uif(UINT32_MAX); + } else { + if (desc->channel[non_void].normalized) + dst->f[i] = 1.0; + else if (desc->channel[non_void].type == UTIL_FORMAT_TYPE_SIGNED) + dst->i[i] = INT32_MAX; + else + dst->ui[i] = UINT32_MAX; + } + break; + case UTIL_FORMAT_TYPE_SIGNED: + if (desc->channel[i].normalized) + dst->i[i] = src->i[i]; + else { + dst->i[i] = MAX2(src->i[i], -(1<<(desc->channel[i].size - 1))); + dst->i[i] = MIN2(dst->i[i], (1 << (desc->channel[i].size - 1)) - 1); + } + break; + case UTIL_FORMAT_TYPE_UNSIGNED: + if (desc->channel[i].normalized) + dst->ui[i] = src->ui[i]; + else + dst->ui[i] = MIN2(src->ui[i], BITFIELD_MASK(desc->channel[i].size)); + break; + case UTIL_FORMAT_TYPE_FIXED: + case UTIL_FORMAT_TYPE_FLOAT: + dst->ui[i] = src->ui[i]; + break; + } +} + void zink_clear(struct pipe_context *pctx, unsigned buffers, @@ -265,6 +303,7 @@ zink_clear(struct pipe_context *pctx, for (unsigned i = 0; i < fb->nr_cbufs; i++) { if ((buffers & (PIPE_CLEAR_COLOR0 << i)) && fb->cbufs[i]) { struct pipe_surface *psurf = fb->cbufs[i]; + const struct util_format_description *desc = util_format_description(psurf->format); struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[i]; struct zink_framebuffer_clear_data *clear = get_clear_data(ctx, fb_clear, needs_rp ? scissor_state : NULL); @@ -273,7 +312,8 @@ zink_clear(struct pipe_context *pctx, clear->has_scissor = needs_rp; if (scissor_state && needs_rp) clear->scissor = *scissor_state; - clear->color.color = *pcolor; + for (unsigned i = 0; i < 4; i++) + clamp_color(desc, &clear->color.color, pcolor, i); clear->color.srgb = psurf->format != psurf->texture->format && !util_format_is_srgb(psurf->format) && util_format_is_srgb(psurf->texture->format); if (zink_fb_clear_first_needs_explicit(fb_clear))