virgl: add flags to (*resource_create) callback

We never seemed to use these. But for ARB_buffer_storage we'll
need it.

Reviewed-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4821>
This commit is contained in:
Gurchetan Singh
2020-04-28 15:02:53 -07:00
parent 1aac47db69
commit c73c0cc317
10 changed files with 46 additions and 20 deletions

View File

@@ -47,7 +47,7 @@ fake_resource_create(struct virgl_winsys *vws,
uint32_t width, uint32_t height, uint32_t width, uint32_t height,
uint32_t depth, uint32_t array_size, uint32_t depth, uint32_t array_size,
uint32_t last_level, uint32_t nr_samples, uint32_t last_level, uint32_t nr_samples,
uint32_t size) uint32_t flags, uint32_t size)
{ {
struct virgl_hw_res *hw_res = CALLOC_STRUCT(virgl_hw_res); struct virgl_hw_res *hw_res = CALLOC_STRUCT(virgl_hw_res);
@@ -320,7 +320,7 @@ failing_resource_create(struct virgl_winsys *vws,
uint32_t width, uint32_t height, uint32_t width, uint32_t height,
uint32_t depth, uint32_t array_size, uint32_t depth, uint32_t array_size,
uint32_t last_level, uint32_t nr_samples, uint32_t last_level, uint32_t nr_samples,
uint32_t size) uint32_t flags, uint32_t size)
{ {
return NULL; return NULL;
} }

View File

@@ -335,10 +335,11 @@ virgl_resource_realloc(struct virgl_context *vctx, struct virgl_resource *res)
{ {
struct virgl_screen *vs = virgl_screen(vctx->base.screen); struct virgl_screen *vs = virgl_screen(vctx->base.screen);
const struct pipe_resource *templ = &res->u.b; const struct pipe_resource *templ = &res->u.b;
unsigned vbind; unsigned vbind, vflags;
struct virgl_hw_res *hw_res; struct virgl_hw_res *hw_res;
vbind = pipe_to_virgl_bind(vs, templ->bind, templ->flags); vbind = pipe_to_virgl_bind(vs, templ->bind);
vflags = pipe_to_virgl_flags(vs, templ->flags);
hw_res = vs->vws->resource_create(vs->vws, hw_res = vs->vws->resource_create(vs->vws,
templ->target, templ->target,
templ->format, templ->format,
@@ -349,6 +350,7 @@ virgl_resource_realloc(struct virgl_context *vctx, struct virgl_resource *res)
templ->array_size, templ->array_size,
templ->last_level, templ->last_level,
templ->nr_samples, templ->nr_samples,
vflags,
res->metadata.total_size); res->metadata.total_size);
if (!hw_res) if (!hw_res)
return false; return false;
@@ -501,14 +503,15 @@ static void virgl_resource_layout(struct pipe_resource *pt,
static struct pipe_resource *virgl_resource_create(struct pipe_screen *screen, static struct pipe_resource *virgl_resource_create(struct pipe_screen *screen,
const struct pipe_resource *templ) const struct pipe_resource *templ)
{ {
unsigned vbind; unsigned vbind, vflags;
struct virgl_screen *vs = virgl_screen(screen); struct virgl_screen *vs = virgl_screen(screen);
struct virgl_resource *res = CALLOC_STRUCT(virgl_resource); struct virgl_resource *res = CALLOC_STRUCT(virgl_resource);
res->u.b = *templ; res->u.b = *templ;
res->u.b.screen = &vs->base; res->u.b.screen = &vs->base;
pipe_reference_init(&res->u.b.reference, 1); pipe_reference_init(&res->u.b.reference, 1);
vbind = pipe_to_virgl_bind(vs, templ->bind, templ->flags); vbind = pipe_to_virgl_bind(vs, templ->bind);
vflags = pipe_to_virgl_flags(vs, templ->flags);
virgl_resource_layout(&res->u.b, &res->metadata, 0, 0, 0, 0); virgl_resource_layout(&res->u.b, &res->metadata, 0, 0, 0, 0);
if ((vs->caps.caps.v2.capability_bits & VIRGL_CAP_APP_TWEAK_SUPPORT) && if ((vs->caps.caps.v2.capability_bits & VIRGL_CAP_APP_TWEAK_SUPPORT) &&
@@ -528,6 +531,7 @@ static struct pipe_resource *virgl_resource_create(struct pipe_screen *screen,
templ->array_size, templ->array_size,
templ->last_level, templ->last_level,
templ->nr_samples, templ->nr_samples,
vflags,
res->metadata.total_size); res->metadata.total_size);
if (!res->hw_res) { if (!res->hw_res) {
FREE(res); FREE(res);

View File

@@ -105,7 +105,7 @@ static inline struct virgl_transfer *virgl_transfer(struct pipe_transfer *trans)
void virgl_buffer_init(struct virgl_resource *res); void virgl_buffer_init(struct virgl_resource *res);
static inline unsigned pipe_to_virgl_bind(const struct virgl_screen *vs, static inline unsigned pipe_to_virgl_bind(const struct virgl_screen *vs,
unsigned pbind, unsigned flags) unsigned pbind)
{ {
unsigned outbind = 0; unsigned outbind = 0;
if (pbind & PIPE_BIND_DEPTH_STENCIL) if (pbind & PIPE_BIND_DEPTH_STENCIL)
@@ -148,6 +148,19 @@ static inline unsigned pipe_to_virgl_bind(const struct virgl_screen *vs,
return outbind; return outbind;
} }
static inline unsigned pipe_to_virgl_flags(const struct virgl_screen *vs,
unsigned pflags)
{
unsigned out_flags = 0;
if (pflags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)
out_flags |= VIRGL_RESOURCE_FLAG_MAP_PERSISTENT;
if (pflags & PIPE_RESOURCE_FLAG_MAP_COHERENT)
out_flags |= VIRGL_RESOURCE_FLAG_MAP_COHERENT;
return out_flags;
}
void * void *
virgl_resource_transfer_map(struct pipe_context *ctx, virgl_resource_transfer_map(struct pipe_context *ctx,
struct pipe_resource *resource, struct pipe_resource *resource,

View File

@@ -55,6 +55,7 @@ virgl_staging_alloc_buffer(struct virgl_staging_mgr *staging, unsigned min_size)
1, /* array_size */ 1, /* array_size */
0, /* last_level */ 0, /* last_level */
0, /* nr_samples */ 0, /* nr_samples */
0, /* flags */
size); /* size */ size); /* size */
if (staging->hw_res == NULL) if (staging->hw_res == NULL)
return false; return false;

View File

@@ -68,7 +68,7 @@ struct virgl_winsys {
uint32_t width, uint32_t height, uint32_t width, uint32_t height,
uint32_t depth, uint32_t array_size, uint32_t depth, uint32_t array_size,
uint32_t last_level, uint32_t nr_samples, uint32_t last_level, uint32_t nr_samples,
uint32_t size); uint32_t flags, uint32_t size);
void (*resource_reference)(struct virgl_winsys *qws, void (*resource_reference)(struct virgl_winsys *qws,
struct virgl_hw_res **dres, struct virgl_hw_res **dres,

View File

@@ -30,11 +30,12 @@
static bool static bool
virgl_resource_cache_entry_is_compatible(struct virgl_resource_cache_entry *entry, virgl_resource_cache_entry_is_compatible(struct virgl_resource_cache_entry *entry,
uint32_t size, uint32_t bind, uint32_t size, uint32_t bind,
uint32_t format) uint32_t format, uint32_t flags)
{ {
return (entry->bind == bind && return (entry->bind == bind &&
entry->format == format && entry->format == format &&
entry->size >= size && entry->size >= size &&
entry->flags == flags &&
/* We don't want to waste space, so don't reuse resource storage to /* We don't want to waste space, so don't reuse resource storage to
* hold much smaller (< 50%) sizes. * hold much smaller (< 50%) sizes.
*/ */
@@ -96,7 +97,8 @@ virgl_resource_cache_add(struct virgl_resource_cache *cache,
struct virgl_resource_cache_entry * struct virgl_resource_cache_entry *
virgl_resource_cache_remove_compatible(struct virgl_resource_cache *cache, virgl_resource_cache_remove_compatible(struct virgl_resource_cache *cache,
uint32_t size, uint32_t bind, uint32_t format) uint32_t size, uint32_t bind,
uint32_t format, uint32_t flags)
{ {
const int64_t now = os_time_get(); const int64_t now = os_time_get();
struct virgl_resource_cache_entry *compat_entry = NULL; struct virgl_resource_cache_entry *compat_entry = NULL;
@@ -108,7 +110,8 @@ virgl_resource_cache_remove_compatible(struct virgl_resource_cache *cache,
list_for_each_entry_safe(struct virgl_resource_cache_entry, list_for_each_entry_safe(struct virgl_resource_cache_entry,
entry, &cache->resources, head) { entry, &cache->resources, head) {
const bool compatible = const bool compatible =
virgl_resource_cache_entry_is_compatible(entry, size, bind, format); virgl_resource_cache_entry_is_compatible(entry, size, bind, format,
flags);
if (compatible) { if (compatible) {
if (!cache->entry_is_busy_func(entry, cache->user_data)) if (!cache->entry_is_busy_func(entry, cache->user_data))

View File

@@ -35,6 +35,7 @@ struct virgl_resource_cache_entry {
uint32_t size; uint32_t size;
uint32_t bind; uint32_t bind;
uint32_t format; uint32_t format;
uint32_t flags;
}; };
/* Pointer to a function that returns whether the resource represented by /* Pointer to a function that returns whether the resource represented by
@@ -81,7 +82,7 @@ virgl_resource_cache_add(struct virgl_resource_cache *cache,
struct virgl_resource_cache_entry * struct virgl_resource_cache_entry *
virgl_resource_cache_remove_compatible(struct virgl_resource_cache *cache, virgl_resource_cache_remove_compatible(struct virgl_resource_cache *cache,
uint32_t size, uint32_t bind, uint32_t size, uint32_t bind,
uint32_t format); uint32_t format, uint32_t flags);
/** Empties the resource cache. */ /** Empties the resource cache. */
void void
@@ -90,11 +91,12 @@ virgl_resource_cache_flush(struct virgl_resource_cache *cache);
static inline void static inline void
virgl_resource_cache_entry_init(struct virgl_resource_cache_entry *entry, virgl_resource_cache_entry_init(struct virgl_resource_cache_entry *entry,
uint32_t size, uint32_t bind, uint32_t size, uint32_t bind,
uint32_t format) uint32_t format, uint32_t flags)
{ {
entry->size = size; entry->size = size;
entry->bind = bind; entry->bind = bind;
entry->format = format; entry->format = format;
entry->flags = flags;
} }
#endif #endif

View File

@@ -55,7 +55,7 @@
#define cache_entry_container_res(ptr) \ #define cache_entry_container_res(ptr) \
(struct virgl_hw_res*)((char*)ptr - offsetof(struct virgl_hw_res, cache_entry)) (struct virgl_hw_res*)((char*)ptr - offsetof(struct virgl_hw_res, cache_entry))
static inline boolean can_cache_resource_with_bind(uint32_t bind) static inline boolean can_cache_resource(uint32_t bind)
{ {
return bind == VIRGL_BIND_CONSTANT_BUFFER || return bind == VIRGL_BIND_CONSTANT_BUFFER ||
bind == VIRGL_BIND_INDEX_BUFFER || bind == VIRGL_BIND_INDEX_BUFFER ||
@@ -132,7 +132,7 @@ static void virgl_drm_resource_reference(struct virgl_winsys *qws,
if (pipe_reference(&(*dres)->reference, &sres->reference)) { if (pipe_reference(&(*dres)->reference, &sres->reference)) {
if (!can_cache_resource_with_bind(old->bind) || if (!can_cache_resource(old->bind) ||
p_atomic_read(&old->external)) { p_atomic_read(&old->external)) {
virgl_hw_res_destroy(qdws, old); virgl_hw_res_destroy(qdws, old);
} else { } else {
@@ -202,7 +202,7 @@ virgl_drm_winsys_resource_create(struct virgl_winsys *qws,
*/ */
p_atomic_set(&res->maybe_busy, for_fencing); p_atomic_set(&res->maybe_busy, for_fencing);
virgl_resource_cache_entry_init(&res->cache_entry, size, bind, format); virgl_resource_cache_entry_init(&res->cache_entry, size, bind, format, 0);
return res; return res;
} }
@@ -272,19 +272,20 @@ virgl_drm_winsys_resource_cache_create(struct virgl_winsys *qws,
uint32_t array_size, uint32_t array_size,
uint32_t last_level, uint32_t last_level,
uint32_t nr_samples, uint32_t nr_samples,
uint32_t flags,
uint32_t size) uint32_t size)
{ {
struct virgl_drm_winsys *qdws = virgl_drm_winsys(qws); struct virgl_drm_winsys *qdws = virgl_drm_winsys(qws);
struct virgl_hw_res *res; struct virgl_hw_res *res;
struct virgl_resource_cache_entry *entry; struct virgl_resource_cache_entry *entry;
if (!can_cache_resource_with_bind(bind)) if (!can_cache_resource(bind))
goto alloc; goto alloc;
mtx_lock(&qdws->mutex); mtx_lock(&qdws->mutex);
entry = virgl_resource_cache_remove_compatible(&qdws->cache, size, entry = virgl_resource_cache_remove_compatible(&qdws->cache, size,
bind, format); bind, format, flags);
if (entry) { if (entry) {
res = cache_entry_container_res(entry); res = cache_entry_container_res(entry);
mtx_unlock(&qdws->mutex); mtx_unlock(&qdws->mutex);

View File

@@ -44,6 +44,7 @@ struct virgl_hw_res {
struct virgl_resource_cache_entry cache_entry; struct virgl_resource_cache_entry cache_entry;
uint32_t bind; uint32_t bind;
uint32_t flags;
uint32_t flink_name; uint32_t flink_name;
/* true when the resource is imported or exported */ /* true when the resource is imported or exported */

View File

@@ -291,7 +291,7 @@ virgl_vtest_winsys_resource_create(struct virgl_winsys *vws,
} }
out: out:
virgl_resource_cache_entry_init(&res->cache_entry, size, bind, format); virgl_resource_cache_entry_init(&res->cache_entry, size, bind, format, 0);
res->res_handle = handle++; res->res_handle = handle++;
pipe_reference_init(&res->reference, 1); pipe_reference_init(&res->reference, 1);
p_atomic_set(&res->num_cs_references, 0); p_atomic_set(&res->num_cs_references, 0);
@@ -347,6 +347,7 @@ virgl_vtest_winsys_resource_cache_create(struct virgl_winsys *vws,
uint32_t array_size, uint32_t array_size,
uint32_t last_level, uint32_t last_level,
uint32_t nr_samples, uint32_t nr_samples,
uint32_t flags,
uint32_t size) uint32_t size)
{ {
struct virgl_vtest_winsys *vtws = virgl_vtest_winsys(vws); struct virgl_vtest_winsys *vtws = virgl_vtest_winsys(vws);
@@ -359,7 +360,7 @@ virgl_vtest_winsys_resource_cache_create(struct virgl_winsys *vws,
mtx_lock(&vtws->mutex); mtx_lock(&vtws->mutex);
entry = virgl_resource_cache_remove_compatible(&vtws->cache, size, entry = virgl_resource_cache_remove_compatible(&vtws->cache, size,
bind, format); bind, format, 0);
if (entry) { if (entry) {
res = cache_entry_container_res(entry); res = cache_entry_container_res(entry);
mtx_unlock(&vtws->mutex); mtx_unlock(&vtws->mutex);