/* * Copyright 2011 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * on the rights to use, copy, modify, merge, publish, distribute, sub * license, and/or sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <linux/delay.h>
#include <trace/events/dma_fence.h>
#include"qxl_drv.h" #include"qxl_object.h"
/* * drawable cmd cache - allocate a bunch of VRAM pages, suballocate * into 256 byte chunks for now - gives 16 cmds per page. * * use an ida to index into the chunks?
*/ /* manage releaseables */ /* stack them 16 high for now -drawable object is 191 */ #define RELEASE_SIZE 256 #define RELEASES_PER_BO (PAGE_SIZE / RELEASE_SIZE) /* put an alloc/dealloc surface cmd into one bo and round up to 128 */ #define SURFACE_RELEASE_SIZE 128 #define SURFACE_RELEASES_PER_BO (PAGE_SIZE / SURFACE_RELEASE_SIZE)
if (!bo->tbo.pin_count) {
qxl_ttm_placement_from_domain(bo, bo->type);
ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); if (ret) return ret;
}
ret = dma_resv_reserve_fences(bo->tbo.base.resv, 1); if (ret) return ret;
/* allocate a surface for reserved + validated buffers */
ret = qxl_bo_check_id(to_qxl(bo->tbo.base.dev), bo); if (ret) return ret; return 0;
}
int qxl_release_reserve_list(struct qxl_release *release, bool no_intr)
{ int ret; struct qxl_bo_list *entry;
/* if only one object on the release its the release itself
since these objects are pinned no need to reserve */ if (list_is_singular(&release->bos)) return 0;
list_for_each_entry(entry, &release->bos, list) {
ret = qxl_release_validate_bo(entry->bo); if (ret) goto error;
} return 0;
error:
drm_exec_fini(&release->exec); return ret;
}
void qxl_release_backoff_reserve_list(struct qxl_release *release)
{ /* if only one object on the release its the release itself
since these objects are pinned no need to reserve */ if (list_is_singular(&release->bos)) return;
drm_exec_fini(&release->exec);
}
int qxl_alloc_surface_release_reserved(struct qxl_device *qdev, enum qxl_surface_cmd_type surface_cmd_type, struct qxl_release *create_rel, struct qxl_release **release)
{ if (surface_cmd_type == QXL_SURFACE_CMD_DESTROY && create_rel) { int idr_ret; struct qxl_bo *bo; union qxl_release_info *info;
/* stash the release after the create command */
idr_ret = qxl_release_alloc(qdev, QXL_RELEASE_SURFACE_CMD, release); if (idr_ret < 0) return idr_ret;
bo = create_rel->release_bo;
int qxl_alloc_release_reserved(struct qxl_device *qdev, unsignedlong size, int type, struct qxl_release **release, struct qxl_bo **rbo)
{ struct qxl_bo *bo, *free_bo = NULL; int idr_ret; int ret = 0; union qxl_release_info *info; int cur_idx;
u32 priority;
spin_lock(&qdev->release_idr_lock);
release = idr_find(&qdev->release_idr, id);
spin_unlock(&qdev->release_idr_lock); if (!release) {
DRM_ERROR("failed to find id in release_idr\n"); return NULL;
}
return release;
}
union qxl_release_info *qxl_release_map(struct qxl_device *qdev, struct qxl_release *release)
{ void *ptr; union qxl_release_info *info; struct qxl_bo *bo = release->release_bo;
/* if only one object on the release its the release itself
since these objects are pinned no need to reserve */ if (list_is_singular(&release->bos) || list_empty(&release->bos)) return;
/* * Since we never really allocated a context and we don't want to conflict, * set the highest bits. This will break if we really allow exporting of dma-bufs.
*/
dma_fence_init(&release->base, &qxl_fence_ops, &qdev->release_lock,
release->id | 0xf0000000, release->base.seqno);
trace_dma_fence_emit(&release->base);
list_for_each_entry(entry, &release->bos, list) {
bo = entry->bo;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.