Generate proc tables by constexpr assignment

Makes it so that we don't need stub implementations if there are
wire-only or native-only procs.

We can't use a normal function to create the procs because these
variables are global statics; there must not be global static
initializers.

Change-Id: I57e75dcd9628945c3390593ad24ade927cece96c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/140421
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Auto-Submit: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/dawn.json b/dawn.json
index 83a66be..0d51ca3 100644
--- a/dawn.json
+++ b/dawn.json
@@ -1157,7 +1157,7 @@
             {
                 "name": "get adapter",
                 "returns": "adapter",
-                "tags": ["dawn"]
+                "tags": ["dawn", "native"]
             },
             {
                 "name": "get queue",
@@ -1239,7 +1239,7 @@
             },
             {
                 "name": "get supported surface usage",
-                "tags": ["dawn"],
+                "tags": ["dawn", "native"],
                 "returns": "texture usage",
                 "args": [
                     {"name": "surface", "type": "surface"}
diff --git a/generator/templates/dawn/native/ProcTable.cpp b/generator/templates/dawn/native/ProcTable.cpp
index ae4e627..4c5ea08 100644
--- a/generator/templates/dawn/native/ProcTable.cpp
+++ b/generator/templates/dawn/native/ProcTable.cpp
@@ -175,16 +175,27 @@
         return result;
     }
 
-    static {{Prefix}}ProcTable gProcTable = {
+
+    template <typename... MemberPtrPairs>
+    constexpr {{Prefix}}ProcTable MakeProcTable(int, MemberPtrPairs... pairs) {
+        {{Prefix}}ProcTable procs = {};
+        ([&](auto& pair){
+            procs.*(pair.first) = pair.second;
+        }(pairs), ...);
+        return procs;
+    }
+
+    static {{Prefix}}ProcTable gProcTable = MakeProcTable(
+        /* unused */ 0
         {% for function in by_category["function"] %}
-            Native{{as_cppType(function.name)}},
+            , std::make_pair(&{{Prefix}}ProcTable::{{as_varName(function.name)}}, Native{{as_cppType(function.name)}})
         {% endfor %}
         {% for type in by_category["object"] %}
             {% for method in c_methods(type) %}
-                Native{{as_MethodSuffix(type.name, method.name)}},
+                , std::make_pair(&{{Prefix}}ProcTable::{{as_varName(type.name, method.name)}}, Native{{as_MethodSuffix(type.name, method.name)}})
             {% endfor %}
         {% endfor %}
-    };
+    );
 
     const {{Prefix}}ProcTable& GetProcsAutogen() {
         return gProcTable;
diff --git a/generator/templates/dawn/wire/client/ApiProcs.cpp b/generator/templates/dawn/wire/client/ApiProcs.cpp
index a5220f6..82bb340 100644
--- a/generator/templates/dawn/wire/client/ApiProcs.cpp
+++ b/generator/templates/dawn/wire/client/ApiProcs.cpp
@@ -176,16 +176,27 @@
     }
 
     {% set Prefix = metadata.proc_table_prefix %}
-    static {{Prefix}}ProcTable gProcTable = {
+
+    template <typename... MemberPtrPairs>
+    constexpr {{Prefix}}ProcTable MakeProcTable(int, MemberPtrPairs... pairs) {
+        {{Prefix}}ProcTable procs = {};
+        ([&](auto& pair){
+            procs.*(pair.first) = pair.second;
+        }(pairs), ...);
+        return procs;
+    }
+
+    static {{Prefix}}ProcTable gProcTable = MakeProcTable(
+        /* unused */ 0
         {% for function in by_category["function"] %}
-            Client{{as_cppType(function.name)}},
+            , std::make_pair(&{{Prefix}}ProcTable::{{as_varName(function.name)}}, Client{{as_cppType(function.name)}})
         {% endfor %}
         {% for type in by_category["object"] %}
             {% for method in c_methods(type) %}
-                Client{{as_MethodSuffix(type.name, method.name)}},
+                , std::make_pair(&{{Prefix}}ProcTable::{{as_varName(type.name, method.name)}}, Client{{as_MethodSuffix(type.name, method.name)}})
             {% endfor %}
         {% endfor %}
-    };
+    );
 
     const {{Prefix}}ProcTable& GetProcs() {
         return gProcTable;
diff --git a/src/dawn/wire/client/Device.cpp b/src/dawn/wire/client/Device.cpp
index 2e6362d..76ac674 100644
--- a/src/dawn/wire/client/Device.cpp
+++ b/src/dawn/wire/client/Device.cpp
@@ -211,18 +211,6 @@
     return Buffer::Create(this, descriptor);
 }
 
-WGPUAdapter Device::GetAdapter() {
-    // Not implemented in the wire.
-    UNREACHABLE();
-    return nullptr;
-}
-
-WGPUTextureUsage Device::GetSupportedSurfaceUsage(WGPUSurface) {
-    // Not implemented in the wire.
-    UNREACHABLE();
-    return WGPUTextureUsage_RenderAttachment;
-}
-
 WGPUQueue Device::GetQueue() {
     // The queue is lazily created because if a Device is created by
     // Reserve/Inject, we cannot send the GetQueue message until
diff --git a/src/dawn/wire/client/Device.h b/src/dawn/wire/client/Device.h
index 1beab67..3be00cd 100644
--- a/src/dawn/wire/client/Device.h
+++ b/src/dawn/wire/client/Device.h
@@ -65,8 +65,6 @@
     void SetLimits(const WGPUSupportedLimits* limits);
     void SetFeatures(const WGPUFeatureName* features, uint32_t featuresCount);
 
-    WGPUAdapter GetAdapter();                                // Not implemented in the wire.
-    WGPUTextureUsage GetSupportedSurfaceUsage(WGPUSurface);  // Not implemented in the wire.
     WGPUQueue GetQueue();
 
     void CancelCallbacksForDisconnect() override;