From cd32258ec12e8edaf9facfa0715ad40032530f7e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 15 Feb 2018 14:20:37 +1000 Subject: [PATCH] virgl: handle getting new capsets. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Dave Airlie --- src/gallium/drivers/virgl/virgl_winsys.h | 25 ++++++++- .../winsys/virgl/drm/virgl_drm_winsys.c | 52 ++++++++----------- .../winsys/virgl/drm/virgl_drm_winsys.h | 1 + src/gallium/winsys/virgl/drm/virtgpu_drm.h | 1 + .../winsys/virgl/vtest/virgl_vtest_socket.c | 2 +- .../winsys/virgl/vtest/virgl_vtest_winsys.c | 2 + 6 files changed, 52 insertions(+), 31 deletions(-) diff --git a/src/gallium/drivers/virgl/virgl_winsys.h b/src/gallium/drivers/virgl/virgl_winsys.h index ea21f2b6712..d633678597b 100644 --- a/src/gallium/drivers/virgl/virgl_winsys.h +++ b/src/gallium/drivers/virgl/virgl_winsys.h @@ -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 diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c index fd6ae98a515..77854680e59 100644 --- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c +++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c @@ -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; } diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h index f6772153a42..b28e7127ca0 100644 --- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h +++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h @@ -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 { diff --git a/src/gallium/winsys/virgl/drm/virtgpu_drm.h b/src/gallium/winsys/virgl/drm/virtgpu_drm.h index 30bc3afdd81..8596febe9fd 100644 --- a/src/gallium/winsys/virgl/drm/virtgpu_drm.h +++ b/src/gallium/winsys/virgl/drm/virtgpu_drm.h @@ -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; diff --git a/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c b/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c index 4541419d8e8..adec26b66b8 100644 --- a/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c +++ b/src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c @@ -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; } diff --git a/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c b/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c index d76be4d5d32..f62d0d0981d 100644 --- a/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c +++ b/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c @@ -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); } -- 2.30.2