int i915_gem_render_state_init(struct drm_i915_gem_request *req) { struct render_state so; struct drm_i915_gem_object *obj; int ret; if (WARN_ON(req->engine->id != RCS)) return -ENOENT; so.rodata = render_state_get_rodata(req); if (!so.rodata) return 0; if (so.rodata->batch_items * 4 > 4096) return -EINVAL; obj = i915_gem_object_create(&req->i915->drm, 4096); if (IS_ERR(obj)) return PTR_ERR(obj); so.vma = i915_vma_create(obj, &req->i915->ggtt.base, NULL); if (IS_ERR(so.vma)) { ret = PTR_ERR(so.vma); goto err_obj; } ret = i915_vma_pin(so.vma, 0, 0, PIN_GLOBAL); if (ret) goto err_obj; ret = render_state_setup(&so); if (ret) goto err_unpin; ret = req->engine->emit_bb_start(req, so.vma->node.start, so.rodata->batch_items * 4, I915_DISPATCH_SECURE); if (ret) goto err_unpin; if (so.aux_batch_size > 8) { ret = req->engine->emit_bb_start(req, (so.vma->node.start + so.aux_batch_offset), so.aux_batch_size, I915_DISPATCH_SECURE); if (ret) goto err_unpin; } i915_vma_move_to_active(so.vma, req, 0); err_unpin: i915_vma_unpin(so.vma); err_obj: i915_gem_object_put(obj); return ret; }
int i915_gem_render_state_emit(struct i915_request *rq) { struct intel_engine_cs *engine = rq->engine; struct intel_render_state so = {}; /* keep the compiler happy */ int err; so.rodata = render_state_get_rodata(engine); if (!so.rodata) return 0; if (so.rodata->batch_items * 4 > PAGE_SIZE) return -EINVAL; so.obj = i915_gem_object_create_internal(engine->i915, PAGE_SIZE); if (IS_ERR(so.obj)) return PTR_ERR(so.obj); so.vma = i915_vma_instance(so.obj, &engine->i915->ggtt.vm, NULL); if (IS_ERR(so.vma)) { err = PTR_ERR(so.vma); goto err_obj; } err = i915_vma_pin(so.vma, 0, 0, PIN_GLOBAL | PIN_HIGH); if (err) goto err_vma; err = render_state_setup(&so, rq->i915); if (err) goto err_unpin; err = engine->emit_bb_start(rq, so.batch_offset, so.batch_size, I915_DISPATCH_SECURE); if (err) goto err_unpin; if (so.aux_size > 8) { err = engine->emit_bb_start(rq, so.aux_offset, so.aux_size, I915_DISPATCH_SECURE); if (err) goto err_unpin; } i915_vma_lock(so.vma); err = i915_vma_move_to_active(so.vma, rq, 0); i915_vma_unlock(so.vma); err_unpin: i915_vma_unpin(so.vma); err_vma: i915_vma_close(so.vma); err_obj: i915_gem_object_put(so.obj); return err; }
int i915_gem_render_state_emit(struct drm_i915_gem_request *req) { struct intel_render_state *so; int ret; lockdep_assert_held(&req->i915->drm.struct_mutex); so = req->engine->render_state; if (!so) return 0; /* Recreate the page after shrinking */ if (!so->vma->obj->mm.pages) so->batch_offset = -1; ret = i915_vma_pin(so->vma, 0, 0, PIN_GLOBAL | PIN_HIGH); if (ret) return ret; if (so->vma->node.start != so->batch_offset) { ret = render_state_setup(so, req->i915); if (ret) goto err_unpin; } ret = req->engine->emit_flush(req, EMIT_INVALIDATE); if (ret) goto err_unpin; ret = req->engine->emit_bb_start(req, so->batch_offset, so->batch_size, I915_DISPATCH_SECURE); if (ret) goto err_unpin; if (so->aux_size > 8) { ret = req->engine->emit_bb_start(req, so->aux_offset, so->aux_size, I915_DISPATCH_SECURE); if (ret) goto err_unpin; } i915_vma_move_to_active(so->vma, req, 0); err_unpin: i915_vma_unpin(so->vma); return ret; }
int i915_gem_render_state_prepare(struct intel_engine_cs *ring, struct render_state *so) { int ret; if (WARN_ON(ring->id != RCS)) return -ENOENT; ret = render_state_init(so, ring->dev); if (ret) return ret; if (so->rodata == NULL) return 0; ret = render_state_setup(so); if (ret) { i915_gem_render_state_fini(so); return ret; } return 0; }