<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/adding-secondary-command-buffers-to-panvk-fudj9lkt4" -->

---
title: Adding secondary command buffers to PanVk | daily.dev
description: PanVk, the open source Vulkan driver for ARM Mali GPUs, lacks native secondary command buffer support because Mali GPUs cannot natively reference or copy...
canonical: https://daily.dev/posts/adding-secondary-command-buffers-to-panvk-fudj9lkt4
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Adding secondary command buffers to PanVk | daily.dev
og:description: PanVk, the open source Vulkan driver for ARM Mali GPUs, lacks native secondary command buffer support because Mali GPUs cannot natively reference or copy...
og:url: https://daily.dev/posts/adding-secondary-command-buffers-to-panvk-fudj9lkt4
og:image: https://api.daily.dev/og/posts/FUDj9lkt4.png
og:image:alt: Adding secondary command buffers to PanVk
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Adding secondary command buffers to PanVk

**[Collabora Blog](https://daily.dev/sources/collabora)** · 18 min read · 0 upvotes · 0 comments

## Summary

PanVk, the open source Vulkan driver for ARM Mali GPUs, lacks native secondary command buffer support because Mali GPUs cannot natively reference or copy command streams. Two emulation approaches were implemented and benchmarked: a high-level software command queue (reusing Mesa's vk_cmd_queue infrastructure from lavapipe) and a low-level pointer relocation method using CPU-only buffer objects. The low-level approach stores secondary command buffer jobs in a single CPU-only memory blob, then copies and relocates GPU address pointers when vkCmdExecuteCommands is called. Profiling with perf shows the low-level relocation method outperforms the high-level queue by 1.5x–2x in CPU cycles, at a cost of roughly 20 MB additional memory usage. All dEQP secondary command buffer tests now pass.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.collabora.com/news-and-blog/blog/2022/06/15/adding-secondary-command-buffers-to-panvk-driver>

## Questions this post answers

### Why can't Mali GPUs natively support Vulkan secondary command buffers?

Mali GPU job descriptors contain absolute GPU addresses pointing to other descriptors (framebuffer descriptors, context descriptors, etc.), so a simple memcpy of a secondary command buffer's jobs produces invalid pointers. Unlike architectures where the command stream can be copied and replayed directly, Mali jobs form a graph of hardware descriptors that require address relocation whenever they are moved to a different memory region.

_Developers working on Mali GPU driver features track implementation progress like this on daily.dev._

### How does PanVk emulate vkCmdExecuteCommands on Mali hardware without native secondary command buffer support?

PanVk stores secondary command buffer jobs in a single CPU-only buffer object using fake GPU base addresses (e.g., 0xffffff00000000). When vkCmdExecuteCommands is called, the entire BO is copied into the primary command buffer's memory pool, then a relocation pass fixes all internal GPU address fields by subtracting the fake base and adding the real destination base. External addresses that depend on primary command buffer context are patched unconditionally via a separate macro.

_GPU driver engineers navigating Vulkan conformance work find implementation deep-dives like this on daily.dev._

### What is the performance difference between high-level software command queues and low-level pointer relocation for Vulkan secondary command buffer emulation?

Low-level pointer relocation outperforms high-level software command queues by roughly 1.5x–2x in CPU cycle consumption across all tested workloads (1 to 20 vkCmdExecuteCommands calls). The trade-off is approximately 20 MB of additional memory usage per test scenario. The high-level approach reuses Mesa's vk_cmd_queue infrastructure but replays full vkCmd* calls, making it slower at execution time despite lighter recording overhead.

_Teams deciding between emulation strategies for Vulkan driver work stay current on findings like these through daily.dev._

## Similar posts on daily.dev

- [PanVK Mali Vulkan Driver Lands In-Memory Cache & On-Disk Shader Cache Support](https://daily.dev/posts/panvk-mali-vulkan-driver-lands-in-memory-cache-on-disk-shader-cache-support-y2z1wbliv) · Phoronix · 0 upvotes · 0 comments
- [Making wl\_shm fast](https://daily.dev/posts/making-wl-shm-fast-xcwnnukrr) · Lobsters · 0 upvotes · 0 comments
- [Vulkan 1.4.346 Released With Notable VK\_KHR\_device\_address\_commands](https://daily.dev/posts/vulkan-1-4-346-released-with-notable-vk-khr-device-address-commands-r2lvmji8l) · Phoronix · 0 upvotes · 0 comments
- [Vulkan Ray Tracing: Deprecating Host-Side Acceleration Structure Builds](https://daily.dev/posts/vulkan-ray-tracing-deprecating-host-side-acceleration-structure-builds-brqwmbipt) · Khronos · 0 upvotes · 0 comments

---

Tags: [#vulkan](https://daily.dev/tags/vulkan), [#mesa](https://daily.dev/tags/mesa)

[View this post on daily.dev](https://daily.dev/posts/adding-secondary-command-buffers-to-panvk-fudj9lkt4)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Adding secondary command buffers to PanVk","url":"https://daily.dev/posts/adding-secondary-command-buffers-to-panvk-fudj9lkt4","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/adding-secondary-command-buffers-to-panvk-fudj9lkt4"},"datePublished":"2026-08-11T08:55:47.149Z","dateModified":"2026-08-11T09:26:58.244Z","description":"PanVk, the open source Vulkan driver for ARM Mali GPUs, lacks native secondary command buffer support because Mali GPUs cannot natively reference or copy...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/162f24ce8f6f5f1a33fb88d0fce4a1e6?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/162f24ce8f6f5f1a33fb88d0fce4a1e6?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Collabora Blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Collabora Blog","logo":"https://media.daily.dev/image/upload/s--ZGZ0FjqS--/f_auto,q_auto/v1786438306/logos/collabora?_a=BAMAMicg0","url":"https://daily.dev/sources/collabora"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/adding-secondary-command-buffers-to-panvk-fudj9lkt4","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"vulkan,mesa","timeRequired":"PT18M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Collabora Blog","item":"https://daily.dev/sources/collabora"},{"@type":"ListItem","position":3,"name":"Adding secondary command buffers to PanVk"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/adding-secondary-command-buffers-to-panvk-fudj9lkt4#faq","mainEntity":[{"@type":"Question","name":"Why can't Mali GPUs natively support Vulkan secondary command buffers?","acceptedAnswer":{"@type":"Answer","text":"Mali GPU job descriptors contain absolute GPU addresses pointing to other descriptors (framebuffer descriptors, context descriptors, etc.), so a simple memcpy of a secondary command buffer's jobs produces invalid pointers. Unlike architectures where the command stream can be copied and replayed directly, Mali jobs form a graph of hardware descriptors that require address relocation whenever they are moved to a different memory region. Developers working on Mali GPU driver features track implementation progress like this on daily.dev."}},{"@type":"Question","name":"How does PanVk emulate vkCmdExecuteCommands on Mali hardware without native secondary command buffer support?","acceptedAnswer":{"@type":"Answer","text":"PanVk stores secondary command buffer jobs in a single CPU-only buffer object using fake GPU base addresses (e.g., 0xffffff00000000). When vkCmdExecuteCommands is called, the entire BO is copied into the primary command buffer's memory pool, then a relocation pass fixes all internal GPU address fields by subtracting the fake base and adding the real destination base. External addresses that depend on primary command buffer context are patched unconditionally via a separate macro. GPU driver engineers navigating Vulkan conformance work find implementation deep-dives like this on daily.dev."}},{"@type":"Question","name":"What is the performance difference between high-level software command queues and low-level pointer relocation for Vulkan secondary command buffer emulation?","acceptedAnswer":{"@type":"Answer","text":"Low-level pointer relocation outperforms high-level software command queues by roughly 1.5x–2x in CPU cycle consumption across all tested workloads (1 to 20 vkCmdExecuteCommands calls). The trade-off is approximately 20 MB of additional memory usage per test scenario. The high-level approach reuses Mesa's vk_cmd_queue infrastructure but replays full vkCmd* calls, making it slower at execution time despite lighter recording overhead. Teams deciding between emulation strategies for Vulkan driver work stay current on findings like these through daily.dev."}}]}
```

