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.
This commit is contained in:
Eric Anholt 2016-10-05 14:10:30 -07:00
parent 8810270d06
commit 9421a6065c
4 changed files with 64 additions and 25 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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)

View file

@ -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.