libdrm学习-dumb buffer

dumb介绍

dumb buffer,一般是指CPU buffer,我们把这个buffer的内容填充,GPU只负责完整显示出来,GPU并不会对dumb buffer做任何加速。

关于dumb名字的由来,可以参照下面文章。
https://blog.csdn.net/hexiaolong2009/article/details/105961192

dumb buffer涉及三个主要操作, create, map, destroy。

dumb使用

dumb的create, map, destroy,三者都是通过drmIoctl调用的,而这个

/* create a dumb scanout buffer */
struct drm_mode_create_dumb {
	__u32 height;
	__u32 width;
	__u32 bpp;
	__u32 flags;
	/* handle, pitch, size will be returned */
	__u32 handle;
	__u32 pitch;
	__u64 size;
};

/* set up for mmap of a dumb scanout buffer */
struct drm_mode_map_dumb {
	/** Handle for the object being mapped. */
	__u32 handle;
	__u32 pad;
	/**
	 * Fake offset to use for subsequent mmap call
	 *
	 * This is a fixed-size type for 32/64 compatibility.
	 */
	__u64 offset;
};

struct drm_mode_destroy_dumb {
	__u32 handle;
};

代码如下:

#include <errno.h>
#include <fcntl.h>
#include <memory.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <xf86drm.h>

static int test_dumb(int fd) {
  struct drm_mode_create_dumb creq = {0};
  struct drm_mode_destroy_dumb dreq = {0};
  struct drm_mode_map_dumb mreq = {0};
  int ret = 0;

  /* create dumb buffer */
  creq.width = 1920;
  creq.height = 1080;
  creq.bpp = 32;
  ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq);
  if (ret < 0) {
    fprintf(stderr, "cannot create dumb buffer (%d): %m\n", errno);
    return -errno;
  }
  printf("dumb created size=%llu, pitch=%d, handle=%d\n", creq.size, creq.pitch,
         creq.handle);

  /* prepare buffer for memory mapping */
  mreq.handle = creq.handle;
  ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq);
  if (ret) {
    fprintf(stderr, "cannot map dumb buffer (%d): %m\n", errno);
    return -errno;
  }

  /* perform actual memory mapping */
  uint8_t* map =
      mmap(0, creq.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mreq.offset);
  if (map == MAP_FAILED) {
    fprintf(stderr, "cannot mmap dumb buffer (%d): %m\n", errno);
    return -errno;
  }

  /* clear the framebuffer to 0 */
  memset(map, 0, creq.size);
  for (int i = 0; i < 8; i++) {
    printf(" 0x%x ", map[i]);
  }
  printf("\n");

  dreq.handle = creq.handle;
  drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
  printf("dumb destroyed\n");

  return 0;
}

int main(int argc, char** argv) {
  int fd = open("/dev/dri/card0", O_RDWR);
  if (fd > 0) {
    printf("drmOpen Succeed\n");
  } else {
    printf("drmOpen failed, fd=0x%x\n", fd);
    return -1;
  }

  test_dumb(fd);

  close(fd);

  return 0;
}

然后使用如下命令编译:

gcc dumb.c -I/usr/include/drm/ -ldrm -o dumb

代码里,先打开了/dev/dri/card0设备,然后create了一个dumb buffer,创建完了的dumb buffer,通过handle返回。之后我们就可以通过这个handle来唯一区分这个buffer了。再通过drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq),将buffer请求map,之后调用mmap进行真正的map,这样就可以拿到map出来的虚拟地址。然后可以对这个虚拟地址,进行读和写操作。最后通过这个handle,将整个dumb buffer 销毁掉。

可以看出,dumb buffer,主要是通过drmIoctl函数,第2个参数和第3个参数传递下面表格的参数,进行使用的。

ioctl结构体
DRM_IOCTL_MODE_CREATE_DUMBstruct drm_mode_create_dumb
DRM_IOCTL_MODE_MAP_DUMBstruct drm_mode_map_dumb
DRM_IOCTL_MODE_DESTROY_DUMBstruct drm_mode_destroy_dumb

而在使用的过程中,通过同一个handle来表示同一个dumb buffer。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值