mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 02:38:04 +02:00
panfrost: Handle non-dithered clear colours
Inb9c095cc2c("panfrost: Rewrite the clear colour packing code"), packing of clear colours was corrected to use the tilebuffer's fractional bits, fixing dithering of the clear colour with formats like RGB565. Unfortunately, that commit did so unconditionally. If the framebuffer is dithered, but dithering is disabled at the time of the clear, we would incorrectly dither the clear. This is a regression, as the old (broken) code passed the relevant CTS test. What's the catch? Depending on dither state, there are two formulas to pack tilebuffer colours. We need to handle both. Fixes KHR-GLES31.core.draw_buffers_indexed.color_masks. Fixes:b9c095cc2c("panfrost: Rewrite the clear colour packing code") Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12460>
This commit is contained in:
parent
1b710d4a96
commit
22538b89b3
5 changed files with 24 additions and 13 deletions
|
|
@ -936,7 +936,7 @@ panfrost_batch_clear(struct panfrost_batch *batch,
|
|||
continue;
|
||||
|
||||
enum pipe_format format = ctx->pipe_framebuffer.cbufs[i]->format;
|
||||
pan_pack_color(batch->clear_color[i], color, format);
|
||||
pan_pack_color(batch->clear_color[i], color, format, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,13 +52,22 @@ pan_pack_color_32(uint32_t *packed, uint32_t v)
|
|||
}
|
||||
|
||||
/* For m integer bits and n fractional bits, calculate the conversion factor,
|
||||
* multiply the source value, and convert to integer rounding to even */
|
||||
* multiply the source value, and convert to integer rounding to even. When
|
||||
* dithering, the fractional bits are used. When not dithered, only the integer
|
||||
* bits are used and the fractional bits must remain zero. */
|
||||
|
||||
static inline uint32_t
|
||||
float_to_fixed(float f, unsigned bits_int, unsigned bits_frac)
|
||||
float_to_fixed(float f, unsigned bits_int, unsigned bits_frac, bool dither)
|
||||
{
|
||||
float factor = ((1 << bits_int) - 1) << bits_frac;
|
||||
return _mesa_roundevenf(f * factor);
|
||||
uint32_t m = (1 << bits_int) - 1;
|
||||
|
||||
if (dither) {
|
||||
float factor = m << bits_frac;
|
||||
return _mesa_roundevenf(f * factor);
|
||||
} else {
|
||||
uint32_t v = _mesa_roundevenf(f * (float) m);
|
||||
return v << bits_frac;
|
||||
}
|
||||
}
|
||||
|
||||
/* These values are shared across hardware versions. Don't include GenXML. */
|
||||
|
|
@ -116,7 +125,8 @@ pan_pack_raw(uint32_t *packed, const union pipe_color_union *color, enum pipe_fo
|
|||
}
|
||||
|
||||
void
|
||||
pan_pack_color(uint32_t *packed, const union pipe_color_union *color, enum pipe_format format)
|
||||
pan_pack_color(uint32_t *packed, const union pipe_color_union *color,
|
||||
enum pipe_format format, bool dithered)
|
||||
{
|
||||
/* Set of blendable formats is common across versions. TODO: v9 */
|
||||
enum mali_color_buffer_internal_format internal =
|
||||
|
|
@ -157,10 +167,10 @@ pan_pack_color(uint32_t *packed, const union pipe_color_union *color, enum pipe_
|
|||
assert(count_a == 32);
|
||||
|
||||
/* Convert the transformed float colour to the given layout */
|
||||
uint32_t ur = float_to_fixed(r, l.int_r, l.frac_r) << 0;
|
||||
uint32_t ug = float_to_fixed(g, l.int_g, l.frac_g) << count_r;
|
||||
uint32_t ub = float_to_fixed(b, l.int_b, l.frac_b) << count_g;
|
||||
uint32_t ua = float_to_fixed(a, l.int_a, l.frac_a) << count_b;
|
||||
uint32_t ur = float_to_fixed(r, l.int_r, l.frac_r, dithered) << 0;
|
||||
uint32_t ug = float_to_fixed(g, l.int_g, l.frac_g, dithered) << count_r;
|
||||
uint32_t ub = float_to_fixed(b, l.int_b, l.frac_b, dithered) << count_g;
|
||||
uint32_t ua = float_to_fixed(a, l.int_a, l.frac_a, dithered) << count_b;
|
||||
|
||||
pan_pack_color_32(packed, ur | ug | ub | ua);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ panfrost_format_to_bifrost_blend(const struct panfrost_device *dev,
|
|||
bool dithered);
|
||||
|
||||
void
|
||||
pan_pack_color(uint32_t *packed, const union pipe_color_union *color, enum pipe_format format);
|
||||
pan_pack_color(uint32_t *packed, const union pipe_color_union *color,
|
||||
enum pipe_format format, bool dithered);
|
||||
|
||||
#endif /* PAN_UTIL_H */
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ int main(int argc, const char **argv)
|
|||
for (unsigned i = 0; i < ARRAY_SIZE(clear_tests); ++i) {
|
||||
struct test T = clear_tests[i];
|
||||
uint32_t packed[4];
|
||||
pan_pack_color(&packed[0], &T.colour, T.format);
|
||||
pan_pack_color(&packed[0], &T.colour, T.format, T.dithered);
|
||||
|
||||
ASSERT_EQ(T.packed, packed);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -593,7 +593,7 @@ panvk_cmd_prepare_clear_values(struct panvk_cmd_buffer *cmdbuf,
|
|||
}
|
||||
} else if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
|
||||
union pipe_color_union *col = (union pipe_color_union *) &in[i].color;
|
||||
pan_pack_color(cmdbuf->state.clear[i].color, col, fmt);
|
||||
pan_pack_color(cmdbuf->state.clear[i].color, col, fmt, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue