libdrm full analysis sixteen - full source code analysis (13)

Continued from the previous article: Full analysis of libdrm 15 - Full analysis of source code (12)

This article refers to the following blog posts:

DRM driver development (VKMS)

Thank you very much!

This article continues to explain the actual function macro definition in include/drm/drm.h.

21. DRM_IOCTL_ADD_BUFS

The 21st macro is DRM_IOCTL_ADD_BUFS, the corresponding code is as follows:

#define DRM_IOCTL_ADD_BUFS		DRM_IOWR(0x16, struct drm_buf_desc)

Combined with the final definition of _IOWR(type,nr,size) in the previous article, the following code is obtained:

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

struct drm_buf_desc is defined in the same file (include/drm/drm.h), the code is as follows:

/*
 * 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
				  */
};

The meaning code comments of each member in the drm_buf_desc structure are clearly described, so there is no need to repeat them here.

The Userspace API corresponding to DRM_IOCTL_ADD_BUFS is: drmAddBufs(). This function is also in xf86drm.c, the code is as follows:

/**
 * 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;
}

The role of the function is to make the buffer (buffers) suitable for DMA transfer. This function will be analyzed in detail later when the function is explained in detail. Let's get to know each other first and have an impression.

22. DRM_IOCTL_MARK_BUFS

The 22nd macro is DRM_IOCTL_MARK_BUFS, the corresponding code is as follows:

#define DRM_IOCTL_MARK_BUFS		DRM_IOW( 0x17, struct drm_buf_desc)

Combined with the final definition of _IOW(type,nr,size) in the previous article, the following code is obtained:

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

The struct drm_buf_desc has been listed above and will not be repeated here.

The Userspace API corresponding to DRM_IOCTL_MARK_BUFS is: drmMarkBufs(). This function is also in xf86drm.c, the code is as follows:

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;
}

This function is closely related to the drmAddBufs function corresponding to DRM_IOCTL_ADD_BUFS above. This function will be analyzed in detail later when the function is explained in detail. Let's get to know each other first and have an impression.

The remaining macro definitions will continue to be analyzed in subsequent articles.

Guess you like

Origin blog.csdn.net/phmatthaus/article/details/132480034