[webgpu-headers] Introduces WGPUBool for boolean compatibility.

On Dawn side, this includes some compatibility changes so that it is
ergonomic to use the new underlying bool type transparently.

This change must wait for the following change(s) to land:
- https://chromium-review.googlesource.com/c/chromium/src/+/4740656

github.com/webgpu-native/webgpu-headers/issues/84

Change-Id: Ie0f37dfc313ec32ae4aa5236ec0ecf4dab353923
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/144207
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Loko Kung <lokokung@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
diff --git a/generator/dawn_json_generator.py b/generator/dawn_json_generator.py
index 1605ceb..daaec67 100644
--- a/generator/dawn_json_generator.py
+++ b/generator/dawn_json_generator.py
@@ -699,7 +699,8 @@
 
 
 def as_cType(c_prefix, name):
-    if name.native:
+    # Special case for 'bool' because it has a typedef for compatibility.
+    if name.native and name.get() != 'bool':
         return name.concatcase()
     else:
         return c_prefix + name.CamelCase()
@@ -713,7 +714,8 @@
 
 
 def as_cppType(name):
-    if name.native:
+    # Special case for 'bool' because it has a typedef for compatibility.
+    if name.native and name.get() != 'bool':
         return name.concatcase()
     else:
         return name.CamelCase()
@@ -798,7 +800,7 @@
 def as_frontendType(metadata, typ):
     if typ.category == 'object':
         return typ.name.CamelCase() + 'Base*'
-    elif typ.category in ['bitmask', 'enum']:
+    elif typ.category in ['bitmask', 'enum'] or typ.name.get() == 'bool':
         return metadata.namespace + '::' + typ.name.CamelCase()
     elif typ.category == 'structure':
         return as_cppType(typ.name)
diff --git a/generator/templates/api.h b/generator/templates/api.h
index 7502c3c..393e5b4 100644
--- a/generator/templates/api.h
+++ b/generator/templates/api.h
@@ -76,6 +76,8 @@
 {% endfor %}
 
 typedef uint32_t {{API}}Flags;
+#define WGPU_BREAKING_CHANGE_BOOL
+typedef uint32_t {{API}}Bool;
 
 {% for type in by_category["object"] %}
     typedef struct {{as_cType(type.name)}}Impl* {{as_cType(type.name)}} {{API}}_OBJECT_ATTRIBUTE;
diff --git a/generator/templates/api_cpp.h b/generator/templates/api_cpp.h
index 12ce340..1447fe4 100644
--- a/generator/templates/api_cpp.h
+++ b/generator/templates/api_cpp.h
@@ -27,6 +27,7 @@
 #include <cmath>
 #include <cstddef>
 #include <cstdint>
+#include <functional>
 
 namespace {{metadata.namespace}} {
 
@@ -67,6 +68,26 @@
         struct {{as_cppType(type.name)}};
     {% endfor %}
 
+
+    // Special class for booleans in order to allow implicit conversions.
+    {% set BoolCppType = as_cppType(types["bool"].name) %}
+    {% set BoolCType = as_cType(types["bool"].name) %}
+    class {{BoolCppType}} {
+      public:
+        constexpr {{BoolCppType}}() = default;
+        // NOLINTNEXTLINE(runtime/explicit) allow implicit construction
+        constexpr {{BoolCppType}}(bool value) : mValue(static_cast<{{BoolCType}}>(value)) {}
+        // NOLINTNEXTLINE(runtime/explicit) allow implicit construction
+        {{BoolCppType}}({{BoolCType}} value): mValue(value) {}
+
+        constexpr operator bool() const { return static_cast<bool>(mValue); }
+
+      private:
+        friend struct std::hash<{{BoolCppType}}>;
+        // Default to false.
+        {{BoolCType}} mValue = static_cast<{{BoolCType}}>(false);
+    };
+
     {% for typeDef in by_category["typedef"] %}
         // {{as_cppType(typeDef.name)}} is deprecated.
         // Use {{as_cppType(typeDef.type.name)}} instead.
@@ -262,4 +283,15 @@
     {% endfor %}
 } // namespace dawn
 
+namespace std {
+// Custom boolean class needs corresponding hash function so that it appears as a transparent bool.
+template <>
+struct hash<{{metadata.namespace}}::{{BoolCppType}}> {
+  public:
+    size_t operator()(const {{metadata.namespace}}::{{BoolCppType}} &v) const {
+        return hash<bool>()(v);
+    }
+};
+}  // namespace std
+
 #endif // {{API}}_CPP_H_
diff --git a/generator/templates/dawn/native/api_StreamImpl.cpp b/generator/templates/dawn/native/api_StreamImpl.cpp
index e6617aa..79bb32c 100644
--- a/generator/templates/dawn/native/api_StreamImpl.cpp
+++ b/generator/templates/dawn/native/api_StreamImpl.cpp
@@ -24,17 +24,17 @@
 
 namespace {{native_namespace}} {
 
-//
-// Streaming readers for wgpu structures.
-//
+//*
+//* Streaming readers for wgpu structures.
+//*
 {% macro render_reader(member) %}
     {%- set name = member.name.camelCase() -%}
     DAWN_TRY(StreamOut(source, &t->{{name}}));
 {% endmacro %}
 
-//
-// Streaming writers for wgpu structures.
-//
+//*
+//* Streaming writers for wgpu structures.
+//*
 {% macro render_writer(member) %}
     {%- set name = member.name.camelCase() -%}
     {% if member.length == None %}
@@ -83,6 +83,13 @@
     {% endif %}
 {% endmacro %}
 
+// Custom stream operator for special bool type.
+{% set BoolCppType = metadata.namespace + "::" + as_cppType(types["bool"].name) %}
+template <>
+void stream::Stream<{{BoolCppType}}>::Write(stream::Sink* sink, const {{BoolCppType}}& t) {
+    StreamIn(sink, static_cast<bool>(t));
+}
+
 {% call render_streaming_impl("adapter properties", true, false) %}
 {% endcall %}
 
diff --git a/generator/templates/dawn/native/api_structs.cpp b/generator/templates/dawn/native/api_structs.cpp
index 86f54f0..7e7a0b8 100644
--- a/generator/templates/dawn/native/api_structs.cpp
+++ b/generator/templates/dawn/native/api_structs.cpp
@@ -52,7 +52,7 @@
         {% for member in type.members %}
             {% set memberName = member.name.camelCase() %}
             static_assert(offsetof({{CppType}}, {{memberName}}) == offsetof({{CType}}, {{memberName}}),
-                    "offsetof mismatch for {{CppType}}::{{memberName}}");
+                         "offsetof mismatch for {{CppType}}::{{memberName}}");
         {% endfor %}
 
         bool {{CppType}}::operator==(const {{as_cppType(type.name)}}& rhs) const {
diff --git a/src/dawn/node/binding/Converter.cpp b/src/dawn/node/binding/Converter.cpp
index 452b523..27ef394 100644
--- a/src/dawn/node/binding/Converter.cpp
+++ b/src/dawn/node/binding/Converter.cpp
@@ -1765,4 +1765,9 @@
     return true;
 }
 
+bool Converter::Convert(wgpu::Bool& out, const bool& in) {
+    out = in;
+    return true;
+}
+
 }  // namespace wgpu::binding
diff --git a/src/dawn/node/binding/Converter.h b/src/dawn/node/binding/Converter.h
index a90834e..02a345c 100644
--- a/src/dawn/node/binding/Converter.h
+++ b/src/dawn/node/binding/Converter.h
@@ -247,6 +247,8 @@
 
     [[nodiscard]] bool Convert(wgpu::PipelineLayout& out, const interop::GPUAutoLayoutMode& in);
 
+    [[nodiscard]] bool Convert(wgpu::Bool& out, const bool& in);
+
     // Below are the various overloads of Convert() used to convert the Dawn types -> interop.
     [[nodiscard]] bool Convert(interop::GPUTextureDimension& out, wgpu::TextureDimension in);