freedreno/a6xx: Fix sRGB/snorm vs sysmem clear path

This shows up when, thanks to the next patch, we decide to start doing
bypass instead of GMEM for some dEQP's

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9535>
This commit is contained in:
Rob Clark
2021-03-15 13:42:37 -07:00
committed by Marge Bot
parent 2e529ed7ef
commit 0610c7ba84
2 changed files with 45 additions and 8 deletions

View File

@@ -27,6 +27,7 @@
#include "util/u_dump.h"
#include "util/half_float.h"
#include "util/format_srgb.h"
#include "freedreno_blitter.h"
#include "freedreno_fence.h"
@@ -720,10 +721,18 @@ emit_clear_color(struct fd_ringbuffer *ring,
switch (fd6_ifmt(fd6_pipe2color(pfmt))) {
case R2D_UNORM8:
case R2D_UNORM8_SRGB:
OUT_RING(ring, float_to_ubyte(color->f[0]));
OUT_RING(ring, float_to_ubyte(color->f[1]));
OUT_RING(ring, float_to_ubyte(color->f[2]));
OUT_RING(ring, float_to_ubyte(color->f[3]));
/* The r2d ifmt is badly named, it also covers the signed case: */
if (util_format_is_snorm(pfmt)) {
OUT_RING(ring, float_to_byte_tex(color->f[0]));
OUT_RING(ring, float_to_byte_tex(color->f[1]));
OUT_RING(ring, float_to_byte_tex(color->f[2]));
OUT_RING(ring, float_to_byte_tex(color->f[3]));
} else {
OUT_RING(ring, float_to_ubyte(color->f[0]));
OUT_RING(ring, float_to_ubyte(color->f[1]));
OUT_RING(ring, float_to_ubyte(color->f[2]));
OUT_RING(ring, float_to_ubyte(color->f[3]));
}
break;
case R2D_FLOAT16:
OUT_RING(ring, _mesa_float_to_half(color->f[0]));
@@ -744,6 +753,32 @@ emit_clear_color(struct fd_ringbuffer *ring,
}
}
/**
* Handle conversion of clear color
*/
static union pipe_color_union
convert_color(enum pipe_format format, union pipe_color_union *pcolor)
{
union pipe_color_union color = *pcolor;
/* For solid-fill blits, the hw isn't going to convert from
* linear to srgb for us:
*/
if (util_format_is_srgb(format)) {
for (int i = 0; i < 3; i++)
color.f[i] = util_format_linear_to_srgb_float(color.f[i]);
}
if (util_format_is_snorm(format)) {
for (int i = 0; i < 3; i++)
color.f[i] = CLAMP(color.f[i], -1.0f, 1.0f);
}
/* Note that float_to_ubyte() already clamps, for the unorm case */
return color;
}
void
fd6_clear_surface(struct fd_context *ctx,
struct fd_ringbuffer *ring, struct pipe_surface *psurf,
@@ -761,8 +796,10 @@ fd6_clear_surface(struct fd_context *ctx,
OUT_RING(ring, A6XX_GRAS_2D_DST_BR_X(width * nr_samples - 1) |
A6XX_GRAS_2D_DST_BR_Y(height - 1));
emit_clear_color(ring, psurf->format, color);
emit_blit_setup(ring, psurf->format, false, color);
union pipe_color_union clear_color = convert_color(psurf->format, color);
emit_clear_color(ring, psurf->format, &clear_color);
emit_blit_setup(ring, psurf->format, false, &clear_color);
for (unsigned i = psurf->u.tex.first_layer; i <= psurf->u.tex.last_layer; i++) {
emit_blit_dst(ring, psurf->texture, psurf->format, psurf->u.tex.level, i);

View File

@@ -1344,7 +1344,7 @@ emit_sysmem_clears(struct fd_batch *batch, struct fd_ringbuffer *ring)
if (buffers & PIPE_CLEAR_COLOR) {
for (int i = 0; i < pfb->nr_cbufs; i++) {
union pipe_color_union *color = &batch->clear_color[i];
union pipe_color_union color = batch->clear_color[i];
if (!pfb->cbufs[i])
continue;
@@ -1353,7 +1353,7 @@ emit_sysmem_clears(struct fd_batch *batch, struct fd_ringbuffer *ring)
continue;
fd6_clear_surface(ctx, ring,
pfb->cbufs[i], pfb->width, pfb->height, color);
pfb->cbufs[i], pfb->width, pfb->height, &color);
}
}
if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) {