virgl: Add more meta data to cached resources
authorRohan Garg <rohan.garg@collabora.com>
Tue, 8 Jun 2021 09:43:35 +0000 (11:43 +0200)
committerMarge Bot <eric+marge@anholt.net>
Tue, 27 Jul 2021 20:34:38 +0000 (20:34 +0000)
By expanding the meta data about resources in the cache we can match more
resources such as 3D textures, samplers and render targets.

Signed-off-by: Rohan Garg <rohan.garg@collabora.com>
Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11241>

src/gallium/winsys/virgl/common/virgl_resource_cache.c
src/gallium/winsys/virgl/common/virgl_resource_cache.h
src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c

index d7d6a61..ba00a05 100644 (file)
  * data of the specified size, bind and format.
  */
 static bool
-virgl_resource_cache_entry_is_compatible(struct virgl_resource_cache_entry *entry,
-                                         uint32_t size, uint32_t bind,
-                                         uint32_t format, uint32_t flags)
+virgl_resource_cache_entry_is_compatible(struct virgl_resource_cache_entry *entry, struct virgl_resource_params params)
 {
-   return (entry->bind == bind &&
-           entry->format == format &&
-           entry->size >= size &&
-           entry->flags == flags &&
-           /* We don't want to waste space, so don't reuse resource storage to
-            * hold much smaller (< 50%) sizes.
-            */
-           entry->size <= size * 2);
+   if (entry->params.target == PIPE_BUFFER) {
+         return (entry->params.bind == params.bind &&
+                 entry->params.format == params.format &&
+                 entry->params.size >= params.size &&
+                 entry->params.flags == params.flags &&
+                 /* We don't want to waste space, so don't reuse resource storage to
+                 * hold much smaller (< 50%) sizes.
+                 */
+                 entry->params.size <= params.size * 2 &&
+                 entry->params.width >= params.width &&
+                 entry->params.target == params.target);
+   } else {
+      return memcmp(&entry->params, &params, sizeof(params)) == 0;
+   }
 }
 
 static void
@@ -97,8 +101,7 @@ virgl_resource_cache_add(struct virgl_resource_cache *cache,
 
 struct virgl_resource_cache_entry *
 virgl_resource_cache_remove_compatible(struct virgl_resource_cache *cache,
-                                       uint32_t size, uint32_t bind,
-                                       uint32_t format, uint32_t flags)
+                                       struct virgl_resource_params params)
 {
    const int64_t now = os_time_get();
    struct virgl_resource_cache_entry *compat_entry = NULL;
@@ -110,8 +113,7 @@ virgl_resource_cache_remove_compatible(struct virgl_resource_cache *cache,
    list_for_each_entry_safe(struct virgl_resource_cache_entry,
                             entry, &cache->resources, head) {
       const bool compatible =
-         virgl_resource_cache_entry_is_compatible(entry, size, bind, format,
-                                                 flags);
+         virgl_resource_cache_entry_is_compatible(entry, params);
 
       if (compatible) {
          if (!cache->entry_is_busy_func(entry, cache->user_data))
index e5f710d..e7979c4 100644 (file)
 #include <stdint.h>
 
 #include "util/list.h"
+#include "gallium/include/pipe/p_defines.h"
 
-struct virgl_resource_cache_entry {
-   struct list_head head;
-   int64_t timeout_start;
-   int64_t timeout_end;
+struct virgl_resource_params {
    uint32_t size;
    uint32_t bind;
    uint32_t format;
    uint32_t flags;
+   uint32_t nr_samples;
+   uint32_t width;
+   uint32_t height;
+   uint32_t depth;
+   uint32_t array_size;
+   uint32_t last_level;
+   enum pipe_texture_target target;
+};
+
+struct virgl_resource_cache_entry {
+   struct list_head head;
+   int64_t timeout_start;
+   int64_t timeout_end;
+   struct virgl_resource_params params;
 };
 
 /* Pointer to a function that returns whether the resource represented by
@@ -81,8 +93,7 @@ virgl_resource_cache_add(struct virgl_resource_cache *cache,
  */
 struct virgl_resource_cache_entry *
 virgl_resource_cache_remove_compatible(struct virgl_resource_cache *cache,
-                                       uint32_t size, uint32_t bind,
-                                       uint32_t format, uint32_t flags);
+                                       struct virgl_resource_params params);
 
 /** Empties the resource cache. */
 void
@@ -90,13 +101,9 @@ virgl_resource_cache_flush(struct virgl_resource_cache *cache);
 
 static inline void
 virgl_resource_cache_entry_init(struct virgl_resource_cache_entry *entry,
-                                uint32_t size, uint32_t bind,
-                                uint32_t format, uint32_t flags)
+                                struct virgl_resource_params params)
 {
-   entry->size = size;
-   entry->bind = bind;
-   entry->format = format;
-   entry->flags = flags;
+   entry->params = params;
 }
 
 #endif
index dfa145a..694c061 100644 (file)
@@ -176,6 +176,17 @@ virgl_drm_winsys_resource_create_blob(struct virgl_winsys *qws,
    struct virgl_drm_winsys *qdws = virgl_drm_winsys(qws);
    struct drm_virtgpu_resource_create_blob drm_rc_blob = { 0 };
    struct virgl_hw_res *res;
+   struct virgl_resource_params params = { .size = size,
+                                           .bind = bind,
+                                           .format = format,
+                                           .flags = flags,
+                                           .nr_samples = nr_samples,
+                                           .width = width,
+                                           .height = height,
+                                           .depth = depth,
+                                           .array_size = array_size,
+                                           .last_level = last_level,
+                                           .target = target };
 
    res = CALLOC_STRUCT(virgl_hw_res);
    if (!res)
@@ -224,8 +235,7 @@ virgl_drm_winsys_resource_create_blob(struct virgl_winsys *qws,
    pipe_reference_init(&res->reference, 1);
    p_atomic_set(&res->external, false);
    p_atomic_set(&res->num_cs_references, 0);
-   virgl_resource_cache_entry_init(&res->cache_entry, size, bind, format,
-                                    flags);
+   virgl_resource_cache_entry_init(&res->cache_entry, params);
    return res;
 }
 
@@ -248,6 +258,17 @@ virgl_drm_winsys_resource_create(struct virgl_winsys *qws,
    int ret;
    struct virgl_hw_res *res;
    uint32_t stride = width * util_format_get_blocksize(format);
+   struct virgl_resource_params params = { .size = size,
+                                           .bind = bind,
+                                           .format = format,
+                                           .flags = 0,
+                                           .nr_samples = nr_samples,
+                                           .width = width,
+                                           .height = height,
+                                           .depth = depth,
+                                           .array_size = array_size,
+                                           .last_level = last_level,
+                                           .target = target };
 
    res = CALLOC_STRUCT(virgl_hw_res);
    if (!res)
@@ -289,7 +310,7 @@ virgl_drm_winsys_resource_create(struct virgl_winsys *qws,
     */
    p_atomic_set(&res->maybe_busy, for_fencing);
 
-   virgl_resource_cache_entry_init(&res->cache_entry, size, bind, format, 0);
+   virgl_resource_cache_entry_init(&res->cache_entry, params);
 
    return res;
 }
@@ -390,14 +411,24 @@ virgl_drm_winsys_resource_cache_create(struct virgl_winsys *qws,
    struct virgl_drm_winsys *qdws = virgl_drm_winsys(qws);
    struct virgl_hw_res *res;
    struct virgl_resource_cache_entry *entry;
+   struct virgl_resource_params params = { .size = size,
+                                     .bind = bind,
+                                     .format = format,
+                                     .flags = flags,
+                                     .nr_samples = nr_samples,
+                                     .width = width,
+                                     .height = height,
+                                     .depth = depth,
+                                     .array_size = array_size,
+                                     .last_level = last_level,
+                                     .target = target };
 
    if (!can_cache_resource(bind))
       goto alloc;
 
    mtx_lock(&qdws->mutex);
 
-   entry = virgl_resource_cache_remove_compatible(&qdws->cache, size,
-                                                  bind, format, flags);
+   entry = virgl_resource_cache_remove_compatible(&qdws->cache, params);
    if (entry) {
       res = cache_entry_container_res(entry);
       mtx_unlock(&qdws->mutex);
index 669cd76..5c7d73a 100644 (file)
@@ -238,6 +238,17 @@ virgl_vtest_winsys_resource_create(struct virgl_winsys *vws,
    struct virgl_hw_res *res;
    static int handle = 1;
    int fd = -1;
+   struct virgl_resource_params params = { .size = size,
+                                           .bind = bind,
+                                           .format = format,
+                                           .flags = 0,
+                                           .nr_samples = nr_samples,
+                                           .width = width,
+                                           .height = height,
+                                           .depth = depth,
+                                           .array_size = array_size,
+                                           .last_level = last_level,
+                                           .target = target };
 
    res = CALLOC_STRUCT(virgl_hw_res);
    if (!res)
@@ -291,7 +302,7 @@ virgl_vtest_winsys_resource_create(struct virgl_winsys *vws,
    }
 
 out:
-   virgl_resource_cache_entry_init(&res->cache_entry, size, bind, format, 0);
+   virgl_resource_cache_entry_init(&res->cache_entry, params);
    res->res_handle = handle++;
    pipe_reference_init(&res->reference, 1);
    p_atomic_set(&res->num_cs_references, 0);
@@ -353,14 +364,24 @@ virgl_vtest_winsys_resource_cache_create(struct virgl_winsys *vws,
    struct virgl_vtest_winsys *vtws = virgl_vtest_winsys(vws);
    struct virgl_hw_res *res;
    struct virgl_resource_cache_entry *entry;
+   struct virgl_resource_params params = { .size = size,
+                                           .bind = bind,
+                                           .format = format,
+                                           .flags = 0,
+                                           .nr_samples = nr_samples,
+                                           .width = width,
+                                           .height = height,
+                                           .depth = depth,
+                                           .array_size = array_size,
+                                           .last_level = last_level,
+                                           .target = target };
 
    if (!can_cache_resource_with_bind(bind))
       goto alloc;
 
    mtx_lock(&vtws->mutex);
 
-   entry = virgl_resource_cache_remove_compatible(&vtws->cache, size,
-                                                  bind, format, 0);
+   entry = virgl_resource_cache_remove_compatible(&vtws->cache, params);
    if (entry) {
       res = cache_entry_container_res(entry);
       mtx_unlock(&vtws->mutex);