OSDN Git Service

virgl: add openarena readpixels workaround.
authorDave Airlie <airlied@redhat.com>
Wed, 29 Jun 2016 06:42:29 +0000 (16:42 +1000)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Sun, 14 Aug 2016 17:31:37 +0000 (01:31 +0800)
So OA with flares does 8 readback from the depth buffer,
each of those was causing a host roundtrip and readback,

instead just sync the whole buffer and see how things go.

I'm not sure this won't destroy some other apps

src/gallium/drivers/virgl/virgl_texture.c

index c8e8866..f8936a6 100644 (file)
@@ -179,16 +179,33 @@ static void *virgl_texture_transfer_map(struct pipe_context *ctx,
       offset = 0;
    } else {
       offset = vrend_get_tex_image_offset(vtex, level, box->z);
-
       offset += box->y / util_format_get_blockheight(format) * trans->base.stride +
-      box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
+         box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
+
       hw_res = vtex->base.hw_res;
       trans->resolve_tmp = NULL;
    }
 
    readback = virgl_res_needs_readback(vctx, &vtex->base, usage);
-   if (readback)
-      vs->vws->transfer_get(vs->vws, hw_res, box, trans->base.stride, l_stride, offset, level);
+
+   if (readback) {
+      if (resource->target == PIPE_TEXTURE_2D &&
+          !vs->vws->res_is_synced(vs->vws, hw_res)) {
+         struct pipe_box sync_box = {
+            .width = u_minify(vtex->base.u.b.width0, level),
+            .height = u_minify(vtex->base.u.b.height0, level),
+            .depth = 1,
+         };
+
+         vs->vws->transfer_get(vs->vws, hw_res, &sync_box, trans->base.stride, l_stride,
+                               vrend_get_tex_image_offset(vtex, level, box->z), level);
+         vs->vws->resource_wait(vs->vws, vtex->base.hw_res);
+         vs->vws->res_set_synced(vtex->base.hw_res);
+         doflushwait = false;
+         readback = false;
+      } else
+         vs->vws->transfer_get(vs->vws, hw_res, box, trans->base.stride, l_stride, offset, level);
+   }
 
    if (doflushwait || readback)
       vs->vws->resource_wait(vs->vws, vtex->base.hw_res);