3.6.4. Build Guide
The graphics stack on rogue has fluctuated a little over the years as we’ve adjusted for binary longevity in the proprietary stack. This will attempt to go over some of the discrepancies between releases and how you can build the releases stand alone.
3.6.4.1. Proprietary Stack
The proprietary stack has been our default offering for all releases so far. It consists of 3 main components with varying classifications:
The kernel module (KM) (Open Source, but out-of-tree)
The GLES / Vulkan / OpenCL implementation (UM) (Closed Source, binary release)
The mesa shim (Open Source, but out-of-tree)
All 3 of these components are required for GLES and Vulkan support. Exceptions will be covered in Proprietary Mesa Components.
3.6.4.1.1. Proprietary Kernel Module
The kernel module is required for:
Memory and power management
Loading firmware
Monitoring device state
Orchestrating hardware recoveries
Creating an interface for the userspace server
The source for the component is available at:
3.6.4.1.1.1. Building the Proprietary Kernel Module
Pick a branch that corresponds to your particular kernel. Keep note of the name. The UM component must match this release.
The INSTALL
file gives a brief overview of how to build and install the
module. This gives you the common variables, but it does leave out some of the
more important ones for the build. The following variables are key and must
match with the values used in the UM release:
BUILD
– Options:release
ordebug
PVR_BUILD_DIR
– Options:<platform>_linux
, for exampleam62_linux
WINDOW_SYSTEM
– Options:lws-generic
,xorg
,wayland
, …
These variables must be set for the build. To check for updated build variables
please see the EXTRA_OEMAKE
variable in the ti-img-rogue-driver recipe in
meta-ti. This will always contain the latest required variables to compile the
driver.
As previously mentioned these build options must match with the corresponding UM
build options. Currently we only release binaries with BUILD=release
and
WINDOW_SYSTEM=lws-generic
. The UM section will go previous exceptions
to this.
3.6.4.1.2. Proprietary Userspace Components
The proprietary userspace components are required for all interactions with the GPU. It contains the actual firmware binaries, GLES / Vulkan / OpenCL implementation, and the primary control server.
The binary release for this component is available at:
3.6.4.1.2.1. Installing the Proprietary Userspace Components
The repository contains binaries for each platform in release specific branches. Newer releases will match 1:1 with the kernel module branch name you would have picked in the Building the Proprietary Kernel Module stage.
In the repository the following structure can be seen:
.
├── LICENSE
├── Makefile
├── README
└── targetfs
├── am62_linux
│ └── lws-generic
│ └── release
├── am62p_linux
│ └── lws-generic
│ └── release
├── j721e_linux
│ └── lws-generic
│ └── release
├── j721s2_linux
│ └── lws-generic
│ └── release
├── j722s_linux
│ └── lws-generic
│ └── release
└── j784s4_linux
└── lws-generic
└── release
Under the targetfs
directory there is a subdirectory for each
PVR_BUILD_DIR
build variable. Under that directory is a subdirectory
corresponding to the WINDOW_SYSTEM
build variable. Finally, under that
directory is a subdirectory corresponding to the BUILD
build variable.
This is reflected in the Makefile
as:
SRCDIR = ./targetfs/${TARGET_PRODUCT}/${WINDOW_SYSTEM}/${BUILD}
The Makefile
simply unpacks this directory structure and installs the
corresponding files into DESTDIR
in the install step. Do not worry about the
clean step, as this is used for development.
3.6.4.1.3. Proprietary Mesa Components
Mesa, at this point in time, is a collection of GFX tools and utilities for setting up and interacting with rendering contexts. It contains everything from a DRI “megadriver” to full GLES/GL implementations. If you’re interested in learning GFX under Linux it’s worth familiarizing yourself with everything else it provides.
For us, the important part is that DRI megadriver. This is the mechanism used to determine what GLES / GL implementation is picked when you bind one of the previously mentioned API to a EGL context. This is also where things get tricky.
Historically there has been some issues with embedded GFX because, unlike your
standard PC GPU, we tend to mix and match actual Graphics Processing Units and
Display Controllers. The megadriver uses the display device name to coordinate
between API implementations. As such, we need a shim to act as a tidss
DRI driver and coordinate the link with the PVR GLES implementation.
This shim, currently, is provided in the form of a Gallium Frontend. This is the main reason for the fork and the 60 odd patches we carry at the following repo:
There are also other nice-to-have features there such as additional pixel formats, minor fixups, and a few performance tweaks IMG have picked up over the years, but the main reason we need it is for that shim.
3.6.4.1.3.1. Building the Proprietary Mesa Components
We recommend following the Mesa build guide for general options. Right now
the mesa components use a standard interface that allows you to pick any
powervr/*
branch you desire.
Note
Releases prior to 1.18 did not use this standard interface. Instead all relevant mesa components for those releases are bundled with the UM binaries.
The only necessary build options are:
-Dgallium-drivers=pvr
– This is a comma separated list, just make sure pvr is present in it.
-Dgallium-pvr-alias=tidss
– This should match the display controller you want to bind to. For all K3 devices this istidss
.
-Dvulkan-drivers=pvr
– If using Vulkan
This will produce 2 important files relevant to the shim mechanism we discussed earlier:
pvr_dri.so
– Main DRI interface
tidss_dri.so
– Display controller interface that points back atpvr_dri.so
. Will be named after the value specified with-Dgallium-pvr-alias
.
3.6.4.1.4. Using the Proprietary Stack
Assuming you’re using the SDK or you’ve built and installed the above correctly, you should see a message similar to the following in dmesg after the kernel module is loaded:
[ 7.716820] pvrsrvkm: loading out-of-tree module taints kernel.
[ 7.796345] PVR_K: 172: Device: 4e20000000.gpu
[ 7.859807] PVR_K: 172: Read BVNC 36.53.104.796 from HW device registers
[ 7.870809] PVR_K: 172: RGX Device registered BVNC 36.53.104.796 with 1 core in the system
[ 7.881015] [drm] Initialized pvr 24.1.6554834 20170530 for 4e20000000.gpu on minor 0
The BVNC should correspond with the BVNC set in
build/linux/PVR_BUILD_DIR/Makefile
in the kernel module repository. If
the module loads but does not detect the device, make sure your device tree has
defined the node properly, corresponding to the value of SYS_RGX_OF_COMPATIBLE
in the services/system/rogue/platform/sysinfo.h
.
You should now be able to issue a simple test. The UM repository provides the rgx_compute_test as a simple test that does not depend on the display or mesa components. You should see the following reported by the kernel module upon launching that test:
[ 460.674895] PVR_K: 332: RGX Firmware image 'rgx.fw.36.53.104.796' loaded
[ 460.694849] PVR_K: 332: Shader binary image 'rgx.sh.36.53.104.796' loaded
3.6.4.2. Open Source Stack
The open source driver is currently available for the AXE-1-16M core, but it should be noted that performance is not up to par with the proprietary driver at the moment. Performance improvements are on the table, but core enablement is the main priority right now.
It currently offers experimental Vulkan 1.0 support. In the future it will provide at least GL 2.1 via Zink. Please note that Zink support for this driver is not mainline, and it is still experimental. If you want to follow development check out the Imagination mesa fork
3.6.4.2.1. Open Source Kernel Module
This is provided in the upstream linux repo as of version 6.8. It has been enabled in the arm64 defconfig as a module since this release as well.
3.6.4.2.2. Open Source Firmware
Firmware is provided with linux-firmware as of tag 20231211.
Note
This a binary, and the firmware itself is still closed source right now, but this is not the same firmware as the proprietary driver.
3.6.4.2.3. Open Source Mesa Components
The open source stack dramatically reduces the number of moving pieces by combining the Vulkan implementation with Mesa. This Vulkan implementation is still marked as experimental, though. Once again, we recommend following the Mesa build guide for general options.
The only necessary build options are:
-Dvulkan-drivers=imagination-experimental
– Enable the experimental AXE Vulkan driver
-Dimagination-srv=true
– Enable the open control server
-Dgallium-drivers=zink
– Enable GL 2.1 through Zink
3.6.4.2.4. Using the Open Source Stack
After collecting the above artifacts you should be able to see the following message in dmesg:
[ 8.489877] powervr fd00000.gpu: [drm] loaded firmware powervr/rogue_33.15.11.3_v1.fw
[ 8.489916] powervr fd00000.gpu: [drm] FW version v1.0 (build 6503725 OS)
[ 8.543073] [drm] Initialized powervr 1.0.0 for fd00000.gpu on minor 1
Once again, if the module is loaded but you do not see the device being registered make sure the device tree node matches the binding provided in the upstream kernel.
At this point you should be able to run a simple test. The tool
vulkaninfo from the package vulkan-tools
is useful for printing
information about available Vulkan implementations.
The following will print a brief summary:
root@am62xx-evm:~# PVR_I_WANT_A_BROKEN_VULKAN_DRIVER=1 vulkaninfo --summary
MESA: debug: Found compatible render device '/dev/dri/renderD128'.
MESA: debug: Found compatible display device '/dev/dri/card0'.
MESA: error: No hard coded idfwdf program. Returning empty program.
MESA: error: No hard coded passthrough vertex shader. Returning empty shader.
MESA: debug: Format VK_FORMAT_X8_D24_UNORM_PACK32(125) not supported
MESA: debug: Format VK_FORMAT_D16_UNORM_S8_UINT(128) not supported
MESA: debug: Format VK_FORMAT_D32_SFLOAT_S8_UINT(130) not supported
MESA: debug: Format VK_FORMAT_X8_D24_UNORM_PACK32(125) not supported
MESA: debug: Format VK_FORMAT_D16_UNORM_S8_UINT(128) not supported
MESA: debug: Format VK_FORMAT_D32_SFLOAT_S8_UINT(130) not supported
==========
VULKANINFO
==========
Vulkan Instance Version: 1.3.275
Instance Extensions: count = 16
-------------------------------
VK_EXT_debug_report : extension revision 10
VK_EXT_debug_utils : extension revision 2
VK_EXT_headless_surface : extension revision 1
VK_KHR_device_group_creation : extension revision 1
VK_KHR_display : extension revision 23
VK_KHR_external_fence_capabilities : extension revision 1
VK_KHR_external_memory_capabilities : extension revision 1
VK_KHR_external_semaphore_capabilities : extension revision 1
VK_KHR_get_display_properties2 : extension revision 1
VK_KHR_get_physical_device_properties2 : extension revision 2
VK_KHR_get_surface_capabilities2 : extension revision 1
VK_KHR_portability_enumeration : extension revision 1
VK_KHR_surface : extension revision 25
VK_KHR_surface_protected_capabilities : extension revision 1
VK_KHR_wayland_surface : extension revision 6
VK_LUNARG_direct_driver_loading : extension revision 1
Instance Layers:
----------------
Devices:
========
GPU0:
apiVersion = 1.0.296
driverVersion = 101068899
vendorID = 0x1010
deviceID = 0x33011003
deviceType = PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU
deviceName = PowerVR A-Series AXE-1-16M
GPU1:
apiVersion = 1.3.255
driverVersion = 0.0.1
vendorID = 0x10005
deviceID = 0x0000
deviceType = PHYSICAL_DEVICE_TYPE_CPU
deviceName = llvmpipe (LLVM 18.1.6, 128 bits)
driverID = DRIVER_ID_MESA_LLVMPIPE
driverName = llvmpipe
driverInfo = Mesa 23.2.1 (git-0e75e7ded3) (LLVM 18.1.6)
conformanceVersion = 1.3.1.1
deviceUUID = 6d657361-3233-2e32-2e31-000000000000
driverUUID = 6c6c766d-7069-7065-5555-494400000000