summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2018-02-15 14:20:37 +1000
committerDave Airlie <airlied@redhat.com>2018-03-05 13:29:38 +1000
commitcd32258ec12e8edaf9facfa0715ad40032530f7e (patch)
tree2bfc7f9f4bcfdebf9fc4af0735273e38b69a558c
parent70190a656766019107d82aa5404ffa1cad9fb6e4 (diff)
virgl: handle getting new capsets.
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>
-rw-r--r--src/gallium/drivers/virgl/virgl_winsys.h25
-rw-r--r--src/gallium/winsys/virgl/drm/virgl_drm_winsys.c52
-rw-r--r--src/gallium/winsys/virgl/drm/virgl_drm_winsys.h1
-rw-r--r--src/gallium/winsys/virgl/drm/virtgpu_drm.h1
-rw-r--r--src/gallium/winsys/virgl/vtest/virgl_vtest_socket.c2
-rw-r--r--src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c2
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);
}