Specialize WireServer objects

This removes unnecessary builder and buffer info from server objects that
do not need them.

Bug: dawn:86
Change-Id: I97b11615da763725281495f05c70a4ee7a9c9e5a
Reviewed-on: https://dawn-review.googlesource.com/c/3780
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index 8a10090..786b231 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -671,6 +671,7 @@
 dawn_generator("libdawn_wire_gen") {
   target = "dawn_wire"
   outputs = [
+    "dawn_wire/TypeTraits_autogen.h",
     "dawn_wire/WireServer.cpp",
     "dawn_wire/WireCmd_autogen.h",
     "dawn_wire/WireClient.cpp",
diff --git a/generator/main.py b/generator/main.py
index 017a941..a5c5a7d 100644
--- a/generator/main.py
+++ b/generator/main.py
@@ -479,6 +479,7 @@
                 'as_wireType': lambda typ: typ.name.CamelCase() + '*' if typ.category == 'object' else as_cppType(typ.name)
             }
         ]
+        renders.append(FileRender('dawn_wire/TypeTraits.h', 'dawn_wire/TypeTraits_autogen.h', wire_params))
         renders.append(FileRender('dawn_wire/WireCmd.h', 'dawn_wire/WireCmd_autogen.h', wire_params))
         renders.append(FileRender('dawn_wire/WireCmd.cpp', 'dawn_wire/WireCmd_autogen.cpp', wire_params))
         renders.append(FileRender('dawn_wire/WireClient.cpp', 'dawn_wire/WireClient.cpp', wire_params))
diff --git a/generator/templates/dawn_wire/TypeTraits.h b/generator/templates/dawn_wire/TypeTraits.h
new file mode 100644
index 0000000..26a91ee
--- /dev/null
+++ b/generator/templates/dawn_wire/TypeTraits.h
@@ -0,0 +1,35 @@
+//* 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 DAWNWIRE_TYPETRAITS_AUTOGEN_H_
+#define DAWNWIRE_TYPETRAITS_AUTOGEN_H_
+
+#include <dawn/dawn.h>
+
+//* This file can be removed when WebGPU error handling is implemented
+namespace dawn_wire {
+    template <typename T>
+    struct IsBuilderType {
+        static constexpr bool value = false;
+    };
+
+    {% for type in by_category["object"] if type.is_builder %}
+        template<>
+        struct IsBuilderType<{{as_cType(type.name)}}> {
+            static constexpr bool value = true;
+        };
+    {% endfor %}
+}
+
+#endif  // DAWNWIRE_TYPETRAITS_AUTOGEN_H_
diff --git a/generator/templates/dawn_wire/WireServer.cpp b/generator/templates/dawn_wire/WireServer.cpp
index 9ea671a..49a9f71 100644
--- a/generator/templates/dawn_wire/WireServer.cpp
+++ b/generator/templates/dawn_wire/WireServer.cpp
@@ -12,6 +12,7 @@
 //* See the License for the specific language governing permissions and
 //* limitations under the License.
 
+#include "dawn_wire/TypeTraits_autogen.h"
 #include "dawn_wire/Wire.h"
 #include "dawn_wire/WireCmd.h"
 
@@ -44,18 +45,12 @@
             uint64_t value;
         };
 
-        //* Stores what the backend knows about the type.
-        template<typename T>
+        template <typename T>
         struct ObjectDataBase {
             //* The backend-provided handle and serial to this object.
             T handle;
             uint32_t serial = 0;
 
-            //* Built object ID and serial, needed to send to the client along with builder error callbacks
-            //* TODO(cwallez@chromium.org) only have this for builder T
-            uint32_t builtObjectId = 0;
-            uint32_t builtObjectSerial = 0;
-
             //* Used by the error-propagation mechanism to know if this object is an error.
             //* TODO(cwallez@chromium.org): this is doubling the memory usage of
             //* std::vector<ObjectDataBase> consider making it a special marker value in handle instead.
@@ -63,8 +58,22 @@
             //* Whether this object has been allocated, used by the KnownObjects queries
             //* TODO(cwallez@chromium.org): make this an internal bit vector in KnownObjects.
             bool allocated;
+        };
 
-            //* TODO(cwallez@chromium.org): this is only useful for buffers
+        //* Stores what the backend knows about the type.
+        template<typename T, bool IsBuilder = IsBuilderType<T>::value>
+        struct ObjectData : public ObjectDataBase<T> {
+        };
+
+
+        template <typename T>
+        struct ObjectData<T, true> : public ObjectDataBase<T> {
+            uint32_t builtObjectId = 0;
+            uint32_t builtObjectSerial = 0;
+        };
+
+        template <>
+        struct ObjectData<dawnBuffer, false> : public ObjectDataBase<dawnBuffer> {
             void* mappedData = nullptr;
             size_t mappedDataSize = 0;
         };
@@ -73,7 +82,7 @@
         template<typename T>
         class KnownObjects {
             public:
-                using Data = ObjectDataBase<T>;
+                using Data = ObjectData<T>;
 
                 KnownObjects() {
                     //* Pre-allocate ID 0 to refer to the null handle.