virgl: track level cleanliness rather than resource cleanliness
authorGurchetan Singh <gurchetansingh@chromium.org>
Sat, 12 Jan 2019 01:38:55 +0000 (17:38 -0800)
committerGert Wollny <gert.wollny@collabora.com>
Fri, 15 Feb 2019 10:19:04 +0000 (11:19 +0100)
This allows a minor optimization for texture upload.

Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
src/gallium/drivers/virgl/virgl_buffer.c
src/gallium/drivers/virgl/virgl_context.c
src/gallium/drivers/virgl/virgl_encode.c
src/gallium/drivers/virgl/virgl_resource.c
src/gallium/drivers/virgl/virgl_resource.h
src/gallium/drivers/virgl/virgl_texture.c

index 25fb992..3c732c9 100644 (file)
@@ -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);
index d1348f1..b924aa7 100644 (file)
@@ -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);
 }
index 6fbefc5..ddab378 100644 (file)
@@ -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);
index 883dad0..40f70be 100644 (file)
@@ -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;
+   }
 }
index 3341195..4aa2e71 100644 (file)
@@ -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);
index 59dbd15..9a40205 100644 (file)
@@ -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,