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" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Chad Versace <chadversary@chromium.org>
This commit is contained in:
Jason Ekstrand 2017-06-16 00:13:45 -07:00
parent 793b312b4a
commit f1fa4be871

View file

@ -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;