Factor PassResourceUsageTracker to its own file

GPURenderBundleEncoder and GPUCommandEncoder will need to share code
for tracking resource usages.

Bug: dawn:154
Change-Id: I0286f71c4c0638f89be2754c8e9691e67e5db335
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/9700
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index b07b3b1..aed63b1 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -154,6 +154,8 @@
     "src/dawn_native/ObjectBase.cpp",
     "src/dawn_native/ObjectBase.h",
     "src/dawn_native/PassResourceUsage.h",
+    "src/dawn_native/PassResourceUsageTracker.cpp",
+    "src/dawn_native/PassResourceUsageTracker.h",
     "src/dawn_native/PerStage.cpp",
     "src/dawn_native/PerStage.h",
     "src/dawn_native/Pipeline.cpp",
diff --git a/src/dawn_native/CommandEncoder.cpp b/src/dawn_native/CommandEncoder.cpp
index be33223..0fff02f 100644
--- a/src/dawn_native/CommandEncoder.cpp
+++ b/src/dawn_native/CommandEncoder.cpp
@@ -23,6 +23,7 @@
 #include "dawn_native/ComputePassEncoder.h"
 #include "dawn_native/Device.h"
 #include "dawn_native/ErrorData.h"
+#include "dawn_native/PassResourceUsageTracker.h"
 #include "dawn_native/RenderPassEncoder.h"
 #include "dawn_native/RenderPipeline.h"
 
@@ -475,117 +476,6 @@
             return {};
         }
 
-        enum class PassType {
-            Render,
-            Compute,
-        };
-
-        // Helper class to encapsulate the logic of tracking per-resource usage during the
-        // validation of command buffer passes. It is used both to know if there are validation
-        // errors, and to get a list of resources used per pass for backends that need the
-        // information.
-        class PassResourceUsageTracker {
-          public:
-            void BufferUsedAs(BufferBase* buffer, dawn::BufferUsageBit usage) {
-                // std::map's operator[] will create the key and return 0 if the key didn't exist
-                // before.
-                dawn::BufferUsageBit& storedUsage = mBufferUsages[buffer];
-
-                if (usage == dawn::BufferUsageBit::Storage &&
-                    storedUsage & dawn::BufferUsageBit::Storage) {
-                    mStorageUsedMultipleTimes = true;
-                }
-
-                storedUsage |= usage;
-            }
-
-            void TextureUsedAs(TextureBase* texture, dawn::TextureUsageBit usage) {
-                // std::map's operator[] will create the key and return 0 if the key didn't exist
-                // before.
-                dawn::TextureUsageBit& storedUsage = mTextureUsages[texture];
-
-                if (usage == dawn::TextureUsageBit::Storage &&
-                    storedUsage & dawn::TextureUsageBit::Storage) {
-                    mStorageUsedMultipleTimes = true;
-                }
-
-                storedUsage |= usage;
-            }
-
-            // Performs the per-pass usage validation checks
-            MaybeError ValidateUsages(PassType pass) const {
-                // Storage resources cannot be used twice in the same compute pass
-                if (pass == PassType::Compute && mStorageUsedMultipleTimes) {
-                    return DAWN_VALIDATION_ERROR(
-                        "Storage resource used multiple times in compute pass");
-                }
-
-                // Buffers can only be used as single-write or multiple read.
-                for (auto& it : mBufferUsages) {
-                    BufferBase* buffer = it.first;
-                    dawn::BufferUsageBit usage = it.second;
-
-                    if (usage & ~buffer->GetUsage()) {
-                        return DAWN_VALIDATION_ERROR("Buffer missing usage for the pass");
-                    }
-
-                    bool readOnly = (usage & kReadOnlyBufferUsages) == usage;
-                    bool singleUse = dawn::HasZeroOrOneBits(usage);
-
-                    if (!readOnly && !singleUse) {
-                        return DAWN_VALIDATION_ERROR(
-                            "Buffer used as writable usage and another usage in pass");
-                    }
-                }
-
-                // Textures can only be used as single-write or multiple read.
-                // TODO(cwallez@chromium.org): implement per-subresource tracking
-                for (auto& it : mTextureUsages) {
-                    TextureBase* texture = it.first;
-                    dawn::TextureUsageBit usage = it.second;
-
-                    if (usage & ~texture->GetUsage()) {
-                        return DAWN_VALIDATION_ERROR("Texture missing usage for the pass");
-                    }
-
-                    // For textures the only read-only usage in a pass is Sampled, so checking the
-                    // usage constraint simplifies to checking a single usage bit is set.
-                    if (!dawn::HasZeroOrOneBits(it.second)) {
-                        return DAWN_VALIDATION_ERROR(
-                            "Texture used with more than one usage in pass");
-                    }
-                }
-
-                return {};
-            }
-
-            // Returns the per-pass usage for use by backends for APIs with explicit barriers.
-            PassResourceUsage AcquireResourceUsage() {
-                PassResourceUsage result;
-                result.buffers.reserve(mBufferUsages.size());
-                result.bufferUsages.reserve(mBufferUsages.size());
-                result.textures.reserve(mTextureUsages.size());
-                result.textureUsages.reserve(mTextureUsages.size());
-
-                for (auto& it : mBufferUsages) {
-                    result.buffers.push_back(it.first);
-                    result.bufferUsages.push_back(it.second);
-                }
-
-                for (auto& it : mTextureUsages) {
-                    result.textures.push_back(it.first);
-                    result.textureUsages.push_back(it.second);
-                }
-
-                return result;
-            }
-
-          private:
-            std::map<BufferBase*, dawn::BufferUsageBit> mBufferUsages;
-            std::map<TextureBase*, dawn::TextureUsageBit> mTextureUsages;
-            bool mStorageUsedMultipleTimes = false;
-        };
-
         void TrackBindGroupResourceUsage(BindGroupBase* group, PassResourceUsageTracker* tracker) {
             const auto& layoutInfo = group->GetLayout()->GetBindingInfo();
 
@@ -1003,7 +893,7 @@
 
                     DAWN_TRY(ValidateDebugGroups(mDebugGroupStackSize));
 
-                    DAWN_TRY(usageTracker.ValidateUsages(PassType::Compute));
+                    DAWN_TRY(usageTracker.ValidateComputePassUsages());
                     mResourceUsages.perPass.push_back(usageTracker.AcquireResourceUsage());
                     return {};
                 } break;
@@ -1092,7 +982,7 @@
 
                     DAWN_TRY(ValidateDebugGroups(mDebugGroupStackSize));
 
-                    DAWN_TRY(usageTracker.ValidateUsages(PassType::Render));
+                    DAWN_TRY(usageTracker.ValidateRenderPassUsages());
                     mResourceUsages.perPass.push_back(usageTracker.AcquireResourceUsage());
                     return {};
                 } break;
diff --git a/src/dawn_native/PassResourceUsageTracker.cpp b/src/dawn_native/PassResourceUsageTracker.cpp
new file mode 100644
index 0000000..4f26112
--- /dev/null
+++ b/src/dawn_native/PassResourceUsageTracker.cpp
@@ -0,0 +1,121 @@
+// Copyright 2019 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "dawn_native/PassResourceUsageTracker.h"
+
+#include "dawn_native/Buffer.h"
+#include "dawn_native/Texture.h"
+
+namespace dawn_native {
+
+    void PassResourceUsageTracker::BufferUsedAs(BufferBase* buffer, dawn::BufferUsageBit usage) {
+        // std::map's operator[] will create the key and return 0 if the key didn't exist
+        // before.
+        dawn::BufferUsageBit& storedUsage = mBufferUsages[buffer];
+
+        if (usage == dawn::BufferUsageBit::Storage && storedUsage & dawn::BufferUsageBit::Storage) {
+            mStorageUsedMultipleTimes = true;
+        }
+
+        storedUsage |= usage;
+    }
+
+    void PassResourceUsageTracker::TextureUsedAs(TextureBase* texture,
+                                                 dawn::TextureUsageBit usage) {
+        // std::map's operator[] will create the key and return 0 if the key didn't exist
+        // before.
+        dawn::TextureUsageBit& storedUsage = mTextureUsages[texture];
+
+        if (usage == dawn::TextureUsageBit::Storage &&
+            storedUsage & dawn::TextureUsageBit::Storage) {
+            mStorageUsedMultipleTimes = true;
+        }
+
+        storedUsage |= usage;
+    }
+
+    MaybeError PassResourceUsageTracker::ValidateComputePassUsages() const {
+        // Storage resources cannot be used twice in the same compute pass
+        if (mStorageUsedMultipleTimes) {
+            return DAWN_VALIDATION_ERROR("Storage resource used multiple times in compute pass");
+        }
+        return ValidateUsages();
+    }
+
+    MaybeError PassResourceUsageTracker::ValidateRenderPassUsages() const {
+        return ValidateUsages();
+    }
+
+    // Performs the per-pass usage validation checks
+    MaybeError PassResourceUsageTracker::ValidateUsages() const {
+        // Buffers can only be used as single-write or multiple read.
+        for (auto& it : mBufferUsages) {
+            BufferBase* buffer = it.first;
+            dawn::BufferUsageBit usage = it.second;
+
+            if (usage & ~buffer->GetUsage()) {
+                return DAWN_VALIDATION_ERROR("Buffer missing usage for the pass");
+            }
+
+            bool readOnly = (usage & kReadOnlyBufferUsages) == usage;
+            bool singleUse = dawn::HasZeroOrOneBits(usage);
+
+            if (!readOnly && !singleUse) {
+                return DAWN_VALIDATION_ERROR(
+                    "Buffer used as writable usage and another usage in pass");
+            }
+        }
+
+        // Textures can only be used as single-write or multiple read.
+        // TODO(cwallez@chromium.org): implement per-subresource tracking
+        for (auto& it : mTextureUsages) {
+            TextureBase* texture = it.first;
+            dawn::TextureUsageBit usage = it.second;
+
+            if (usage & ~texture->GetUsage()) {
+                return DAWN_VALIDATION_ERROR("Texture missing usage for the pass");
+            }
+
+            // For textures the only read-only usage in a pass is Sampled, so checking the
+            // usage constraint simplifies to checking a single usage bit is set.
+            if (!dawn::HasZeroOrOneBits(it.second)) {
+                return DAWN_VALIDATION_ERROR("Texture used with more than one usage in pass");
+            }
+        }
+
+        return {};
+    }
+
+    // Returns the per-pass usage for use by backends for APIs with explicit barriers.
+    PassResourceUsage PassResourceUsageTracker::AcquireResourceUsage() {
+        PassResourceUsage result;
+        result.buffers.reserve(mBufferUsages.size());
+        result.bufferUsages.reserve(mBufferUsages.size());
+        result.textures.reserve(mTextureUsages.size());
+        result.textureUsages.reserve(mTextureUsages.size());
+
+        for (auto& it : mBufferUsages) {
+            result.buffers.push_back(it.first);
+            result.bufferUsages.push_back(it.second);
+        }
+
+        for (auto& it : mTextureUsages) {
+            result.textures.push_back(it.first);
+            result.textureUsages.push_back(it.second);
+        }
+
+        return result;
+    }
+
+}  // namespace dawn_native
diff --git a/src/dawn_native/PassResourceUsageTracker.h b/src/dawn_native/PassResourceUsageTracker.h
new file mode 100644
index 0000000..6942058
--- /dev/null
+++ b/src/dawn_native/PassResourceUsageTracker.h
@@ -0,0 +1,56 @@
+// Copyright 2019 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef DAWNNATIVE_PASSRESOURCEUSAGETRACKER_H_
+#define DAWNNATIVE_PASSRESOURCEUSAGETRACKER_H_
+
+#include "dawn_native/Error.h"
+#include "dawn_native/PassResourceUsage.h"
+
+#include "dawn_native/dawn_platform.h"
+
+#include <map>
+
+namespace dawn_native {
+
+    class BufferBase;
+    class TextureBase;
+
+    // Helper class to encapsulate the logic of tracking per-resource usage during the
+    // validation of command buffer passes. It is used both to know if there are validation
+    // errors, and to get a list of resources used per pass for backends that need the
+    // information.
+    class PassResourceUsageTracker {
+      public:
+        void BufferUsedAs(BufferBase* buffer, dawn::BufferUsageBit usage);
+        void TextureUsedAs(TextureBase* texture, dawn::TextureUsageBit usage);
+
+        MaybeError ValidateComputePassUsages() const;
+        MaybeError ValidateRenderPassUsages() const;
+
+        // Returns the per-pass usage for use by backends for APIs with explicit barriers.
+        PassResourceUsage AcquireResourceUsage();
+
+      private:
+        // Performs the per-pass usage validation checks
+        MaybeError ValidateUsages() const;
+
+        std::map<BufferBase*, dawn::BufferUsageBit> mBufferUsages;
+        std::map<TextureBase*, dawn::TextureUsageBit> mTextureUsages;
+        bool mStorageUsedMultipleTimes = false;
+    };
+
+}  // namespace dawn_native
+
+#endif  // DAWNNATIVE_PASSRESOURCEUSAGETRACKER_H_