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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
@@ -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,
|
||||||
|
@@ -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;
|
||||||
|
@@ -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,
|
||||||
|
@@ -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))
|
||||||
|
@@ -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
|
||||||
|
@@ -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);
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user