OpenCL with AMD Radeon GPUs on FreeBSD (Mesa rusticl)
There is no ROCm/HIP on FreeBSD. The path to OpenCL on AMD GPUs is Mesa’s rusticl backend, which exposes the same radeonsi Gallium driver used for desktop graphics as an OpenCL device. It works for real workloads — hashcat, OpenCL-accelerated video encoding, whisper.cpp with the OpenCL backend, the classic clinfo / clpeak suite.
Tested on FreeBSD 15.0-RELEASE amd64 with an AMD RX 6900 XT (Sienna Cichlid / navi21), but the recipe works for any AMD GPU supported by the in-kernel amdgpu driver (RDNA 1/2/3, Vega, Polaris).
TL;DR
doas pkg install -y graphics/drm-latest-kmod graphics/mesa-dri \
graphics/mesa-libs devel/ocl-icd security/hashcat
doas sysrc kld_list+=amdgpu
doas pw groupmod video -m $(id -un)
doas shutdown -r now
# After reboot:
OCL_ICD_VENDORS=/usr/local/etc/OpenCL/vendors RUSTICL_ENABLE=radeonsi \
hashcat -I
You should see Mesa Rusticl listed with your AMD GPU. If you get “No devices found”, scroll to the troubleshooting section.
What you’re installing and why
| package | what it is |
|---|---|
graphics/drm-latest-kmod | The amdgpu kernel module + GPU firmware blobs. On 14.x, use graphics/drm-61-kmod instead — it tracks the Linux 6.1 LTS DRM. |
graphics/mesa-dri | Mesa’s gallium drivers, including radeonsi for AMD GCN+ chips. |
graphics/mesa-libs | Mesa’s userland libraries (libGL, libEGL, etc.). |
devel/ocl-icd | The OpenCL ICD loader. Apps link against libOpenCL.so from this; it dispatches to whatever ICDs are installed. |
security/hashcat | Optional — but the easiest “is OpenCL working” test. |
The Mesa packages on FreeBSD ship the rusticl ICD at /usr/local/etc/OpenCL/vendors/rusticl.icd. Hashcat (and any other Linux-leaning OpenCL app) looks at /etc/OpenCL/vendors by default, which doesn’t exist on FreeBSD. Hence the OCL_ICD_VENDORS env var later.
The two mandatory env vars
Every OpenCL run on FreeBSD with AMD needs both:
export OCL_ICD_VENDORS=/usr/local/etc/OpenCL/vendors
export RUSTICL_ENABLE=radeonsi
OCL_ICD_VENDORS— points the ICD loader at the right ICD directory.RUSTICL_ENABLE=radeonsi— Mesa gates the radeonsi rusticl backend behind this var. Without it, rusticl loads but exposes zero devices.
Drop them into /etc/profile so login shells inherit them:
doas tee -a /etc/profile <<'EOF'
export OCL_ICD_VENDORS=/usr/local/etc/OpenCL/vendors
export RUSTICL_ENABLE=radeonsi
EOF
Cron jobs and systemd-style invocations don’t read /etc/profile; set them explicitly in those contexts.
Loading amdgpu at boot
Don’t kldload amdgpu after a desktop session is already running — on some boards the existing framebuffer console interferes and the GPU enters an inconsistent state. Always load it from kld_list:
doas sysrc kld_list+=amdgpu
doas shutdown -r now
After reboot:
$ kldstat | grep -E '(amdgpu|drm)'
3 1 0xffffffff83400000 6ddad0 amdgpu.ko
4 2 0xffffffff83310000 8a190 drm.ko
$ ls /dev/dri
card0 renderD128
renderD128 is what OpenCL actually uses (no display surface). card0 is for graphics.
Permissions: the video group
OpenCL apps need read/write on /dev/dri/renderD128. The default permissions are crw-rw---- root:video, so:
doas pw groupmod video -m $(id -un)
# log out and back in for the group to take effect
You can verify:
$ id
uid=1001(you) gid=1001(you) groups=1001(you),44(video),0(wheel),...
$ stat -f '%Sp %Su:%Sg' /dev/dri/renderD128
crw-rw---- root:video
Verifying
Quickest probe — clinfo from devel/clinfo:
$ doas pkg install -y devel/clinfo
$ OCL_ICD_VENDORS=/usr/local/etc/OpenCL/vendors RUSTICL_ENABLE=radeonsi clinfo
Number of platforms 1
Platform Name rusticl
Platform Vendor Mesa/X.org
...
Device Name AMD Radeon RX 6900 XT (radeonsi, navi21, ...)
Device Vendor AMD
Device Type GPU
...
Or hashcat:
$ OCL_ICD_VENDORS=/usr/local/etc/OpenCL/vendors RUSTICL_ENABLE=radeonsi hashcat -I
OpenCL Info:
============
OpenCL Platform ID #1
Vendor..: Mesa/X.org
Name....: rusticl
Version.: OpenCL 3.0
Backend Device ID #1
Type...........: GPU
Vendor.ID......: 4098
Vendor.........: AMD
Name...........: AMD Radeon RX 6900 XT (...)
Processor(s)...: 40
Clock..........: 2250
Memory.Total...: 16368 MB (free: 15234 MB)
A quick benchmark to confirm performance is reasonable:
OCL_ICD_VENDORS=/usr/local/etc/OpenCL/vendors RUSTICL_ENABLE=radeonsi \
hashcat -b -m 0 # MD5 mode
For reference, an RX 6900 XT on rusticl gets ~50 GH/s on MD5 — within ~10% of the same card on Linux ROCm.
Performance notes
- Multiple processes share the GPU. rusticl does not take an exclusive lock. Two
hashcatruns against the same card both finish, with throughput split between them. Useful for ad-hoc short attacks alongside a long-running job. - No HIP, no ROCm. If a workload requires AMDGPU compute via HIP (PyTorch ROCm, llama.cpp HIP backend), it won’t work — only OpenCL via rusticl.
- No multi-GPU peer access. Each GPU is a separate OpenCL device; you can’t do peer DMA between them.
Troubleshooting
| symptom | likely cause |
|---|---|
clinfo shows zero platforms | OCL_ICD_VENDORS not set, or /usr/local/etc/OpenCL/vendors/rusticl.icd missing |
clinfo shows rusticl platform but zero devices | RUSTICL_ENABLE not set |
hashcat -I: “No devices found” | one of the env vars; check both |
radeonsi: failed to open device | user not in video group, or amdgpu not loaded |
kldload amdgpu says firmware missing | install/reinstall graphics/drm-latest-kmod (provides firmware) |
| Random GPU hangs / dmesg ring oops | kldload-ed amdgpu after boot — load via kld_list and reboot instead |
| OpenCL works as root, not as user | pw groupmod video -m $(id -un), then re-login |
If you’re testing inside a jail and still get “No devices found” after both env vars are set, the host hasn’t exposed /dev/dri/* to the jail. See the companion post on OpenCL in FreeBSD jails.
See also
- OpenCL in FreeBSD jails (AMD GPU passthrough) — devfs ruleset setup to share the GPU with a jail.
- Running Claude Code on FreeBSD via the Linuxulator — if you want claude to drive hashcat or other OpenCL tools.