Hi
Am 14.07.26 um 12:11 schrieb Leander Kieweg:
Hi everyone,
This series adds a DRM driver for GlandaGPU, a custom open-source 2D
graphics core I designed in VHDL. It currently runs on a Cyclone V
SoC (Terasic DE10-Standard), with VGA output at 640x480@60Hz. I also
built a QEMU fork that emulates the same MMIO/VRAM interface as a
digital twin, so I can develop and test without needing the FPGA
board.
That is a pretty cool project.
Hardware/VHDL: https://github.com/stiangglanda/GlandaGPU
QEMU fork: https://github.com/stiangglanda/qemu-glandagpu
Userspace tests: https://github.com/stiangglanda/GlandaGPU-userspace-tests
I'm sending this as an RFC because I'd like feedback on the
following points before cleaning up the series further:
1) Mainline viability of custom FPGA hardware
GlandaGPU isn't a commercial chip, it's an open-source soft GPU
core. The DE10-Standard itself is a regular purchasable dev
board, and the RTL is public, so anyone can reproduce the exact
hardware. Testing doesn't require the FPGA either, since the
QEMU twin models the same interface. I know this is unusual
compared to typical mainline DRM hardware. I'd like to know
whether this is workable, or whether it's a dealbreaker for
mainline.
We already have a driver for a RasPi-based USB display that someone made
in their spare time. So being a hobbyist project is not a problem per se.
2) UAPI / ioctls / userspace
The driver currently exposes three fixed ioctls (CLEAR,
DRAW_RECT, DRAW_LINE), mapping directly onto the current
hardware command set. I have two related questions here:
2d primitives are likely not very useful for DRM. The canonical
reference of why is at [1]. The tl;dr is that there's no standard API,
and GPU-CPU transfers and setup costs are too high to make it
significantly faster than software rendering.
Various people have proposed to add some form of 2d pipeline to DRM, but
nothing concrete has ever emerged.
Conceptually, DRM doesn't really render anything. It composes the screen
from already-rendered buffers. Rendering to these buffers is mostly done
by Mesa drivers with some help from DRM's kernel drivers. If you want
hardware rendering, you'd need memory management for off-screen
rendering that Mesa can use independently from display output. Therefore
these simple draw and clear primitives aren't that useful. You need to
design a full rendering pipeline instead.
[1] https://blog.ffwll.ch/2018/08/no-2d-in-drm.html
a) I plan to keep developing the hardware further, which will
likely mean more ioctls over time (for example, polygon/3D
rendering is one direction I'm considering). Is it acceptable
to keep adding a new, separate ioctl for each drawing
primitive like this, or should I move to a generic
command-buffer submission model instead, similar to
DRM_IOCTL_VIRTGPU_EXECBUFFER in virtio_gpu, before this is
treated as stable?
Using a single ioctl per command will kill performance. So, if anything,
you'd want the command-buffer model. To make it fast for 2d primitives,
you'd likely have to model it like a 3d pipeline: have all 2d graphics
buffers in the display memory already and submit a large batch of
rendering commands that generate the entire screen at once.
b) If I do end up with an ioctl-based acceleration UAPI, is
writing a Mesa/Gallium3D driver the expected way to make it
usable from userspace, or is there a lighter-weight option
that makes more sense for a project this size?
Rule of thumb is that you need a working user-space side for ioctls.
Mesa would be the premier target for 3d.
I'm not much involved in Mesa, but I think Mesa is quickly moving
towards programmable pipelines. Getting drivers for fixed-function
hardware merged might be hard.
How complicated is it to model a stream processor (i.e. GPU core) in VHDL?
3) x86 QEMU platform test device
To let reviewers try the driver against the QEMU twin without
cross-compiling an ARM kernel and rootfs, I registered a
platform device at a fixed address on x86. I'm aware this
doesn't belong in the driver itself, so I isolated it into patch
3/3 and marked it "NOT FOR MERGE". Let me know if you'd rather
see it dropped entirely, relying only on documentation of the
QEMU-on-ARM testing path instead.
Can you use a PCI device for that and let the kernel do all the work?
See [2] for how to get a PCI device id.
[2] https://www.qemu.org/docs/master/specs/pci-ids.html
4) Pixel format conversion
glanda_pipe_update() currently does a per-pixel software
conversion from XRGB8888 into the hardware's native packed
format on every flip. I'm aware this is a known bottleneck. I'm
planning to extend the VHDL to accept XRGB8888 natively so I can
drop this conversion entirely. I'm flagging it here as a known
limitation rather than blocking on it, since it's a hardware-side
change and doesn't affect the UAPI.
That's indeed a good thing to have in hardware.
I mentioned that the 2d/3d rendering is probably complicated to get
done. If I may suggest an alternative, you could implement additional
features of the mode-setting pipeline. Besides the primary plane that
your hardware already supports, you could add a cursor plane. Or you
could add overlay planes for displaying YUV formats (i.e., video
frames). Or you could implement existing DRM properties, such as
scaling, background colors, or HDR. These features are already
supported by user space. Your device would be usable immediately.
5) drm_simple_display_pipe vs. manual plane/CRTC/encoder
Since the driver only has a single plane, CRTC, and encoder, I
tried converting it to use drm_simple_display_pipe instead of the
manual setup. It compiled cleanly, but my userspace tests didn't
behave the way I expected. I haven't figured out why yet, so I
kept the manual setup for this RFC. I'm open to revisiting this
if that's the preferred direction.
Glad to hear it didn't work. drm_simple_display_pipe is obsolete and on
its way out. Please don't use it.
Best regards
Thomas
Testing Status:
The driver has been tested and verified on both the QEMU fork (x86)
and physical FPGA hardware (ARM) using:
- A custom static userspace test:
https://github.com/stiangglanda/GlandaGPU-userspace-tests
- `modetest -M glandagpu -s 36:640x480 -v` (which successfully
displays the test pattern)
Thanks for any feedback,
Leander Kieweg
Leander Kieweg (3):
dt-bindings: display: Add GlandaGPU binding
drm/glanda: Add initial DRM driver for GlandaGPU
NOT FOR MERGE: drm/glanda: Add x86 platform test device
.../bindings/display/glanda,gpu.yaml | 49 ++
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
MAINTAINERS | 7 +
drivers/gpu/drm/tiny/Kconfig | 25 +
drivers/gpu/drm/tiny/Makefile | 1 +
drivers/gpu/drm/tiny/glandagpu.c | 808 ++++++++++++++++++
include/uapi/drm/glanda_drm.h | 40 +
7 files changed, 932 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/glanda,gpu.yaml
create mode 100644 drivers/gpu/drm/tiny/glandagpu.c
create mode 100644 include/uapi/drm/glanda_drm.h
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, (HRB 36809, AG Nürnberg)