Quest 3 zero copy Vulkan

  • I’m implementing a zero‑copy video pipeline on Meta Quest 3 (Adreno, Android, Unreal Engine 5.7, Vulkan):

    Step 1: AHardwareBuffer arrives from AImageReader
    Step 2: RHICreateTexture2DFromAndroidHardwareBuffer imports AHB → VkImage
    Step 3: UE Vulkan RHI creates VkSamplerYcbcrConversion
    Step 4: UE Vulkan RHI creates VkImageView + immutable sampler
    Step 5: Hardware performs YUV→RGB conversion
    Step 6: The RHI texture is wrapped into UTexture2D
    Step 7: UTexture2D is used in a material

    Initially I used AIMAGE_FORMAT_PRIVATE, but on Quest 3 the Adreno driver always produced UBWC (0x7FA30C06), which UE5 Vulkan cannot sample.

    Following recommendations, I switched to AIMAGE_FORMAT_YUV_420_888 to get linear NV12 (0x23).
    However, on Quest 3 the Adreno/qdgralloc driver still forcibly overrides the format to UBWC, even with minimal usage flags (GPU_SAMPLED_IMAGE, CPU_READ_OFTEN, no FRAMEBUFFER).

    As a result:

    with PRIVATE, UBWC reached Vulkan → white screen (pipeline failure)

    with YUV_420_888, UBWC is rejected early → black screen (no frames)

    Question:
    On the stack Meta Quest 3 + Adreno + MediaCodec + AImageReader + UE 5.7 Vulkan RHI, is it actually possible to obtain non‑compressed linear NV12 for zero‑copy Vulkan sampling, or will the Quest 3 driver always enforce UBWC for Surface decoding?
    If it is possible, which usage flags or MediaCodec settings reliably disable UBWC?