drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c
Extension
.c
Size
10935 bytes
Lines
369
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct vmw_dx_streamoutput {
	struct vmw_resource res;
	struct vmw_resource *ctx;
	struct vmw_resource *cotable;
	struct list_head cotable_head;
	u32 id;
	u32 size;
	bool committed;
};

static int vmw_dx_streamoutput_create(struct vmw_resource *res);
static int vmw_dx_streamoutput_bind(struct vmw_resource *res,
				    struct ttm_validate_buffer *val_buf);
static int vmw_dx_streamoutput_unbind(struct vmw_resource *res, bool readback,
				      struct ttm_validate_buffer *val_buf);
static void vmw_dx_streamoutput_commit_notify(struct vmw_resource *res,
					      enum vmw_cmdbuf_res_state state);

static const struct vmw_res_func vmw_dx_streamoutput_func = {
	.res_type = vmw_res_streamoutput,
	.needs_guest_memory = true,
	.may_evict = false,
	.type_name = "DX streamoutput",
	.domain = VMW_BO_DOMAIN_MOB,
	.busy_domain = VMW_BO_DOMAIN_MOB,
	.create = vmw_dx_streamoutput_create,
	.destroy = NULL, /* Command buffer managed resource. */
	.bind = vmw_dx_streamoutput_bind,
	.unbind = vmw_dx_streamoutput_unbind,
	.commit_notify = vmw_dx_streamoutput_commit_notify,
};

static inline struct vmw_dx_streamoutput *
vmw_res_to_dx_streamoutput(struct vmw_resource *res)
{
	return container_of(res, struct vmw_dx_streamoutput, res);
}

/**
 * vmw_dx_streamoutput_unscrub - Reattach the MOB to streamoutput.
 * @res: The streamoutput resource.
 *
 * Return: 0 on success, negative error code on failure.
 */
static int vmw_dx_streamoutput_unscrub(struct vmw_resource *res)
{
	struct vmw_dx_streamoutput *so = vmw_res_to_dx_streamoutput(res);
	struct vmw_private *dev_priv = res->dev_priv;
	struct {
		SVGA3dCmdHeader header;
		SVGA3dCmdDXBindStreamOutput body;
	} *cmd;

	if (!list_empty(&so->cotable_head) || !so->committed )
		return 0;

	cmd = VMW_CMD_CTX_RESERVE(dev_priv, sizeof(*cmd), so->ctx->id);
	if (!cmd)
		return -ENOMEM;

	cmd->header.id = SVGA_3D_CMD_DX_BIND_STREAMOUTPUT;
	cmd->header.size = sizeof(cmd->body);
	cmd->body.soid = so->id;
	cmd->body.mobid = res->guest_memory_bo->tbo.resource->start;
	cmd->body.offsetInBytes = res->guest_memory_offset;
	cmd->body.sizeInBytes = so->size;
	vmw_cmd_commit(dev_priv, sizeof(*cmd));

	vmw_cotable_add_resource(so->cotable, &so->cotable_head);

	return 0;
}

static int vmw_dx_streamoutput_create(struct vmw_resource *res)
{
	struct vmw_private *dev_priv = res->dev_priv;
	struct vmw_dx_streamoutput *so = vmw_res_to_dx_streamoutput(res);
	int ret = 0;

	WARN_ON_ONCE(!so->committed);

	if (vmw_resource_mob_attached(res)) {
		mutex_lock(&dev_priv->binding_mutex);
		ret = vmw_dx_streamoutput_unscrub(res);
		mutex_unlock(&dev_priv->binding_mutex);
	}

	res->id = so->id;

	return ret;

Annotation

Implementation Notes