virgl: Support v2 caps struct (v2)
authorStéphane Marchesin <marcheu@chromium.org>
Sat, 10 Feb 2018 01:21:59 +0000 (17:21 -0800)
committerDave Airlie <airlied@redhat.com>
Tue, 13 Feb 2018 04:23:54 +0000 (14:23 +1000)
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 <airlied@redhat.com>
src/gallium/drivers/virgl/virgl_hw.h
src/gallium/drivers/virgl/virgl_screen.c
src/gallium/winsys/virgl/drm/virgl_drm_winsys.c

index e3c56db2ac60ebb4856dabd220f28b7aec0a4ae0..833ab91eee75e3d39c7f2887f7e40716fae02045 100644 (file)
@@ -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 {
index ca73b90e0fda9fd3a78bd9befe2dc1fd4fe5fa19..72dce08c286ab4c03e946616da536c2ba549792a 100644 (file)
@@ -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:
index 71e652ebf31bee58d958ce57f98da86a0209d540..fd6ae98a515d1fbfc3fdd0d11f901632c83ffd76 100644 (file)
@@ -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)))