kgsl_ioctl_gpu_command

本文详细介绍了通过ioctl命令处理GPU命令的过程,包括命令参数解析、命令对象创建与管理、命令对象链表操作以及命令提交等关键步骤。针对不同类型的GPU命令,文章深入探讨了其内部实现机制。
// ioctl命令:IOCTL_KGSL_GPU_COMMAND
// ioctl参数:kgsl_gpu_command
// ioctl函数:kgsl_ioctl_gpu_command
KGSL_IOCTL_FUNC(IOCTL_KGSL_GPU_COMMAND, kgsl_ioctl_gpu_command),

1. kgsl_ioctl_gpu_command

long kgsl_ioctl_gpu_command(struct kgsl_device_private *dev_priv,
		unsigned int cmd, void *data)
{
   
   
    // IOCTL_KGSL_GPU_COMMAND命令参数[见1.1节]
	struct kgsl_gpu_command *param = data;
	struct kgsl_device *device = dev_priv->device;
	struct kgsl_context *context;
    // kgsl_drawobj[见第1.2节]数组:用于存放kgsl_drawobj_sync和kgsl_drawobj_cmd中的kgsl_drawobj
	struct kgsl_drawobj *drawobj[2];
	unsigned int type;
	long result;
	unsigned int i = 0;

    // 根据参数计算对象类型[见第2节]
	type = _process_command_input(device, param->flags, param->numcmds,
			param->numobjs, param->numsyncs);
	if (!type)
		return -EINVAL;

    // 根据context id查找对应的kgsl_context
	context = kgsl_context_get_owner(dev_priv, param->context_id);
	if (context == NULL)
		return -EINVAL;

    // 1.如果指定KGSL_DRAWOBJ_SYNC标志位, 则命令类型为SYNCOBJ_TYPE
    // 2.如果传入的kgsl_gpu_command的numsyncs大于0, 则命令类型包含SYNCOBJ_TYPE
	if (type & SYNCOBJ_TYPE) {
   
   
		struct kgsl_drawobj_sync *syncobj =
				kgsl_drawobj_sync_create(device, context);

		if (IS_ERR(syncobj)) {
   
   
			result = PTR_ERR(syncobj);
			goto done;
		}

		drawobj[i++] = DRAWOBJ(syncobj);

		result = kgsl_drawobj_sync_add_synclist(device, syncobj,
				u64_to_user_ptr(param->synclist),
				param->syncsize, param->numsyncs);
		if (result)
			goto done;
	}

    // 1.如果指定KGSL_DRAWOBJ_MARKER标志位, 则命令类型为MARKEROBJ_TYPE
    // 2.如果传入的kgsl_gpu_command的numcmds大于0, 则命令类型包含CMDOBJ_TYPE
    // 3.如果传入的kgsl_gpu_command的numcmds等于0, 则命令类型为MARKEROBJ_TYPE
	if (type & (CMDOBJ_TYPE | MARKEROBJ_TYPE)) {
   
   
        // 调用kgsl_drawobj_cmd_create[见第3节]创建kgsl_drawobj_cmd
		struct kgsl_drawobj_cmd *cmdobj =
				kgsl_drawobj_cmd_create(device,
					context, param->flags, type);

		if (IS_ERR(cmdobj)) {
   
   
			result = PTR_ERR(cmdobj);
			goto done;
		}

        // drawobj数组元素加1
		drawobj[i++] = DRAWOBJ(cmdobj);

        // 将cmdlist插入kgsl_drawobj_cmd的cmdlist链表[第4节]
		result = kgsl_drawobj_cmd_add_cmdlist(device, cmdobj,
			u64_to_user_ptr(param->cmdlist),
			param->cmdsize, param->numcmds);
		if (result)
			goto done;

        // 将objlist插入kgsl_drawobj_cmd的memlist链表[第5节]
		result = kgsl_drawobj_cmd_add_memlist(device, cmdobj,
			u64_to_user_ptr(param->objlist),
			param->objsize, param->numobjs);
		if (result)
			goto done;

		/* If no profiling buffer was specified, clear the flag */
		if (cmdobj->profiling_buf_entry == NULL)
			DRAWOBJ(cmdobj)->flags &=
				~(unsigned long)KGSL_DRAWOBJ_PROFILING;
	}

    // 调用adreno_functable中定义的adreno_queue_cmds[第6节]将kgsl_drawobj提交给ringbuffer
	result = device->ftbl->queue_cmds(dev_priv, context, drawobj,
				i, &param->timestamp);

done:
	/*
	 * -EPROTO is a "success" error - it just tells the user that the
	 * context had previously faulted
	 */
	if (result && result != -EPROTO)
		while (i--)
			kgsl_drawobj_destroy(drawobj[i]);

	kgsl_context_put(context);
	return result;
}

1.1 kgsl_gpu_command

/**
 * struct kgsl_command_object - Argument for IOCTL_KGSL_GPU_COMMAND
 */
struct kgsl_gpu_command {
   
   
    // 标志位
	__u64 flags;

    // 指向kgsl_command_object链表的指针(for submission)
	__u64 __user cmdlist;
    // kgsl_command_object的大小
	unsigned int cmdsize;
    // cmdlist中kgsl_command_object的数量
	unsigned int numcmds;

    // 指向kgsl_command_object链表的指针(for tracking)
	__u64 __user objlist;
    // kgsl_command_object的大小
	unsigned int objsize;
    // objlist中kgsl_command_object的数量
	unsigned int numobjs;

    // 指向kgsl_command_syncpoint链表的指针
    __u64 __user synclist;
    // kgsl_command_syncpoint的大小
	unsigned int syncsize;
    // synclist中kgsl_command_syncpoint的数量
	unsigned int numsyncs;

    // kgsl_context的id
	unsigned int context_id;
    // Timestamp for the submitted commands
	unsigned int timestamp;
};

1.2 kgsl_drawobj

/**
 * struct kgsl_drawobj - KGSL drawobj descriptor
 */
// kgsl_drawobj的容器为kgsl_drawobj_cmd[见1.3节]
struct kgsl_drawobj {
   
   
    // KGSL GPU device that the command was created for
	struct kgsl_device *device;
    // KGSL context that created the command
	struct kgsl_context *context;
    // Object type
	uint32_t
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值