virgl: Use virgl_resource_cache in the drm winsys
authorAlexandros Frantzis <alexandros.frantzis@collabora.com>
Wed, 12 Jun 2019 07:30:26 +0000 (10:30 +0300)
committerAlexandros Frantzis <alexandros.frantzis@collabora.com>
Fri, 14 Jun 2019 09:59:43 +0000 (12:59 +0300)
Replace the cache implementation in the drm winsys with
virgl_resource_cache.

Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
src/gallium/winsys/virgl/drm/Android.mk
src/gallium/winsys/virgl/drm/meson.build
src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
src/gallium/winsys/virgl/drm/virgl_drm_winsys.h

index 4256f467d48f5cd8c02e4d19e0d83787700e9200..5e2500774e7d4f154f53558ae7ffafe124c5ad3f 100644 (file)
@@ -29,5 +29,7 @@ LOCAL_SRC_FILES := $(C_SOURCES)
 
 LOCAL_MODULE := libmesa_winsys_virgl
 
+LOCAL_STATIC_LIBRARIES := libmesa_winsys_virgl_common
+
 include $(GALLIUM_COMMON_MK)
 include $(BUILD_STATIC_LIBRARY)
index 89626e786375caabb7291bf6c4a0d2c381093261..cbb5fb9d4b2da7029e98e30e381e017280d868fd 100644 (file)
@@ -23,5 +23,5 @@ libvirgldrm = static_library(
   'virgl_drm_winsys.c',
   c_args : c_vis_args,
   include_directories : [inc_common, inc_gallium_drivers],
-  dependencies : dep_libdrm,
+  dependencies : [dep_libdrm, dep_libvirglcommon],
 )
index 6f215b5ecdb84ec9e7bda186a235599c27be13f7..4ce2302f317fbfe95327a895616457834e84984a 100644 (file)
@@ -49,6 +49,9 @@
 #define VIRGL_DRM_VERSION(major, minor) ((major) << 16 | (minor))
 #define VIRGL_DRM_VERSION_FENCE_FD      VIRGL_DRM_VERSION(0, 1)
 
+/* Gets a pointer to the virgl_hw_res containing the pointed to cache entry. */
+#define cache_entry_container_res(ptr) \
+    (struct virgl_hw_res*)((char*)ptr - offsetof(struct virgl_hw_res, cache_entry))
 
 static inline boolean can_cache_resource_with_bind(uint32_t bind)
 {
@@ -103,31 +106,12 @@ static boolean virgl_drm_resource_is_busy(struct virgl_winsys *vws,
    return FALSE;
 }
 
-static void
-virgl_cache_flush(struct virgl_drm_winsys *qdws)
-{
-   struct list_head *curr, *next;
-   struct virgl_hw_res *res;
-
-   mtx_lock(&qdws->mutex);
-   curr = qdws->delayed.next;
-   next = curr->next;
-
-   while (curr != &qdws->delayed) {
-      res = LIST_ENTRY(struct virgl_hw_res, curr, head);
-      LIST_DEL(&res->head);
-      virgl_hw_res_destroy(qdws, res);
-      curr = next;
-      next = curr->next;
-   }
-   mtx_unlock(&qdws->mutex);
-}
 static void
 virgl_drm_winsys_destroy(struct virgl_winsys *qws)
 {
    struct virgl_drm_winsys *qdws = virgl_drm_winsys(qws);
 
-   virgl_cache_flush(qdws);
+   virgl_resource_cache_flush(&qdws->cache);
 
    util_hash_table_destroy(qdws->bo_handles);
    util_hash_table_destroy(qdws->bo_names);
@@ -137,28 +121,6 @@ virgl_drm_winsys_destroy(struct virgl_winsys *qws)
    FREE(qdws);
 }
 
-static void
-virgl_cache_list_check_free(struct virgl_drm_winsys *qdws)
-{
-   struct list_head *curr, *next;
-   struct virgl_hw_res *res;
-   int64_t now;
-
-   now = os_time_get();
-   curr = qdws->delayed.next;
-   next = curr->next;
-   while (curr != &qdws->delayed) {
-      res = LIST_ENTRY(struct virgl_hw_res, curr, head);
-      if (!os_time_timeout(res->start, res->end, now))
-         break;
-
-      LIST_DEL(&res->head);
-      virgl_hw_res_destroy(qdws, res);
-      curr = next;
-      next = curr->next;
-   }
-}
-
 static void virgl_drm_resource_reference(struct virgl_drm_winsys *qdws,
                                        struct virgl_hw_res **dres,
                                        struct virgl_hw_res *sres)
@@ -171,12 +133,7 @@ static void virgl_drm_resource_reference(struct virgl_drm_winsys *qdws,
          virgl_hw_res_destroy(qdws, old);
       } else {
          mtx_lock(&qdws->mutex);
-         virgl_cache_list_check_free(qdws);
-
-         old->start = os_time_get();
-         old->end = old->start + qdws->usecs;
-         LIST_ADDTAIL(&old->head, &qdws->delayed);
-         qdws->num_delayed++;
+         virgl_resource_cache_add(&qdws->cache, &old->cache_entry);
          mtx_unlock(&qdws->mutex);
       }
    }
@@ -243,28 +200,9 @@ virgl_drm_winsys_resource_create(struct virgl_winsys *qws,
     */
    p_atomic_set(&res->maybe_busy, for_fencing);
 
-   return res;
-}
-
-static inline int virgl_is_res_compat(struct virgl_drm_winsys *qdws,
-                                      struct virgl_hw_res *res,
-                                      uint32_t size, uint32_t bind,
-                                      uint32_t format)
-{
-   if (res->bind != bind)
-      return 0;
-   if (res->format != format)
-      return 0;
-   if (res->size < size)
-      return 0;
-   if (res->size > size * 2)
-      return 0;
+   virgl_resource_cache_entry_init(&res->cache_entry, size, bind, format);
 
-   if (virgl_drm_resource_is_busy(&qdws->base, res)) {
-      return -1;
-   }
-
-   return 1;
+   return res;
 }
 
 static int
@@ -335,57 +273,18 @@ virgl_drm_winsys_resource_cache_create(struct virgl_winsys *qws,
                                        uint32_t size)
 {
    struct virgl_drm_winsys *qdws = virgl_drm_winsys(qws);
-   struct virgl_hw_res *res, *curr_res;
-   struct list_head *curr, *next;
-   int64_t now;
-   int ret = 0;
+   struct virgl_hw_res *res;
+   struct virgl_resource_cache_entry *entry;
 
    if (!can_cache_resource_with_bind(bind))
       goto alloc;
 
    mtx_lock(&qdws->mutex);
 
-   res = NULL;
-   curr = qdws->delayed.next;
-   next = curr->next;
-
-   now = os_time_get();
-   while (curr != &qdws->delayed) {
-      curr_res = LIST_ENTRY(struct virgl_hw_res, curr, head);
-
-      if (!res && ((ret = virgl_is_res_compat(qdws, curr_res, size, bind, format)) > 0))
-         res = curr_res;
-      else if (os_time_timeout(curr_res->start, curr_res->end, now)) {
-         LIST_DEL(&curr_res->head);
-         virgl_hw_res_destroy(qdws, curr_res);
-      } else
-         break;
-
-      if (ret == -1)
-         break;
-
-      curr = next;
-      next = curr->next;
-   }
-
-   if (!res && ret != -1) {
-      while (curr != &qdws->delayed) {
-         curr_res = LIST_ENTRY(struct virgl_hw_res, curr, head);
-         ret = virgl_is_res_compat(qdws, curr_res, size, bind, format);
-         if (ret > 0) {
-            res = curr_res;
-            break;
-         }
-         if (ret == -1)
-            break;
-         curr = next;
-         next = curr->next;
-      }
-   }
-
-   if (res) {
-      LIST_DEL(&res->head);
-      --qdws->num_delayed;
+   entry = virgl_resource_cache_remove_compatible(&qdws->cache, size,
+                                                  bind, format);
+   if (entry) {
+      res = cache_entry_container_res(entry);
       mtx_unlock(&qdws->mutex);
       pipe_reference_init(&res->reference, 1);
       return res;
@@ -1026,9 +925,30 @@ static int virgl_drm_get_version(int fd)
        return ret;
 }
 
+static bool
+virgl_drm_resource_cache_entry_is_busy(struct virgl_resource_cache_entry *entry,
+                                       void *user_data)
+{
+   struct virgl_drm_winsys *qdws = user_data;
+   struct virgl_hw_res *res = cache_entry_container_res(entry);
+
+   return virgl_drm_resource_is_busy(&qdws->base, res);
+}
+
+static void
+virgl_drm_resource_cache_entry_release(struct virgl_resource_cache_entry *entry,
+                                       void *user_data)
+{
+   struct virgl_drm_winsys *qdws = user_data;
+   struct virgl_hw_res *res = cache_entry_container_res(entry);
+
+   virgl_hw_res_destroy(qdws, res);
+}
+
 static struct virgl_winsys *
 virgl_drm_winsys_create(int drmFD)
 {
+   static const unsigned CACHE_TIMEOUT_USEC = 1000000;
    struct virgl_drm_winsys *qdws;
    int drm_version;
    int ret;
@@ -1050,9 +970,10 @@ virgl_drm_winsys_create(int drmFD)
       return NULL;
 
    qdws->fd = drmFD;
-   qdws->num_delayed = 0;
-   qdws->usecs = 1000000;
-   LIST_INITHEAD(&qdws->delayed);
+   virgl_resource_cache_init(&qdws->cache, CACHE_TIMEOUT_USEC,
+                             virgl_drm_resource_cache_entry_is_busy,
+                             virgl_drm_resource_cache_entry_release,
+                             qdws);
    (void) mtx_init(&qdws->mutex, mtx_plain);
    (void) mtx_init(&qdws->bo_handles_mutex, mtx_plain);
    qdws->bo_handles = util_hash_table_create(handle_hash, handle_compare);
index 2f27c811b6771b8423d4f50107e10ccc2e8f2200..b233e57d176488861a879527d24b899e1217ed6a 100644 (file)
@@ -29,6 +29,7 @@
 #include "util/list.h"
 
 #include "virgl/virgl_winsys.h"
+#include "virgl_resource_cache.h"
 
 struct pipe_fence_handle;
 struct util_hash_table;
@@ -42,10 +43,9 @@ struct virgl_hw_res {
    void *ptr;
    uint32_t stride;
 
-   struct list_head head;
+   struct virgl_resource_cache_entry cache_entry;
    uint32_t format;
    uint32_t bind;
-   int64_t start, end;
    uint32_t flink_name;
 
    /* true when the resource is imported or exported */
@@ -59,9 +59,7 @@ struct virgl_drm_winsys
 {
    struct virgl_winsys base;
    int fd;
-   struct list_head delayed;
-   int num_delayed;
-   unsigned usecs;
+   struct virgl_resource_cache cache;
    mtx_t mutex;
 
    struct util_hash_table *bo_handles;