GPU and Metal adaptation
Complete platform DMA and basic display presentation first. Read the Adreno740 runtime path and AdrenoMetal interface.
Use driver build integration to connect initialization, archive recipes and the OS ABI, then run this page's hardware checks.
Sources and interfaces
These links identify reviewed source revisions. Match interfaces to the selected SoC, component and OS versions. Files in UniXNU-sheng provide board integration examples.
| Implementation | Source | What to read and implement |
|---|---|---|
| Power and firmware | NativeAdrenoGmuPlatform.h, build-adreno740-kits.py | NativeAdrenoGmuPlatform::bind/services, mapped windows, timers and firmware inputs |
| Submission and memory | NativeAdrenoClient.h, NativeAdrenoVm.h | NativeAdrenoTransport, BO lifetime, GPU mappings and completion |
| OS/frontend interface | NativeOfflineAccelerator.cpp, OfflineMetalWire.h | Accelerator publication and request structures used by the matching frontend |
1. Match the GPU generation and OS ABI
Adreno740 implements the A740 kernel interface. AdrenoMetal uses that interface, Turnip, metal2vulkan and the selected OS GPU/IOSurface ABI. Identify the target GPU revision and compare register, firmware, packet and memory interfaces. For another GPU generation, implement the matching kernel backend and compiler support before selecting its frontend.
For another A740 board, collect GPU/GMU registers, interrupts, SMMU context and stream IDs, firmware, power domains, clock/voltage levels, interconnect votes, RAM reservations and scanout layout. Check them against the selected firmware.
2. Adapt power and firmware inputs
Read the SM8550 platform sources and the sheng package. Sm8550Platform supplies shared GMU operations and command-database handling. ShengGmuVotes.c and ShengGmuVotesSource.h supply the board's OPP and bandwidth policy. Port those inputs to the target's rails and command database.
The sheng recipe scripts/build-adreno740-kits.py embeds these local inputs:
| Firmware | Purpose |
|---|---|
qcom/gmu_gen70200.bin | GMU image |
qcom/a740_sqe.fw | Command processor firmware |
qcom/sm8550/sheng/a740_zap.mbn | Board's signed ZAP image |
The recipe checks pins in scripts/data/adreno-inputs.json and reads .cache/firmware/sheng-gpu/. Adapt the extraction paths and pins to the target's verified firmware; record provenance in proprietary-files.txt.
Expected result: board power inputs and firmware match the target GPU. Confirm GMU startup and HFI response before submitting commands.
3. Establish memory and command submission
- Review ArmSmmu4K context ownership, stream selection, address width and cache maintenance. Use the target GPU and firmware stream IDs from its hardware description.
- Adapt reserved memory and GPU virtual-address windows. Keep scanout, firmware, ring and client allocations within their owned ranges.
- Confirm CP initialization, ring progress and fence completion with bounded work.
- Render a known image and inspect the result before using UI workloads.
- Verify client teardown, mapping lifetime and fence failures.
Use AdrenoFirmware for firmware/HFI operations and AdrenoPM4 for supported packet encoding. The sheng recipe links these kits, ArmSmmu4K and board votes into libAdreno740.a, then builds the accelerator through build-adreno740-accelerator.py. Preserve that order when creating the target recipe.
Expected result: commands complete, fences advance and the known image is correct. Record GPU results independently from desktop presentation.
Keep mapping and submission cheap
A desktop frame allocates, maps and frees many buffers, so per-call cost decides smoothness. Adreno740 and ArmSmmu4K use these rules; keep them when porting:
| Operation | Rule |
|---|---|
| Object lookup | Each client holds up to 16384 objects and finds them through a handle index. |
| Allocation | BOs come from a contiguous write-combined pool the board reserves (1 GiB on sheng), and from scattered pages when it is full. |
| Map of owned memory | ArmSmmu4KLiveMapContextBatchExclusive: no alias check against the existing ranges. |
| Map of imported memory | The same call when every mapped import shares its cache class and its pages overlap neither the pool nor an owned mapping; otherwise the fully checked batch map. |
| Unmap | Up to 512 pages: one TLBIVAL per page. Larger: invalidate the ASID. |
| Submission | No TLB invalidation. A map fills only invalid leaves, an unmap invalidates its own pages, and the upper tables never change. A stalled fence still invalidates. |
The boot log's [vm map], [vm unmap], [vm kinds] and [bo pool] rows give the count and time of each operation. Compare them before and after a change.
With NativeAdrenoClient, implement one bounded submission in this order: query ABI/capabilities, allocate a BO, map it to an allowed IOVA, populate commands, submit and wait for the returned fence. Bind NativeAdrenoTransport.call to the actual kernel dispatcher, preserving each request's input/output sizes. Synchronize caches before CPU readback. On fence timeout, stop the queue and confirm DMA has stopped before releasing the BO and mapping. Report the failed request, handle and fence to distinguish allocation, mapping and execution failures.
4. Build and stage Metal
Run these commands from the resolved target tree after preparing the matching SDK, compiler dependencies and ABI inputs:
python3 scripts/build-turnip-darwin.py --target ios
python3 scripts/build-adreno-metal-plugin.py
python3 scripts/add-gpu-plugin-data.py --publish /path/to/base.dbr /path/to/gpu.dbrThe staging command uses macOS image tools and writes a copy of the Data seed. Use that output as --data-ramdisk when building the payload, then rebuild the boot image. For selected app processes, the staging command also accepts --clients NAME,.... The runtime plugin name is NativeAdrenoMetal.
Check the selected OS profile's sandbox, user-client and trust-cache integration. The Metal bridge never returns a nil encoder: a pass it cannot encode gets an encoder whose command buffer is refused, because RenderBox caches the encoder's methods. The process's first problem appears on the driver's per-process text line ([gpu client text] in the boot log). AirNir is the offline compiler kit; the runtime frontend uses the AIR → SPIR-V → NIR → IR3 chain described in the component page.
Expected result: Metal device discovery, client connection, pipeline creation, rendering and presentation each succeed. Record firmware, compiler and plugin revisions with the frame result. Cold pipeline compilation and cache reuse need separate timing observations.
Next step
Continue with Wi-Fi, or return to the driver checklist.