virgl/drm: query for resource blob and host visible memory region

Check for these features.

v2: refactor querying params in general (@shadeslayer)

Reviewed-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4821>
diff --git a/src/gallium/drivers/virgl/virgl_winsys.h b/src/gallium/drivers/virgl/virgl_winsys.h
index 2db2e29..30d2afb 100644
--- a/src/gallium/drivers/virgl/virgl_winsys.h
+++ b/src/gallium/drivers/virgl/virgl_winsys.h
@@ -47,6 +47,7 @@
    unsigned pci_id;
    int supports_fences; /* In/Out fences are supported */
    int supports_encoded_transfers; /* Encoded transfers are supported */
+   int supports_coherent;          /* Coherent memory is supported */
 
    void (*destroy)(struct virgl_winsys *vws);
 
diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
index 3cbe9a5..84c985d 100644
--- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
+++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
@@ -775,7 +775,7 @@
    virgl_ws_fill_new_caps_defaults(caps);
 
    memset(&args, 0, sizeof(args));
-   if (vdws->has_capset_query_fix) {
+   if (params[param_capset_fix].value) {
       /* if we have the query fix - try and get cap set id 2 first */
       args.cap_set_id = 2;
       args.size = sizeof(union virgl_caps);
@@ -941,13 +941,17 @@
    struct virgl_drm_winsys *qdws;
    int drm_version;
    int ret;
-   int gl = 0;
-   struct drm_virtgpu_getparam getparam = {0};
 
-   getparam.param = VIRTGPU_PARAM_3D_FEATURES;
-   getparam.value = (uint64_t)(uintptr_t)&gl;
-   ret = drmIoctl(drmFD, DRM_IOCTL_VIRTGPU_GETPARAM, &getparam);
-   if (ret < 0 || !gl)
+   for (uint32_t i = 0; i < ARRAY_SIZE(params); i++) {
+      struct drm_virtgpu_getparam getparam = { 0 };
+      uint64_t value = 0;
+      getparam.param = params[i].param;
+      getparam.value = (uint64_t)(uintptr_t)&value;
+      ret = drmIoctl(drmFD, DRM_IOCTL_VIRTGPU_GETPARAM, &getparam);
+      params[i].value = (ret == 0) ? value : 0;
+   }
+
+   if (!params[param_3d_features].value)
       return NULL;
 
    drm_version = virgl_drm_get_version(drmFD);
@@ -989,20 +993,12 @@
    qdws->base.fence_reference = virgl_fence_reference;
    qdws->base.fence_server_sync = virgl_fence_server_sync;
    qdws->base.fence_get_fd = virgl_fence_get_fd;
+   qdws->base.get_caps = virgl_drm_get_caps;
    qdws->base.supports_fences =  drm_version >= VIRGL_DRM_VERSION_FENCE_FD;
    qdws->base.supports_encoded_transfers = 1;
 
-   qdws->base.get_caps = virgl_drm_get_caps;
-
-   uint32_t value = 0;
-   getparam.param = VIRTGPU_PARAM_CAPSET_QUERY_FIX;
-   getparam.value = (uint64_t)(uintptr_t)&value;
-   ret = drmIoctl(qdws->fd, DRM_IOCTL_VIRTGPU_GETPARAM, &getparam);
-   if (ret == 0) {
-      if (value == 1)
-         qdws->has_capset_query_fix = true;
-   }
-
+   qdws->base.supports_coherent = params[param_resource_blob].value &&
+                                  params[param_host_visible].value;
    return &qdws->base;
 
 }
diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h
index 29612c0..8516245 100644
--- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h
+++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h
@@ -54,6 +54,30 @@
    int maybe_busy;
 };
 
+
+struct param {
+   uint64_t param;
+   const char *name;
+   uint64_t value;
+};
+
+enum param_id {
+   param_3d_features,
+   param_capset_fix,
+   param_resource_blob,
+   param_host_visible,
+   param_max,
+};
+
+#define PARAM(x) (struct param) { x, #x, 0 }
+
+struct param params[] = { PARAM(VIRTGPU_PARAM_3D_FEATURES),
+                          PARAM(VIRTGPU_PARAM_CAPSET_QUERY_FIX),
+                          PARAM(VIRTGPU_PARAM_RESOURCE_BLOB),
+                          PARAM(VIRTGPU_PARAM_HOST_VISIBLE),
+                          PARAM(VIRTGPU_PARAM_CROSS_DEVICE)
+};
+
 struct virgl_drm_winsys
 {
    struct virgl_winsys base;
@@ -64,7 +88,6 @@
    struct hash_table *bo_handles;
    struct hash_table *bo_names;
    mtx_t bo_handles_mutex;
-   bool has_capset_query_fix;
 };
 
 struct virgl_drm_fence {