OSDN Git Service

minigbm: virtio: Advertise BO_USE_SCANOUT correctly.
authorLepton Wu <lepton@chromium.org>
Wed, 26 Feb 2020 23:13:34 +0000 (15:13 -0800)
committerCommit Bot <commit-bot@chromium.org>
Fri, 28 Feb 2020 01:04:56 +0000 (01:04 +0000)
If host doesn't support BO_USE_SCANOUT for some format, we shouldn't
advertise it. Otherwise the bo will fail to allocate at host side
with minigbm.

BUG=b:145603024
TEST=tast run 127.0.0.1:9222 arc.Boot.vm

Change-Id: I9e2c8141462b630bf18cc8859df607dca7b335c9
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2076580
Reviewed-by: Jason Macnak <natsu@google.com>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Tested-by: Lepton Wu <lepton@chromium.org>
Commit-Queue: Lepton Wu <lepton@chromium.org>
Auto-Submit: Lepton Wu <lepton@chromium.org>

virgl_hw.h
virtio_gpu.c

index 8c169a7..145780b 100644 (file)
@@ -400,6 +400,7 @@ struct virgl_caps_v2 {
         uint32_t max_combined_atomic_counter_buffers;
         uint32_t host_feature_check_version;
         struct virgl_supported_format_mask supported_readback_formats;
+        struct virgl_supported_format_mask scanout;
 };
 
 union virgl_caps {
index d6c9974..b061e8b 100644 (file)
@@ -38,6 +38,7 @@ static const uint32_t texture_source_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_R
 
 struct virtio_gpu_priv {
        int has_3d;
+       int caps_is_v2;
        union virgl_caps caps;
 };
 
@@ -89,17 +90,22 @@ static void virtio_gpu_add_combination(struct driver *drv, uint32_t drm_format,
        struct virtio_gpu_priv *priv = (struct virtio_gpu_priv *)drv->priv;
 
        if (priv->has_3d) {
-               if ((use_flags & BO_USE_RENDERING) != 0 &&
+               if ((use_flags & BO_USE_RENDERING) &&
                    !virtio_gpu_supports_format(&priv->caps.v1.render, drm_format)) {
                        drv_log("Skipping unsupported render format: %d\n", drm_format);
                        return;
                }
 
-               if ((use_flags & BO_USE_TEXTURE) != 0 &&
+               if ((use_flags & BO_USE_TEXTURE) &&
                    !virtio_gpu_supports_format(&priv->caps.v1.sampler, drm_format)) {
                        drv_log("Skipping unsupported texture format: %d\n", drm_format);
                        return;
                }
+               if ((use_flags & BO_USE_SCANOUT) && priv->caps_is_v2 &&
+                   !virtio_gpu_supports_format(&priv->caps.v2.scanout, drm_format)) {
+                       drv_log("Unsupported scanout format: %d\n", drm_format);
+                       use_flags &= ~BO_USE_SCANOUT;
+               }
        }
 
        drv_add_combination(drv, drm_format, metadata, use_flags);
@@ -229,7 +235,7 @@ static void *virtio_virgl_bo_map(struct bo *bo, struct vma *vma, size_t plane, u
                    gem_map.offset);
 }
 
-static int virtio_gpu_get_caps(struct driver *drv, union virgl_caps *caps)
+static int virtio_gpu_get_caps(struct driver *drv, union virgl_caps *caps, int *caps_is_v2)
 {
        int ret;
        struct drm_virtgpu_get_caps cap_args;
@@ -244,9 +250,11 @@ static int virtio_gpu_get_caps(struct driver *drv, union virgl_caps *caps)
                drv_log("DRM_IOCTL_VIRTGPU_GETPARAM failed with %s\n", strerror(errno));
        }
 
+       *caps_is_v2 = 0;
        memset(&cap_args, 0, sizeof(cap_args));
        cap_args.addr = (unsigned long long)caps;
        if (can_query_v2) {
+               *caps_is_v2 = 1;
                cap_args.cap_set_id = 2;
                cap_args.size = sizeof(union virgl_caps);
        } else {
@@ -257,6 +265,7 @@ static int virtio_gpu_get_caps(struct driver *drv, union virgl_caps *caps)
        ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GET_CAPS, &cap_args);
        if (ret) {
                drv_log("DRM_IOCTL_VIRTGPU_GET_CAPS failed with %s\n", strerror(errno));
+               *caps_is_v2 = 0;
 
                // Fallback to v1
                cap_args.cap_set_id = 1;
@@ -291,7 +300,7 @@ static int virtio_gpu_init(struct driver *drv)
        }
 
        if (priv->has_3d) {
-               virtio_gpu_get_caps(drv, &priv->caps);
+               virtio_gpu_get_caps(drv, &priv->caps, &priv->caps_is_v2);
 
                /* This doesn't mean host can scanout everything, it just means host
                 * hypervisor can show it. */