Add dawn/wire/client/webgpu{_cpp}.h
client/webgpu.h includes webgpu/webgpu.h, but also declares
wgpuDawnWireClient-prefixed methods.
client/webgpu_cpp.h is a duplicate copy of the webgpu_cpp.h header
except it includes client/webgpu.h, has different include guards,
and uses wgpuDawnWireClient-prefixed methods.
Objects and structs are defined in the wgpu::dawn::wire::client
namespace, and then aliased into the wgpu:: namespace.
This means that use of the methods will dispatch to the wire client,
implementation of them, and we avoid duplicate definitions of other
definitions in the wgpu namespace
It is not valid to include both client/webgpu_cpp.h and
webgpu/webgpu_cpp.h. This will result in errors about duplicate dfns.
Bug: chromium:40195122
Change-Id: I6eec057253bfbe0cf2292210c82d2fc2b663dc89
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/184243
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/generator/dawn_json_generator.py b/generator/dawn_json_generator.py
index e605181..92181ae 100644
--- a/generator/dawn_json_generator.py
+++ b/generator/dawn_json_generator.py
@@ -945,15 +945,20 @@
assert not type_name.native and not value_name.native
return c_prefix + type_name.CamelCase() + '_' + value_name.CamelCase()
- def as_cMethod(type_name, method_name):
+ def as_cMethodNamespaced(type_name, method_name, namespace=None):
c_method = c_prefix.lower()
- if type_name != None:
+ if namespace is not None:
+ c_method += namespace.CamelCase()
+ if type_name is not None:
assert not type_name.native
c_method += type_name.CamelCase()
assert not method_name.native
c_method += method_name.CamelCase()
return c_method
+ def as_cMethod(type_name, method_name):
+ return as_cMethodNamespaced(type_name, method_name)
+
def as_cProc(type_name, method_name):
c_proc = c_prefix + 'Proc'
if type_name != None:
@@ -972,6 +977,7 @@
'as_cEnum': as_cEnum,
'as_cppEnum': as_cppEnum,
'as_cMethod': as_cMethod,
+ 'as_cMethodNamespaced': as_cMethodNamespaced,
'as_MethodSuffix': as_MethodSuffix,
'as_CppMethodSuffix': as_CppMethodSuffix,
'as_cProc': as_cProc,
@@ -1047,14 +1053,32 @@
FileRender('api.h', 'include/dawn/' + api + '.h',
[RENDER_PARAMS_BASE, params_dawn]))
renders.append(
+ FileRender('dawn/wire/client/api.h',
+ 'include/dawn/wire/client/' + api + '.h',
+ [RENDER_PARAMS_BASE, params_dawn]))
+ renders.append(
FileRender('dawn_proc_table.h',
'include/dawn/' + prefix + '_proc_table.h',
[RENDER_PARAMS_BASE, params_dawn]))
if 'cpp_headers' in targets:
renders.append(
- FileRender('api_cpp.h', 'include/dawn/' + api + '_cpp.h',
- [RENDER_PARAMS_BASE, params_dawn]))
+ FileRender('api_cpp.h', 'include/dawn/' + api + '_cpp.h', [
+ RENDER_PARAMS_BASE, params_dawn, {
+ 'c_header': api + '/' + api + '.h',
+ 'c_namespace': None,
+ }
+ ]))
+
+ renders.append(
+ FileRender(
+ 'api_cpp.h', 'include/dawn/wire/client/' + api + '_cpp.h',
+ [
+ RENDER_PARAMS_BASE, params_dawn, {
+ 'c_header': 'dawn/wire/client/' + api + '.h',
+ 'c_namespace': Name('dawn wire client'),
+ }
+ ]))
renders.append(
FileRender('api_cpp_print.h',
@@ -1101,8 +1125,12 @@
renders.append(
FileRender(
'api_cpp.h',
- 'emscripten-bits/system/include/webgpu/webgpu_cpp.h',
- [RENDER_PARAMS_BASE, params_emscripten]))
+ 'emscripten-bits/system/include/webgpu/webgpu_cpp.h', [
+ RENDER_PARAMS_BASE, params_emscripten, {
+ 'c_header': api + '/' + api + '.h',
+ 'c_namespace': None,
+ }
+ ]))
renders.append(
FileRender(
'api_cpp_chained_struct.h',
diff --git a/generator/templates/api_cpp.h b/generator/templates/api_cpp.h
index 18b83ee..9dbb2a6 100644
--- a/generator/templates/api_cpp.h
+++ b/generator/templates/api_cpp.h
@@ -31,10 +31,16 @@
#error "Do not include this header. Emscripten already provides headers needed for {{metadata.api}}."
#endif
{% endif %}
-#ifndef {{API}}_CPP_H_
-#define {{API}}_CPP_H_
+{% set PREFIX = "" if not c_namespace else c_namespace.SNAKE_CASE() + "_" %}
+#ifndef {{PREFIX}}{{API}}_CPP_H_
+#define {{PREFIX}}{{API}}_CPP_H_
-#include "{{api}}/{{api}}.h"
+#include <cmath>
+#include <cstddef>
+#include <cstdint>
+#include <functional>
+
+#include "{{c_header}}"
#include "{{api}}/{{api}}_cpp_chained_struct.h"
#include "{{api}}/{{api}}_enum_class_bitmasks.h"
#include <cmath>
@@ -81,7 +87,7 @@
{%- endmacro -%}
{%- macro render_cpp_to_c_method_call(type, method) -%}
- {{as_cMethod(type.name, method.name)}}(Get()
+ {{as_cMethodNamespaced(type.name, method.name, c_namespace)}}(Get()
{%- for arg in method.arguments -%},{{" "}}{{render_c_actual_arg(arg)}}
{%- endfor -%}
)
@@ -117,15 +123,6 @@
using {{as_cppType(type.name)}} = {{as_cType(type.name)}};
{% endfor %}
-{% for type in by_category["object"] %}
- class {{as_cppType(type.name)}};
-{% endfor %}
-
-{% for type in by_category["structure"] %}
- 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) %}
@@ -145,12 +142,6 @@
{{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.
- using {{as_cppType(typeDef.name)}} = {{as_cppType(typeDef.type.name)}};
-
-{% endfor %}
template<typename Derived, typename CType>
class ObjectBase {
public:
@@ -264,6 +255,32 @@
) const
{%- endmacro %}
+{%- macro render_function_call(function) -%}
+ {{as_cMethodNamespaced(None, function.name, c_namespace)}}(
+ {%- for arg in function.arguments -%}
+ {% if not loop.first %}, {% endif %}{{render_c_actual_arg(arg)}}
+ {%- endfor -%}
+ )
+{%- endmacro -%}
+
+{%- if metadata.namespace != 'wgpu' %}
+ // The operators of webgpu_enum_class_bitmasks.h are in the wgpu:: namespace,
+ // and need to be imported into this namespace for Argument Dependent Lookup.
+ WGPU_IMPORT_BITMASK_OPERATORS
+{% endif %}
+
+{% if c_namespace %}
+ namespace {{c_namespace.namespace_case()}} {
+{% endif %}
+
+{% for type in by_category["object"] %}
+ class {{as_cppType(type.name)}};
+{% endfor %}
+
+{% for type in by_category["structure"] %}
+ struct {{as_cppType(type.name)}};
+{% endfor %}
+
{% for type in by_category["object"] %}
{% set CppType = as_cppType(type.name) %}
{% set CType = as_cType(type.name) %}
@@ -284,32 +301,6 @@
{% 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 %}
- 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),
@@ -368,12 +359,6 @@
{% endfor %}
-{%- if metadata.namespace != 'wgpu' %}
- // The operators of webgpu_enum_class_bitmasks.h are in the wgpu:: namespace,
- // 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
@@ -391,7 +376,7 @@
this->{{member.name.camelCase()}} != nullptr
{%- endfor -%}
) {
- {{as_cMethod(type.name, Name("free members"))}}(
+ {{as_cMethodNamespaced(type.name, Name("free members"), c_namespace)}}(
*reinterpret_cast<{{as_cType(type.name)}}*>(this));
}
}
@@ -463,12 +448,12 @@
{% endfor %}
void {{CppType}}::{{c_prefix}}AddRef({{CType}} handle) {
if (handle != nullptr) {
- {{as_cMethod(type.name, Name("add ref"))}}(handle);
+ {{as_cMethodNamespaced(type.name, Name("add ref"), c_namespace)}}(handle);
}
}
void {{CppType}}::{{c_prefix}}Release({{CType}} handle) {
if (handle != nullptr) {
- {{as_cMethod(type.name, Name("release"))}}(handle);
+ {{as_cMethodNamespaced(type.name, Name("release"), c_namespace)}}(handle);
}
}
static_assert(sizeof({{CppType}}) == sizeof({{CType}}), "sizeof mismatch for {{CppType}}");
@@ -476,6 +461,41 @@
{% endfor %}
+{% if c_namespace %}
+ } // namespace {{c_namespace.namespace_case()}}
+
+ {% for type in by_category["object"] %}
+ using {{as_cppType(type.name)}} = {{c_namespace.namespace_case()}}::{{as_cppType(type.name)}};
+ {% endfor %}
+
+ {% for type in by_category["structure"] %}
+ using {{as_cppType(type.name)}} = {{c_namespace.namespace_case()}}::{{as_cppType(type.name)}};
+ {% endfor %}
+{% endif %}
+
+{% for typeDef in by_category["typedef"] %}
+ // {{as_cppType(typeDef.name)}} is deprecated.
+ // Use {{as_cppType(typeDef.type.name)}} instead.
+ using {{as_cppType(typeDef.name)}} = {{as_cppType(typeDef.type.name)}};
+{% endfor %}
+
+// Free Functions
+{% for function in by_category["function"] if not function.no_cpp %}
+ static 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 %}
+
} // namespace {{metadata.namespace}}
namespace wgpu {
@@ -499,4 +519,4 @@
};
} // namespace std
-#endif // {{API}}_CPP_H_
+#endif // {{PREFIX}}{{API}}_CPP_H_
diff --git a/generator/templates/dawn/wire/client/ApiProcs.cpp b/generator/templates/dawn/wire/client/ApiProcs.cpp
index a5d45aa..a8ace32 100644
--- a/generator/templates/dawn/wire/client/ApiProcs.cpp
+++ b/generator/templates/dawn/wire/client/ApiProcs.cpp
@@ -25,16 +25,15 @@
//* 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 "dawn/wire/client/ApiObjects.h"
-#include "dawn/wire/client/Client.h"
-#include "dawn/wire/client/Instance.h"
-
#include <algorithm>
#include <cstring>
#include <string>
#include <type_traits>
#include <vector>
+#include "dawn/wire/client/Client.h"
+#include "dawn/wire/client/webgpu.h"
+
namespace dawn::wire::client {
// Template function for constexpr branching when creating new objects.
@@ -53,127 +52,120 @@
}
}
- //* Outputs an rvalue that's the number of elements a pointer member points to.
- {% macro member_length(member, accessor) -%}
- {%- if member.length == "constant" -%}
- {{member.constant_length}}
- {%- else -%}
- {{accessor}}{{as_varName(member.length.name)}}
- {%- endif -%}
- {%- endmacro %}
+} // namespace dawn::wire::client
- //* Implementation of the client API functions.
- {% for type in by_category["object"] %}
- {% set Type = type.name.CamelCase() %}
- {% set cType = as_cType(type.name) %}
+//* Implementation of the client API functions.
+{% for type in by_category["object"] %}
+ {%- set Type = "dawn::wire::client::" + type.name.CamelCase() -%}
+ {%- set cType = as_cType(type.name) -%}
- {% for method in type.methods %}
- {% set Suffix = as_MethodSuffix(type.name, method.name) %}
+ {% for method in type.methods %}
+ {% set Suffix = as_MethodSuffix(type.name, method.name) %}
- {% if Suffix in client_handwritten_commands %}
- static
- {% endif %}
- {{as_cReturnType(method.return_type)}} Client{{Suffix}}(
- {{-cType}} cSelf
- {%- for arg in method.arguments -%}
- , {{as_annotated_cType(arg)}}
- {%- endfor -%}
- ) {
- auto self = reinterpret_cast<{{as_wireType(type)}}>(cSelf);
- {% if Suffix not in client_handwritten_commands %}
- {{Suffix}}Cmd cmd;
+ DAWN_WIRE_EXPORT {{as_cReturnType(method.return_type)}} {{as_cMethodNamespaced(type.name, method.name, Name('dawn wire client'))}}(
+ {{-cType}} cSelf
+ {%- for arg in method.arguments -%}
+ , {{as_annotated_cType(arg)}}
+ {%- endfor -%}
+ ) {
+ auto self = reinterpret_cast<dawn::wire::client::{{as_wireType(type)}}>(cSelf);
+ {% if Suffix not in client_handwritten_commands %}
+ dawn::wire::{{Suffix}}Cmd cmd;
- //* Create the structure going on the wire on the stack and fill it with the value
- //* arguments so it can compute its size.
- cmd.self = cSelf;
+ //* Create the structure going on the wire on the stack and fill it with the value
+ //* arguments so it can compute its size.
+ cmd.self = cSelf;
- //* For object creation, store the object ID the client will use for the result.
- {% if method.return_type.category == "object" %}
- {% set ReturnObj = method.return_type.name.CamelCase() %}
- {{ReturnObj}}* returnObject = Create<{{as_wireType(type)}}, {{ReturnObj}}>(self
- {%- for arg in method.arguments -%}
- , {{as_varName(arg.name)}}
- {%- endfor -%}
- );
- cmd.result = returnObject->GetWireHandle();
- {% endif %}
-
- {% for arg in method.arguments %}
- //* Commands with mutable pointers should not be autogenerated.
- {{assert(arg.annotation != "*")}}
- cmd.{{as_varName(arg.name)}} = {{as_varName(arg.name)}};
- {% endfor %}
-
- //* Allocate space to send the command and copy the value args over.
- self->GetClient()->SerializeCommand(cmd);
-
- {% if method.return_type.category == "object" %}
- return ToAPI(returnObject);
- {% endif %}
- {% else %}
- return self->{{method.name.CamelCase()}}(
+ //* For object creation, store the object ID the client will use for the result.
+ {% if method.return_type.category == "object" %}
+ {% set ReturnObj = "dawn::wire::client::" + method.return_type.name.CamelCase() %}
+ {{ReturnObj}}* returnObject = dawn::wire::client::Create<dawn::wire::client::{{as_wireType(type)}}, {{ReturnObj}}>(self
{%- for arg in method.arguments -%}
- {%if not loop.first %}, {% endif %} {{as_varName(arg.name)}}
- {%- endfor -%});
+ , {{as_varName(arg.name)}}
+ {%- endfor -%}
+ );
+ cmd.result = returnObject->GetWireHandle();
{% endif %}
- }
- {% endfor %}
- //* When an object's refcount reaches 0, notify the server side of it and delete it.
- void Client{{as_MethodSuffix(type.name, Name("release"))}}({{cType}} cObj) {
- {{Type}}* obj = reinterpret_cast<{{Type}}*>(cObj);
- obj->Release();
- }
+ {% for arg in method.arguments %}
+ //* Commands with mutable pointers should not be autogenerated.
+ {{assert(arg.annotation != "*")}}
+ cmd.{{as_varName(arg.name)}} = {{as_varName(arg.name)}};
+ {% endfor %}
- void Client{{as_MethodSuffix(type.name, Name("add ref"))}}({{cType}} cObj) {
- reinterpret_cast<{{Type}}*>(cObj)->AddRef();
- }
+ //* Allocate space to send the command and copy the value args over.
+ self->GetClient()->SerializeCommand(cmd);
- //* TODO(dawn:2234): Deprecated. Remove once no longer user.
- void Client{{as_MethodSuffix(type.name, Name("reference"))}}({{cType}} cObj) {
- Client{{as_MethodSuffix(type.name, Name("add ref"))}}(cObj);
+ {% if method.return_type.category == "object" %}
+ return ToAPI(returnObject);
+ {% endif %}
+ {% else %}
+ return self->{{method.name.CamelCase()}}(
+ {%- for arg in method.arguments -%}
+ {%if not loop.first %}, {% endif %} {{as_varName(arg.name)}}
+ {%- endfor -%});
+ {% endif %}
}
{% endfor %}
- namespace {
- struct ProcEntry {
- WGPUProc proc;
- const char* name;
- };
- static const ProcEntry sProcMap[] = {
- {% for (type, method) in c_methods_sorted_by_name %}
- { reinterpret_cast<WGPUProc>(Client{{as_MethodSuffix(type.name, method.name)}}), "{{as_cMethod(type.name, method.name)}}" },
- {% endfor %}
- };
- static constexpr size_t sProcMapSize = sizeof(sProcMap) / sizeof(sProcMap[0]);
- } // anonymous namespace
+ //* When an object's refcount reaches 0, notify the server side of it and delete it.
+ DAWN_WIRE_EXPORT void {{as_cMethodNamespaced(type.name, Name("release"), Name('dawn wire client'))}}({{cType}} cObj) {
+ {{Type}}* obj = reinterpret_cast<{{Type}}*>(cObj);
+ obj->Release();
+ }
- WGPUProc ClientGetProcAddress(WGPUDevice, const char* procName) {
- if (procName == nullptr) {
- return nullptr;
- }
+ DAWN_WIRE_EXPORT void {{as_cMethodNamespaced(type.name, Name("add ref"), Name('dawn wire client'))}}({{cType}} cObj) {
+ reinterpret_cast<{{Type}}*>(cObj)->AddRef();
+ }
- const ProcEntry* entry = std::lower_bound(&sProcMap[0], &sProcMap[sProcMapSize], procName,
- [](const ProcEntry &a, const char *b) -> bool {
- return strcmp(a.name, b) < 0;
- }
- );
+ //* TODO(dawn:2234): Deprecated. Remove once no longer user.
+ DAWN_WIRE_EXPORT void {{as_cMethodNamespaced(type.name, Name("reference"), Name('dawn wire client'))}}({{cType}} cObj) {
+ {{as_cMethodNamespaced(type.name, Name("add ref"), Name('dawn wire client'))}}(cObj);
+ }
- if (entry != &sProcMap[sProcMapSize] && strcmp(entry->name, procName) == 0) {
- return entry->proc;
- }
+{% endfor %}
- // Special case the free-standing functions of the API.
- // TODO(dawn:1238) Checking string one by one is slow, it needs to be optimized.
- {% for function in by_category["function"] %}
- if (strcmp(procName, "{{as_cMethod(None, function.name)}}") == 0) {
- return reinterpret_cast<WGPUProc>(Client{{as_cppType(function.name)}});
- }
-
+namespace {
+ struct ProcEntry {
+ WGPUProc proc;
+ const char* name;
+ };
+ static const ProcEntry sProcMap[] = {
+ {% for (type, method) in c_methods_sorted_by_name %}
+ { reinterpret_cast<WGPUProc>({{as_cMethodNamespaced(type.name, method.name, Name('dawn wire client'))}}), "{{as_cMethod(type.name, method.name)}}" },
{% endfor %}
+ };
+ static constexpr size_t sProcMapSize = sizeof(sProcMap) / sizeof(sProcMap[0]);
+} // anonymous namespace
+
+DAWN_WIRE_EXPORT WGPUProc {{as_cMethodNamespaced(None, Name('get proc address'), Name('dawn wire client'))}}(WGPUDevice, const char* procName) {
+ if (procName == nullptr) {
return nullptr;
}
+ const ProcEntry* entry = std::lower_bound(&sProcMap[0], &sProcMap[sProcMapSize], procName,
+ [](const ProcEntry &a, const char *b) -> bool {
+ return strcmp(a.name, b) < 0;
+ }
+ );
+
+ if (entry != &sProcMap[sProcMapSize] && strcmp(entry->name, procName) == 0) {
+ return entry->proc;
+ }
+
+ // Special case the free-standing functions of the API.
+ // TODO(dawn:1238) Checking string one by one is slow, it needs to be optimized.
+ {% for function in by_category["function"] %}
+ if (strcmp(procName, "{{as_cMethod(None, function.name)}}") == 0) {
+ return reinterpret_cast<WGPUProc>({{as_cMethodNamespaced(None, function.name, Name('dawn wire client'))}});
+ }
+
+ {% endfor %}
+ return nullptr;
+}
+
+namespace dawn::wire::client {
+
std::vector<const char*> GetProcMapNamesForTesting() {
std::vector<const char*> result;
result.reserve(sProcMapSize);
@@ -188,11 +180,11 @@
constexpr {{Prefix}}ProcTable MakeProcTable() {
{{Prefix}}ProcTable procs = {};
{% for function in by_category["function"] %}
- procs.{{as_varName(function.name)}} = Client{{as_cppType(function.name)}};
+ procs.{{as_varName(function.name)}} = {{as_cMethodNamespaced(None, function.name, Name('dawn wire client'))}};
{% endfor %}
{% for type in by_category["object"] %}
{% for method in c_methods(type) %}
- procs.{{as_varName(type.name, method.name)}} = Client{{as_MethodSuffix(type.name, method.name)}};
+ procs.{{as_varName(type.name, method.name)}} = {{as_cMethodNamespaced(type.name, method.name, Name('dawn wire client'))}};
{% endfor %}
{% endfor %}
return procs;
@@ -203,4 +195,5 @@
const {{Prefix}}ProcTable& GetProcs() {
return gProcTable;
}
+
} // namespace dawn::wire::client
diff --git a/generator/templates/dawn/wire/client/api.h b/generator/templates/dawn/wire/client/api.h
new file mode 100644
index 0000000..d287001
--- /dev/null
+++ b/generator/templates/dawn/wire/client/api.h
@@ -0,0 +1,70 @@
+//* Copyright 2024 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.
+//*
+//*
+{% set API = metadata.c_prefix %}
+{% set api = metadata.api.lower() %}
+#ifndef DAWN_WIRE_CLIENT_{{metadata.api.upper()}}_H_
+#define DAWN_WIRE_CLIENT_{{metadata.api.upper()}}_H_
+
+#include "{{api}}/{{api}}.h"
+#include "dawn/wire/dawn_wire_export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+{% for function in by_category["function"] %}
+ DAWN_WIRE_EXPORT {{as_cType(function.return_type.name)}} {{as_cMethodNamespaced(None, function.name, Name('dawn wire client'))}}(
+ {%- for arg in function.arguments -%}
+ {% if not loop.first %}, {% endif -%}
+ {%- if arg.optional %}{{API}}_NULLABLE {% endif -%}
+ {{as_annotated_cType(arg)}}
+ {%- endfor -%}
+ ) {{API}}_FUNCTION_ATTRIBUTE;
+{% endfor %}
+
+{% for type in by_category["object"] if len(c_methods(type)) > 0 %}
+ // Methods of {{type.name.CamelCase()}}
+ {% for method in c_methods(type) %}
+ DAWN_WIRE_EXPORT {{as_cReturnType(method.return_type)}} {{as_cMethodNamespaced(type.name, method.name, Name('dawn wire client'))}}(
+ {{-as_cType(type.name)}} {{as_varName(type.name)}}
+ {%- for arg in method.arguments -%}
+ ,{{" "}}
+ {%- if arg.optional %}{{API}}_NULLABLE {% endif -%}
+ {{as_annotated_cType(arg)}}
+ {%- endfor -%}
+ ) {{API}}_FUNCTION_ATTRIBUTE;
+ {% endfor %}
+
+{% endfor %}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // DAWN_WIRE_CLIENT_{{metadata.api.upper()}}_H_
diff --git a/include/dawn/BUILD.gn b/include/dawn/BUILD.gn
index d935ffa..503daff 100644
--- a/include/dawn/BUILD.gn
+++ b/include/dawn/BUILD.gn
@@ -39,6 +39,7 @@
outputs = [
"include/dawn/dawn_proc_table.h",
"include/dawn/webgpu.h",
+ "include/dawn/wire/client/webgpu.h",
]
}
@@ -59,6 +60,7 @@
"include/dawn/webgpu_cpp.h",
"include/dawn/webgpu_cpp_print.h",
"include/webgpu/webgpu_cpp_chained_struct.h",
+ "include/dawn/wire/client/webgpu_cpp.h",
]
}
diff --git a/src/dawn/wire/client/Adapter.cpp b/src/dawn/wire/client/Adapter.cpp
index 846fc86..e4a240f 100644
--- a/src/dawn/wire/client/Adapter.cpp
+++ b/src/dawn/wire/client/Adapter.cpp
@@ -32,6 +32,7 @@
#include "dawn/common/Log.h"
#include "dawn/wire/client/Client.h"
+#include "dawn/wire/client/webgpu.h"
#include "partition_alloc/pointers/raw_ptr.h"
namespace dawn::wire::client {
@@ -237,20 +238,6 @@
ptr += driverDescriptionCLen;
}
-void ClientAdapterPropertiesFreeMembers(WGPUAdapterProperties properties) {
- // This single delete is enough because everything is a single allocation.
- delete[] properties.vendorName;
-}
-
-void ClientAdapterPropertiesMemoryHeapsFreeMembers(
- WGPUAdapterPropertiesMemoryHeaps memoryHeapProperties) {
- delete[] memoryHeapProperties.heapInfo;
-}
-
-void ClientDrmFormatCapabilitiesFreeMembers(WGPUDrmFormatCapabilities capabilities) {
- delete[] capabilities.properties;
-}
-
void Adapter::RequestDevice(const WGPUDeviceDescriptor* descriptor,
WGPURequestDeviceCallback callback,
void* userdata) {
@@ -325,3 +312,19 @@
}
} // namespace dawn::wire::client
+
+DAWN_WIRE_EXPORT void wgpuDawnWireClientAdapterPropertiesFreeMembers(
+ WGPUAdapterProperties properties) {
+ // This single delete is enough because everything is a single allocation.
+ delete[] properties.vendorName;
+}
+
+DAWN_WIRE_EXPORT void wgpuDawnWireClientAdapterPropertiesMemoryHeapsFreeMembers(
+ WGPUAdapterPropertiesMemoryHeaps memoryHeapProperties) {
+ delete[] memoryHeapProperties.heapInfo;
+}
+
+DAWN_WIRE_EXPORT void wgpuDawnWireClientDrmFormatCapabilitiesFreeMembers(
+ WGPUDrmFormatCapabilities capabilities) {
+ delete[] capabilities.properties;
+}
diff --git a/src/dawn/wire/client/Adapter.h b/src/dawn/wire/client/Adapter.h
index cac6111..1dfe881 100644
--- a/src/dawn/wire/client/Adapter.h
+++ b/src/dawn/wire/client/Adapter.h
@@ -30,7 +30,6 @@
#include <vector>
-#include "dawn/webgpu.h"
#include "dawn/wire/WireClient.h"
#include "dawn/wire/WireCmd_autogen.h"
#include "dawn/wire/client/LimitsAndFeatures.h"
@@ -71,10 +70,6 @@
WGPUAdapterPropertiesVk mVkProperties;
};
-void ClientAdapterPropertiesFreeMembers(WGPUAdapterProperties);
-void ClientAdapterPropertiesMemoryHeapsFreeMembers(WGPUAdapterPropertiesMemoryHeaps);
-void ClientDrmFormatCapabilitiesFreeMembers(WGPUDrmFormatCapabilities capabilities);
-
} // namespace dawn::wire::client
#endif // SRC_DAWN_WIRE_CLIENT_ADAPTER_H_
diff --git a/src/dawn/wire/client/Instance.cpp b/src/dawn/wire/client/Instance.cpp
index 27e2091..8a764d1 100644
--- a/src/dawn/wire/client/Instance.cpp
+++ b/src/dawn/wire/client/Instance.cpp
@@ -36,6 +36,7 @@
#include "dawn/wire/client/ApiObjects_autogen.h"
#include "dawn/wire/client/Client.h"
#include "dawn/wire/client/EventManager.h"
+#include "dawn/wire/client/webgpu.h"
#include "partition_alloc/pointers/raw_ptr.h"
#include "tint/lang/wgsl/features/language_feature.h"
#include "tint/lang/wgsl/features/status.h"
@@ -121,23 +122,6 @@
} // anonymous namespace
-// Free-standing API functions
-
-WGPUBool ClientGetInstanceFeatures(WGPUInstanceFeatures* features) {
- if (features->nextInChain != nullptr) {
- return false;
- }
-
- features->timedWaitAnyEnable = false;
- features->timedWaitAnyMaxCount = kTimedWaitAnyMaxCountDefault;
- return true;
-}
-
-WGPUInstance ClientCreateInstance(WGPUInstanceDescriptor const* descriptor) {
- DAWN_UNREACHABLE();
- return nullptr;
-}
-
// Instance
Instance::Instance(const ObjectBaseParams& params) : ObjectWithEventsBase(params, params.handle) {}
@@ -338,3 +322,21 @@
}
} // namespace dawn::wire::client
+
+// Free-standing API functions
+
+DAWN_WIRE_EXPORT WGPUBool wgpuDawnWireClientGetInstanceFeatures(WGPUInstanceFeatures* features) {
+ if (features->nextInChain != nullptr) {
+ return false;
+ }
+
+ features->timedWaitAnyEnable = false;
+ features->timedWaitAnyMaxCount = dawn::kTimedWaitAnyMaxCountDefault;
+ return true;
+}
+
+DAWN_WIRE_EXPORT WGPUInstance
+wgpuDawnWireClientCreateInstance(WGPUInstanceDescriptor const* descriptor) {
+ DAWN_UNREACHABLE();
+ return nullptr;
+}
diff --git a/src/dawn/wire/client/Instance.h b/src/dawn/wire/client/Instance.h
index 3963fc8..466385c 100644
--- a/src/dawn/wire/client/Instance.h
+++ b/src/dawn/wire/client/Instance.h
@@ -29,16 +29,12 @@
#define SRC_DAWN_WIRE_CLIENT_INSTANCE_H_
#include "absl/container/flat_hash_set.h"
-#include "dawn/webgpu.h"
#include "dawn/wire/WireClient.h"
#include "dawn/wire/WireCmd_autogen.h"
#include "dawn/wire/client/ObjectBase.h"
namespace dawn::wire::client {
-WGPUBool ClientGetInstanceFeatures(WGPUInstanceFeatures* features);
-WGPUInstance ClientCreateInstance(WGPUInstanceDescriptor const* descriptor);
-
class Instance final : public ObjectWithEventsBase {
public:
explicit Instance(const ObjectBaseParams& params);
diff --git a/src/dawn/wire/client/Surface.cpp b/src/dawn/wire/client/Surface.cpp
index 24d947e..d72592e 100644
--- a/src/dawn/wire/client/Surface.cpp
+++ b/src/dawn/wire/client/Surface.cpp
@@ -32,6 +32,7 @@
#include "dawn/wire/client/Client.h"
#include "dawn/wire/client/Device.h"
#include "dawn/wire/client/Texture.h"
+#include "dawn/wire/client/webgpu.h"
namespace dawn::wire::client {
@@ -84,9 +85,10 @@
wireClient->SerializeCommand(cmd);
}
-void ClientSurfaceCapabilitiesFreeMembers(WGPUSurfaceCapabilities capabilities) {
+} // namespace dawn::wire::client
+
+DAWN_WIRE_EXPORT void wgpuDawnWireClientSurfaceCapabilitiesFreeMembers(
+ WGPUSurfaceCapabilities capabilities) {
// TODO(dawn:2320): Implement this
dawn::ErrorLog() << "surfaceCapabilities.FreeMembers not supported yet with dawn_wire.";
}
-
-} // namespace dawn::wire::client
diff --git a/src/dawn/wire/client/Surface.h b/src/dawn/wire/client/Surface.h
index cb776ea..f153c63 100644
--- a/src/dawn/wire/client/Surface.h
+++ b/src/dawn/wire/client/Surface.h
@@ -29,7 +29,6 @@
#define SRC_DAWN_WIRE_CLIENT_SURFACE_H_
#include "dawn/webgpu.h"
-
#include "dawn/wire/client/ObjectBase.h"
namespace dawn::wire::client {
@@ -55,8 +54,6 @@
WGPUTextureDescriptor mTextureDescriptor;
};
-void ClientSurfaceCapabilitiesFreeMembers(WGPUSurfaceCapabilities capabilities);
-
} // namespace dawn::wire::client
#endif // SRC_DAWN_WIRE_CLIENT_SURFACE_H_