D3D12: Support creating compute pipeline asynchronously

This patch implements the asynchronous path of CreateComputePipelineAsync
on D3D12 backend with the basic framework of the dawn_unittest
AsyncTaskTest.Basic.

1. Call the constructor of dawn_native::d3d12::ComputePipeline in the main
   thread.
2. Execute dawn_native::ComputePipelineBase::Initialize() (a virtual function)
   asynchronously.
3. Ensure every operation in dawn_native::d3d12::ComputePipeline::Initialize()
   is thread-safe (PersistentCache).
4. Save all the return values (pipeline object or error message, userdata, etc)
   in a CreateComputePipelineAsyncWaitableCallbackTask object and insert this
   callback task into CallbackTaskManager.
5. In Callback.Finish():
- Insert the pipeline object into the pipeline cache if necessary
- Call WGPUCreateComputePipelineAsyncCallback

Note that as we always handle the front-end pipeline cache in the main thread,
we don't need to make it thread-safe right now.

BUG=dawn:529
TEST=dawn_end2end_tests

Change-Id: I7eba2ce550b32439a94b2a4d1aa7f1b3383aa514
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/47900
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/Device.h b/src/dawn_native/Device.h
index 7d96481..c16d01b 100644
--- a/src/dawn_native/Device.h
+++ b/src/dawn_native/Device.h
@@ -26,11 +26,15 @@
 #include "dawn_native/DawnNative.h"
 #include "dawn_native/dawn_platform.h"
 
-#include <memory>
 #include <utility>
 
+namespace dawn_platform {
+    class WorkerTaskPool;
+}  // namespace dawn_platform
+
 namespace dawn_native {
     class AdapterBase;
+    class AsyncTaskManager;
     class AttachmentState;
     class AttachmentStateBlueprint;
     class BindGroupLayoutBase;
@@ -41,6 +45,7 @@
     class OwnedCompilationMessages;
     class PersistentCache;
     class StagingBufferBase;
+    struct CallbackTask;
     struct InternalPipelineStore;
     struct ShaderModuleParseResult;
 
@@ -278,6 +283,16 @@
 
         virtual float GetTimestampPeriodInNS() const = 0;
 
+        AsyncTaskManager* GetAsyncTaskManager() const;
+        CallbackTaskManager* GetCallbackTaskManager() const;
+        dawn_platform::WorkerTaskPool* GetWorkerTaskPool() const;
+
+        void AddComputePipelineAsyncCallbackTask(Ref<ComputePipelineBase> pipeline,
+                                                 std::string errorMessage,
+                                                 WGPUCreateComputePipelineAsyncCallback callback,
+                                                 void* userdata,
+                                                 size_t blueprintHash);
+
       protected:
         void SetToggle(Toggle toggle, bool isEnabled);
         void ForceSetToggle(Toggle toggle, bool isEnabled);
@@ -332,10 +347,10 @@
             const ComputePipelineDescriptor* descriptor);
         Ref<ComputePipelineBase> AddOrGetCachedPipeline(Ref<ComputePipelineBase> computePipeline,
                                                         size_t blueprintHash);
-        void CreateComputePipelineAsyncImpl(const ComputePipelineDescriptor* descriptor,
-                                            size_t blueprintHash,
-                                            WGPUCreateComputePipelineAsyncCallback callback,
-                                            void* userdata);
+        virtual void CreateComputePipelineAsyncImpl(const ComputePipelineDescriptor* descriptor,
+                                                    size_t blueprintHash,
+                                                    WGPUCreateComputePipelineAsyncCallback callback,
+                                                    void* userdata);
 
         void ApplyToggleOverrides(const DeviceDescriptor* deviceDescriptor);
         void ApplyExtensions(const DeviceDescriptor* deviceDescriptor);
@@ -398,7 +413,7 @@
         Ref<BindGroupLayoutBase> mEmptyBindGroupLayout;
 
         std::unique_ptr<DynamicUploader> mDynamicUploader;
-        std::unique_ptr<CallbackTaskManager> mCallbackTaskManager;
+        std::unique_ptr<AsyncTaskManager> mAsyncTaskManager;
         Ref<QueueBase> mQueue;
 
         struct DeprecationWarnings;
@@ -417,6 +432,9 @@
         std::unique_ptr<InternalPipelineStore> mInternalPipelineStore;
 
         std::unique_ptr<PersistentCache> mPersistentCache;
+
+        std::unique_ptr<CallbackTaskManager> mCallbackTaskManager;
+        std::unique_ptr<dawn_platform::WorkerTaskPool> mWorkerTaskPool;
     };
 
 }  // namespace dawn_native