Unable to wrap nv12 gbm buffer from vaapi decoder into vkimage via VK_EXT_external_memory_dma_buf extension on Intel ChromeOS device
Chromium WebGPU 0-copy video import uses the Gbm buffer to hold the decoded video frame from VAAPI, and then in Dawn it uses the fd, and modifier of the buffer to wrap it into a VkImage via VK_EXT_external_memory_dma_buf extension. The detailed implementation of this Vulkan wrapping in Dawn can be found here.
It actually worked on my Flex(ICL) chromebook, but can’t work now on the Brya(ADL) board(Mesa-Iris 21.2.5). It might be some regressions in Mesa. The Gbm buffer is created in Chromium like this:
uint32_t flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING | GBM_BO_USE_HW_VIDEO_DECODER;
gbm_bo* gbmBo = gbm_bo_create(mGbmDevice, width, height, GBM_FORMAT_NV12, flags);
memoryFD = gbm_bo_get_fd(gbmBo);
drmModifier = gbm_bo_get_modifier(gbmBo);
It's 100% reproducible with the attached test case. The steps to reproduce is simply that:
- scpcros_test.tar.gz to the device, and untar it.
- run "out_amd64-generic/Release/dawn_end2end_tests --gtest_filter=VideoViewsTests.CreateVulkan_Intel" inside the folder.
The output would be:
Click to expand
Warning: loader_scanned_icd_add: Driver /usr/lib64/libvulkan_intel.so supports Vulkan 1.2, but only supports loader interface version 4. Interface version 5 or newer required to support this version of Vulkan (Policy #LDP_DRIVER_7) MESA-INTEL: warning: Performance support disabled, consider sysctl dev.i915.perf_stream_paranoid=0-------- 1 test from VideoViewsTests [ RUN ] VideoViewsTests.CreateVideoTextureWithoutInitializedData/Vulkan_Intel_R_Graphics VkResult:c4641cbd, vkAllocateMemory failed with unknown file: Failure
Unexpected mock function call - returning directly. Function call: Call(0, 0x31de00c5b000 pointing to "vkAllocateMemory failed with \n at CheckVkSuccessImpl (../../third_party/dawn/src/dawn/native/vulkan/VulkanError.cpp:90)\n at ImportMemory (../../third_party/dawn/src/dawn/native/vulkan/external_memory/MemoryServiceDmaBuf.cpp:284)\n at ImportExternalImage (../../third_party/dawn/src/dawn/native/vulkan/DeviceVk.cpp:789)\n", 0x31de009cc000) Google Mock tried the following 1 expectation, but it didn't match:
../../third_party/dawn/src/dawn/tests/DawnTest.cpp:966: EXPECT_CALL(mDeviceLostCallback, Call(WGPUDeviceLostReason_Destroyed, testing::_, device.Get()))... Expected arg #0: is equal to 1 Actual: 0 Expected: to be called at most once Actual: never called - satisfied and active Stack trace: #0 0x5901ae1d79ac testing::internal::GoogleTestFailureReporter::ReportFailure() #1 (closed) 0x5901ae1d9123 testing::internal::UntypedFunctionMockerBase::UntypedInvokeWith() #2 (closed) 0x5901ae03978f testing::internal::MockFunction<>::Call() #3 (closed) 0x5901ae22d3ed dawn::native::DeviceBase::HandleError() #4 (closed) 0x5901ae22d55f dawn::native::DeviceBase::ConsumeError() #5 (closed) 0x5901ae210093 dawn::native::DeviceBase::ConsumedError() #6 (closed) 0x5901ae28df07 dawn::native::vulkan::Device::CreateTextureWrappingVulkanImage() #7 (closed) 0x5901ae1384e1 VideoViewsTestBackendGbm::CreateVideoTextureForTest() #8 (closed) 0x5901ae1354b2 VideoViewsTests_CreateVideoTextureWithoutInitializedData_Test::TestBody()
../../third_party/dawn/src/dawn/tests/end2end/VideoViewsTests.cpp:204: Failure Expected: (platformTexture.get()) != (nullptr), actual: NULL vs (nullptr) Stack trace: #0 0x5901ae135576 VideoViewsTests_CreateVideoTextureWithoutInitializedData_Test::TestBody()
The cause of the failure is this code line in mesa
if (mem->bo->size < aligned_alloc_size) {
result = vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE,
"aligned allocationSize too large for "
"VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: "
"%"PRIu64"B > %"PRIu64"B",
aligned_alloc_size, mem->bo->size);
anv_device_release_bo(device, mem->bo);
goto fail;
}
If the video is 640x360, the mem->bo->size
would be 368640, while aligned_alloc_size
would be 589824.
Probably it is a regression caused by this mesa commit (00dc4e0d)
,but not confirmed and verified.