GPU纹理零拷贝被证明在 K3 上不可行

VMA_MEMORY_USAGE_AUTO_PREFER_HOST 没有生效——VMA 在 K3 上仍然选择了 DEVICE_LOCAL 内存。

原因可能是 PowerVR GPU 驱动上报的内存类型中,渲染目标不支持 HOST_VISIBLE 。这是硬件层面的限制——即使 VMA 倾向于 HOST_VISIBLE ,但 VkImage 的 VK_IMAGE_TILING_OPTIMAL 强制要求 DEVICE_LOCAL 内存。

这说明在 K3 的 PowerVR BXM-4-64 上,纹理零拷贝不可行

请官方确认一下我的结论是否正确

配置 VmaAllocationCreateInfo 的 flag 试一下:

VmaAllocationCreateInfo allocCI = {};
allocCI.usage = VMA_MEMORY_USAGE_AUTO;
allocCI.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;

还是失败了。VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT 也没用——K3 的 PowerVR BXM-4-64 驱动上报的内存类型中,渲染目标确实不支持 host 访问

[2026-06-04 11:50:36] [INFO] [63331] [test_mesh_renderer_multithread_uma.cpp:95 main] Multi-thread UMA zero-copy: 1024x768, 300 frames, 8 lights, BGRA passthrough
[2026-06-04 11:50:37] [INFO] [63331] [test_mesh_renderer_multithread_uma.cpp:116 main] Memory architecture: UMA (zero-copy, skip copyTextureToBuffer)
[VULKAN ERROR] vkMapMemory(): Mapping memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set. Memory has type 0 which has properties VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT.
eddle@eddle-spacemitk3picoitx:~/Documents/3DGameMovieEngine/build$

vulkaninfo的输出是可以看到支持的:

vulkaninfo 2>/dev/null | grep -A 50 'VkPhysicalDeviceMemoryProperties'
VkPhysicalDeviceMemoryProperties:
=================================
memoryHeaps: count = 1
        memoryHeaps[0]:
                size   = 16741261312 (0x3e5db6000) (15.59 GiB)
                flags: count = 1
                        MEMORY_HEAP_DEVICE_LOCAL_BIT
memoryTypes: count = 4
        memoryTypes[0]:
                heapIndex     = 0
                propertyFlags = 0x0001: count = 1
                        MEMORY_PROPERTY_DEVICE_LOCAL_BIT
                usable for:
                        IMAGE_TILING_OPTIMAL:
                                color images
                                FORMAT_D16_UNORM
                                FORMAT_X8_D24_UNORM_PACK32
                                FORMAT_D32_SFLOAT
                                FORMAT_S8_UINT
                                FORMAT_D24_UNORM_S8_UINT
                                FORMAT_D32_SFLOAT_S8_UINT
                        IMAGE_TILING_LINEAR:
                                color images
        memoryTypes[1]:
                heapIndex     = 0
                propertyFlags = 0x0011: count = 2
                        MEMORY_PROPERTY_DEVICE_LOCAL_BIT
                        MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
                usable for:
                        IMAGE_TILING_OPTIMAL:
                                color images
                                FORMAT_D16_UNORM
                                FORMAT_X8_D24_UNORM_PACK32
                                FORMAT_D32_SFLOAT
                                FORMAT_S8_UINT
                                FORMAT_D24_UNORM_S8_UINT
                                FORMAT_D32_SFLOAT_S8_UINT
                                (transient only)
                        IMAGE_TILING_LINEAR:
                                color images
                                (transient only)
        memoryTypes[2]:
                heapIndex     = 0
                propertyFlags = 0x0007: count = 3
                        MEMORY_PROPERTY_DEVICE_LOCAL_BIT
                        MEMORY_PROPERTY_HOST_VISIBLE_BIT
                        MEMORY_PROPERTY_HOST_COHERENT_BIT
                usable for:
                        IMAGE_TILING_OPTIMAL:
                                color images
                                FORMAT_D16_UNORM

可能是 VMA 版本问题,试一下指定 require_flage:

VmaAllocationCreateInfo allocCI = {};
allocCI.usage = VMA_MEMORY_USAGE_AUTO;
allocCI.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;

这个地方建议检查一下你的引擎为什么选择了内存类型 0 而不是 2 ?

好的,我试试

Vma的自动最优选择好像永远会选o,它好像不管是不是UMA内存架构

试了一下,在UMA架构下,vma能够选择host_visible内存类型了,成功了,视频编码正确。图形能够准确显示

经过评估,我最终还是放弃了gpu纹理采用host_visible方案,我决定还是让gpu纹理采用device_local方案,因为k3的gpu是TBDR架构,即使是在UMA架构下,也无法实现gpu纹理零拷贝。

如果未来的硬件平台能够采用渲染计算后是RGBA/BGRA纹理的GPU,那在UMA下就可以实现零拷贝了。

禁用 PVRIC 压缩是可以的

不 PVRIC 也有 twiddle/tile , IMG Vulkan 驱动现阶段对于 sample from linear image 支持非常烂(