Skip to content

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.

ImplementationSourceWhat to read and implement
Power and firmwareNativeAdrenoGmuPlatform.h, build-adreno740-kits.pyNativeAdrenoGmuPlatform::bind/services, mapped windows, timers and firmware inputs
Submission and memoryNativeAdrenoClient.h, NativeAdrenoVm.hNativeAdrenoTransport, BO lifetime, GPU mappings and completion
OS/frontend interfaceNativeOfflineAccelerator.cpp, OfflineMetalWire.hAccelerator 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:

FirmwarePurpose
qcom/gmu_gen70200.binGMU image
qcom/a740_sqe.fwCommand processor firmware
qcom/sm8550/sheng/a740_zap.mbnBoard'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 ​

  1. Review ArmSmmu4K context ownership, stream selection, address width and cache maintenance. Use the target GPU and firmware stream IDs from its hardware description.
  2. Adapt reserved memory and GPU virtual-address windows. Keep scanout, firmware, ring and client allocations within their owned ranges.
  3. Confirm CP initialization, ring progress and fence completion with bounded work.
  4. Render a known image and inspect the result before using UI workloads.
  5. 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:

OperationRule
Object lookupEach client holds up to 16384 objects and finds them through a handle index.
AllocationBOs 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 memoryArmSmmu4KLiveMapContextBatchExclusive: no alias check against the existing ranges.
Map of imported memoryThe 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.
UnmapUp to 512 pages: one TLBIVAL per page. Larger: invalidate the ASID.
SubmissionNo 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:

sh
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.dbr

The 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.

Released under the BSD-2-Clause-Patent License.