static void virgl_cache_flush(struct virgl_vtest_winsys *vtws) { struct list_head *curr, *next; struct virgl_hw_res *res; pipe_mutex_lock(vtws->mutex); curr = vtws->delayed.next; next = curr->next; while (curr != &vtws->delayed) { res = LIST_ENTRY(struct virgl_hw_res, curr, head); LIST_DEL(&res->head); virgl_hw_res_destroy(vtws, res); curr = next; next = curr->next; } pipe_mutex_unlock(vtws->mutex); }
static void virgl_cache_flush(struct virgl_drm_winsys *qdws) { struct list_head *curr, *next; struct virgl_hw_res *res; mtx_lock(&qdws->mutex); curr = qdws->delayed.next; next = curr->next; while (curr != &qdws->delayed) { res = LIST_ENTRY(struct virgl_hw_res, curr, head); LIST_DEL(&res->head); virgl_hw_res_destroy(qdws, res); curr = next; next = curr->next; } mtx_unlock(&qdws->mutex); }
static void virgl_vtest_resource_reference(struct virgl_vtest_winsys *vtws, struct virgl_hw_res **dres, struct virgl_hw_res *sres) { struct virgl_hw_res *old = *dres; if (pipe_reference(&(*dres)->reference, &sres->reference)) { if (!can_cache_resource(old)) { virgl_hw_res_destroy(vtws, old); } else { pipe_mutex_lock(vtws->mutex); virgl_cache_list_check_free(vtws); old->start = os_time_get(); old->end = old->start + vtws->usecs; LIST_ADDTAIL(&old->head, &vtws->delayed); vtws->num_delayed++; pipe_mutex_unlock(vtws->mutex); } } *dres = sres; }
static void virgl_cache_list_check_free(struct virgl_vtest_winsys *vtws) { struct list_head *curr, *next; struct virgl_hw_res *res; int64_t now; now = os_time_get(); curr = vtws->delayed.next; next = curr->next; while (curr != &vtws->delayed) { res = LIST_ENTRY(struct virgl_hw_res, curr, head); if (!os_time_timeout(res->start, res->end, now)) break; LIST_DEL(&res->head); virgl_hw_res_destroy(vtws, res); curr = next; next = curr->next; } }
static struct virgl_hw_res * virgl_vtest_winsys_resource_cache_create(struct virgl_winsys *vws, enum pipe_texture_target target, uint32_t format, uint32_t bind, uint32_t width, uint32_t height, uint32_t depth, uint32_t array_size, uint32_t last_level, uint32_t nr_samples, uint32_t size) { struct virgl_vtest_winsys *vtws = virgl_vtest_winsys(vws); struct virgl_hw_res *res, *curr_res; struct list_head *curr, *next; int64_t now; int ret; /* only store binds for vertex/index/const buffers */ if (bind != VIRGL_BIND_CONSTANT_BUFFER && bind != VIRGL_BIND_INDEX_BUFFER && bind != VIRGL_BIND_VERTEX_BUFFER && bind != VIRGL_BIND_CUSTOM) goto alloc; pipe_mutex_lock(vtws->mutex); res = NULL; curr = vtws->delayed.next; next = curr->next; now = os_time_get(); while (curr != &vtws->delayed) { curr_res = LIST_ENTRY(struct virgl_hw_res, curr, head); if (!res && ((ret = virgl_is_res_compat(vtws, curr_res, size, bind, format)) > 0)) res = curr_res; else if (os_time_timeout(curr_res->start, curr_res->end, now)) { LIST_DEL(&curr_res->head); virgl_hw_res_destroy(vtws, curr_res); } else break; if (ret == -1) break; curr = next; next = curr->next; } if (!res && ret != -1) { while (curr != &vtws->delayed) { curr_res = LIST_ENTRY(struct virgl_hw_res, curr, head); ret = virgl_is_res_compat(vtws, curr_res, size, bind, format); if (ret > 0) { res = curr_res; break; } if (ret == -1) break; curr = next; next = curr->next; } } if (res) { LIST_DEL(&res->head); --vtws->num_delayed; pipe_mutex_unlock(vtws->mutex); pipe_reference_init(&res->reference, 1); return res; } pipe_mutex_unlock(vtws->mutex); alloc: res = virgl_vtest_winsys_resource_create(vws, target, format, bind, width, height, depth, array_size, last_level, nr_samples, size); if (bind == VIRGL_BIND_CONSTANT_BUFFER || bind == VIRGL_BIND_INDEX_BUFFER || bind == VIRGL_BIND_VERTEX_BUFFER) res->cacheable = TRUE; return res; }