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 <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Jie A Chen <jie.a.chen@intel.com>
This commit is contained in:
jchen10 2022-05-24 03:01:15 +00:00 committed by Dawn LUCI CQ
parent 136a0a4269
commit c45f11ddb5
5 changed files with 64 additions and 31 deletions

View File

@ -194,13 +194,25 @@ wgpu::ShaderModule VideoViewsTests::GetTestVertexShaderModule() const {
})"); })");
} }
// Create video texture uninitialized.
TEST_P(VideoViewsTests, CreateVideoTextureWithoutInitializedData) {
std::unique_ptr<VideoViewsTestBackend::PlatformTexture> 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 // 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. // output attachment and checks for the expected pixel value in the rendered quad.
TEST_P(VideoViewsTests, NV12SampleYtoR) { TEST_P(VideoViewsTests, NV12SampleYtoR) {
std::unique_ptr<VideoViewsTestBackend::PlatformTexture> platformTexture = std::unique_ptr<VideoViewsTestBackend::PlatformTexture> platformTexture =
mBackend->CreateVideoTextureForTest(wgpu::TextureFormat::R8BG8Biplanar420Unorm, mBackend->CreateVideoTextureForTest(wgpu::TextureFormat::R8BG8Biplanar420Unorm,
wgpu::TextureUsage::TextureBinding, wgpu::TextureUsage::TextureBinding,
/*isCheckerboard*/ false); /*isCheckerboard*/ false,
/*initialized*/ true);
ASSERT_NE(platformTexture.get(), nullptr); ASSERT_NE(platformTexture.get(), nullptr);
if (!platformTexture->CanWrapAsWGPUTexture()) { if (!platformTexture->CanWrapAsWGPUTexture()) {
mBackend->DestroyVideoTextureForTest(std::move(platformTexture)); mBackend->DestroyVideoTextureForTest(std::move(platformTexture));
@ -257,7 +269,8 @@ TEST_P(VideoViewsTests, NV12SampleUVtoRG) {
std::unique_ptr<VideoViewsTestBackend::PlatformTexture> platformTexture = std::unique_ptr<VideoViewsTestBackend::PlatformTexture> platformTexture =
mBackend->CreateVideoTextureForTest(wgpu::TextureFormat::R8BG8Biplanar420Unorm, mBackend->CreateVideoTextureForTest(wgpu::TextureFormat::R8BG8Biplanar420Unorm,
wgpu::TextureUsage::TextureBinding, wgpu::TextureUsage::TextureBinding,
/*isCheckerboard*/ false); /*isCheckerboard*/ false,
/*initialized*/ true);
ASSERT_NE(platformTexture.get(), nullptr); ASSERT_NE(platformTexture.get(), nullptr);
if (!platformTexture->CanWrapAsWGPUTexture()) { if (!platformTexture->CanWrapAsWGPUTexture()) {
mBackend->DestroyVideoTextureForTest(std::move(platformTexture)); mBackend->DestroyVideoTextureForTest(std::move(platformTexture));
@ -320,7 +333,8 @@ TEST_P(VideoViewsTests, NV12SampleYUVtoRGB) {
std::unique_ptr<VideoViewsTestBackend::PlatformTexture> platformTexture = std::unique_ptr<VideoViewsTestBackend::PlatformTexture> platformTexture =
mBackend->CreateVideoTextureForTest(wgpu::TextureFormat::R8BG8Biplanar420Unorm, mBackend->CreateVideoTextureForTest(wgpu::TextureFormat::R8BG8Biplanar420Unorm,
wgpu::TextureUsage::TextureBinding, wgpu::TextureUsage::TextureBinding,
/*isCheckerboard*/ true); /*isCheckerboard*/ true,
/*initialized*/ true);
ASSERT_NE(platformTexture.get(), nullptr); ASSERT_NE(platformTexture.get(), nullptr);
if (!platformTexture->CanWrapAsWGPUTexture()) { if (!platformTexture->CanWrapAsWGPUTexture()) {
mBackend->DestroyVideoTextureForTest(std::move(platformTexture)); mBackend->DestroyVideoTextureForTest(std::move(platformTexture));

View File

@ -46,7 +46,8 @@ class VideoViewsTestBackend {
}; };
virtual std::unique_ptr<PlatformTexture> CreateVideoTextureForTest(wgpu::TextureFormat format, virtual std::unique_ptr<PlatformTexture> CreateVideoTextureForTest(wgpu::TextureFormat format,
wgpu::TextureUsage usage, wgpu::TextureUsage usage,
bool isCheckerboard) = 0; bool isCheckerboard,
bool initialized) = 0;
virtual void DestroyVideoTextureForTest(std::unique_ptr<PlatformTexture>&& platformTexture) = 0; virtual void DestroyVideoTextureForTest(std::unique_ptr<PlatformTexture>&& platformTexture) = 0;
}; };

View File

@ -125,9 +125,17 @@ class VideoViewsTestBackendGbm : public VideoViewsTestBackend {
std::unique_ptr<VideoViewsTestBackend::PlatformTexture> CreateVideoTextureForTest( std::unique_ptr<VideoViewsTestBackend::PlatformTexture> CreateVideoTextureForTest(
wgpu::TextureFormat format, wgpu::TextureFormat format,
wgpu::TextureUsage usage, wgpu::TextureUsage usage,
bool isCheckerboard) override { bool isCheckerboard,
uint32_t flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING | GBM_BO_USE_HW_VIDEO_DECODER | bool initialized) override {
GBM_BO_USE_SW_WRITE_RARELY; // 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, gbm_bo* gbmBo = gbm_bo_create(mGbmDevice, VideoViewsTests::kYUVImageDataWidthInTexels,
VideoViewsTests::kYUVImageDataHeightInTexels, VideoViewsTests::kYUVImageDataHeightInTexels,
GetGbmBoFormat(format), flags); GetGbmBoFormat(format), flags);
@ -135,17 +143,19 @@ class VideoViewsTestBackendGbm : public VideoViewsTestBackend {
return nullptr; return nullptr;
} }
void* mapHandle = nullptr; if (initialized) {
uint32_t strideBytes = 0; void* mapHandle = nullptr;
void* addr = gbm_bo_map(gbmBo, 0, 0, VideoViewsTests::kYUVImageDataWidthInTexels, uint32_t strideBytes = 0;
VideoViewsTests::kYUVImageDataHeightInTexels, GBM_BO_TRANSFER_WRITE, void* addr = gbm_bo_map(gbmBo, 0, 0, VideoViewsTests::kYUVImageDataWidthInTexels,
&strideBytes, &mapHandle); VideoViewsTests::kYUVImageDataHeightInTexels,
EXPECT_NE(addr, nullptr); GBM_BO_TRANSFER_WRITE, &strideBytes, &mapHandle);
std::vector<uint8_t> initialData = EXPECT_NE(addr, nullptr);
VideoViewsTests::GetTestTextureData(format, isCheckerboard); std::vector<uint8_t> initialData =
std::memcpy(addr, initialData.data(), initialData.size()); VideoViewsTests::GetTestTextureData(format, isCheckerboard);
std::memcpy(addr, initialData.data(), initialData.size());
gbm_bo_unmap(gbmBo, mapHandle); gbm_bo_unmap(gbmBo, mapHandle);
}
wgpu::TextureDescriptor textureDesc; wgpu::TextureDescriptor textureDesc;
textureDesc.format = format; textureDesc.format = format;
@ -168,9 +178,12 @@ class VideoViewsTestBackendGbm : public VideoViewsTestBackend {
descriptor.drmModifier = gbm_bo_get_modifier(gbmBo); descriptor.drmModifier = gbm_bo_get_modifier(gbmBo);
descriptor.waitFDs = {}; descriptor.waitFDs = {};
return std::make_unique<PlatformTextureGbm>( WGPUTexture texture = dawn::native::vulkan::WrapVulkanImage(mWGPUDevice, &descriptor);
wgpu::Texture::Acquire(dawn::native::vulkan::WrapVulkanImage(mWGPUDevice, &descriptor)), if (texture != nullptr) {
gbmBo); return std::make_unique<PlatformTextureGbm>(wgpu::Texture::Acquire(texture), gbmBo);
} else {
return nullptr;
}
} }
void DestroyVideoTextureForTest( void DestroyVideoTextureForTest(

View File

@ -86,7 +86,8 @@ class VideoViewsTestBackendIOSurface : public VideoViewsTestBackend {
std::unique_ptr<VideoViewsTestBackend::PlatformTexture> CreateVideoTextureForTest( std::unique_ptr<VideoViewsTestBackend::PlatformTexture> CreateVideoTextureForTest(
wgpu::TextureFormat format, wgpu::TextureFormat format,
wgpu::TextureUsage usage, wgpu::TextureUsage usage,
bool isCheckerboard) override { bool isCheckerboard,
bool initialized) override {
CFMutableDictionaryRef dict(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, CFMutableDictionaryRef dict(CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks)); &kCFTypeDictionaryValueCallBacks));
@ -134,15 +135,17 @@ class VideoViewsTestBackendIOSurface : public VideoViewsTestBackend {
IOSurfaceRef surface = IOSurfaceCreate(dict); IOSurfaceRef surface = IOSurfaceCreate(dict);
CFRelease(dict); CFRelease(dict);
IOSurfaceLock(surface, 0, nullptr); if (initialized) {
for (size_t plane = 0; plane < num_planes; ++plane) { IOSurfaceLock(surface, 0, nullptr);
std::vector<uint8_t> data = VideoViewsTests::GetTestTextureDataWithPlaneIndex( for (size_t plane = 0; plane < num_planes; ++plane) {
plane, IOSurfaceGetBytesPerRowOfPlane(surface, plane), std::vector<uint8_t> data = VideoViewsTests::GetTestTextureDataWithPlaneIndex(
IOSurfaceGetHeightOfPlane(surface, plane), isCheckerboard); plane, IOSurfaceGetBytesPerRowOfPlane(surface, plane),
void* pointer = IOSurfaceGetBaseAddressOfPlane(surface, plane); IOSurfaceGetHeightOfPlane(surface, plane), isCheckerboard);
memcpy(pointer, data.data(), data.size()); void* pointer = IOSurfaceGetBaseAddressOfPlane(surface, plane);
memcpy(pointer, data.data(), data.size());
}
IOSurfaceUnlock(surface, 0, nullptr);
} }
IOSurfaceUnlock(surface, 0, nullptr);
wgpu::TextureDescriptor textureDesc; wgpu::TextureDescriptor textureDesc;
textureDesc.format = format; textureDesc.format = format;

View File

@ -90,7 +90,8 @@ class VideoViewsTestBackendWin : public VideoViewsTestBackend {
std::unique_ptr<VideoViewsTestBackend::PlatformTexture> CreateVideoTextureForTest( std::unique_ptr<VideoViewsTestBackend::PlatformTexture> CreateVideoTextureForTest(
wgpu::TextureFormat format, wgpu::TextureFormat format,
wgpu::TextureUsage usage, wgpu::TextureUsage usage,
bool isCheckerboard) override { bool isCheckerboard,
bool initialized) override {
wgpu::TextureDescriptor textureDesc; wgpu::TextureDescriptor textureDesc;
textureDesc.format = format; textureDesc.format = format;
textureDesc.dimension = wgpu::TextureDimension::e2D; textureDesc.dimension = wgpu::TextureDimension::e2D;
@ -121,7 +122,8 @@ class VideoViewsTestBackendWin : public VideoViewsTestBackend {
subres.SysMemPitch = VideoViewsTests::kYUVImageDataWidthInTexels; subres.SysMemPitch = VideoViewsTests::kYUVImageDataWidthInTexels;
ComPtr<ID3D11Texture2D> d3d11Texture; ComPtr<ID3D11Texture2D> d3d11Texture;
HRESULT hr = mD3d11Device->CreateTexture2D(&d3dDescriptor, &subres, &d3d11Texture); HRESULT hr = mD3d11Device->CreateTexture2D(
&d3dDescriptor, (initialized ? &subres : nullptr), &d3d11Texture);
ASSERT(hr == S_OK); ASSERT(hr == S_OK);
ComPtr<IDXGIResource1> dxgiResource; ComPtr<IDXGIResource1> dxgiResource;