From c73c0cc31775f3a1532e0f0b9e1d2e956ff1b00e Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Tue, 28 Apr 2020 15:02:53 -0700 Subject: [PATCH] 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 Part-of: --- .../virgl/tests/virgl_staging_mgr_test.cpp | 4 ++-- src/gallium/drivers/virgl/virgl_resource.c | 12 ++++++++---- src/gallium/drivers/virgl/virgl_resource.h | 15 ++++++++++++++- src/gallium/drivers/virgl/virgl_staging_mgr.c | 1 + src/gallium/drivers/virgl/virgl_winsys.h | 2 +- .../winsys/virgl/common/virgl_resource_cache.c | 9 ++++++--- .../winsys/virgl/common/virgl_resource_cache.h | 6 ++++-- src/gallium/winsys/virgl/drm/virgl_drm_winsys.c | 11 ++++++----- src/gallium/winsys/virgl/drm/virgl_drm_winsys.h | 1 + .../winsys/virgl/vtest/virgl_vtest_winsys.c | 5 +++-- 10 files changed, 46 insertions(+), 20 deletions(-) diff --git a/src/gallium/drivers/virgl/tests/virgl_staging_mgr_test.cpp b/src/gallium/drivers/virgl/tests/virgl_staging_mgr_test.cpp index b241f393f86..a475ff408b4 100644 --- a/src/gallium/drivers/virgl/tests/virgl_staging_mgr_test.cpp +++ b/src/gallium/drivers/virgl/tests/virgl_staging_mgr_test.cpp @@ -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; } diff --git a/src/gallium/drivers/virgl/virgl_resource.c b/src/gallium/drivers/virgl/virgl_resource.c index a75236b7012..be87e6b3da2 100644 --- a/src/gallium/drivers/virgl/virgl_resource.c +++ b/src/gallium/drivers/virgl/virgl_resource.c @@ -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); diff --git a/src/gallium/drivers/virgl/virgl_resource.h b/src/gallium/drivers/virgl/virgl_resource.h index ef9e0681a02..2e0a078ad50 100644 --- a/src/gallium/drivers/virgl/virgl_resource.h +++ b/src/gallium/drivers/virgl/virgl_resource.h @@ -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, diff --git a/src/gallium/drivers/virgl/virgl_staging_mgr.c b/src/gallium/drivers/virgl/virgl_staging_mgr.c index a5e9d771a38..b6f52090310 100644 --- a/src/gallium/drivers/virgl/virgl_staging_mgr.c +++ b/src/gallium/drivers/virgl/virgl_staging_mgr.c @@ -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; diff --git a/src/gallium/drivers/virgl/virgl_winsys.h b/src/gallium/drivers/virgl/virgl_winsys.h index cdfeeaca96c..2db2e29d507 100644 --- a/src/gallium/drivers/virgl/virgl_winsys.h +++ b/src/gallium/drivers/virgl/virgl_winsys.h @@ -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, diff --git a/src/gallium/winsys/virgl/common/virgl_resource_cache.c b/src/gallium/winsys/virgl/common/virgl_resource_cache.c index 21ec987ba4d..d7d6a610ea9 100644 --- a/src/gallium/winsys/virgl/common/virgl_resource_cache.c +++ b/src/gallium/winsys/virgl/common/virgl_resource_cache.c @@ -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)) diff --git a/src/gallium/winsys/virgl/common/virgl_resource_cache.h b/src/gallium/winsys/virgl/common/virgl_resource_cache.h index f57d4af94b5..e5f710dc2cc 100644 --- a/src/gallium/winsys/virgl/common/virgl_resource_cache.h +++ b/src/gallium/winsys/virgl/common/virgl_resource_cache.h @@ -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 diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c index c6cc99bbe0e..3cbe9a5280f 100644 --- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c +++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c @@ -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); diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h index f3cb7f2fd07..29612c0e4f2 100644 --- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h +++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h @@ -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 */ diff --git a/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c b/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c index 2f79909d540..669cd763e56 100644 --- a/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c +++ b/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c @@ -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);