virgl: handle getting new capsets.
authorDave Airlie <airlied@redhat.com>
Thu, 15 Feb 2018 04:20:37 +0000 (14:20 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 5 Mar 2018 03:29:38 +0000 (13:29 +1000)
This checks the kernel api is new enough and asks for the
larger caps size since the kernel won't mess it up now.

Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/virgl/virgl_winsys.h
src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
src/gallium/winsys/virgl/drm/virgl_drm_winsys.h
src/gallium/winsys/virgl/drm/virtgpu_drm.h
src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c
src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c

index ea21f2b67126d4586b8109b40965609888ff1024..d633678597b454320d0e932d8ce09548dcd9cb32 100644 (file)
@@ -109,5 +109,28 @@ struct virgl_winsys {
                              struct pipe_box *sub_box);
 };
 
-
+/* this defaults all newer caps,
+ * the kernel will overwrite these if newer version is available.
+ */
+static inline void virgl_ws_fill_new_caps_defaults(struct virgl_drm_caps *caps)
+{
+   caps->caps.v2.min_aliased_point_size = 0.f;
+   caps->caps.v2.max_aliased_point_size = 255.f;
+   caps->caps.v2.min_smooth_point_size = 0.f;
+   caps->caps.v2.max_smooth_point_size = 255.f;
+   caps->caps.v2.min_aliased_line_width = 0.f;
+   caps->caps.v2.max_aliased_line_width = 255.f;
+   caps->caps.v2.min_smooth_line_width = 0.f;
+   caps->caps.v2.max_smooth_line_width = 255.f;
+   caps->caps.v2.max_texture_lod_bias = 16.0f;
+   caps->caps.v2.max_geom_output_vertices = 256;
+   caps->caps.v2.max_geom_total_output_components = 16384;
+   caps->caps.v2.max_vertex_outputs = 32;
+   caps->caps.v2.max_vertex_attribs = 16;
+   caps->caps.v2.max_shader_patch_varyings = 0;
+   caps->caps.v2.min_texel_offset = -8;
+   caps->caps.v2.max_texel_offset = 7;
+   caps->caps.v2.min_texture_gather_offset = -8;
+   caps->caps.v2.max_texture_gather_offset = 7;
+}
 #endif
index fd6ae98a515d1fbfc3fdd0d11f901632c83ffd76..77854680e59c8d77b5158b9f0ba5707a81f884a7 100644 (file)
@@ -705,46 +705,28 @@ static int virgl_drm_get_caps(struct virgl_winsys *vws,
    struct virgl_drm_winsys *vdws = virgl_drm_winsys(vws);
    struct drm_virtgpu_get_caps args;
    int ret;
-   bool fill_v2 = false;
 
-   memset(&args, 0, sizeof(args));
+   virgl_ws_fill_new_caps_defaults(caps);
 
-   args.cap_set_id = 1;
+   memset(&args, 0, sizeof(args));
+   if (vdws->has_capset_query_fix) {
+      /* 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);
+   } else {
+      args.cap_set_id = 1;
+      args.size = sizeof(struct virgl_caps_v1);
+   }
    args.addr = (unsigned long)&caps->caps;
-   args.size = sizeof(union virgl_caps);
 
    ret = drmIoctl(vdws->fd, DRM_IOCTL_VIRTGPU_GET_CAPS, &args);
-
    if (ret == -1 && errno == EINVAL) {
       /* Fallback to v1 */
+      args.cap_set_id = 1;
       args.size = sizeof(struct virgl_caps_v1);
       ret = drmIoctl(vdws->fd, DRM_IOCTL_VIRTGPU_GET_CAPS, &args);
       if (ret == -1)
           return ret;
-      fill_v2 = true;
-   }
-   if (caps->caps.max_version == 1)
-       fill_v2 = true;
-
-   if (fill_v2) {
-      caps->caps.v2.min_aliased_point_size = 0.f;
-      caps->caps.v2.max_aliased_point_size = 255.f;
-      caps->caps.v2.min_smooth_point_size = 0.f;
-      caps->caps.v2.max_smooth_point_size = 255.f;
-      caps->caps.v2.min_aliased_line_width = 0.f;
-      caps->caps.v2.max_aliased_line_width = 255.f;
-      caps->caps.v2.min_smooth_line_width = 0.f;
-      caps->caps.v2.max_smooth_line_width = 255.f;
-      caps->caps.v2.max_texture_lod_bias = 16.0f;
-      caps->caps.v2.max_geom_output_vertices = 256;
-      caps->caps.v2.max_geom_total_output_components = 16384;
-      caps->caps.v2.max_vertex_outputs = 32;
-      caps->caps.v2.max_vertex_attribs = 16;
-      caps->caps.v2.max_shader_patch_varyings = 0;
-      caps->caps.v2.min_texel_offset = -8;
-      caps->caps.v2.max_texel_offset = 7;
-      caps->caps.v2.min_texture_gather_offset = -8;
-      caps->caps.v2.max_texture_gather_offset = 7;
    }
    return ret;
 }
@@ -813,6 +795,8 @@ static struct virgl_winsys *
 virgl_drm_winsys_create(int drmFD)
 {
    struct virgl_drm_winsys *qdws;
+   int ret;
+   struct drm_virtgpu_getparam getparam = {0};
 
    qdws = CALLOC_STRUCT(virgl_drm_winsys);
    if (!qdws)
@@ -847,6 +831,16 @@ virgl_drm_winsys_create(int drmFD)
    qdws->base.fence_reference = virgl_fence_reference;
 
    qdws->base.get_caps = virgl_drm_get_caps;
+
+   uint32_t value;
+   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;
+   }
+
    return &qdws->base;
 
 }
index f6772153a42a39e9c460c93439ea549d3886d1c8..b28e7127ca00bf61afcbe9f616ba54f6e85dfb59 100644 (file)
@@ -64,6 +64,7 @@ struct virgl_drm_winsys
    struct util_hash_table *bo_handles;
    struct util_hash_table *bo_names;
    mtx_t bo_handles_mutex;
+   bool has_capset_query_fix;
 };
 
 struct virgl_drm_cmd_buf {
index 30bc3afdd8147f3e2773793c39c8502f195f8168..8596febe9fd25e8c55b0e30c35234d133af863de 100644 (file)
@@ -60,6 +60,7 @@ struct drm_virtgpu_execbuffer {
 };
 
 #define VIRTGPU_PARAM_3D_FEATURES 1 /* do we have 3D features in the hw */
+#define VIRTGPU_PARAM_CAPSET_QUERY_FIX 2
 
 struct drm_virtgpu_getparam {
        uint64_t param;
index 4541419d8e85a6f350df0ec8d9682ad310b4f77c..adec26b66b861e32bec43b08ed74645deafc0671 100644 (file)
@@ -142,7 +142,7 @@ int virgl_vtest_send_get_caps(struct virgl_vtest_winsys *vws,
    if (ret <= 0)
       return 0;
 
-   ret = virgl_block_read(vws->sock_fd, &caps->caps, sizeof(union virgl_caps));
+   ret = virgl_block_read(vws->sock_fd, &caps->caps, sizeof(struct virgl_caps_v1));
 
    return 0;
 }
index d76be4d5d32a551825897078f39d6329ae2ce8dd..f62d0d0981dd162f26f835d77f646b8d1b827dca 100644 (file)
@@ -519,6 +519,8 @@ static int virgl_vtest_get_caps(struct virgl_winsys *vws,
                                 struct virgl_drm_caps *caps)
 {
    struct virgl_vtest_winsys *vtws = virgl_vtest_winsys(vws);
+
+   virgl_ws_fill_new_caps_defaults(caps);
    return virgl_vtest_send_get_caps(vtws, caps);
 }