virgl: Add more meta data to cached resources

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>
This commit is contained in:
Rohan Garg
2021-06-08 11:43:35 +02:00
committed by Marge Bot
parent 8d104a387a
commit a425c5df78
4 changed files with 96 additions and 35 deletions
@@ -28,18 +28,22 @@
* 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))
@@ -27,15 +27,27 @@
#include <stdint.h>
#include "util/list.h"
#include "gallium/include/pipe/p_defines.h"
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;
uint32_t size;
uint32_t bind;
uint32_t format;
uint32_t flags;
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
@@ -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);
@@ -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);