跳到主要内容

G2D 使用指南

概述

G2D 是 Allwinner SoC 集成的 2D 图形硬件加速器,负责图像旋转、缩放、格式转换、颜色填充等操作。

提示

新版镜像已默认启用 g2d,可直接跳转到下方验证驱动状态确认。若处于旧版镜像,请展开下方手动安装。

旧版镜像:手动安装 g2d 内核
Device
wget https://github.com/cubie-image/sun60iw2p1/releases/download/linux_package4/linux-headers-5.15.147-100-a733_5.15.147-100_arm64.deb
wget https://github.com/cubie-image/sun60iw2p1/releases/download/linux_package4/linux-image-5.15.147-100-a733_5.15.147-100_arm64.deb
sudo dpkg -i linux-headers-5.15.147-100-a733_5.15.147-100_arm64.deb
sudo dpkg -i linux-image-5.15.147-100-a733_5.15.147-100_arm64.deb
# 然后重启
sudo reboot

典型应用场景:

  • 视频编解码前后的图像预处理(缩放、色彩空间转换)
  • 相机实时预览的图像处理
  • 显示输出前的格式转换(RGB ↔ YUV)
  • 批量图像处理流水线

本项目环境:

项目
SoCAllwinner A733
Linux5.15.147-100-a733
G2D 驱动版本1.0.0
驱动模块g2d_sunxi
设备节点/dev/g2d/dev/dma_heap/system

环境准备

验证驱动状态

Device
# 检查驱动模块是否已加载
lsmod | grep g2d
# 输出类似: g2d_sunxi 90112 0

# 查看驱动版本
cat /sys/module/g2d_sunxi/version
# 输出: 1.0.0

若未加载,手动加载:

Device
sudo modprobe g2d_sunxi

设备节点权限

当前系统已配置为无需 root 运行:

/dev/g2d              (0666)
/dev/dma_heap/system (0666)

如遇权限不够,推荐配置 udev 规则:

Device
sudo sh -c 'echo "KERNEL==\"g2d\", MODE=\"0666\"" > /etc/udev/rules.d/99-g2d.rules'
sudo sh -c 'echo "KERNEL==\"system\", SUBSYSTEM==\"dma_heap\", MODE=\"0666\"" >> /etc/udev/rules.d/99-g2d.rules'
sudo udevadm control --reload-rules
sudo udevadm trigger

头文件

G2D API 头文件位于:

/usr/include/bsp/linux/sunxi-g2d.h

快速启动

核心概念

使用 G2D 的标准流程:

1. 分配 DMA buffer(图像数据缓冲区)
2. 填充源图像数据
3. 配置 g2d_blit_h 结构体
4. 调用 ioctl(G2D_CMD_BITBLT_H, ...)
5. 从目标 DMA buffer 读取结果
6. 释放资源

关键:G2D 操作的是 DMA buffer,不是普通内存。

DMA buffer 由 /dev/dma_heap/system 分配,物理地址连续,硬件可直接访问。

示例(旋转 90°)

Device
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <bsp/linux/sunxi-g2d.h>
#include <linux/dma-heap.h>
#include <sys/mman.h>

#define W 1920
#define H 1080

// 分配 DMA buffer,返回 fd 和虚拟地址
static int alloc_dmabuf(int *fd, void **vaddr, size_t size)
{
struct dma_heap_allocation_data alloc_data = {
.len = size, .fd_flags = O_RDWR | O_CLOEXEC, .heap_flags = 0,
};
int heap_fd = open("/dev/dma_heap/system", O_RDONLY);
if (heap_fd < 0) return -1;
if (ioctl(heap_fd, DMA_HEAP_IOCTL_ALLOC, &alloc_data) < 0) {
close(heap_fd); return -1;
}
close(heap_fd);
*fd = alloc_data.fd;
*vaddr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
if (*vaddr == MAP_FAILED) { close(*fd); return -1; }
return 0;
}

int main(void)
{
int g2d_fd, src_fd, dst_fd;
void *src_v, *dst_v;
g2d_blt_h blit;

// 1. 分配两个 DMA buffer(源和目标)
alloc_dmabuf(&src_fd, &src_v, W * H * 4);
alloc_dmabuf(&dst_fd, &dst_v, W * H * 4);

// 2. 填充源图像数据(渐变示例)
fill_pattern(src_v, W, H);

// 3. 打开 G2D 设备
g2d_fd = open("/dev/g2d", O_RDWR);

// 4. 配置操作参数
memset(&blit, 0, sizeof(blit));
blit.flag_h = G2D_ROT_90; // 旋转 90°

blit.src_image_h.fd = src_fd;
blit.src_image_h.format = G2D_FORMAT_ARGB8888;
blit.src_image_h.width = W;
blit.src_image_h.height = H;

blit.dst_image_h.fd = dst_fd;
blit.dst_image_h.format = G2D_FORMAT_ARGB8888;
blit.dst_image_h.width = H; // 旋转后宽高互换
blit.dst_image_h.height = W;

// 5. 执行硬件加速操作
ioctl(g2d_fd, G2D_CMD_BITBLT_H, (unsigned long)(&blit));

// 6. 结果已在 dst_v 中,验证或提交给后续流程

// 7. 释放资源
close(g2d_fd);
munmap(src_v, W * H * 4); close(src_fd);
munmap(dst_v, W * H * 4); close(dst_fd);
return 0;
}

编译

Device
sudo apt install gcc g++ cmake
gcc -o g2d_rotation g2d_rotation.c

示例运行结果

提示

示例代码可查阅 github

示例操作结果
g2d_rotationARGB8888 1920×1080 旋转 90°8.24 ms,251.8 MP/sec
g2d_format_convARGB8888 → YUV420 1920×10809.56 ms,216.8 MP/sec
g2d_scaler4096×4096 → 1920×1080 缩放68.60 ms,244.6 MP/sec
g2d_color_fill1920×1080 纯色填充8.53 ms,243.2 MP/sec

注:g2d_scaler 源图分辨率上限为 4096×4096(8192×8192 会触发 EPERM)。

API 参考

完整 API 定义和所有支持格式见头文件:

/usr/include/bsp/linux/sunxi-g2d.h

常用 ioctl 命令:

命令用途
G2D_CMD_BITBLT_H单图像位块传输(旋转/缩放/格式转换)
G2D_CMD_FILLRECT_H颜色填充矩形
G2D_CMD_STRETCHBLT伸缩位块传输
G2D_CMD_BLD_HPorter-Duff 混合操作
G2D_CMD_MIXER_TASK批量任务(一次提交多个操作)

支持格式(部分):

格式说明
G2D_FORMAT_ARGB888832bpp Alpha-RGB
G2D_FORMAT_RGB88824bpp RGB
G2D_FORMAT_RGB56516bpp
G2D_FORMAT_YUV420UVC_U1V1U0V0NV12 标准格式

旋转标志:G2D_ROT_0 / G2D_ROT_90 / G2D_ROT_180 / G2D_ROT_270 / G2D_ROT_H(水平翻转)/ G2D_ROT_V(垂直翻转)

注意事项

  • DMA buffer 必须物理连续,普通 malloc 不能用于 G2D
  • IOMMU 负责地址翻译,G2D 访问的是 IOMMU 映射后的物理地址,无需关心具体地址值
  • DMA buffer 通过 fd 传递,用户空间用 mmap 后的虚拟地址读写
  • 目标分辨率应与源配合,旋转 90° 时宽高互换
  • 格式转换(如 RGB → YUV)由 G2D 硬件完成,源和目标 format 字段分别设置即可
  • 调试时,失败返回 -1errno 记录具体原因,用 perror() 打印

关于 2.0 接口与 1.0 接口

本文档示例默认使用 G2D 2.0 接口(G2D_CMD_BITBLT_H,结构体 g2d_blt_h)。部分系统(如某些旧版镜像或特定内核配置)下,2.0 接口可能返回 "Operation not permitted" 或 "G2D irq pending flag timeout" 错误。

如遇此情况,可尝试改用 G2D 1.0 接口(G2D_CMD_BITBLT,结构体 g2d_blt)作为兼容方案。两者的主要区别在于结构体字段命名(flag_h/src_image_h 等 2.0 专用字段在 1.0 结构体中对应名称不同),请参考头文件 /usr/include/bsp/linux/sunxi-g2d.hg2d_blt 的定义。

    您需要登录 GitHub 才能发表评论。如果您已登录,请忽略此消息。

    Radxa-docs © 2026 by Radxa Computer (Shenzhen) Co.,Ltd. is licensed under CC BY 4.0