for (i = 0, bo = submit_bos; i < nr_bos; i++, bo++) { struct drm_gem_object *obj;
if (bo->flags & BO_INVALID_FLAGS) {
DRM_ERROR("invalid flags: %x\n", bo->flags);
ret = -EINVAL; goto out_unlock;
}
submit->bos[i].flags = bo->flags; if (submit->flags & ETNA_SUBMIT_SOFTPIN) { if (bo->presumed < ETNAVIV_SOFTPIN_START_ADDRESS) {
DRM_ERROR("invalid softpin address\n");
ret = -EINVAL; goto out_unlock;
}
submit->bos[i].va = bo->presumed;
}
/* normally use drm_gem_object_lookup(), but for bulk lookup *allundersingletable_lockjusthitobject_idrdirectly:
*/
obj = idr_find(&file->object_idr, bo->handle); if (!obj) {
DRM_ERROR("invalid handle %u at index %u\n",
bo->handle, i);
ret = -EINVAL; goto out_unlock;
}
staticint submit_lock_objects(struct etnaviv_gem_submit *submit, struct ww_acquire_ctx *ticket)
{ int contended, slow_locked = -1, i, ret = 0;
retry: for (i = 0; i < submit->nr_bos; i++) { struct drm_gem_object *obj = &submit->bos[i].obj->base;
if (slow_locked == i)
slow_locked = -1;
contended = i;
if (!(submit->bos[i].flags & BO_LOCKED)) {
ret = dma_resv_lock_interruptible(obj->resv, ticket); if (ret == -EALREADY)
DRM_ERROR("BO at index %u already on submit list\n",
i); if (ret) goto fail;
submit->bos[i].flags |= BO_LOCKED;
}
}
ww_acquire_done(ticket);
return0;
fail: for (; i >= 0; i--)
submit_unlock_object(submit, i);
if (slow_locked > 0)
submit_unlock_object(submit, slow_locked);
if (ret == -EDEADLK) { struct drm_gem_object *obj;
obj = &submit->bos[contended].obj->base;
/* we lost out in a seqno race, lock and retry.. */
ret = dma_resv_lock_slow_interruptible(obj->resv, ticket); if (!ret) {
submit->bos[contended].flags |= BO_LOCKED;
slow_locked = contended; goto retry;
}
}
return ret;
}
staticint submit_fence_sync(struct etnaviv_gem_submit *submit)
{ int i, ret = 0;
for (i = 0; i < submit->nr_bos; i++) { struct etnaviv_gem_submit_bo *bo = &submit->bos[i]; struct dma_resv *robj = bo->obj->base.resv;
ret = dma_resv_reserve_fences(robj, 1); if (ret) return ret;
if (submit->flags & ETNA_SUBMIT_NO_IMPLICIT) continue;
ret = drm_sched_job_add_implicit_dependencies(&submit->sched_job,
&bo->obj->base,
bo->flags & ETNA_SUBMIT_BO_WRITE); if (ret) return ret;
}
return ret;
}
staticvoid submit_attach_object_fences(struct etnaviv_gem_submit *submit)
{ int i;
for (i = 0; i < submit->nr_bos; i++) { struct drm_gem_object *obj = &submit->bos[i].obj->base; bool write = submit->bos[i].flags & ETNA_SUBMIT_BO_WRITE;
/* process the reloc's and patch up the cmdstream as needed: */ staticint submit_reloc(struct etnaviv_gem_submit *submit, void *stream,
u32 size, conststruct drm_etnaviv_gem_submit_reloc *relocs,
u32 nr_relocs)
{
u32 i, last_offset = 0;
u32 *ptr = stream; int ret;
/* Submits using softpin don't blend with relocs */ if ((submit->flags & ETNA_SUBMIT_SOFTPIN) && nr_relocs != 0) return -EINVAL;
for (i = 0; i < nr_relocs; i++) { conststruct drm_etnaviv_gem_submit_reloc *r = relocs + i; struct etnaviv_gem_submit_bo *bo;
u32 off;
if (unlikely(r->flags)) {
DRM_ERROR("invalid reloc flags\n"); return -EINVAL;
}
for (i = 0; i < submit->nr_pmrs; i++) { conststruct drm_etnaviv_gem_submit_pmr *r = pmrs + i; struct etnaviv_gem_submit_bo *bo; int ret;
ret = submit_bo(submit, r->read_idx, &bo); if (ret) return ret;
/* at offset 0 a sequence number gets stored used for userspace sync */ if (r->read_offset == 0) {
DRM_ERROR("perfmon request: offset is 0"); return -EINVAL;
}
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.