mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 09:28:07 +02:00
freedreno/a6xx: Fix partial z/s clears with sysmem.
We have to set 8c01 to say "leave these channels alone" when
clearing/storing just Z or S of z24s8. Fixes the bypass path for
KHR-GLES3.packed_depth_stencil.verify_read_pixels.depth24_stencil8.
Cc: mesa-stable
Fixes: #5592
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13659>
(cherry picked from commit f0f5b8d47c)
This commit is contained in:
parent
8b46e23ef2
commit
5b0ab532d4
5 changed files with 39 additions and 20 deletions
|
|
@ -1804,7 +1804,7 @@
|
|||
"description": "freedreno/a6xx: Fix partial z/s clears with sysmem.",
|
||||
"nominated": true,
|
||||
"nomination_type": 0,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": null
|
||||
},
|
||||
|
|
|
|||
|
|
@ -624,8 +624,6 @@ spec@!opengl 2.1@pbo,Fail
|
|||
spec@!opengl 2.1@pbo@test_polygon_stip,Fail
|
||||
spec@!opengl 2.1@polygon-stipple-fs,Fail
|
||||
spec@!opengl 3.0@clearbuffer-depth-cs-probe,Timeout
|
||||
spec@!opengl 3.0@clearbuffer-depth,Fail
|
||||
spec@!opengl 3.0@clearbuffer-stencil,Fail
|
||||
spec@!opengl 3.1@primitive-restart-xfb generated,Fail
|
||||
|
||||
# "../src/gallium/drivers/freedreno/a6xx/fd6_gmem.c:976:emit_blit: Assertion `psurf->u.tex.first_layer == psurf->u.tex.last_layer' failed."
|
||||
|
|
|
|||
|
|
@ -250,7 +250,8 @@ emit_setup(struct fd_batch *batch)
|
|||
|
||||
static void
|
||||
emit_blit_setup(struct fd_ringbuffer *ring, enum pipe_format pfmt,
|
||||
bool scissor_enable, union pipe_color_union *color)
|
||||
bool scissor_enable, union pipe_color_union *color,
|
||||
uint32_t unknown_8c01)
|
||||
{
|
||||
enum a6xx_format fmt = fd6_color_format(pfmt, TILE6_LINEAR);
|
||||
bool is_srgb = util_format_is_srgb(pfmt);
|
||||
|
|
@ -290,7 +291,7 @@ emit_blit_setup(struct fd_ringbuffer *ring, enum pipe_format pfmt,
|
|||
A6XX_SP_2D_DST_FORMAT_MASK(0xf));
|
||||
|
||||
OUT_PKT4(ring, REG_A6XX_RB_2D_UNKNOWN_8C01, 1);
|
||||
OUT_RING(ring, 0);
|
||||
OUT_RING(ring, unknown_8c01);
|
||||
}
|
||||
|
||||
/* buffers need to be handled specially since x/width can exceed the bounds
|
||||
|
|
@ -345,7 +346,7 @@ emit_blit_buffer(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
|||
sshift = sbox->x & 0x3f;
|
||||
dshift = dbox->x & 0x3f;
|
||||
|
||||
emit_blit_setup(ring, PIPE_FORMAT_R8_UNORM, false, NULL);
|
||||
emit_blit_setup(ring, PIPE_FORMAT_R8_UNORM, false, NULL, 0);
|
||||
|
||||
for (unsigned off = 0; off < sbox->width; off += (0x4000 - 0x40)) {
|
||||
unsigned soff, doff, w, p;
|
||||
|
|
@ -430,7 +431,7 @@ fd6_clear_ubwc(struct fd_batch *batch, struct fd_resource *rsc) assert_dt
|
|||
struct fd_ringbuffer *ring = fd_batch_get_prologue(batch);
|
||||
union pipe_color_union color = {};
|
||||
|
||||
emit_blit_setup(ring, PIPE_FORMAT_R8_UNORM, false, &color);
|
||||
emit_blit_setup(ring, PIPE_FORMAT_R8_UNORM, false, &color, 0);
|
||||
|
||||
OUT_PKT4(ring, REG_A6XX_SP_PS_2D_SRC_INFO, 13);
|
||||
OUT_RING(ring, 0x00000000);
|
||||
|
|
@ -669,7 +670,7 @@ emit_blit_texture(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
|||
A6XX_GRAS_2D_RESOLVE_CNTL_1_Y(info->scissor.maxy - 1));
|
||||
}
|
||||
|
||||
emit_blit_setup(ring, info->dst.format, info->scissor_enable, NULL);
|
||||
emit_blit_setup(ring, info->dst.format, info->scissor_enable, NULL, 0);
|
||||
|
||||
for (unsigned i = 0; i < info->dst.box.depth; i++) {
|
||||
|
||||
|
|
@ -782,7 +783,7 @@ convert_color(enum pipe_format format, union pipe_color_union *pcolor)
|
|||
void
|
||||
fd6_clear_surface(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
struct pipe_surface *psurf, uint32_t width, uint32_t height,
|
||||
union pipe_color_union *color)
|
||||
union pipe_color_union *color, uint32_t unknown_8c01)
|
||||
{
|
||||
if (DEBUG_BLIT) {
|
||||
fprintf(stderr, "surface clear:\ndst resource: ");
|
||||
|
|
@ -799,7 +800,7 @@ fd6_clear_surface(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
|||
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);
|
||||
emit_blit_setup(ring, psurf->format, false, &clear_color, unknown_8c01);
|
||||
|
||||
for (unsigned i = psurf->u.tex.first_layer; i <= psurf->u.tex.last_layer;
|
||||
i++) {
|
||||
|
|
@ -827,7 +828,7 @@ fd6_clear_surface(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
|||
|
||||
void
|
||||
fd6_resolve_tile(struct fd_batch *batch, struct fd_ringbuffer *ring,
|
||||
uint32_t base, struct pipe_surface *psurf)
|
||||
uint32_t base, struct pipe_surface *psurf, uint32_t unknown_8c01)
|
||||
{
|
||||
const struct fd_gmem_stateobj *gmem = batch->gmem_state;
|
||||
uint64_t gmem_base = batch->ctx->screen->gmem_base + base;
|
||||
|
|
@ -848,7 +849,7 @@ fd6_resolve_tile(struct fd_batch *batch, struct fd_ringbuffer *ring,
|
|||
/* Enable scissor bit, which will take into account the window scissor
|
||||
* which is set per-tile
|
||||
*/
|
||||
emit_blit_setup(ring, psurf->format, true, NULL);
|
||||
emit_blit_setup(ring, psurf->format, true, NULL, unknown_8c01);
|
||||
|
||||
/* We shouldn't be using GMEM in the layered rendering case: */
|
||||
assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer);
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ unsigned fd6_tile_mode(const struct pipe_resource *tmpl);
|
|||
void fd6_clear_surface(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
struct pipe_surface *psurf, uint32_t width,
|
||||
uint32_t height,
|
||||
union pipe_color_union *color) assert_dt;
|
||||
union pipe_color_union *color, uint32_t unknown_8c01) assert_dt;
|
||||
void fd6_resolve_tile(struct fd_batch *batch, struct fd_ringbuffer *ring,
|
||||
uint32_t base, struct pipe_surface *psurf) assert_dt;
|
||||
uint32_t base, struct pipe_surface *psurf, uint32_t unknown_8c01) assert_dt;
|
||||
|
||||
#endif /* FD6_BLIT_H_ */
|
||||
|
|
|
|||
|
|
@ -1299,6 +1299,22 @@ needs_resolve(struct pipe_surface *psurf)
|
|||
(psurf->nr_samples != psurf->texture->nr_samples);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the UNKNOWN_8C01 value for handling partial depth/stencil
|
||||
* clear/stores to Z24S8.
|
||||
*/
|
||||
static uint32_t
|
||||
fd6_unknown_8c01(enum pipe_format format, unsigned buffers)
|
||||
{
|
||||
if (format == PIPE_FORMAT_Z24_UNORM_S8_UINT) {
|
||||
if (buffers == FD_BUFFER_DEPTH)
|
||||
return 0x08000041;
|
||||
else if (buffers == FD_BUFFER_STENCIL)
|
||||
return 0x00084001;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
emit_resolve_blit(struct fd_batch *batch, struct fd_ringbuffer *ring,
|
||||
uint32_t base, struct pipe_surface *psurf,
|
||||
|
|
@ -1318,7 +1334,12 @@ emit_resolve_blit(struct fd_batch *batch, struct fd_ringbuffer *ring,
|
|||
*/
|
||||
if (needs_resolve(psurf) && !blit_can_resolve(psurf->format) &&
|
||||
(buffer != FD_BUFFER_STENCIL)) {
|
||||
fd6_resolve_tile(batch, ring, base, psurf);
|
||||
/* We could potentially use fd6_unknown_8c01() to handle partial z/s
|
||||
* resolve to packed z/s, but we would need a corresponding ability in the
|
||||
* !resolve case below, so batch_draw_tracking_for_dirty_bits() has us
|
||||
* just do a restore of the other channel for partial packed z/s writes.
|
||||
*/
|
||||
fd6_resolve_tile(batch, ring, base, psurf, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1477,7 +1498,7 @@ emit_sysmem_clears(struct fd_batch *batch, struct fd_ringbuffer *ring) assert_dt
|
|||
continue;
|
||||
|
||||
fd6_clear_surface(ctx, ring, pfb->cbufs[i], pfb->width, pfb->height,
|
||||
&color);
|
||||
&color, 0);
|
||||
}
|
||||
}
|
||||
if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) {
|
||||
|
|
@ -1489,12 +1510,11 @@ emit_sysmem_clears(struct fd_batch *batch, struct fd_ringbuffer *ring) assert_dt
|
|||
? &fd_resource(pfb->zsbuf->texture)->stencil->b.b
|
||||
: NULL;
|
||||
|
||||
if ((has_depth && (buffers & PIPE_CLEAR_DEPTH)) ||
|
||||
(!separate_stencil && (buffers & PIPE_CLEAR_STENCIL))) {
|
||||
if ((buffers & PIPE_CLEAR_DEPTH) || (!separate_stencil && (buffers & PIPE_CLEAR_STENCIL))) {
|
||||
value.f[0] = batch->clear_depth;
|
||||
value.ui[1] = batch->clear_stencil;
|
||||
fd6_clear_surface(ctx, ring, pfb->zsbuf, pfb->width, pfb->height,
|
||||
&value);
|
||||
&value, fd6_unknown_8c01(pfb->zsbuf->format, buffers));
|
||||
}
|
||||
|
||||
if (separate_stencil && (buffers & PIPE_CLEAR_STENCIL)) {
|
||||
|
|
@ -1505,7 +1525,7 @@ emit_sysmem_clears(struct fd_batch *batch, struct fd_ringbuffer *ring) assert_dt
|
|||
stencil_surf.texture = separate_stencil;
|
||||
|
||||
fd6_clear_surface(ctx, ring, &stencil_surf, pfb->width, pfb->height,
|
||||
&value);
|
||||
&value, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue