Beispiel #1
0
/**
 * The default context needs to exist per ring that uses contexts. It stores the
 * context state of the GPU for applications that don't utilize HW contexts, as
 * well as an idle case.
 */
static struct i915_gem_context *
i915_gem_create_context(struct drm_i915_private *dev_priv,
			struct drm_i915_file_private *file_priv)
{
	struct i915_gem_context *ctx;

	lockdep_assert_held(&dev_priv->drm.struct_mutex);

	ctx = __create_hw_context(dev_priv, file_priv);
	if (IS_ERR(ctx))
		return ctx;

	if (USES_FULL_PPGTT(dev_priv)) {
		struct i915_hw_ppgtt *ppgtt;

		ppgtt = i915_ppgtt_create(dev_priv, file_priv, ctx->name);
		if (IS_ERR(ppgtt)) {
			DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n",
					 PTR_ERR(ppgtt));
			__destroy_hw_context(ctx, file_priv);
			return ERR_CAST(ppgtt);
		}

		ctx->ppgtt = ppgtt;
		ctx->desc_template = default_desc_template(dev_priv, ppgtt);
	}

	trace_i915_context_create(ctx);

	return ctx;
}
/**
 * The default context needs to exist per ring that uses contexts. It stores the
 * context state of the GPU for applications that don't utilize HW contexts, as
 * well as an idle case.
 */
static struct intel_context *
i915_gem_create_context(struct drm_device *dev,
                        struct drm_i915_file_private *file_priv)
{
    const bool is_global_default_ctx = file_priv == NULL;
    struct intel_context *ctx;
    int ret = 0;

    BUG_ON(!mutex_is_locked(&dev->struct_mutex));

    ctx = __create_hw_context(dev, file_priv);
    if (IS_ERR(ctx))
        return ctx;

    if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state) {
        /* We may need to do things with the shrinker which
         * require us to immediately switch back to the default
         * context. This can cause a problem as pinning the
         * default context also requires GTT space which may not
         * be available. To avoid this we always pin the default
         * context.
         */
        ret = i915_gem_obj_ggtt_pin(ctx->legacy_hw_ctx.rcs_state,
                                    get_context_alignment(dev), 0);
        if (ret) {
            DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret);
            goto err_destroy;
        }
    }

    if (USES_FULL_PPGTT(dev)) {
        struct i915_hw_ppgtt *ppgtt = i915_ppgtt_create(dev, file_priv);

        if (IS_ERR_OR_NULL(ppgtt)) {
            DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n",
                             PTR_ERR(ppgtt));
            ret = PTR_ERR(ppgtt);
            goto err_unpin;
        }

        ctx->ppgtt = ppgtt;
    }

    trace_i915_context_create(ctx);

    return ctx;

err_unpin:
    if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state)
        i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state);
err_destroy:
    i915_gem_context_unreference(ctx);
    return ERR_PTR(ret);
}