summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2018-07-12 16:58:07 -0700
committerEric Anholt <[email protected]>2018-07-13 13:29:29 -0700
commitafcc714c981d421f246da60a515f86c73a58c7b0 (patch)
treefc3c73f493146d3ab5a7e1cdfd285ada0f63697d
parent162fcdad6a9db9819f4c18d6f5f4083e50edc00a (diff)
v3d: Work around GFXH-1461 bug losing our Z/S clears.
If you load S and clear Z or vice versa, the clear may get lost. Just fall back to drawing a quad. Fixes KHR-GLES3.packed_depth_stencil.verify_read_pixels.depth24_stencil8
-rw-r--r--src/gallium/drivers/v3d/v3dx_draw.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/gallium/drivers/v3d/v3dx_draw.c b/src/gallium/drivers/v3d/v3dx_draw.c
index 43dd4089f12..38f9e6beed4 100644
--- a/src/gallium/drivers/v3d/v3dx_draw.c
+++ b/src/gallium/drivers/v3d/v3dx_draw.c
@@ -613,6 +613,30 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
v3d_flush(pctx);
}
+/* GFXH-1461: If we were to emit a load of just depth or just stencil, then
+ * the clear for the other may get lost. Just fall back to drawing a quad in
+ * that case.
+ */
+static bool
+v3d_gfxh1461_clear_workaround(struct v3d_context *v3d,
+ unsigned buffers, double depth, unsigned stencil)
+{
+ unsigned zsclear = buffers & PIPE_CLEAR_DEPTHSTENCIL;
+ if (!zsclear || zsclear == PIPE_CLEAR_DEPTHSTENCIL)
+ return false;
+
+ static const union pipe_color_union dummy_color = {};
+
+ v3d_blitter_save(v3d);
+ util_blitter_clear(v3d->blitter,
+ v3d->framebuffer.width,
+ v3d->framebuffer.height,
+ 1,
+ zsclear,
+ &dummy_color, depth, stencil);
+ return true;
+}
+
static void
v3d_clear(struct pipe_context *pctx, unsigned buffers,
const union pipe_color_union *color, double depth, unsigned stencil)
@@ -620,6 +644,12 @@ v3d_clear(struct pipe_context *pctx, unsigned buffers,
struct v3d_context *v3d = v3d_context(pctx);
struct v3d_job *job = v3d_get_job_for_fbo(v3d);
+ if (v3d_gfxh1461_clear_workaround(v3d, buffers, depth, stencil))
+ buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
+
+ if (!buffers)
+ return;
+
/* We can't flag new buffers for clearing once we've queued draws. We
* could avoid this by using the 3d engine to clear.
*/