[SharedTextureMemory] Do per-format restrictions in frontend

This CL eliminates redundancy in the SharedTextureMemory structure by
moving calculation of per-format restrictions on the SharedTextureMemory
usage from the platform-specific backends to the common frontend. The
backends now populate all usages that are supported by the underlying
texture.

Change-Id: Ica1cb777285884bc98c3498f7ec9ed12668b5c0b
Bug: 1493854
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/162269
Commit-Queue: Colin Blundell <blundell@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/dawn/native/SharedTextureMemory.cpp b/src/dawn/native/SharedTextureMemory.cpp
index 9bb3706..bd3be8a 100644
--- a/src/dawn/native/SharedTextureMemory.cpp
+++ b/src/dawn/native/SharedTextureMemory.cpp
@@ -82,13 +82,19 @@
                                                  const char* label,
                                                  const SharedTextureMemoryProperties& properties)
     : ApiObjectBase(device, label), mProperties(properties) {
+    // `properties.usage` contains all usages supported by the underlying
+    // texture. Strip out any not supported for `format`.
     const Format& internalFormat = device->GetValidInternalFormat(properties.format);
-    if (!internalFormat.supportsStorageUsage) {
-        DAWN_ASSERT(!(mProperties.usage & wgpu::TextureUsage::StorageBinding));
+    if (!internalFormat.supportsStorageUsage || internalFormat.IsMultiPlanar()) {
+        mProperties.usage = mProperties.usage & ~wgpu::TextureUsage::StorageBinding;
     }
-    if (!internalFormat.isRenderable) {
-        DAWN_ASSERT(!(mProperties.usage & wgpu::TextureUsage::RenderAttachment));
+    if (!internalFormat.isRenderable || internalFormat.IsMultiPlanar()) {
+        mProperties.usage = mProperties.usage & ~wgpu::TextureUsage::RenderAttachment;
     }
+    if (internalFormat.IsMultiPlanar()) {
+        mProperties.usage = mProperties.usage & ~wgpu::TextureUsage::CopyDst;
+    }
+
     GetObjectTrackingList()->Track(this);
 }
 
diff --git a/src/dawn/native/SharedTextureMemory.h b/src/dawn/native/SharedTextureMemory.h
index 7b3a884..674456e 100644
--- a/src/dawn/native/SharedTextureMemory.h
+++ b/src/dawn/native/SharedTextureMemory.h
@@ -87,7 +87,7 @@
 
     void DestroyImpl() override;
 
-    const SharedTextureMemoryProperties mProperties;
+    SharedTextureMemoryProperties mProperties;
 
     Ref<TextureBase> mCurrentAccess;
 
diff --git a/src/dawn/native/d3d11/SharedTextureMemoryD3D11.cpp b/src/dawn/native/d3d11/SharedTextureMemoryD3D11.cpp
index 56928b0..bc68c46 100644
--- a/src/dawn/native/d3d11/SharedTextureMemoryD3D11.cpp
+++ b/src/dawn/native/d3d11/SharedTextureMemoryD3D11.cpp
@@ -65,29 +65,22 @@
 
     DAWN_TRY_ASSIGN(properties.format, d3d::FromUncompressedColorDXGITextureFormat(desc.Format));
 
-    const Format* internalFormat = nullptr;
-    DAWN_TRY_ASSIGN(internalFormat, device->GetInternalFormat(properties.format));
-
+    // The usages that the underlying D3D11 texture supports are partially
+    // dependent on its creation flags. Note that the SharedTextureMemory
+    // frontend takes care of stripping out any usages that are not supported
+    // for `format`.
     wgpu::TextureUsage textureBindingUsage = (desc.BindFlags & D3D11_BIND_SHADER_RESOURCE)
                                                  ? wgpu::TextureUsage::TextureBinding
                                                  : wgpu::TextureUsage::None;
+    wgpu::TextureUsage storageBindingUsage = (desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS)
+                                                 ? wgpu::TextureUsage::StorageBinding
+                                                 : wgpu::TextureUsage::None;
+    wgpu::TextureUsage renderAttachmentUsage = (desc.BindFlags & D3D11_BIND_RENDER_TARGET)
+                                                   ? wgpu::TextureUsage::RenderAttachment
+                                                   : wgpu::TextureUsage::None;
 
-    wgpu::TextureUsage storageBindingUsage =
-        internalFormat->supportsStorageUsage && (desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS)
-            ? wgpu::TextureUsage::StorageBinding
-            : wgpu::TextureUsage::None;
-
-    wgpu::TextureUsage renderAttachmentUsage =
-        internalFormat->isRenderable && (desc.BindFlags & D3D11_BIND_RENDER_TARGET)
-            ? wgpu::TextureUsage::RenderAttachment
-            : wgpu::TextureUsage::None;
-
-    if (internalFormat->IsMultiPlanar()) {
-        properties.usage = wgpu::TextureUsage::CopySrc | textureBindingUsage;
-    } else {
-        properties.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst |
-                           textureBindingUsage | storageBindingUsage | renderAttachmentUsage;
-    }
+    properties.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst |
+                       textureBindingUsage | storageBindingUsage | renderAttachmentUsage;
     return properties;
 }
 
diff --git a/src/dawn/native/d3d12/SharedTextureMemoryD3D12.cpp b/src/dawn/native/d3d12/SharedTextureMemoryD3D12.cpp
index c14f9f9..77c2692 100644
--- a/src/dawn/native/d3d12/SharedTextureMemoryD3D12.cpp
+++ b/src/dawn/native/d3d12/SharedTextureMemoryD3D12.cpp
@@ -74,27 +74,22 @@
 
     DAWN_TRY_ASSIGN(properties.format, d3d::FromUncompressedColorDXGITextureFormat(desc.Format));
 
-    const Format* internalFormat = nullptr;
-    DAWN_TRY_ASSIGN(internalFormat, device->GetInternalFormat(properties.format));
-
+    // The usages that the underlying D3D12 texture supports are partially
+    // dependent on its creation flags. Note that the SharedTextureMemory
+    // frontend takes care of stripping out any usages that are not supported
+    // for `format`.
     wgpu::TextureUsage storageBindingUsage =
-        internalFormat->supportsStorageUsage &&
-                (desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
+        (desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
             ? wgpu::TextureUsage::StorageBinding
             : wgpu::TextureUsage::None;
-
     wgpu::TextureUsage renderAttachmentUsage =
-        internalFormat->isRenderable && (desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET)
+        (desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET)
             ? wgpu::TextureUsage::RenderAttachment
             : wgpu::TextureUsage::None;
 
-    if (internalFormat->IsMultiPlanar()) {
-        properties.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding;
-    } else {
-        properties.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst |
-                           wgpu::TextureUsage::TextureBinding | storageBindingUsage |
-                           renderAttachmentUsage;
-    }
+    properties.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst |
+                       wgpu::TextureUsage::TextureBinding | storageBindingUsage |
+                       renderAttachmentUsage;
 
     auto result =
         AcquireRef(new SharedTextureMemory(device, label, properties, std::move(d3d12Resource)));
diff --git a/src/dawn/native/metal/SharedTextureMemoryMTL.mm b/src/dawn/native/metal/SharedTextureMemoryMTL.mm
index 6860dd0..7545253 100644
--- a/src/dawn/native/metal/SharedTextureMemoryMTL.mm
+++ b/src/dawn/native/metal/SharedTextureMemoryMTL.mm
@@ -85,9 +85,6 @@
     DAWN_TRY_ASSIGN(format,
                     GetFormatEquivalentToIOSurfaceFormat(IOSurfaceGetPixelFormat(ioSurface)));
 
-    const Format* internalFormat = nullptr;
-    DAWN_TRY_ASSIGN(internalFormat, device->GetInternalFormat(format));
-
     size_t width = IOSurfaceGetWidth(ioSurface);
     size_t height = IOSurfaceGetHeight(ioSurface);
 
@@ -100,18 +97,15 @@
                     "IOSurface height (%u) exceeds maxTextureDimension2D (%u).", height,
                     limits.v1.maxTextureDimension2D);
 
+    // IO surfaces support the following usages (the SharedTextureMemory frontend strips
+    // out any usages that are not supported by `format`).
+    const wgpu::TextureUsage kIOSurfaceSupportedUsages =
+        wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst |
+        wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::StorageBinding |
+        wgpu::TextureUsage::RenderAttachment;
+
     SharedTextureMemoryProperties properties;
-    if (internalFormat->IsMultiPlanar()) {
-        properties.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding;
-    } else {
-        properties.usage =
-            wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst |
-            wgpu::TextureUsage::TextureBinding |
-            (internalFormat->supportsStorageUsage ? wgpu::TextureUsage::StorageBinding
-                                                  : wgpu::TextureUsage::None) |
-            (internalFormat->isRenderable ? wgpu::TextureUsage::RenderAttachment
-                                          : wgpu::TextureUsage::None);
-    }
+    properties.usage = kIOSurfaceSupportedUsages;
     properties.format = format;
     properties.size = {static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1};