Direct3D: More interface changes to support mipmap generation.

Adds aliasing barriers, a texture copy convenience routine, and
subresource support in texture resource state transitions. Also
some minor formatting cleanup.

Change-Id: Ic8ba504350a3f954a21d24a214d9cceb3f5fc44d
Bug: skia:10446
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/403600
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/d3d/GrD3DCommandList.cpp b/src/gpu/d3d/GrD3DCommandList.cpp
index 3370787..e27a9ba 100644
--- a/src/gpu/d3d/GrD3DCommandList.cpp
+++ b/src/gpu/d3d/GrD3DCommandList.cpp
@@ -125,6 +125,27 @@
     }
 }
 
+void GrD3DCommandList::aliasingBarrier(sk_sp<GrManagedResource> beforeManagedResource,
+                                       ID3D12Resource* beforeResource,
+                                       sk_sp<GrManagedResource> afterManagedResource,
+                                       ID3D12Resource* afterResource) {
+    SkASSERT(fIsActive);
+    // D3D will apply barriers in order so we can just add onto the end
+    D3D12_RESOURCE_BARRIER& newBarrier = fResourceBarriers.push_back();
+    newBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING;
+    newBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
+    newBarrier.Aliasing.pResourceBefore = beforeResource;
+    newBarrier.Aliasing.pResourceAfter = afterResource;
+
+    fHasWork = true;
+    // Aliasing barriers can accept a null pointer for one of the resources,
+    // but at this point we're not using that feature.
+    SkASSERT(beforeManagedResource);
+    this->addResource(std::move(beforeManagedResource));
+    SkASSERT(afterManagedResource);
+    this->addResource(std::move(afterManagedResource));
+}
+
 void GrD3DCommandList::submitResourceBarriers() {
     SkASSERT(fIsActive);
 
@@ -190,6 +211,38 @@
     fCommandList->CopyTextureRegion(dstLocation, dstX, dstY, 0, srcLocation, srcBox);
 }
 
+
+void GrD3DCommandList::copyTextureToTexture(const GrD3DTexture* dst, const GrD3DTexture* src,
+                                            UINT subresourceIndex) {
+    SkASSERT(fIsActive);
+    SkASSERT(src);
+    SkASSERT(dst);
+    SkASSERT(src->width() == dst->width() && src->height() == dst->height());
+
+    this->addingWork();
+    ID3D12Resource* dstTexture = dst->d3dResource();
+    ID3D12Resource* srcTexture = src->d3dResource();
+    if (subresourceIndex == (UINT)-1) {
+        fCommandList->CopyResource(dstTexture, srcTexture);
+    } else {
+        SkASSERT(subresourceIndex < src->mipLevels() &&
+                 subresourceIndex < dst->mipLevels());
+        D3D12_TEXTURE_COPY_LOCATION srcLoc = {};
+        srcLoc.pResource = srcTexture;
+        srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
+        srcLoc.SubresourceIndex = subresourceIndex;
+
+        D3D12_TEXTURE_COPY_LOCATION dstLoc = {};
+        dstLoc.pResource = dstTexture;
+        dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
+        dstLoc.SubresourceIndex = subresourceIndex;
+
+        fCommandList->CopyTextureRegion(&dstLoc, 0, 0, 0, &srcLoc, nullptr);
+    }
+    this->addResource(dst->resource());
+    this->addResource(src->resource());
+}
+
 void GrD3DCommandList::copyBufferToBuffer(sk_sp<GrD3DBuffer> dst, uint64_t dstOffset,
                                           ID3D12Resource* srcBuffer, uint64_t srcOffset,
                                           uint64_t numBytes) {
diff --git a/src/gpu/d3d/GrD3DCommandList.h b/src/gpu/d3d/GrD3DCommandList.h
index 1bd23b4..597c903 100644
--- a/src/gpu/d3d/GrD3DCommandList.h
+++ b/src/gpu/d3d/GrD3DCommandList.h
@@ -57,6 +57,11 @@
     void uavBarrier(sk_sp<GrManagedResource> managedResource,
                     ID3D12Resource* uavResource);
 
+    void aliasingBarrier(sk_sp<GrManagedResource> beforeManagedResource,
+                         ID3D12Resource* beforeResource,
+                         sk_sp<GrManagedResource> afterManagedResource,
+                         ID3D12Resource* afterResource);
+
     // Helper method that calls copyTextureRegion multiple times, once for each subresource
     // The srcBuffer comes from a staging buffer so we don't need to take any refs to it. Instead,
     // we ref the whole buffer during sumbit.
@@ -81,6 +86,10 @@
                                     const D3D12_TEXTURE_COPY_LOCATION* srcLocation,
                                     const D3D12_BOX* srcBox);
 
+     void copyTextureToTexture(const GrD3DTexture* dst,
+                               const GrD3DTexture* src,
+                               UINT subresourceIndex = -1);
+
     // We don't take a ref to the src buffer because we assume the src buffer is coming from a
     // staging buffer which will get ref'd during submit.
     void copyBufferToBuffer(sk_sp<GrD3DBuffer> dstBuffer, uint64_t dstOffset,
diff --git a/src/gpu/d3d/GrD3DDescriptorTableManager.cpp b/src/gpu/d3d/GrD3DDescriptorTableManager.cpp
index 9abd90f..ec2ff19 100644
--- a/src/gpu/d3d/GrD3DDescriptorTableManager.cpp
+++ b/src/gpu/d3d/GrD3DDescriptorTableManager.cpp
@@ -14,8 +14,7 @@
     , fSamplerDescriptorPool(gpu, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) {}
 
 sk_sp<GrD3DDescriptorTable>
-        GrD3DDescriptorTableManager::createShaderViewTable(GrD3DGpu* gpu,
-                                                                         unsigned int size) {
+        GrD3DDescriptorTableManager::createShaderViewTable(GrD3DGpu* gpu, unsigned int size) {
     sk_sp<GrD3DDescriptorTable> table = fShaderViewDescriptorPool.allocateTable(gpu, size);
     this->setHeaps(gpu);
     return table;
diff --git a/src/gpu/d3d/GrD3DRootSignature.cpp b/src/gpu/d3d/GrD3DRootSignature.cpp
index 65ea500..7a13ae2 100644
--- a/src/gpu/d3d/GrD3DRootSignature.cpp
+++ b/src/gpu/d3d/GrD3DRootSignature.cpp
@@ -40,7 +40,7 @@
             samplerRanges[i].RegisterSpace = GrSPIRVUniformHandler::kSamplerTextureDescriptorSet;
             // In the descriptor table the descriptors will all be contiguous.
             samplerRanges[i].OffsetInDescriptorsFromTableStart =
-                D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
+                    D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
 
             shaderViewRanges[i].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
             shaderViewRanges[i].NumDescriptors = 1;
@@ -49,7 +49,7 @@
             shaderViewRanges[i].RegisterSpace = GrSPIRVUniformHandler::kSamplerTextureDescriptorSet;
             // In the descriptor table the descriptors will all be contiguous.
             shaderViewRanges[i].OffsetInDescriptorsFromTableStart =
-                D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
+                    D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
         }
     }
     if (numUAVs) {
@@ -60,10 +60,10 @@
         shaderViewRanges[numTextureSamplers].BaseShaderRegister = 2 * numTextureSamplers;
         // We share texture descriptor set
         shaderViewRanges[numTextureSamplers].RegisterSpace =
-            GrSPIRVUniformHandler::kSamplerTextureDescriptorSet;
+                GrSPIRVUniformHandler::kSamplerTextureDescriptorSet;
         // In the descriptor table the descriptors will all be contiguous.
         shaderViewRanges[numTextureSamplers].OffsetInDescriptorsFromTableStart =
-            D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
+                D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
     }
 
     if (numShaderViews) {
diff --git a/src/gpu/d3d/GrD3DTextureResource.cpp b/src/gpu/d3d/GrD3DTextureResource.cpp
index 3f3439b..8a835f6 100644
--- a/src/gpu/d3d/GrD3DTextureResource.cpp
+++ b/src/gpu/d3d/GrD3DTextureResource.cpp
@@ -11,7 +11,8 @@
 #include "src/gpu/d3d/GrD3DTextureResource.h"
 
 void GrD3DTextureResource::setResourceState(const GrD3DGpu* gpu,
-                                            D3D12_RESOURCE_STATES newResourceState) {
+                                            D3D12_RESOURCE_STATES newResourceState,
+                                            unsigned int subresource) {
     D3D12_RESOURCE_STATES currentResourceState = this->currentState();
     if (newResourceState == currentResourceState) {
         return;
@@ -19,7 +20,7 @@
 
     D3D12_RESOURCE_TRANSITION_BARRIER barrier;
     barrier.pResource = this->d3dResource();
-    barrier.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
+    barrier.Subresource = subresource;
     barrier.StateBefore = currentResourceState;
     barrier.StateAfter = newResourceState;
     gpu->addResourceBarriers(this->resource(), 1, &barrier);
diff --git a/src/gpu/d3d/GrD3DTextureResource.h b/src/gpu/d3d/GrD3DTextureResource.h
index 37ee930..c104daa 100644
--- a/src/gpu/d3d/GrD3DTextureResource.h
+++ b/src/gpu/d3d/GrD3DTextureResource.h
@@ -51,7 +51,8 @@
         return fState->getResourceState();
     }
 
-    void setResourceState(const GrD3DGpu* gpu, D3D12_RESOURCE_STATES newResourceState);
+    void setResourceState(const GrD3DGpu* gpu, D3D12_RESOURCE_STATES newResourceState,
+                          unsigned int subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES);
 
     // Changes the layout to present
     void prepareForPresent(GrD3DGpu* gpu);