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 depth, uint32_t array_size,
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);
@ -320,7 +320,7 @@ failing_resource_create(struct virgl_winsys *vws,
uint32_t width, uint32_t height,
uint32_t depth, uint32_t array_size,
uint32_t last_level, uint32_t nr_samples,
uint32_t size)
uint32_t flags, uint32_t size)
{
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);
const struct pipe_resource *templ = &res->u.b;
unsigned vbind;
unsigned vbind, vflags;
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,
templ->target,
templ->format,
@ -349,6 +350,7 @@ virgl_resource_realloc(struct virgl_context *vctx, struct virgl_resource *res)
templ->array_size,
templ->last_level,
templ->nr_samples,
vflags,
res->metadata.total_size);
if (!hw_res)
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,
const struct pipe_resource *templ)
{
unsigned vbind;
unsigned vbind, vflags;
struct virgl_screen *vs = virgl_screen(screen);
struct virgl_resource *res = CALLOC_STRUCT(virgl_resource);
res->u.b = *templ;
res->u.b.screen = &vs->base;
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);
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->last_level,
templ->nr_samples,
vflags,
res->metadata.total_size);
if (!res->hw_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);
static inline unsigned pipe_to_virgl_bind(const struct virgl_screen *vs,
unsigned pbind, unsigned flags)
unsigned pbind)
{
unsigned outbind = 0;
if (pbind & PIPE_BIND_DEPTH_STENCIL)
@ -148,6 +148,19 @@ static inline unsigned pipe_to_virgl_bind(const struct virgl_screen *vs,
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 *
virgl_resource_transfer_map(struct pipe_context *ctx,
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 */
0, /* last_level */
0, /* nr_samples */
0, /* flags */
size); /* size */
if (staging->hw_res == NULL)
return false;

View File

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

View File

@ -30,11 +30,12 @@
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 format, uint32_t flags)
{
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.
*/
@ -96,7 +97,8 @@ 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 size, uint32_t bind,
uint32_t format, uint32_t flags)
{
const int64_t now = os_time_get();
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,
entry, &cache->resources, head) {
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 (!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 bind;
uint32_t format;
uint32_t flags;
};
/* 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 *
virgl_resource_cache_remove_compatible(struct virgl_resource_cache *cache,
uint32_t size, uint32_t bind,
uint32_t format);
uint32_t format, uint32_t flags);
/** Empties the resource cache. */
void
@ -90,11 +91,12 @@ 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 format, uint32_t flags)
{
entry->size = size;
entry->bind = bind;
entry->format = format;
entry->flags = flags;
}
#endif

View File

@ -55,7 +55,7 @@
#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)
static inline boolean can_cache_resource(uint32_t bind)
{
return bind == VIRGL_BIND_CONSTANT_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 (!can_cache_resource_with_bind(old->bind) ||
if (!can_cache_resource(old->bind) ||
p_atomic_read(&old->external)) {
virgl_hw_res_destroy(qdws, old);
} else {
@ -202,7 +202,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);
virgl_resource_cache_entry_init(&res->cache_entry, size, bind, format, 0);
return res;
}
@ -272,19 +272,20 @@ virgl_drm_winsys_resource_cache_create(struct virgl_winsys *qws,
uint32_t array_size,
uint32_t last_level,
uint32_t nr_samples,
uint32_t flags,
uint32_t size)
{
struct virgl_drm_winsys *qdws = virgl_drm_winsys(qws);
struct virgl_hw_res *res;
struct virgl_resource_cache_entry *entry;
if (!can_cache_resource_with_bind(bind))
if (!can_cache_resource(bind))
goto alloc;
mtx_lock(&qdws->mutex);
entry = virgl_resource_cache_remove_compatible(&qdws->cache, size,
bind, format);
bind, format, flags);
if (entry) {
res = cache_entry_container_res(entry);
mtx_unlock(&qdws->mutex);

View File

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

View File

@ -291,7 +291,7 @@ virgl_vtest_winsys_resource_create(struct virgl_winsys *vws,
}
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++;
pipe_reference_init(&res->reference, 1);
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 last_level,
uint32_t nr_samples,
uint32_t flags,
uint32_t size)
{
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);
entry = virgl_resource_cache_remove_compatible(&vtws->cache, size,
bind, format);
bind, format, 0);
if (entry) {
res = cache_entry_container_res(entry);
mtx_unlock(&vtws->mutex);