From 7626e6e18956cac0de9077694c97a388c739bdd0 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Fri, 11 Jan 2019 17:38:55 -0800 Subject: [PATCH] virgl: track level cleanliness rather than resource cleanliness This allows a minor optimization for texture upload. Reviewed-by: Gert Wollny --- src/gallium/drivers/virgl/virgl_buffer.c | 2 +- src/gallium/drivers/virgl/virgl_context.c | 12 ++++++++---- src/gallium/drivers/virgl/virgl_encode.c | 3 +-- src/gallium/drivers/virgl/virgl_resource.c | 12 ++++++++---- src/gallium/drivers/virgl/virgl_resource.h | 2 +- src/gallium/drivers/virgl/virgl_texture.c | 3 +-- 6 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/virgl/virgl_buffer.c b/src/gallium/drivers/virgl/virgl_buffer.c index 25fb992ef1f..3c732c90132 100644 --- a/src/gallium/drivers/virgl/virgl_buffer.c +++ b/src/gallium/drivers/virgl/virgl_buffer.c @@ -53,7 +53,7 @@ static void *virgl_buffer_transfer_map(struct pipe_context *ctx, trans = virgl_resource_create_transfer(ctx, resource, &vbuf->metadata, level, usage, box); - readback = virgl_res_needs_readback(vctx, vbuf, usage); + readback = virgl_res_needs_readback(vctx, vbuf, usage, 0); if (readback) vs->vws->transfer_get(vs->vws, vbuf->hw_res, box, trans->base.stride, trans->l_stride, trans->offset, level); diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c index d1348f17719..b924aa759d7 100644 --- a/src/gallium/drivers/virgl/virgl_context.c +++ b/src/gallium/drivers/virgl/virgl_context.c @@ -70,15 +70,19 @@ static void virgl_attach_res_framebuffer(struct virgl_context *vctx) surf = vctx->framebuffer.zsbuf; if (surf) { res = virgl_resource(surf->texture); - if (res) + if (res) { vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE); + virgl_resource_dirty(res, surf->u.tex.level); + } } for (i = 0; i < vctx->framebuffer.nr_cbufs; i++) { surf = vctx->framebuffer.cbufs[i]; if (surf) { res = virgl_resource(surf->texture); - if (res) + if (res) { vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE); + virgl_resource_dirty(res, surf->u.tex.level); + } } } } @@ -975,7 +979,7 @@ static void virgl_resource_copy_region(struct pipe_context *ctx, struct virgl_resource *dres = virgl_resource(dst); struct virgl_resource *sres = virgl_resource(src); - virgl_resource_dirty(dres, 0); + virgl_resource_dirty(dres, dst_level); virgl_encode_resource_copy_region(vctx, dres, dst_level, dstx, dsty, dstz, sres, src_level, @@ -1000,7 +1004,7 @@ static void virgl_blit(struct pipe_context *ctx, (util_format_is_srgb(blit->dst.resource->format) == util_format_is_srgb(blit->dst.format))); - virgl_resource_dirty(dres, 0); + virgl_resource_dirty(dres, blit->dst.level); virgl_encode_blit(vctx, dres, sres, blit); } diff --git a/src/gallium/drivers/virgl/virgl_encode.c b/src/gallium/drivers/virgl/virgl_encode.c index 6fbefc5933b..ddab3788353 100644 --- a/src/gallium/drivers/virgl/virgl_encode.c +++ b/src/gallium/drivers/virgl/virgl_encode.c @@ -615,7 +615,6 @@ int virgl_encode_sampler_view(struct virgl_context *ctx, if (res->u.b.target == PIPE_BUFFER) { virgl_encoder_write_dword(ctx->cbuf, state->u.buf.offset / elem_size); virgl_encoder_write_dword(ctx->cbuf, (state->u.buf.offset + state->u.buf.size) / elem_size - 1); - virgl_resource_dirty(res, 0); } else { virgl_encoder_write_dword(ctx->cbuf, state->u.tex.first_layer | state->u.tex.last_layer << 16); virgl_encoder_write_dword(ctx->cbuf, state->u.tex.first_level | state->u.tex.last_level << 8); @@ -1002,7 +1001,7 @@ int virgl_encode_set_shader_images(struct virgl_context *ctx, virgl_encoder_write_dword(ctx->cbuf, images[i].u.buf.offset); virgl_encoder_write_dword(ctx->cbuf, images[i].u.buf.size); virgl_encoder_write_res(ctx, res); - virgl_resource_dirty(res, 0); + virgl_resource_dirty(res, images[i].u.tex.level); } else { virgl_encoder_write_dword(ctx->cbuf, 0); virgl_encoder_write_dword(ctx->cbuf, 0); diff --git a/src/gallium/drivers/virgl/virgl_resource.c b/src/gallium/drivers/virgl/virgl_resource.c index 883dad0e386..40f70be8036 100644 --- a/src/gallium/drivers/virgl/virgl_resource.c +++ b/src/gallium/drivers/virgl/virgl_resource.c @@ -41,10 +41,10 @@ bool virgl_res_needs_flush_wait(struct virgl_context *vctx, bool virgl_res_needs_readback(struct virgl_context *vctx, struct virgl_resource *res, - unsigned usage) + unsigned usage, unsigned level) { bool readback = true; - if (res->clean[0]) + if (res->clean[level]) readback = false; else if (usage & PIPE_TRANSFER_DISCARD_RANGE) readback = false; @@ -281,6 +281,10 @@ boolean virgl_resource_get_handle(struct pipe_screen *screen, void virgl_resource_dirty(struct virgl_resource *res, uint32_t level) { - if (res) - res->clean[0] = FALSE; + if (res) { + if (res->u.b.target == PIPE_BUFFER) + res->clean[0] = FALSE; + else + res->clean[level] = FALSE; + } } diff --git a/src/gallium/drivers/virgl/virgl_resource.h b/src/gallium/drivers/virgl/virgl_resource.h index 33411959678..4aa2e71ecee 100644 --- a/src/gallium/drivers/virgl/virgl_resource.h +++ b/src/gallium/drivers/virgl/virgl_resource.h @@ -116,7 +116,7 @@ bool virgl_res_needs_flush_wait(struct virgl_context *vctx, unsigned usage); bool virgl_res_needs_readback(struct virgl_context *vctx, struct virgl_resource *res, - unsigned usage); + unsigned usage, unsigned level); void virgl_resource_layout(struct pipe_resource *pt, struct virgl_resource_metadata *metadata); diff --git a/src/gallium/drivers/virgl/virgl_texture.c b/src/gallium/drivers/virgl/virgl_texture.c index 59dbd1509c1..9a402056e7a 100644 --- a/src/gallium/drivers/virgl/virgl_texture.c +++ b/src/gallium/drivers/virgl/virgl_texture.c @@ -137,7 +137,7 @@ static void *virgl_texture_transfer_map(struct pipe_context *ctx, trans->resolve_tmp = NULL; } - readback = virgl_res_needs_readback(vctx, vtex, usage); + readback = virgl_res_needs_readback(vctx, vtex, usage, level); if (readback) vs->vws->transfer_get(vs->vws, hw_res, box, trans->base.stride, trans->l_stride, trans->offset, level); @@ -165,7 +165,6 @@ static void virgl_texture_transfer_unmap(struct pipe_context *ctx, if (trans->base.usage & PIPE_TRANSFER_WRITE) { if (!(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT)) { struct virgl_screen *vs = virgl_screen(ctx->screen); - vtex->clean[0] = FALSE; vctx->num_transfers++; vs->vws->transfer_put(vs->vws, vtex->hw_res, &transfer->box, trans->base.stride, -- 2.30.2