From c45f11ddb539f095c74d3a7acffb530ad9b1169d Mon Sep 17 00:00:00 2001 From: jchen10 Date: Tue, 24 May 2022 03:01:15 +0000 Subject: [PATCH] Add VideoViewsTests.CreateVideoTextureWithoutInitializedData Chromium creates gbm_bo buffers without the GBM_BO_USE_SW_WRITE_RARELY flag to hold the video frames from VAAPI decoder. The added case could better cover this and catch the recent mesa regression: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5940 Bug: chromium:1258986 Change-Id: Ib8313b35fe90928aae03791560d80fdb47bcea32 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/91081 Reviewed-by: Austin Eng Kokoro: Kokoro Commit-Queue: Jie A Chen --- src/dawn/tests/end2end/VideoViewsTests.cpp | 20 +++++++-- src/dawn/tests/end2end/VideoViewsTests.h | 3 +- .../tests/end2end/VideoViewsTests_gbm.cpp | 45 ++++++++++++------- .../tests/end2end/VideoViewsTests_mac.cpp | 21 +++++---- .../tests/end2end/VideoViewsTests_win.cpp | 6 ++- 5 files changed, 64 insertions(+), 31 deletions(-) diff --git a/src/dawn/tests/end2end/VideoViewsTests.cpp b/src/dawn/tests/end2end/VideoViewsTests.cpp index 32666db667..3e937c1d9c 100644 --- a/src/dawn/tests/end2end/VideoViewsTests.cpp +++ b/src/dawn/tests/end2end/VideoViewsTests.cpp @@ -194,13 +194,25 @@ wgpu::ShaderModule VideoViewsTests::GetTestVertexShaderModule() const { })"); } +// Create video texture uninitialized. +TEST_P(VideoViewsTests, CreateVideoTextureWithoutInitializedData) { + std::unique_ptr platformTexture = + mBackend->CreateVideoTextureForTest(wgpu::TextureFormat::R8BG8Biplanar420Unorm, + wgpu::TextureUsage::TextureBinding, + /*isCheckerboard*/ false, + /*initialized*/ false); + ASSERT_NE(platformTexture.get(), nullptr); + mBackend->DestroyVideoTextureForTest(std::move(platformTexture)); +} + // Samples the luminance (Y) plane from an imported NV12 texture into a single channel of an RGBA // output attachment and checks for the expected pixel value in the rendered quad. TEST_P(VideoViewsTests, NV12SampleYtoR) { std::unique_ptr platformTexture = mBackend->CreateVideoTextureForTest(wgpu::TextureFormat::R8BG8Biplanar420Unorm, wgpu::TextureUsage::TextureBinding, - /*isCheckerboard*/ false); + /*isCheckerboard*/ false, + /*initialized*/ true); ASSERT_NE(platformTexture.get(), nullptr); if (!platformTexture->CanWrapAsWGPUTexture()) { mBackend->DestroyVideoTextureForTest(std::move(platformTexture)); @@ -257,7 +269,8 @@ TEST_P(VideoViewsTests, NV12SampleUVtoRG) { std::unique_ptr platformTexture = mBackend->CreateVideoTextureForTest(wgpu::TextureFormat::R8BG8Biplanar420Unorm, wgpu::TextureUsage::TextureBinding, - /*isCheckerboard*/ false); + /*isCheckerboard*/ false, + /*initialized*/ true); ASSERT_NE(platformTexture.get(), nullptr); if (!platformTexture->CanWrapAsWGPUTexture()) { mBackend->DestroyVideoTextureForTest(std::move(platformTexture)); @@ -320,7 +333,8 @@ TEST_P(VideoViewsTests, NV12SampleYUVtoRGB) { std::unique_ptr platformTexture = mBackend->CreateVideoTextureForTest(wgpu::TextureFormat::R8BG8Biplanar420Unorm, wgpu::TextureUsage::TextureBinding, - /*isCheckerboard*/ true); + /*isCheckerboard*/ true, + /*initialized*/ true); ASSERT_NE(platformTexture.get(), nullptr); if (!platformTexture->CanWrapAsWGPUTexture()) { mBackend->DestroyVideoTextureForTest(std::move(platformTexture)); diff --git a/src/dawn/tests/end2end/VideoViewsTests.h b/src/dawn/tests/end2end/VideoViewsTests.h index e614fea9f3..cf2a6bb28d 100644 --- a/src/dawn/tests/end2end/VideoViewsTests.h +++ b/src/dawn/tests/end2end/VideoViewsTests.h @@ -46,7 +46,8 @@ class VideoViewsTestBackend { }; virtual std::unique_ptr CreateVideoTextureForTest(wgpu::TextureFormat format, wgpu::TextureUsage usage, - bool isCheckerboard) = 0; + bool isCheckerboard, + bool initialized) = 0; virtual void DestroyVideoTextureForTest(std::unique_ptr&& platformTexture) = 0; }; diff --git a/src/dawn/tests/end2end/VideoViewsTests_gbm.cpp b/src/dawn/tests/end2end/VideoViewsTests_gbm.cpp index 4a7b81fb82..bc9b903b16 100644 --- a/src/dawn/tests/end2end/VideoViewsTests_gbm.cpp +++ b/src/dawn/tests/end2end/VideoViewsTests_gbm.cpp @@ -125,9 +125,17 @@ class VideoViewsTestBackendGbm : public VideoViewsTestBackend { std::unique_ptr CreateVideoTextureForTest( wgpu::TextureFormat format, wgpu::TextureUsage usage, - bool isCheckerboard) override { - uint32_t flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING | GBM_BO_USE_HW_VIDEO_DECODER | - GBM_BO_USE_SW_WRITE_RARELY; + bool isCheckerboard, + bool initialized) override { + // The flags Chromium is using for the VAAPI decoder. + uint32_t flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING | GBM_BO_USE_HW_VIDEO_DECODER; + if (initialized) { + // The flag specifically used for tests, which need to initialize the GBM buffer with + // the expected raw video data via CPU, and then sample and draw the buffer via GPU. + // With the flag added, the buffer's drm modifier will be DRM_FORMAT_MOD_LINEAR instead + // of I915_FORMAT_MOD_Y_TILED. + flags |= GBM_BO_USE_SW_WRITE_RARELY; + } gbm_bo* gbmBo = gbm_bo_create(mGbmDevice, VideoViewsTests::kYUVImageDataWidthInTexels, VideoViewsTests::kYUVImageDataHeightInTexels, GetGbmBoFormat(format), flags); @@ -135,17 +143,19 @@ class VideoViewsTestBackendGbm : public VideoViewsTestBackend { return nullptr; } - void* mapHandle = nullptr; - uint32_t strideBytes = 0; - void* addr = gbm_bo_map(gbmBo, 0, 0, VideoViewsTests::kYUVImageDataWidthInTexels, - VideoViewsTests::kYUVImageDataHeightInTexels, GBM_BO_TRANSFER_WRITE, - &strideBytes, &mapHandle); - EXPECT_NE(addr, nullptr); - std::vector initialData = - VideoViewsTests::GetTestTextureData(format, isCheckerboard); - std::memcpy(addr, initialData.data(), initialData.size()); + if (initialized) { + void* mapHandle = nullptr; + uint32_t strideBytes = 0; + void* addr = gbm_bo_map(gbmBo, 0, 0, VideoViewsTests::kYUVImageDataWidthInTexels, + VideoViewsTests::kYUVImageDataHeightInTexels, + GBM_BO_TRANSFER_WRITE, &strideBytes, &mapHandle); + EXPECT_NE(addr, nullptr); + std::vector initialData = + VideoViewsTests::GetTestTextureData(format, isCheckerboard); + std::memcpy(addr, initialData.data(), initialData.size()); - gbm_bo_unmap(gbmBo, mapHandle); + gbm_bo_unmap(gbmBo, mapHandle); + } wgpu::TextureDescriptor textureDesc; textureDesc.format = format; @@ -168,9 +178,12 @@ class VideoViewsTestBackendGbm : public VideoViewsTestBackend { descriptor.drmModifier = gbm_bo_get_modifier(gbmBo); descriptor.waitFDs = {}; - return std::make_unique( - wgpu::Texture::Acquire(dawn::native::vulkan::WrapVulkanImage(mWGPUDevice, &descriptor)), - gbmBo); + WGPUTexture texture = dawn::native::vulkan::WrapVulkanImage(mWGPUDevice, &descriptor); + if (texture != nullptr) { + return std::make_unique(wgpu::Texture::Acquire(texture), gbmBo); + } else { + return nullptr; + } } void DestroyVideoTextureForTest( diff --git a/src/dawn/tests/end2end/VideoViewsTests_mac.cpp b/src/dawn/tests/end2end/VideoViewsTests_mac.cpp index c7f480efea..d23cc1355c 100644 --- a/src/dawn/tests/end2end/VideoViewsTests_mac.cpp +++ b/src/dawn/tests/end2end/VideoViewsTests_mac.cpp @@ -86,7 +86,8 @@ class VideoViewsTestBackendIOSurface : public VideoViewsTestBackend { std::unique_ptr CreateVideoTextureForTest( wgpu::TextureFormat format, wgpu::TextureUsage usage, - bool isCheckerboard) override { + bool isCheckerboard, + bool initialized) override { CFMutableDictionaryRef dict(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); @@ -134,15 +135,17 @@ class VideoViewsTestBackendIOSurface : public VideoViewsTestBackend { IOSurfaceRef surface = IOSurfaceCreate(dict); CFRelease(dict); - IOSurfaceLock(surface, 0, nullptr); - for (size_t plane = 0; plane < num_planes; ++plane) { - std::vector data = VideoViewsTests::GetTestTextureDataWithPlaneIndex( - plane, IOSurfaceGetBytesPerRowOfPlane(surface, plane), - IOSurfaceGetHeightOfPlane(surface, plane), isCheckerboard); - void* pointer = IOSurfaceGetBaseAddressOfPlane(surface, plane); - memcpy(pointer, data.data(), data.size()); + if (initialized) { + IOSurfaceLock(surface, 0, nullptr); + for (size_t plane = 0; plane < num_planes; ++plane) { + std::vector data = VideoViewsTests::GetTestTextureDataWithPlaneIndex( + plane, IOSurfaceGetBytesPerRowOfPlane(surface, plane), + IOSurfaceGetHeightOfPlane(surface, plane), isCheckerboard); + void* pointer = IOSurfaceGetBaseAddressOfPlane(surface, plane); + memcpy(pointer, data.data(), data.size()); + } + IOSurfaceUnlock(surface, 0, nullptr); } - IOSurfaceUnlock(surface, 0, nullptr); wgpu::TextureDescriptor textureDesc; textureDesc.format = format; diff --git a/src/dawn/tests/end2end/VideoViewsTests_win.cpp b/src/dawn/tests/end2end/VideoViewsTests_win.cpp index a402deec5e..45991dd5ab 100644 --- a/src/dawn/tests/end2end/VideoViewsTests_win.cpp +++ b/src/dawn/tests/end2end/VideoViewsTests_win.cpp @@ -90,7 +90,8 @@ class VideoViewsTestBackendWin : public VideoViewsTestBackend { std::unique_ptr CreateVideoTextureForTest( wgpu::TextureFormat format, wgpu::TextureUsage usage, - bool isCheckerboard) override { + bool isCheckerboard, + bool initialized) override { wgpu::TextureDescriptor textureDesc; textureDesc.format = format; textureDesc.dimension = wgpu::TextureDimension::e2D; @@ -121,7 +122,8 @@ class VideoViewsTestBackendWin : public VideoViewsTestBackend { subres.SysMemPitch = VideoViewsTests::kYUVImageDataWidthInTexels; ComPtr d3d11Texture; - HRESULT hr = mD3d11Device->CreateTexture2D(&d3dDescriptor, &subres, &d3d11Texture); + HRESULT hr = mD3d11Device->CreateTexture2D( + &d3dDescriptor, (initialized ? &subres : nullptr), &d3d11Texture); ASSERT(hr == S_OK); ComPtr dxgiResource;