[virglrenderer-devel] [PATCH] virglrenderer: introduce a second capability set to workaround bugs in first.

Dave Airlie airlied at gmail.com
Thu Feb 15 04:28:20 UTC 2018


From: Dave Airlie <airlied at redhat.com>

This introduces a second capability set exposing a larger struct size.

The kernel ioctl has some bugs that necessitated this change.
---
 src/virgl_hw.h       | 23 ++++++++++++++++++
 src/virglrenderer.h  |  3 +++
 src/vrend_renderer.c | 68 ++++++++++++++++++++++++++++++++++++++++++++--------
 src/vrend_renderer.h |  1 +
 4 files changed, 85 insertions(+), 10 deletions(-)

diff --git a/src/virgl_hw.h b/src/virgl_hw.h
index 151b514..6468e27 100644
--- a/src/virgl_hw.h
+++ b/src/virgl_hw.h
@@ -260,9 +260,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/virglrenderer.h b/src/virglrenderer.h
index 6eb7bdb..0639261 100644
--- a/src/virglrenderer.h
+++ b/src/virglrenderer.h
@@ -169,4 +169,7 @@ VIRGL_EXPORT void virgl_renderer_cleanup(void *cookie);
 VIRGL_EXPORT void virgl_renderer_reset(void);
 
 VIRGL_EXPORT int virgl_renderer_get_poll_fd(void);
+
+#define VIRGLRENDERER_SUPPORTS_CAPSET2
+
 #endif
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 99c0b63..6b4f9d0 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -6292,19 +6292,25 @@ void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
 {
    int i;
    GLint max;
+   GLfloat range[2];
    int gl_ver = epoxy_gl_version();
-
+   bool fill_v2 = false;
    if (!caps)
       return;
 
-   memset(caps, 0, sizeof(*caps));
-
-   if (set != 1 && set != 0) {
+   if (set > 2) {
       caps->max_version = 0;
       return;
    }
 
-   caps->max_version = 1;
+   if (set == 1) {
+      memset(caps, 0, sizeof(struct virgl_caps_v1));
+      caps->max_version = 1;
+   } else if (set == 2) {
+      fill_v2 = true;
+      memset(caps, 0, sizeof(*caps));
+      caps->max_version = 2;
+   }
 
    caps->v1.bset.occlusion_query = 1;
    if (gl_ver >= 30) {
@@ -6471,6 +6477,42 @@ void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
          }
       }
    }
+
+   if (fill_v2) {
+      glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, range);
+      caps->v2.min_aliased_point_size = range[0];
+      caps->v2.max_aliased_point_size = range[1];
+
+      glGetFloatv(GL_SMOOTH_POINT_SIZE_RANGE, range);
+      caps->v2.min_smooth_point_size = range[0];
+      caps->v2.max_smooth_point_size = range[1];
+
+      glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range);
+      caps->v2.min_aliased_line_width = range[0];
+      caps->v2.max_aliased_line_width = range[1];
+
+      glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, range);
+      caps->v2.min_smooth_line_width = range[0];
+      caps->v2.max_smooth_line_width = range[1];
+
+      glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &caps->v2.max_texture_lod_bias);
+      glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps->v2.max_vertex_attribs);
+      glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS, &max);
+      caps->v2.max_vertex_outputs = max / 4;
+
+      if (gl_ver >= 32) {
+         glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &caps->v2.max_geom_output_vertices);
+         glGetIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &caps->v2.max_geom_total_output_components);
+      }
+      caps->v2.max_shader_patch_varyings = 0; // until we do tess.
+
+      if (epoxy_has_gl_extension("GL_ARB_texture_gather")) {
+         glGetIntegerv(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET, &caps->v2.min_texture_gather_offset);
+         glGetIntegerv(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET, &caps->v2.max_texture_gather_offset);
+      }
+      glGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &caps->v2.min_texel_offset);
+      glGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET, &caps->v2.max_texel_offset);
+   }
 }
 
 GLint64 vrend_renderer_get_timestamp(void)
@@ -6669,14 +6711,20 @@ int vrend_renderer_resource_get_info(int res_handle,
 void vrend_renderer_get_cap_set(uint32_t cap_set, uint32_t *max_ver,
                                 uint32_t *max_size)
 {
-   if (cap_set != VREND_CAP_SET) {
+   switch (cap_set) {
+   case VREND_CAP_SET:
+      *max_ver = 1;
+      *max_size = sizeof(struct virgl_caps_v1);
+      break;
+   case VREND_CAP_SET2:
+      *max_ver = 2;
+      *max_size = sizeof(union virgl_caps);
+      break;
+   default:
       *max_ver = 0;
       *max_size = 0;
-      return;
+      break;
    }
-
-   *max_ver = 1;
-   *max_size = sizeof(union virgl_caps);
 }
 
 void vrend_renderer_create_sub_ctx(struct vrend_context *ctx, int sub_ctx_id)
diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h
index 71d14c4..0d8089b 100644
--- a/src/vrend_renderer.h
+++ b/src/vrend_renderer.h
@@ -353,6 +353,7 @@ int vrend_renderer_resource_get_info(int res_handle,
                                      struct vrend_renderer_resource_info *info);
 
 #define VREND_CAP_SET 1
+#define VREND_CAP_SET2 2
 
 void vrend_renderer_get_cap_set(uint32_t cap_set, uint32_t *max_ver,
                                 uint32_t *max_size);
-- 
2.14.3



More information about the virglrenderer-devel mailing list