From: Eric Anholt Date: Wed, 5 Oct 2016 21:10:30 +0000 (-0700) Subject: vc4: Fix fallback to quad clears of depth in GLX. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9421a6065c4eafbc92657f75da46a4bb70577154;p=mesa.git 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. --- 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 @@ -70,6 +70,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.