Make the C++ api header-only
The goal is to make it much easier to use alternative C++ wrappers
(in different namespaces) that may wrap dawn::native or dawn::wire
directly.
Across Chrome, in //gpu, Skia, and Dawn, this change has a zero-sized
net impact on Android binary size.
This change caught some BUILD.gn issues where the samples depended on
dawn:proc_shared when their deps also depended on dawn:proc(static),
leading to duplicate symbol collisions.
Bug: chromium:40195122
Change-Id: I873776464c5017b7a439acf03a8a6274cd91badf
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/175947
Auto-Submit: Austin Eng <enga@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/docs/dawn/codegen.md b/docs/dawn/codegen.md
index 4293887..47702db 100644
--- a/docs/dawn/codegen.md
+++ b/docs/dawn/codegen.md
@@ -11,7 +11,7 @@
At this time it is used to generate:
- the Dawn, Emscripten, and upstream webgpu-native `webgpu.h` C header
- - the Dawn and Emscripten `webgpu_cpp.cpp/h` C++ wrapper over the C header
+ - the Dawn and Emscripten `webgpu_cpp.h` C++ wrapper over the C header
- libraries that implements `webgpu.h` by calling in a static or `thread_local` proc table
- other parts of the [Emscripten](https://emscripten.org/) WebGPU implementation
- a GMock version of the API with its proc table for testing
diff --git a/generator/dawn_json_generator.py b/generator/dawn_json_generator.py
index d6e2091..bb27818 100644
--- a/generator/dawn_json_generator.py
+++ b/generator/dawn_json_generator.py
@@ -1079,11 +1079,6 @@
'src/dawn/native/webgpu_dawn_native_proc.cpp',
[RENDER_PARAMS_BASE, params_dawn]))
- if 'cpp' in targets:
- renders.append(
- FileRender('api_cpp.cpp', 'src/dawn/' + api + '_cpp.cpp',
- [RENDER_PARAMS_BASE, params_dawn]))
-
if 'webgpu_headers' in targets:
params_upstream = parse_json(loaded_json,
enabled_tags=['upstream', 'native'],
@@ -1111,11 +1106,6 @@
'api_cpp_chained_struct.h',
'emscripten-bits/system/include/webgpu/webgpu_cpp_chained_struct.h',
[RENDER_PARAMS_BASE, params_emscripten]))
- # system/lib/webgpu
- renders.append(
- FileRender('api_cpp.cpp',
- 'emscripten-bits/system/lib/webgpu/webgpu_cpp.cpp',
- [RENDER_PARAMS_BASE, params_emscripten]))
# Snippets to paste into existing Emscripten files
renders.append(
FileRender('api_struct_info.json',
diff --git a/generator/templates/api_cpp.cpp b/generator/templates/api_cpp.cpp
index d534984..e69de29 100644
--- a/generator/templates/api_cpp.cpp
+++ b/generator/templates/api_cpp.cpp
@@ -1,251 +0,0 @@
-//* Copyright 2017 The Dawn & Tint Authors
-//*
-//* Redistribution and use in source and binary forms, with or without
-//* modification, are permitted provided that the following conditions are met:
-//*
-//* 1. Redistributions of source code must retain the above copyright notice, this
-//* list of conditions and the following disclaimer.
-//*
-//* 2. Redistributions in binary form must reproduce the above copyright notice,
-//* this list of conditions and the following disclaimer in the documentation
-//* and/or other materials provided with the distribution.
-//*
-//* 3. Neither the name of the copyright holder nor the names of its
-//* contributors may be used to endorse or promote products derived from
-//* this software without specific prior written permission.
-//*
-//* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-//* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-//* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-//* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-//* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-//* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-//* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-//* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-//* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <utility>
-
-{% set api = metadata.api.lower() %}
-{% if 'dawn' in enabled_tags %}
- #include "dawn/{{api}}_cpp.h"
-{% else %}
- #include "{{api}}/{{api}}_cpp.h"
-{% endif %}
-
-#if defined(__GNUC__) || defined(__clang__)
-// error: 'offsetof' within non-standard-layout type '{{metadata.namespace}}::XXX' is conditionally-supported
-#pragma GCC diagnostic ignored "-Winvalid-offsetof"
-#endif
-
-namespace {{metadata.namespace}} {
- {% for type in by_category["enum"] %}
- {% set CppType = as_cppType(type.name) %}
- {% set CType = as_cType(type.name) %}
-
- // {{CppType}}
-
- static_assert(sizeof({{CppType}}) == sizeof({{CType}}), "sizeof mismatch for {{CppType}}");
- static_assert(alignof({{CppType}}) == alignof({{CType}}), "alignof mismatch for {{CppType}}");
-
- {% for value in type.values %}
- static_assert(static_cast<uint32_t>({{CppType}}::{{as_cppEnum(value.name)}}) == {{as_cEnum(type.name, value.name)}}, "value mismatch for {{CppType}}::{{as_cppEnum(value.name)}}");
- {% endfor %}
- {% endfor -%}
-
- {% for type in by_category["bitmask"] %}
- {% set CppType = as_cppType(type.name) %}
- {% set CType = as_cType(type.name) + "Flags" %}
-
- // {{CppType}}
-
- static_assert(sizeof({{CppType}}) == sizeof({{CType}}), "sizeof mismatch for {{CppType}}");
- static_assert(alignof({{CppType}}) == alignof({{CType}}), "alignof mismatch for {{CppType}}");
-
- {% for value in type.values %}
- static_assert(static_cast<uint32_t>({{CppType}}::{{as_cppEnum(value.name)}}) == {{as_cEnum(type.name, value.name)}}, "value mismatch for {{CppType}}::{{as_cppEnum(value.name)}}");
- {% endfor %}
- {% endfor %}
-
- // ChainedStruct
-
- {% set c_prefix = metadata.c_prefix %}
- static_assert(sizeof(ChainedStruct) == sizeof({{c_prefix}}ChainedStruct),
- "sizeof mismatch for ChainedStruct");
- static_assert(alignof(ChainedStruct) == alignof({{c_prefix}}ChainedStruct),
- "alignof mismatch for ChainedStruct");
- static_assert(offsetof(ChainedStruct, nextInChain) == offsetof({{c_prefix}}ChainedStruct, next),
- "offsetof mismatch for ChainedStruct::nextInChain");
- static_assert(offsetof(ChainedStruct, sType) == offsetof({{c_prefix}}ChainedStruct, sType),
- "offsetof mismatch for ChainedStruct::sType");
- {% for type in by_category["structure"] %}
- {% set CppType = as_cppType(type.name) %}
- {% set CType = as_cType(type.name) %}
-
- // {{CppType}}
-
- static_assert(sizeof({{CppType}}) == sizeof({{CType}}), "sizeof mismatch for {{CppType}}");
- static_assert(alignof({{CppType}}) == alignof({{CType}}), "alignof mismatch for {{CppType}}");
-
- {% if type.extensible %}
- static_assert(offsetof({{CppType}}, nextInChain) == offsetof({{CType}}, nextInChain),
- "offsetof mismatch for {{CppType}}::nextInChain");
- {% endif %}
- {% for member in type.members %}
- {% set memberName = member.name.camelCase() %}
- static_assert(offsetof({{CppType}}, {{memberName}}) == offsetof({{CType}}, {{memberName}}),
- "offsetof mismatch for {{CppType}}::{{memberName}}");
- {% endfor %}
- {% endfor -%}
-
- {%- macro render_c_actual_arg(arg) -%}
- {%- if arg.annotation == "value" -%}
- {%- if arg.type.category == "object" -%}
- {{as_varName(arg.name)}}.Get()
- {%- elif arg.type.category == "enum" or arg.type.category == "bitmask" -%}
- static_cast<{{as_cType(arg.type.name)}}>({{as_varName(arg.name)}})
- {%- elif arg.type.category == "structure" -%}
- *reinterpret_cast<{{as_cType(arg.type.name)}} const*>(&{{as_varName(arg.name)}})
- {%- elif arg.type.category in ["function pointer", "native"] -%}
- {{as_varName(arg.name)}}
- {%- else -%}
- UNHANDLED
- {%- endif -%}
- {%- else -%}
- reinterpret_cast<{{decorate("", as_cType(arg.type.name), arg)}}>({{as_varName(arg.name)}})
- {%- endif -%}
- {%- endmacro -%}
-
- template <typename T>
- static T& AsNonConstReference(const T& value) {
- return const_cast<T&>(value);
- }
-
- {% for type in by_category["structure"] if type.has_free_members_function %}
- // {{as_cppType(type.name)}}
- {{as_cppType(type.name)}}::~{{as_cppType(type.name)}}() {
- if (
- {%- for member in type.members if member.annotation != 'value' %}
- {% if not loop.first %} || {% endif -%}
- this->{{member.name.camelCase()}} != nullptr
- {%- endfor -%}
- ) {
- {{as_cMethod(type.name, Name("free members"))}}(
- *reinterpret_cast<{{as_cType(type.name)}}*>(this));
- }
- }
-
- static void Reset({{as_cppType(type.name)}}& value) {
- {{as_cppType(type.name)}} defaultValue{};
- {% for member in type.members %}
- AsNonConstReference(value.{{member.name.camelCase()}}) = defaultValue.{{member.name.camelCase()}};
- {% endfor %}
- }
-
- {{as_cppType(type.name)}}::{{as_cppType(type.name)}}({{as_cppType(type.name)}}&& rhs)
- : {% for member in type.members %}
- {%- set memberName = member.name.camelCase() -%}
- {{memberName}}(rhs.{{memberName}}){% if not loop.last %},{{"\n "}}{% endif %}
- {% endfor -%}
- {
- Reset(rhs);
- }
-
- {{as_cppType(type.name)}}& {{as_cppType(type.name)}}::operator=({{as_cppType(type.name)}}&& rhs) {
- if (&rhs == this) {
- return *this;
- }
- this->~{{as_cppType(type.name)}}();
- {% for member in type.members %}
- AsNonConstReference(this->{{member.name.camelCase()}}) = std::move(rhs.{{member.name.camelCase()}});
- {% endfor %}
- Reset(rhs);
- return *this;
- }
-
- {% endfor %}
-
- {% for type in by_category["object"] %}
- {% set CppType = as_cppType(type.name) %}
- {% set CType = as_cType(type.name) %}
-
- // {{CppType}}
-
- static_assert(sizeof({{CppType}}) == sizeof({{CType}}), "sizeof mismatch for {{CppType}}");
- static_assert(alignof({{CppType}}) == alignof({{CType}}), "alignof mismatch for {{CppType}}");
-
- {% macro render_cpp_method_declaration(type, method) -%}
- {% set CppType = as_cppType(type.name) %}
- {% set OriginalMethodName = method.name.CamelCase() %}
- {% set MethodName = OriginalMethodName[:-1] if method.name.chunks[-1] == "f" else OriginalMethodName %}
- {{as_cppType(method.return_type.name)}} {{CppType}}::{{MethodName}}(
- {%- for arg in method.arguments -%}
- {%- if not loop.first %}, {% endif -%}
- {%- if arg.type.category == "object" and arg.annotation == "value" -%}
- {{as_cppType(arg.type.name)}} const& {{as_varName(arg.name)}}
- {%- else -%}
- {{as_annotated_cppType(arg)}}
- {%- endif -%}
- {%- endfor -%}
- ) const
- {%- endmacro -%}
-
- {%- macro render_cpp_to_c_method_call(type, method) -%}
- {{as_cMethod(type.name, method.name)}}(Get()
- {%- for arg in method.arguments -%},{{" "}}{{render_c_actual_arg(arg)}}
- {%- endfor -%}
- )
- {%- endmacro -%}
-
- {% for method in type.methods -%}
- {{render_cpp_method_declaration(type, method)}} {
- {% for arg in method.arguments if arg.type.has_free_members_function and arg.annotation == '*' %}
- *{{as_varName(arg.name)}} = {{as_cppType(arg.type.name)}}();
- {% endfor %}
- {% if method.return_type.name.concatcase() == "void" %}
- {{render_cpp_to_c_method_call(type, method)}};
- {% else %}
- auto result = {{render_cpp_to_c_method_call(type, method)}};
- return {{convert_cType_to_cppType(method.return_type, 'value', 'result') | indent(8)}};
- {% endif %}
- }
- {% endfor %}
- void {{CppType}}::{{c_prefix}}Reference({{CType}} handle) {
- if (handle != nullptr) {
- {{as_cMethod(type.name, Name("reference"))}}(handle);
- }
- }
- void {{CppType}}::{{c_prefix}}Release({{CType}} handle) {
- if (handle != nullptr) {
- {{as_cMethod(type.name, Name("release"))}}(handle);
- }
- }
- {% endfor %}
-
- // Function
-
- {% for function in by_category["function"] if not function.no_cpp %}
- {%- macro render_function_call(function) -%}
- {{as_cMethod(None, function.name)}}(
- {%- for arg in function.arguments -%}
- {% if not loop.first %}, {% endif %}{{render_c_actual_arg(arg)}}
- {%- endfor -%}
- )
- {%- endmacro -%}
-
- {{as_cppType(function.return_type.name) | indent(4, true) }} {{as_cppType(function.name) }}(
- {%- for arg in function.arguments -%}
- {% if not loop.first %}, {% endif %}{{as_annotated_cppType(arg)}}
- {%- endfor -%}
- ) {
- {% if function.return_type.name.concatcase() == "void" %}
- {{render_function_call(function)}};
- {% else %}
- auto result = {{render_function_call(function)}};
- return {{convert_cType_to_cppType(function.return_type, 'value', 'result')}};
- {% endif %}
- }
- {% endfor %}
-
-}
diff --git a/generator/templates/api_cpp.h b/generator/templates/api_cpp.h
index d129f54..ca281fa 100644
--- a/generator/templates/api_cpp.h
+++ b/generator/templates/api_cpp.h
@@ -48,6 +48,11 @@
constexpr size_t ConstexprMax(size_t a, size_t b) {
return a > b ? a : b;
}
+
+ template <typename T>
+ static T& AsNonConstReference(const T& value) {
+ return const_cast<T&>(value);
+ }
} // namespace detail
{% set c_prefix = metadata.c_prefix %}
@@ -57,21 +62,54 @@
static constexpr {{type}} k{{as_cppType(constant.name)}} = {{ value }};
{% endfor %}
+ {%- macro render_c_actual_arg(arg) -%}
+ {%- if arg.annotation == "value" -%}
+ {%- if arg.type.category == "object" -%}
+ {{as_varName(arg.name)}}.Get()
+ {%- elif arg.type.category == "enum" or arg.type.category == "bitmask" -%}
+ static_cast<{{as_cType(arg.type.name)}}>({{as_varName(arg.name)}})
+ {%- elif arg.type.category == "structure" -%}
+ *reinterpret_cast<{{as_cType(arg.type.name)}} const*>(&{{as_varName(arg.name)}})
+ {%- elif arg.type.category in ["function pointer", "native"] -%}
+ {{as_varName(arg.name)}}
+ {%- else -%}
+ UNHANDLED
+ {%- endif -%}
+ {%- else -%}
+ reinterpret_cast<{{decorate("", as_cType(arg.type.name), arg)}}>({{as_varName(arg.name)}})
+ {%- endif -%}
+ {%- endmacro -%}
+
+ {%- macro render_cpp_to_c_method_call(type, method) -%}
+ {{as_cMethod(type.name, method.name)}}(Get()
+ {%- for arg in method.arguments -%},{{" "}}{{render_c_actual_arg(arg)}}
+ {%- endfor -%}
+ )
+ {%- endmacro -%}
+
{% for type in by_category["enum"] %}
- enum class {{as_cppType(type.name)}} : uint32_t {
+ {% set CppType = as_cppType(type.name) %}
+ {% set CType = as_cType(type.name) %}
+ enum class {{CppType}} : uint32_t {
{% for value in type.values %}
- {{as_cppEnum(value.name)}} = 0x{{format(value.value, "08X")}},
+ {{as_cppEnum(value.name)}} = {{as_cEnum(type.name, value.name)}},
{% endfor %}
};
+ static_assert(sizeof({{CppType}}) == sizeof({{CType}}), "sizeof mismatch for {{CppType}}");
+ static_assert(alignof({{CppType}}) == alignof({{CType}}), "alignof mismatch for {{CppType}}");
{% endfor %}
{% for type in by_category["bitmask"] %}
- enum class {{as_cppType(type.name)}} : uint32_t {
+ {% set CppType = as_cppType(type.name) %}
+ {% set CType = as_cType(type.name) + "Flags" %}
+ enum class {{CppType}} : uint32_t {
{% for value in type.values %}
- {{as_cppEnum(value.name)}} = 0x{{format(value.value, "08X")}},
+ {{as_cppEnum(value.name)}} = {{as_cEnum(type.name, value.name)}},
{% endfor %}
};
+ static_assert(sizeof({{CppType}}) == sizeof({{CType}}), "sizeof mismatch for {{CppType}}");
+ static_assert(alignof({{CppType}}) == alignof({{CType}}), "alignof mismatch for {{CppType}}");
{% endfor %}
@@ -208,10 +246,11 @@
{%- endif -%}
{%- endmacro %}
-{% macro render_cpp_method_declaration(type, method) %}
+{% macro render_cpp_method_declaration(type, method, dfn=False) %}
{% set CppType = as_cppType(type.name) %}
{% set OriginalMethodName = method.name.CamelCase() %}
{% set MethodName = OriginalMethodName[:-1] if method.name.chunks[-1] == "f" else OriginalMethodName %}
+ {% set MethodName = CppType + "::" + MethodName if dfn else MethodName %}
{{as_cppType(method.return_type.name)}} {{MethodName}}(
{%- for arg in method.arguments -%}
{%- if not loop.first %}, {% endif -%}
@@ -220,7 +259,7 @@
{%- else -%}
{{as_annotated_cppType(arg)}}
{%- endif -%}
- {{render_cpp_default_value(arg, False)}}
+ {% if not dfn %}{{render_cpp_default_value(arg, False)}}{% endif %}
{%- endfor -%}
) const
{%- endmacro %}
@@ -234,26 +273,54 @@
using ObjectBase::operator=;
{% for method in type.methods %}
- {{render_cpp_method_declaration(type, method)}};
+ inline {{render_cpp_method_declaration(type, method)}};
{% endfor %}
private:
friend ObjectBase<{{CppType}}, {{CType}}>;
- static void {{c_prefix}}Reference({{CType}} handle);
- static void {{c_prefix}}Release({{CType}} handle);
+ static inline void {{c_prefix}}Reference({{CType}} handle);
+ static inline void {{c_prefix}}Release({{CType}} handle);
};
{% endfor %}
+ {%- macro render_function_call(function) -%}
+ {{as_cMethod(None, function.name)}}(
+ {%- for arg in function.arguments -%}
+ {% if not loop.first %}, {% endif %}{{render_c_actual_arg(arg)}}
+ {%- endfor -%}
+ )
+ {%- endmacro -%}
+
+ // Free Functions
+
{% for function in by_category["function"] if not function.no_cpp %}
- {{as_cppType(function.return_type.name)}} {{as_cppType(function.name)}}(
+ inline {{as_cppType(function.return_type.name)}} {{as_cppType(function.name)}}(
{%- for arg in function.arguments -%}
{%- if not loop.first %}, {% endif -%}
{{as_annotated_cppType(arg)}}{{render_cpp_default_value(arg, False)}}
{%- endfor -%}
- );
+ ) {
+ {% if function.return_type.name.concatcase() == "void" %}
+ {{render_function_call(function)}};
+ {% else %}
+ auto result = {{render_function_call(function)}};
+ return {{convert_cType_to_cppType(function.return_type, 'value', 'result')}};
+ {% endif %}
+ }
{% endfor %}
+ // ChainedStruct
+ {% set c_prefix = metadata.c_prefix %}
+ static_assert(sizeof(ChainedStruct) == sizeof({{c_prefix}}ChainedStruct),
+ "sizeof mismatch for ChainedStruct");
+ static_assert(alignof(ChainedStruct) == alignof({{c_prefix}}ChainedStruct),
+ "alignof mismatch for ChainedStruct");
+ static_assert(offsetof(ChainedStruct, nextInChain) == offsetof({{c_prefix}}ChainedStruct, next),
+ "offsetof mismatch for ChainedStruct::nextInChain");
+ static_assert(offsetof(ChainedStruct, sType) == offsetof({{c_prefix}}ChainedStruct, sType),
+ "offsetof mismatch for ChainedStruct::sType");
+
{% for type in by_category["structure"] %}
{% set Out = "Out" if type.output else "" %}
{% set const = "const" if not type.output else "" %}
@@ -272,11 +339,11 @@
{% endif %}
{% endif %}
{% if type.has_free_members_function %}
- ~{{as_cppType(type.name)}}();
+ inline ~{{as_cppType(type.name)}}();
{{as_cppType(type.name)}}(const {{as_cppType(type.name)}}&) = delete;
{{as_cppType(type.name)}}& operator=(const {{as_cppType(type.name)}}&) = delete;
- {{as_cppType(type.name)}}({{as_cppType(type.name)}}&&);
- {{as_cppType(type.name)}}& operator=({{as_cppType(type.name)}}&&);
+ inline {{as_cppType(type.name)}}({{as_cppType(type.name)}}&&);
+ inline {{as_cppType(type.name)}}& operator=({{as_cppType(type.name)}}&&);
{% endif %}
{% if type.extensible %}
ChainedStruct{{Out}} {{const}} * nextInChain = nullptr;
@@ -292,6 +359,11 @@
{{member_declaration}};
{% endif %}
{% endfor %}
+ {% if type.has_free_members_function %}
+
+ private:
+ static inline void Reset({{as_cppType(type.name)}}& value);
+ {% endif %}
};
{% endfor %}
@@ -301,6 +373,109 @@
// and need to be imported into this namespace for Argument Dependent Lookup.
WGPU_IMPORT_BITMASK_OPERATORS
{% endif %}
+
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+// error: 'offsetof' within non-standard-layout type '{{metadata.namespace}}::XXX' is conditionally-supported
+#pragma GCC diagnostic ignored "-Winvalid-offsetof"
+#endif
+ {% for type in by_category["structure"] %}
+ {% set CppType = as_cppType(type.name) %}
+ {% set CType = as_cType(type.name) %}
+ // {{CppType}} implementation
+ {% if type.has_free_members_function %}
+ {{CppType}}::~{{CppType}}() {
+ if (
+ {%- for member in type.members if member.annotation != 'value' %}
+ {% if not loop.first %} || {% endif -%}
+ this->{{member.name.camelCase()}} != nullptr
+ {%- endfor -%}
+ ) {
+ {{as_cMethod(type.name, Name("free members"))}}(
+ *reinterpret_cast<{{as_cType(type.name)}}*>(this));
+ }
+ }
+
+ {{CppType}}::{{CppType}}({{CppType}}&& rhs)
+ : {% for member in type.members %}
+ {%- set memberName = member.name.camelCase() -%}
+ {{memberName}}(rhs.{{memberName}}){% if not loop.last %},{{"\n "}}{% endif %}
+ {% endfor -%}
+ {
+ Reset(rhs);
+ }
+
+ {{CppType}}& {{CppType}}::operator=({{CppType}}&& rhs) {
+ if (&rhs == this) {
+ return *this;
+ }
+ this->~{{CppType}}();
+ {% for member in type.members %}
+ detail::AsNonConstReference(this->{{member.name.camelCase()}}) = std::move(rhs.{{member.name.camelCase()}});
+ {% endfor %}
+ Reset(rhs);
+ return *this;
+ }
+
+ // static
+ void {{CppType}}::Reset({{CppType}}& value) {
+ {{CppType}} defaultValue{};
+ {% for member in type.members %}
+ detail::AsNonConstReference(value.{{member.name.camelCase()}}) = defaultValue.{{member.name.camelCase()}};
+ {% endfor %}
+ }
+ {% endif %}
+
+ static_assert(sizeof({{CppType}}) == sizeof({{CType}}), "sizeof mismatch for {{CppType}}");
+ static_assert(alignof({{CppType}}) == alignof({{CType}}), "alignof mismatch for {{CppType}}");
+ {% if type.extensible %}
+ static_assert(offsetof({{CppType}}, nextInChain) == offsetof({{CType}}, nextInChain),
+ "offsetof mismatch for {{CppType}}::nextInChain");
+ {% endif %}
+ {% for member in type.members %}
+ {% set memberName = member.name.camelCase() %}
+ static_assert(offsetof({{CppType}}, {{memberName}}) == offsetof({{CType}}, {{memberName}}),
+ "offsetof mismatch for {{CppType}}::{{memberName}}");
+ {% endfor %}
+
+ {% endfor %}
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
+ {% for type in by_category["object"] %}
+ {% set CppType = as_cppType(type.name) %}
+ {% set CType = as_cType(type.name) %}
+ // {{CppType}} implementation
+
+ {% for method in type.methods %}
+ {{render_cpp_method_declaration(type, method, dfn=True)}} {
+ {% for arg in method.arguments if arg.type.has_free_members_function and arg.annotation == '*' %}
+ *{{as_varName(arg.name)}} = {{as_cppType(arg.type.name)}}();
+ {% endfor %}
+ {% if method.return_type.name.concatcase() == "void" %}
+ {{render_cpp_to_c_method_call(type, method)}};
+ {% else %}
+ auto result = {{render_cpp_to_c_method_call(type, method)}};
+ return {{convert_cType_to_cppType(method.return_type, 'value', 'result') | indent(8)}};
+ {% endif %}
+ }
+ {% endfor %}
+ void {{CppType}}::{{c_prefix}}Reference({{CType}} handle) {
+ if (handle != nullptr) {
+ {{as_cMethod(type.name, Name("reference"))}}(handle);
+ }
+ }
+ void {{CppType}}::{{c_prefix}}Release({{CType}} handle) {
+ if (handle != nullptr) {
+ {{as_cMethod(type.name, Name("release"))}}(handle);
+ }
+ }
+ static_assert(sizeof({{CppType}}) == sizeof({{CType}}), "sizeof mismatch for {{CppType}}");
+ static_assert(alignof({{CppType}}) == alignof({{CType}}), "alignof mismatch for {{CppType}}");
+
+ {% endfor %}
+
} // namespace {{metadata.namespace}}
namespace wgpu {
diff --git a/src/dawn/BUILD.gn b/src/dawn/BUILD.gn
index 2e243b5..ee5355b 100644
--- a/src/dawn/BUILD.gn
+++ b/src/dawn/BUILD.gn
@@ -34,15 +34,8 @@
# Dawn C++ wrapper
###############################################################################
-dawn_json_generator("cpp_gen") {
- target = "cpp"
- outputs = [ "src/dawn/webgpu_cpp.cpp" ]
-}
-
source_set("cpp") {
public_deps = [ "${dawn_root}/include/dawn:cpp_headers" ]
- deps = [ ":cpp_gen" ]
- sources = get_target_outputs(":cpp_gen")
}
###############################################################################
@@ -87,7 +80,6 @@
"emscripten-bits/system/include/webgpu/webgpu.h",
"emscripten-bits/system/include/webgpu/webgpu_cpp.h",
"emscripten-bits/system/include/webgpu/webgpu_cpp_chained_struct.h",
- "emscripten-bits/system/lib/webgpu/webgpu_cpp.cpp",
"emscripten-bits/webgpu_struct_info.json",
"emscripten-bits/library_webgpu_enum_tables.js",
]
diff --git a/src/dawn/CMakeLists.txt b/src/dawn/CMakeLists.txt
index 4bb4986..6e0932e 100644
--- a/src/dawn/CMakeLists.txt
+++ b/src/dawn/CMakeLists.txt
@@ -86,23 +86,8 @@
target_link_libraries(dawncpp_headers INTERFACE dawn_headers)
install_if_enabled(dawncpp_headers)
-###############################################################################
-# Dawn C++ wrapper
-###############################################################################
-
-DawnJSONGenerator(
- TARGET "cpp"
- PRINT_NAME "Dawn C++ wrapper"
- RESULT_VARIABLE "DAWNCPP_GEN_SOURCES"
-)
-
-add_library(dawncpp)
-common_compile_options(dawncpp)
-target_sources(dawncpp PRIVATE ${DAWNCPP_GEN_SOURCES})
-target_link_libraries(dawncpp PUBLIC dawncpp_headers)
-install_if_enabled(dawncpp)
-
-add_library(webgpu_cpp ALIAS dawncpp)
+add_library(dawncpp ALIAS dawncpp_headers)
+add_library(webgpu_cpp ALIAS dawncpp_headers)
###############################################################################
# libdawn_proc
diff --git a/src/dawn/samples/BUILD.gn b/src/dawn/samples/BUILD.gn
index ed3f26b..9e7eab2 100644
--- a/src/dawn/samples/BUILD.gn
+++ b/src/dawn/samples/BUILD.gn
@@ -48,7 +48,6 @@
# Export all of these as public deps so that `gn check` allows includes
public_deps = [
"${dawn_root}/src/dawn:cpp",
- "${dawn_root}/src/dawn:proc_shared",
"${dawn_root}/src/dawn/common",
"${dawn_root}/src/dawn/glfw",
"${dawn_root}/src/dawn/native",