summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2016-10-05 14:10:30 -0700
committerEric Anholt <[email protected]>2016-10-06 18:09:24 -0700
commit9421a6065c4eafbc92657f75da46a4bb70577154 (patch)
tree1f3adbd697977e4230b3ccf60778ecce1e9b501e /src
parent8810270d066eced5261ab407e2be4e902b102671 (diff)
vc4: Fix fallback to quad clears of depth in GLX.
The fix in the vc4-jobs series ended up triggering the fallback path on GLX apps that use depth but not stencil.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/vc4/vc4_context.c4
-rw-r--r--src/gallium/drivers/vc4/vc4_draw.c70
-rw-r--r--src/gallium/drivers/vc4/vc4_resource.c4
-rw-r--r--src/gallium/drivers/vc4/vc4_resource.h11
4 files changed, 64 insertions, 25 deletions
diff --git a/src/gallium/drivers/vc4/vc4_context.c b/src/gallium/drivers/vc4/vc4_context.c
index b780b13c90f..974df8a1da2 100644
--- a/src/gallium/drivers/vc4/vc4_context.c
+++ b/src/gallium/drivers/vc4/vc4_context.c
@@ -70,6 +70,10 @@ static void
vc4_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
{
struct vc4_context *vc4 = vc4_context(pctx);
+ struct vc4_resource *rsc = vc4_resource(prsc);
+
+ rsc->initialized_buffers = 0;
+
struct hash_entry *entry = _mesa_hash_table_search(vc4->write_jobs,
prsc);
if (!entry)
diff --git a/src/gallium/drivers/vc4/vc4_draw.c b/src/gallium/drivers/vc4/vc4_draw.c
index e4d61795866..49f9479c247 100644
--- a/src/gallium/drivers/vc4/vc4_draw.c
+++ b/src/gallium/drivers/vc4/vc4_draw.c
@@ -444,11 +444,21 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
*/
assert(start_draw_calls_queued == job->draw_calls_queued);
- if (vc4->zsa && vc4->zsa->base.depth.enabled) {
- job->resolve |= PIPE_CLEAR_DEPTH;
+ if (vc4->zsa && vc4->framebuffer.zsbuf) {
+ struct vc4_resource *rsc =
+ vc4_resource(vc4->framebuffer.zsbuf->texture);
+
+ if (vc4->zsa->base.depth.enabled) {
+ job->resolve |= PIPE_CLEAR_DEPTH;
+ rsc->initialized_buffers = PIPE_CLEAR_DEPTH;
+ }
+
+ if (vc4->zsa->base.stencil[0].enabled) {
+ job->resolve |= PIPE_CLEAR_STENCIL;
+ rsc->initialized_buffers |= PIPE_CLEAR_STENCIL;
+ }
}
- if (vc4->zsa && vc4->zsa->base.stencil[0].enabled)
- job->resolve |= PIPE_CLEAR_STENCIL;
+
job->resolve |= PIPE_CLEAR_COLOR0;
if (vc4_debug & VC4_DEBUG_ALWAYS_FLUSH)
@@ -482,38 +492,50 @@ vc4_clear(struct pipe_context *pctx, unsigned buffers,
job = vc4_get_job_for_fbo(vc4);
}
- /* Clearing ZS will clear both Z and stencil, so if we're trying to
- * clear just one then we need to draw a quad to do it instead.
- */
- if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) != 0 &&
- (buffers & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL &&
- util_format_is_depth_and_stencil(vc4->framebuffer.zsbuf->format)) {
- perf_debug("Partial clear of Z+stencil buffer, drawing a quad "
- "instead of fast clearing\n");
- vc4_blitter_save(vc4);
- util_blitter_clear(vc4->blitter,
- vc4->framebuffer.width,
- vc4->framebuffer.height,
- 1,
- buffers & PIPE_CLEAR_DEPTHSTENCIL,
- NULL, depth, stencil);
- buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
- if (!buffers)
- return;
- }
-
if (buffers & PIPE_CLEAR_COLOR0) {
+ struct vc4_resource *rsc =
+ vc4_resource(vc4->framebuffer.cbufs[0]->texture);
+
job->clear_color[0] = job->clear_color[1] =
pack_rgba(vc4->framebuffer.cbufs[0]->format,
color->f);
+ rsc->initialized_buffers |= (buffers & PIPE_CLEAR_COLOR0);
}
if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
+ struct vc4_resource *rsc =
+ vc4_resource(vc4->framebuffer.zsbuf->texture);
+ unsigned zsclear = buffers & PIPE_CLEAR_DEPTHSTENCIL;
+
+ /* Clearing ZS will clear both Z and stencil, so if we're
+ * trying to clear just one then we need to draw a quad to do
+ * it instead.
+ */
+ if ((zsclear == PIPE_CLEAR_DEPTH ||
+ zsclear == PIPE_CLEAR_STENCIL) &&
+ (rsc->initialized_buffers & ~zsclear) &&
+ util_format_is_depth_and_stencil(vc4->framebuffer.zsbuf->format)) {
+ perf_debug("Partial clear of Z+stencil buffer, "
+ "drawing a quad instead of fast clearing\n");
+ vc4_blitter_save(vc4);
+ util_blitter_clear(vc4->blitter,
+ vc4->framebuffer.width,
+ vc4->framebuffer.height,
+ 1,
+ zsclear,
+ NULL, depth, stencil);
+ buffers &= ~zsclear;
+ if (!buffers)
+ return;
+ }
+
/* Though the depth buffer is stored with Z in the high 24,
* for this field we just need to store it in the low 24.
*/
job->clear_depth = util_pack_z(PIPE_FORMAT_Z24X8_UNORM, depth);
job->clear_stencil = stencil;
+
+ rsc->initialized_buffers |= zsclear;
}
job->draw_min_x = 0;
diff --git a/src/gallium/drivers/vc4/vc4_resource.c b/src/gallium/drivers/vc4/vc4_resource.c
index 5f8b6b0f715..4168079cd86 100644
--- a/src/gallium/drivers/vc4/vc4_resource.c
+++ b/src/gallium/drivers/vc4/vc4_resource.c
@@ -193,8 +193,10 @@ vc4_resource_transfer_map(struct pipe_context *pctx,
vc4_flush_jobs_writing_resource(vc4, prsc);
}
- if (usage & PIPE_TRANSFER_WRITE)
+ if (usage & PIPE_TRANSFER_WRITE) {
rsc->writes++;
+ rsc->initialized_buffers = ~0;
+ }
trans = slab_alloc(&vc4->transfer_pool);
if (!trans)
diff --git a/src/gallium/drivers/vc4/vc4_resource.h b/src/gallium/drivers/vc4/vc4_resource.h
index b275050da20..27aa4e87282 100644
--- a/src/gallium/drivers/vc4/vc4_resource.h
+++ b/src/gallium/drivers/vc4/vc4_resource.h
@@ -71,6 +71,17 @@ struct vc4_resource {
uint64_t writes;
/**
+ * Bitmask of PIPE_CLEAR_COLOR0, PIPE_CLEAR_DEPTH, PIPE_CLEAR_STENCIL
+ * for which parts of the resource are defined.
+ *
+ * Used for avoiding fallback to quad clears for clearing just depth,
+ * when the stencil contents have never been initialized. Note that
+ * we're lazy and fields not present in the buffer (DEPTH in a color
+ * buffer) may get marked.
+ */
+ uint32_t initialized_buffers;
+
+ /**
* Resource containing the non-GL_TEXTURE_BASE_LEVEL-rebased texture
* contents, or the 4-byte index buffer.
*