d3d11: use D3D11_COPY_DISCARD for uploading content to textures

Use D3D11_COPY_DISCARD, if Texture::WriteInternal() writes entire
texture, so the driver can avoid extra copy or CPU & GPU
synchronization.

Bug: chromium:342125324
Change-Id: Ifce4ff3204a809f359f15fc51518007d4ba2c7e4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/190763
Commit-Queue: Peng Huang <penghuang@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/native/d3d11/TextureD3D11.cpp b/src/dawn/native/d3d11/TextureD3D11.cpp
index 2a3afaa..45cab9e 100644
--- a/src/dawn/native/d3d11/TextureD3D11.cpp
+++ b/src/dawn/native/d3d11/TextureD3D11.cpp
@@ -728,14 +728,20 @@
     dstBox.top = origin.y;
     dstBox.bottom = origin.y + size.height;
 
+    bool isCompleteSubresourceCopiedTo =
+        IsCompleteSubresourceCopiedTo(this, size, subresources.baseMipLevel, subresources.aspects);
+    DAWN_ASSERT(subresources.levelCount == 1);
+    bool writeCompleteTexture = isCompleteSubresourceCopiedTo && GetNumMipLevels() == 1 &&
+                                GetArrayLayers() == subresources.layerCount;
+
     if (GetDimension() == wgpu::TextureDimension::e3D) {
         dstBox.front = origin.z;
         dstBox.back = origin.z + size.depthOrArrayLayers;
         uint32_t subresource =
             GetSubresourceIndex(subresources.baseMipLevel, 0, D3D11Aspect(subresources.aspects));
+        UINT copyFlag = writeCompleteTexture ? D3D11_COPY_DISCARD : 0;
         commandContext->UpdateSubresource1(GetD3D11Resource(), subresource, &dstBox, data,
-                                           bytesPerRow, bytesPerRow * rowsPerImage,
-                                           /*CopyFlags=*/0);
+                                           bytesPerRow, bytesPerRow * rowsPerImage, copyFlag);
     } else {
         dstBox.front = 0;
         dstBox.back = 1;
@@ -744,8 +750,9 @@
                 GetSubresourceIndex(subresources.baseMipLevel, subresources.baseArrayLayer + layer,
                                     D3D11Aspect(subresources.aspects));
             D3D11_BOX* pDstBox = GetFormat().HasDepthOrStencil() ? nullptr : &dstBox;
+            UINT copyFlag = (writeCompleteTexture && layer == 0) ? D3D11_COPY_DISCARD : 0;
             commandContext->UpdateSubresource1(GetD3D11Resource(), subresource, pDstBox, data,
-                                               bytesPerRow, 0, /*CopyFlags=*/0);
+                                               bytesPerRow, 0, copyFlag);
             data += rowsPerImage * bytesPerRow;
         }
     }