Add tests of expected usages for SharedTextureMemory

This CL adds tests that SharedTextureMemory instances are created with
expected usages for single-planar and multiplanar textures. This will be
helpful for a followup where we extend the set of usages for multiplanar
textures based on the features available on the device.

Bug: 1493854
Change-Id: I88f5a5a998af48bbc223381d6d5438e681dcd616
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/161960
Commit-Queue: Colin Blundell <blundell@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/tests/end2end/SharedTextureMemoryTests.cpp b/src/dawn/tests/end2end/SharedTextureMemoryTests.cpp
index 576e789..521a36e 100644
--- a/src/dawn/tests/end2end/SharedTextureMemoryTests.cpp
+++ b/src/dawn/tests/end2end/SharedTextureMemoryTests.cpp
@@ -390,6 +390,50 @@
     EXPECT_EQ(properties.format, wgpu::TextureFormat::Undefined);
 }
 
+// Tests that a SharedTextureMemory supports expected texture usages.
+TEST_P(SharedTextureMemoryTests, TextureUsages) {
+    for (wgpu::SharedTextureMemory memory :
+         GetParam().mBackend->CreateSharedTextureMemories(device)) {
+        wgpu::SharedTextureMemoryProperties properties;
+        memory.GetProperties(&properties);
+
+        // CopySrc and TextureBinding should always be supported.
+        // TODO(crbug.com/dawn/2262): TextureBinding support on D3D11/D3D12 is actually
+        // dependent on the flags passed to the underlying texture (the relevant
+        // flag is currently always passed in the test context). Add tests where
+        // the D3D texture is not created with the relevant flag.
+        wgpu::TextureUsage expectedUsage =
+            wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding;
+
+        // Additional usages are potentially supported for single-planar
+        // formats.
+        if (!utils::IsMultiPlanarFormat(properties.format)) {
+            expectedUsage |= wgpu::TextureUsage::CopyDst;
+
+            // TODO(crbug.com/dawn/2262): RenderAttachment support on D3D11/D3D12 is
+            // additionally dependent on the flags passed to the underlying
+            // texture (the relevant flag is currently always passed in the test
+            // context). Add tests where the D3D texture is not created with the
+            // relevant flag.
+            if (utils::IsRenderableFormat(device, properties.format)) {
+                expectedUsage |= wgpu::TextureUsage::RenderAttachment;
+            }
+
+            // TODO(crbug.com/dawn/2262): StorageBinding support on D3D11/D3D12 is
+            // additionally dependent on the flags passed to the underlying
+            // texture (the relevant flag is currently always passed in the test
+            // context). Add tests where the D3D texture is not created with the
+            // relevant flag.
+            if (utils::TextureFormatSupportsStorageTexture(properties.format,
+                                                           IsCompatibilityMode())) {
+                expectedUsage |= wgpu::TextureUsage::StorageBinding;
+            }
+        }
+
+        EXPECT_EQ(properties.usage, expectedUsage) << properties.format;
+    }
+}
+
 // Test calling GetProperties with an invalid chained struct. An error is
 // generated, but the properties are still populated.
 TEST_P(SharedTextureMemoryTests, GetPropertiesInvalidChain) {
diff --git a/src/dawn/utils/TextureUtils.cpp b/src/dawn/utils/TextureUtils.cpp
index 9714f7b..5a0a56e 100644
--- a/src/dawn/utils/TextureUtils.cpp
+++ b/src/dawn/utils/TextureUtils.cpp
@@ -189,6 +189,31 @@
     }
 }
 
+bool IsRenderableFormat(const wgpu::Device& device, wgpu::TextureFormat textureFormat) {
+    if (IsBCTextureFormat(textureFormat) || IsETC2TextureFormat(textureFormat) ||
+        IsASTCTextureFormat(textureFormat)) {
+        return false;
+    }
+
+    if (IsNorm16TextureFormat(textureFormat)) {
+        return device.HasFeature(wgpu::FeatureName::Norm16TextureFormats);
+    }
+
+    switch (textureFormat) {
+        case wgpu::TextureFormat::RGB9E5Ufloat:
+        case wgpu::TextureFormat::R8Snorm:
+        case wgpu::TextureFormat::RG8Snorm:
+        case wgpu::TextureFormat::RGBA8Snorm:
+            return false;
+
+        case wgpu::TextureFormat::RG11B10Ufloat:
+            return device.HasFeature(wgpu::FeatureName::RG11B10UfloatRenderable);
+
+        default:
+            return true;
+    }
+}
+
 bool TextureFormatSupportsMultisampling(const wgpu::Device& device,
                                         wgpu::TextureFormat textureFormat) {
     if (IsBCTextureFormat(textureFormat) || IsETC2TextureFormat(textureFormat) ||
diff --git a/src/dawn/utils/TextureUtils.h b/src/dawn/utils/TextureUtils.h
index 4aaa72a..3930151 100644
--- a/src/dawn/utils/TextureUtils.h
+++ b/src/dawn/utils/TextureUtils.h
@@ -280,6 +280,7 @@
 bool IsDepthOrStencilFormat(wgpu::TextureFormat textureFormat);
 
 bool IsMultiPlanarFormat(wgpu::TextureFormat textureFormat);
+bool IsRenderableFormat(const wgpu::Device& device, wgpu::TextureFormat textureFormat);
 
 bool TextureFormatSupportsMultisampling(const wgpu::Device& device,
                                         wgpu::TextureFormat textureFormat);