Skip to main content

G2D Usage Guide

Overview

G2D is a 2D graphics hardware accelerator integrated into Allwinner SoCs, responsible for image rotation, scaling, format conversion, color filling and other operations.

tip

New images already include G2D by default. Skip to Verify Driver Status below to confirm. For older images, expand below for manual installation.

Older images: Manual G2D kernel installation
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
# Then reboot
sudo reboot

Typical application scenarios:

  • Image preprocessing (scaling, color space conversion) before and after video encoding/decoding
  • Camera real-time preview image processing
  • Format conversion (RGB ↔ YUV) before display output
  • Batch image processing pipeline

Project Environment:

ItemValue
SoCAllwinner A733
Linux5.15.147-100-a733
G2D Driver Version1.0.0
Driver Moduleg2d_sunxi
Device Node/dev/g2d, /dev/dma_heap/system

Environment Setup

Verify Driver Status

Device
# Check if driver module is loaded
lsmod | grep g2d
# Output example: g2d_sunxi 90112 0

# Check driver version
cat /sys/module/g2d_sunxi/version
# Output: 1.0.0

If not loaded, manually load:

Device
sudo modprobe g2d_sunxi

Device Node Permissions

Current system is configured to run without root:

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

If you encounter permission issues, it is recommended to configure udev rules:

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

Header Files

G2D API header file location:

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

Quick Start

Core Concepts

Standard workflow for using G2D:

1. Allocate DMA buffer (image data buffer)
2. Fill source image data
3. Configure g2d_blit_h structure
4. Call ioctl(G2D_CMD_BITBLT_H, ...)
5. Read result from target DMA buffer
6. Release resources

Key: G2D operates on DMA buffer, not regular memory.

DMA buffer is allocated by /dev/dma_heap/system, physically contiguous, hardware can access directly.

Example (Rotate 90°)

Complete runnable code see g2d_rotation_or_mirror.c.

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

// Allocate DMA buffer, return fd and virtual address
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. Allocate two DMA buffers (source and destination)
alloc_dmabuf(&src_fd, &src_v, W * H * 4);
alloc_dmabuf(&dst_fd, &dst_v, W * H * 4);

// 2. Fill source image data (gradient example)
fill_pattern(src_v, W, H);

// 3. Open G2D device
g2d_fd = open("/dev/g2d", O_RDWR);

// 4. Configure operation parameters
memset(&blit, 0, sizeof(blit));
blit.flag_h = G2D_ROT_90; // Rotate 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; // Width and height swap after rotation
blit.dst_image_h.height = W;

// 5. Execute hardware accelerated operation
ioctl(g2d_fd, G2D_CMD_BITBLT_H, (unsigned long)(&blit));

// 6. Result is already in dst_v, verify or submit to subsequent process

// 7. Release resources
close(g2d_fd);
munmap(src_v, W * H * 4); close(src_fd);
munmap(dst_v, W * H * 4); close(dst_fd);
return 0;
}

Compilation

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

Example code is available on github.

Example Results

ExampleOperationResult
g2d_rotationARGB8888 1920×1080 rotate 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 scale68.60 ms, 244.6 MP/sec
g2d_color_fill1920×1080 solid color fill8.53 ms, 243.2 MP/sec

Note: g2d_scaler source resolution upper limit is 4096×4096 (8192×8192 triggers EPERM).

API Reference

Complete API definition and all supported formats see header file:

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

Common ioctl commands:

CommandPurpose
G2D_CMD_BITBLT_HSingle image bit block transfer (rotate/scale/format convert)
G2D_CMD_FILLRECT_HColor fill rectangle
G2D_CMD_STRETCHBLTStretch bit block transfer
G2D_CMD_BLD_HPorter-Duff blend operation
G2D_CMD_MIXER_TASKBatch tasks (submit multiple operations at once)

Supported formats (partial):

FormatDescription
G2D_FORMAT_ARGB888832bpp Alpha-RGB
G2D_FORMAT_RGB88824bpp RGB
G2D_FORMAT_RGB56516bpp
G2D_FORMAT_YUV420UVC_U1V1U0V0NV12 standard format

Rotation flags: G2D_ROT_0 / G2D_ROT_90 / G2D_ROT_180 / G2D_ROT_270 / G2D_ROT_H (horizontal flip) / G2D_ROT_V (vertical flip)

Notes

  • DMA buffer must be physically contiguous, regular malloc cannot be used for G2D
  • IOMMU is responsible for address translation, G2D accesses IOMMU-mapped physical addresses, no need to care about specific address values
  • DMA buffer passed through fd, user space uses mmap-ed virtual address for read/write
  • Target resolution should match source, width and height swap when rotating 90°
  • Format conversion (e.g. RGB → YUV) is done by G2D hardware, just set source and destination format fields separately
  • For debugging, failure returns -1, errno records specific reason, use perror() to print

About 2.0 Interface vs 1.0 Interface

The examples in this guide use the G2D 2.0 interface by default (G2D_CMD_BITBLT_H, struct g2d_blt_h). On some systems (such as certain older images or specific kernel configurations), the 2.0 interface may return "Operation not permitted" or "G2D irq pending flag timeout" errors.

If you encounter this situation, you can try using the G2D 1.0 interface (G2D_CMD_BITBLT, struct g2d_blt) as a compatible fallback. The main difference between the two is the struct field naming (flag_h/src_image_h etc. are 2.0-specific fields that have different names in the 1.0 struct). Refer to the header file /usr/include/bsp/linux/sunxi-g2d.h for the g2d_blt definition.

    You need to be logged into GitHub to post a comment. If you are already logged in, please ignore this message.

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