From 5e4a2b394eb03d5b49df8d3f2263c65b24ad2bb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Marchesin?= Date: Fri, 9 Feb 2018 17:21:59 -0800 Subject: [PATCH] virgl: Support v2 caps struct (v2) This struct allows us to report: - accurate max point size/line width. - accurate texel and texture gather offsets - vertex/geometry limits. Signed-off-by: Dave Airlie --- src/gallium/drivers/virgl/virgl_hw.h | 28 ++++++++++++++ src/gallium/drivers/virgl/virgl_screen.c | 29 ++++++++------ .../winsys/virgl/drm/virgl_drm_winsys.c | 38 ++++++++++++++++++- 3 files changed, 82 insertions(+), 13 deletions(-) diff --git a/src/gallium/drivers/virgl/virgl_hw.h b/src/gallium/drivers/virgl/virgl_hw.h index e3c56db2ac6..833ab91eee7 100644 --- a/src/gallium/drivers/virgl/virgl_hw.h +++ b/src/gallium/drivers/virgl/virgl_hw.h @@ -232,6 +232,11 @@ struct virgl_caps_bool_set1 { unsigned poly_stipple:1; /* not in GL 3.1 core profile */ unsigned mirror_clamp:1; unsigned texture_query_lod:1; + unsigned has_fp64:1; + unsigned has_tessellation_shaders:1; + unsigned has_indirect_draw:1; + unsigned has_sample_shading:1; + unsigned has_cull:1; }; /* endless expansion capabilites - current gallium has 252 formats */ @@ -259,9 +264,32 @@ struct virgl_caps_v1 { uint32_t max_texture_gather_components; }; +struct virgl_caps_v2 { + struct virgl_caps_v1 v1; + float min_aliased_point_size; + float max_aliased_point_size; + float min_smooth_point_size; + float max_smooth_point_size; + float min_aliased_line_width; + float max_aliased_line_width; + float min_smooth_line_width; + float max_smooth_line_width; + float max_texture_lod_bias; + uint32_t max_geom_output_vertices; + uint32_t max_geom_total_output_components; + uint32_t max_vertex_outputs; + uint32_t max_vertex_attribs; + uint32_t max_shader_patch_varyings; + int32_t min_texel_offset; + int32_t max_texel_offset; + int32_t min_texture_gather_offset; + int32_t max_texture_gather_offset; +}; + union virgl_caps { uint32_t max_version; struct virgl_caps_v1 v1; + struct virgl_caps_v2 v2; }; enum virgl_errors { diff --git a/src/gallium/drivers/virgl/virgl_screen.c b/src/gallium/drivers/virgl/virgl_screen.c index ca73b90e0fd..72dce08c286 100644 --- a/src/gallium/drivers/virgl/virgl_screen.c +++ b/src/gallium/drivers/virgl/virgl_screen.c @@ -113,11 +113,13 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: return vscreen->caps.caps.v1.max_texture_array_layers; case PIPE_CAP_MIN_TEXEL_OFFSET: + return vscreen->caps.caps.v2.min_texel_offset; case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET: - return -8; + return vscreen->caps.caps.v2.min_texture_gather_offset; case PIPE_CAP_MAX_TEXEL_OFFSET: + return vscreen->caps.caps.v2.max_texel_offset; case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET: - return 7; + return vscreen->caps.caps.v2.max_texture_gather_offset; case PIPE_CAP_CONDITIONAL_RENDER: return vscreen->caps.caps.v1.bset.conditional_render; case PIPE_CAP_TEXTURE_BARRIER: @@ -182,9 +184,9 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT: return 0; case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES: - return 256; + return vscreen->caps.caps.v2.max_geom_output_vertices; case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: - return 16384; + return vscreen->caps.caps.v2.max_geom_total_output_components; case PIPE_CAP_TEXTURE_QUERY_LOD: return vscreen->caps.caps.v1.bset.texture_query_lod; case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: @@ -310,11 +312,13 @@ virgl_get_shader_param(struct pipe_screen *screen, return 1; case PIPE_SHADER_CAP_MAX_INPUTS: if (vscreen->caps.caps.v1.glsl_level < 150) - return 16; + return vscreen->caps.caps.v2.max_vertex_attribs; return (shader == PIPE_SHADER_VERTEX || - shader == PIPE_SHADER_GEOMETRY) ? 16 : 32; + shader == PIPE_SHADER_GEOMETRY) ? vscreen->caps.caps.v2.max_vertex_attribs : 32; case PIPE_SHADER_CAP_MAX_OUTPUTS: - return 32; + if (shader == PIPE_SHADER_FRAGMENT) + return vscreen->caps.caps.v1.max_render_targets; + return vscreen->caps.caps.v2.max_vertex_outputs; // case PIPE_SHADER_CAP_MAX_CONSTS: // return 4096; case PIPE_SHADER_CAP_MAX_TEMPS: @@ -350,19 +354,20 @@ virgl_get_shader_param(struct pipe_screen *screen, static float virgl_get_paramf(struct pipe_screen *screen, enum pipe_capf param) { + struct virgl_screen *vscreen = virgl_screen(screen); switch (param) { case PIPE_CAPF_MAX_LINE_WIDTH: - /* fall-through */ + return vscreen->caps.caps.v2.max_aliased_line_width; case PIPE_CAPF_MAX_LINE_WIDTH_AA: - return 255.0; /* arbitrary */ + return vscreen->caps.caps.v2.max_smooth_line_width; case PIPE_CAPF_MAX_POINT_WIDTH: - /* fall-through */ + return vscreen->caps.caps.v2.max_aliased_point_size; case PIPE_CAPF_MAX_POINT_WIDTH_AA: - return 255.0; /* arbitrary */ + return vscreen->caps.caps.v2.max_smooth_point_size; case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: return 16.0; case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: - return 16.0; /* arbitrary */ + return vscreen->caps.caps.v2.max_texture_lod_bias; case PIPE_CAPF_GUARD_BAND_LEFT: case PIPE_CAPF_GUARD_BAND_TOP: case PIPE_CAPF_GUARD_BAND_RIGHT: diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c index 71e652ebf31..fd6ae98a515 100644 --- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c +++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c @@ -704,13 +704,49 @@ 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)); args.cap_set_id = 1; args.addr = (unsigned long)&caps->caps; args.size = sizeof(union virgl_caps); - return drmIoctl(vdws->fd, DRM_IOCTL_VIRTGPU_GET_CAPS, &args); + + ret = drmIoctl(vdws->fd, DRM_IOCTL_VIRTGPU_GET_CAPS, &args); + + if (ret == -1 && errno == EINVAL) { + /* Fallback to v1 */ + 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; } #define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))