From f1fa4be871e13c68b50685aaf64dc095b49ed0b5 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Fri, 16 Jun 2017 00:13:45 -0700 Subject: [PATCH] i965: Clamp clear colors to the representable range Starting with Sky Lake, we can clear to arbitrary floats or integers. Unfortunately, the hardware isn't particularly smart when it comes sampling from that clear color. If the clear color is out of range for the surface format, it will happily return whatever we put in the surface state packet unmodified. In order to avoid returning bogus values for surfaces with a limited range, we need to do some clamping. Cc: "17.1" Reviewed-by: Chad Versace --- src/mesa/drivers/dri/i965/brw_meta_util.c | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/mesa/drivers/dri/i965/brw_meta_util.c b/src/mesa/drivers/dri/i965/brw_meta_util.c index 575f437..f9fd350 100644 --- a/src/mesa/drivers/dri/i965/brw_meta_util.c +++ b/src/mesa/drivers/dri/i965/brw_meta_util.c @@ -364,6 +364,46 @@ brw_meta_convert_fast_clear_color(const struct brw_context *brw, break; } + switch (_mesa_get_format_datatype(mt->format)) { + case GL_UNSIGNED_NORMALIZED: + for (int i = 0; i < 4; i++) + override_color.f32[i] = CLAMP(override_color.f32[i], 0.0f, 1.0f); + break; + + case GL_SIGNED_NORMALIZED: + for (int i = 0; i < 4; i++) + override_color.f32[i] = CLAMP(override_color.f32[i], -1.0f, 1.0f); + break; + + case GL_UNSIGNED_INT: + for (int i = 0; i < 4; i++) { + unsigned bits = _mesa_get_format_bits(mt->format, GL_RED_BITS + i); + if (bits < 32) { + uint32_t max = (1u << bits) - 1; + override_color.u32[i] = MIN2(override_color.u32[i], max); + } + } + break; + + case GL_INT: + for (int i = 0; i < 4; i++) { + unsigned bits = _mesa_get_format_bits(mt->format, GL_RED_BITS + i); + if (bits < 32) { + int32_t max = (1 << (bits - 1)) - 1; + int32_t min = -(1 << (bits - 1)); + override_color.i32[i] = CLAMP(override_color.i32[i], min, max); + } + } + break; + + case GL_FLOAT: + if (!_mesa_is_format_signed(mt->format)) { + for (int i = 0; i < 4; i++) + override_color.f32[i] = MAX2(override_color.f32[i], 0.0f); + } + break; + } + if (!_mesa_format_has_color_component(mt->format, 3)) { if (_mesa_is_format_integer_color(mt->format)) override_color.u32[3] = 1; -- 2.7.4