libdrm全解析十六 —— 源码全解析(13)

接前一篇文章:libdrm全解析十五 —— 源码全解析(12)

本文参考以下博文:

DRM 驱动程序开发(VKMS)

特此致谢!

本文继续对include/drm/drm.h中实际功能宏定义进行讲解。

21. DRM_IOCTL_ADD_BUFS

第21个宏是DRM_IOCTL_ADD_BUFS,相应代码如下:

#define DRM_IOCTL_ADD_BUFS		DRM_IOWR(0x16, struct drm_buf_desc)

结合之前文章中的_IOWR(type,nr,size)的最终定义,得到如下代码:

#define DRM_IOCTL_ADD_BUFS		( ((3)  << 30) | (('d') << 8) | ((0x16)   << 0) | ((sizeof(struct drm_buf_desc)) << 16) )

struct drm_buf_desc在同文件(include/drm/drm.h)中定义,代码如下:

/*
 * DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type.
 *
 * \sa drmAddBufs().
 */
struct drm_buf_desc {
	int count;		 /**< Number of buffers of this size */
	int size;		 /**< Size in bytes */
	int low_mark;		 /**< Low water mark */
	int high_mark;		 /**< High water mark */
	enum {
		_DRM_PAGE_ALIGN = 0x01,	/**< Align on page boundaries for DMA */
		_DRM_AGP_BUFFER = 0x02,	/**< Buffer is in AGP space */
		_DRM_SG_BUFFER = 0x04,	/**< Scatter/gather memory buffer */
		_DRM_FB_BUFFER = 0x08,	/**< Buffer is in frame buffer */
		_DRM_PCI_BUFFER_RO = 0x10 /**< Map PCI DMA buffer read-only */
	} flags;
	unsigned long agp_start; /**<
				  * Start address of where the AGP buffers are
				  * in the AGP aperture
				  */
};

drm_buf_desc结构中各成员的意义代码注释描述得很清楚了,在此无需赘述。

DRM_IOCTL_ADD_BUFS对应的Userspace API为:drmAddBufs()。该函数也是在xf86drm.c中,代码如下:

/**
 * Make buffers available for DMA transfers.
 *
 * \param fd file descriptor.
 * \param count number of buffers.
 * \param size size of each buffer.
 * \param flags buffer allocation flags.
 * \param agp_offset offset in the AGP aperture
 *
 * \return number of buffers allocated, negative on error.
 *
 * \internal
 * This function is a wrapper around DRM_IOCTL_ADD_BUFS ioctl.
 *
 * \sa drm_buf_desc.
 */
drm_public int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
                          int agp_offset)
{
    drm_buf_desc_t request;

    memclear(request);
    request.count     = count;
    request.size      = size;
    request.flags     = (int)flags;
    request.agp_start = agp_offset;

    if (drmIoctl(fd, DRM_IOCTL_ADD_BUFS, &request))
        return -errno;
    return request.count;
}

函数的作用是使缓冲(buffers)适合DMA传输。此函数在后文具体讲解函数的时候进行详细解析。在此先认识一下、有个印象就好。

22. DRM_IOCTL_MARK_BUFS

第22个宏是DRM_IOCTL_MARK_BUFS,相应代码如下:

#define DRM_IOCTL_MARK_BUFS		DRM_IOW( 0x17, struct drm_buf_desc)

结合之前文章中的_IOW(type,nr,size)的最终定义,得到如下代码:

#define DRM_IOCTL_MAKE_BUFS		( ((1)  << 30) | (('d') << 8) | ((0x17)   << 0) | ((sizeof(struct drm_buf_desc)) << 16) )

struct drm_buf_desc上边已经列出了,在此不重复。

DRM_IOCTL_MARK_BUFS对应的Userspace API为:drmMarkBufs()。该函数也是在xf86drm.c中,代码如下:

drm_public int drmMarkBufs(int fd, double low, double high)
{
    drm_buf_info_t info;
    int            i;

    memclear(info);

    if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
        return -EINVAL;

    if (!info.count)
        return -EINVAL;

    if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
        return -ENOMEM;

    if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
        int retval = -errno;
        drmFree(info.list);
        return retval;
    }

    for (i = 0; i < info.count; i++) {
        info.list[i].low_mark  = low  * info.list[i].count;
        info.list[i].high_mark = high * info.list[i].count;
        if (drmIoctl(fd, DRM_IOCTL_MARK_BUFS, &info.list[i])) {
            int retval = -errno;
            drmFree(info.list);
            return retval;
        }
    }
    drmFree(info.list);

    return 0;
}

该函数与上边DRM_IOCTL_ADD_BUFS对应的drmAddBufs函数联系较为紧密。此函数在后文具体讲解函数的时候进行详细解析。在此先认识一下、有个印象就好。

其余宏定义将在后续文章中继续解析。

猜你喜欢

转载自blog.csdn.net/phmatthaus/article/details/132480034