vmware/core: Handle new scanout field
authorJakob Bornecrantz <jakob@vmware.com>
Sat, 6 Feb 2010 00:21:36 +0000 (01:21 +0100)
committerJakob Bornecrantz <jakob@vmware.com>
Sat, 6 Feb 2010 02:36:47 +0000 (03:36 +0100)
src/gallium/winsys/drm/vmware/core/vmw_screen.c
src/gallium/winsys/drm/vmware/core/vmw_screen.h
src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c

index 911eec5e254714ff2a574ca1ad36f0d45acbe929..6cc9b38293219b1a18a10071af0680123acb56d2 100644 (file)
  * module.
  */
 struct vmw_winsys_screen *
-vmw_winsys_create( int fd )
+vmw_winsys_create( int fd, boolean use_old_scanout_flag )
 {
    struct vmw_winsys_screen *vws = CALLOC_STRUCT(vmw_winsys_screen);
    if (!vws)
       goto out_no_vws;
 
    vws->ioctl.drm_fd = fd;
+   vws->use_old_scanout_flag = use_old_scanout_flag;
+   debug_printf("%s: use_old_scanout_flag == %s\n", __FUNCTION__,
+               use_old_scanout_flag ? "true" : "false");
 
    if (!vmw_ioctl_init(vws))
       goto out_no_ioctl;
index f1d69865e774f35b3f8e6eb29c6ffc2a1c255c64..d3f2c2c7f568274cdc8fa1dee5e736703f388154 100644 (file)
@@ -52,6 +52,8 @@ struct vmw_winsys_screen
 {
    struct svga_winsys_screen base;
 
+   boolean use_old_scanout_flag;
+
    struct {
       volatile uint32_t *fifo_map;
       uint64_t last_fence;
@@ -131,7 +133,7 @@ boolean vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws);
 void vmw_ioctl_cleanup(struct vmw_winsys_screen *vws);
 void vmw_pools_cleanup(struct vmw_winsys_screen *vws);
 
-struct vmw_winsys_screen *vmw_winsys_create(int fd);
+struct vmw_winsys_screen *vmw_winsys_create(int fd, boolean use_old_scanout_flag);
 void vmw_winsys_destroy(struct vmw_winsys_screen *sws);
 
 
index 917b49f1c125db0f0e3eeec059fbba5b72d00f19..b7c02f67177898237fd7c6b890e4b5c7c666729e 100644 (file)
@@ -51,6 +51,7 @@ static struct dri1_api_version dri_required = { 4, 0, 0 };
 static struct dri1_api_version dri_compat = { 4, 0, 0 };
 static struct dri1_api_version drm_required = { 0, 1, 0 };
 static struct dri1_api_version drm_compat = { 0, 0, 0 };
+static struct dri1_api_version drm_scanout = { 0, 9, 0 };
 
 static boolean
 vmw_dri1_check_version(const struct dri1_api_version *cur,
@@ -85,6 +86,7 @@ vmw_drm_create_screen(struct drm_api *drm_api,
    struct vmw_winsys_screen *vws;
    struct pipe_screen *screen;
    struct dri1_create_screen_arg *dri1;
+   boolean use_old_scanout_flag = FALSE;
 
    if (!arg || arg->mode == DRM_CREATE_NORMAL) {
       struct dri1_api_version drm_ver;
@@ -96,11 +98,16 @@ vmw_drm_create_screen(struct drm_api *drm_api,
 
       drm_ver.major = ver->version_major;
       drm_ver.minor = ver->version_minor;
+      drm_ver.patch_level = 0; /* ??? */
 
       drmFreeVersion(ver);
       if (!vmw_dri1_check_version(&drm_ver, &drm_required,
                                  &drm_compat, "vmwgfx drm driver"))
         return NULL;
+
+      if (!vmw_dri1_check_version(&drm_ver, &drm_scanout,
+                                 &drm_compat, "use old scanout field (not a error)"))
+         use_old_scanout_flag = TRUE;
    }
 
    if (arg != NULL) {
@@ -118,6 +125,9 @@ vmw_drm_create_screen(struct drm_api *drm_api,
         if (!vmw_dri1_check_version(&dri1->drm_version, &drm_required,
                                     &drm_compat, "vmwgfx drm driver"))
            return NULL;
+        if (!vmw_dri1_check_version(&dri1->drm_version, &drm_scanout,
+                                    &drm_compat, "use old scanout field (not a error)"))
+           use_old_scanout_flag = TRUE;
         dri1->api = &dri1_api_hooks;
         break;
       default:
@@ -125,7 +135,7 @@ vmw_drm_create_screen(struct drm_api *drm_api,
       }
    }
 
-   vws = vmw_winsys_create( fd );
+   vws = vmw_winsys_create( fd, use_old_scanout_flag );
    if (!vws)
       goto out_no_vws;
 
index ccd0b418a169f6cabc0107db4e638a9cc3cdf4f2..f2de2c333ffa68ce631c3ead5e92f28a017df3a1 100644 (file)
@@ -57,6 +57,12 @@ struct vmw_region
    uint32_t size;
 };
 
+/* XXX: This isn't a real hardware flag, but just a hack for kernel to
+ * know about primary surfaces. In newer versions of the kernel
+ * interface the driver uses a special field.
+ */
+#define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9)
+
 static void
 vmw_check_last_cmd(struct vmw_winsys_screen *vws)
 {
@@ -169,7 +175,17 @@ vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
    vmw_printf("%s flags %d format %d\n", __FUNCTION__, flags, format);
 
    memset(&s_arg, 0, sizeof(s_arg));
-   req->flags = (uint32_t) flags;
+   if (vws->use_old_scanout_flag &&
+       (req->flags & SVGA3D_SURFACE_HINT_SCANOUT)) {
+      req->flags = (uint32_t) (flags & ~SVGA3D_SURFACE_HINT_SCANOUT);
+      req->scanout = false;
+   } else if (req->flags & SVGA3D_SURFACE_HINT_SCANOUT) {
+      req->flags = (uint32_t) (flags & ~SVGA3D_SURFACE_HINT_SCANOUT);
+      req->scanout = false;
+   } else {
+      req->flags = (uint32_t) flags;
+      req->scanout = false;
+   }
    req->format = (uint32_t) format;
    req->shareable = 1;