dawn.json changes for the flexible templates
- Adds "_memtadata" that contains various metadata, the key
"api" represents the target of generating Web Standard API.
Rename webgpu.h to api.h and replace relative content with
metadata.
BUG=dawn:1201
Change-Id: I8b422ce4bd3f33d95e78d6c4b80f1310f7ac6726
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/70220
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Junwei Fu <junwei.fu@intel.com>
diff --git a/dawn.json b/dawn.json
index 29893b0..4954b29 100644
--- a/dawn.json
+++ b/dawn.json
@@ -17,6 +17,12 @@
"_doc": "See docs/codegen.md",
+ "_metadata": {
+ "api": "WebGPU",
+ "c_prefix": "WGPU",
+ "namespace": "wgpu"
+ },
+
"request adapter options": {
"category": "structure",
"extensible": "in",
diff --git a/docs/codegen.md b/docs/codegen.md
index 036305c..e6cb773 100644
--- a/docs/codegen.md
+++ b/docs/codegen.md
@@ -23,6 +23,13 @@
Internally `dawn.json` is a dictionary from the "canonical name" of things to their definition. The "canonical name" is a space-separated (mostly) lower-case version of the name that's parsed into a `Name` Python object. Then that name can be turned into various casings with `.CamelCase()` `.SNAKE_CASE()`, etc. When `dawn.json` things reference each other, it is always via these "canonical names".
+The `"_metadata"` key in the JSON file is used by flexible templates for generating various Web Standard API that contains following metadata:
+
+ - `"api"` a string, the name of the Web API
+ - `"namespace"` a string, the namespace of C++ wrapper
+ - `"c_prefix"` (optional) a string, the prefix of C function and data type, it will default to upper-case of `"namespace"` if it's not provided.
+ - `"copyright_year"` (optional) a string, templates will use the the year of copyright.
+
The basic schema is that every entry is a thing with a `"category"` key what determines the sub-schema to apply to that thing. Categories and their sub-shema are defined below. Several parts of the schema use the concept of "record" which is a list of "record members" which are a combination of a type, a name and other metadata. For example the list of arguments of a function is a record. The list of structure members is a record. This combined concept is useful for the dawn_wire generator to generate code for structure and function calls in a very similar way.
Most items and sub-items can include a list of `"tags"`, which, if specified, conditionally includes the item if any of its tags appears in the `enabled_tags` configuration passed to `parse_json`. This is used to include and exclude various items for Dawn, Emscripten, or upstream header variants. Tags are applied in the "parse_json" step ([rather than later](https://docs.google.com/document/d/1fBniVOxx3-hQbxHMugEPcQsaXaKBZYVO8yG9iXJp-fU/edit?usp=sharing)): this has the benefit of automatically catching when, for a particular tag configuration, an included item references an excluded item.
diff --git a/generator/dawn_json_generator.py b/generator/dawn_json_generator.py
index 8783eb0..be2456a 100644
--- a/generator/dawn_json_generator.py
+++ b/generator/dawn_json_generator.py
@@ -23,6 +23,14 @@
############################################################
+class Metadata:
+ def __init__(self, metadata):
+ self.api = metadata['api']
+ self.namespace = metadata['namespace']
+ self.c_prefix = metadata.get('c_prefix', self.namespace.upper())
+ self.copyright_year = metadata.get('copyright_year', None)
+
+
class Name:
def __init__(self, name, native=False):
self.native = native
@@ -397,6 +405,7 @@
'enabled_tags': enabled_tags,
}
return {
+ 'metadata': Metadata(json['_metadata']),
'types': types,
'by_category': by_category,
'enabled_tags': enabled_tags,
@@ -494,24 +503,11 @@
[name.CamelCase() for name in names[1:]])
-def as_cType(name):
+def as_cType(c_prefix, name):
if name.native:
return name.concatcase()
else:
- return 'WGPU' + name.CamelCase()
-
-
-def as_cTypeDawn(name):
- if name.native:
- return name.concatcase()
- else:
- return 'Dawn' + name.CamelCase()
-
-
-def as_cTypeEnumSpecialCase(typ):
- if typ.category == 'bitmask':
- return as_cType(typ.name) + 'Flags'
- return as_cType(typ.name)
+ return c_prefix + name.CamelCase()
def as_cppType(name):
@@ -575,17 +571,6 @@
return any(tag in enabled_tags for tag in tags)
-def as_cEnum(type_name, value_name):
- assert not type_name.native and not value_name.native
- return 'WGPU' + type_name.CamelCase() + '_' + value_name.CamelCase()
-
-
-def as_cEnumDawn(type_name, value_name):
- assert not type_name.native and not value_name.native
- return ('DAWN' + '_' + type_name.SNAKE_CASE() + '_' +
- value_name.SNAKE_CASE())
-
-
def as_cppEnum(value_name):
assert not value_name.native
if value_name.concatcase()[0].isdigit():
@@ -593,47 +578,27 @@
return value_name.CamelCase()
-def as_cMethod(type_name, method_name):
- assert not type_name.native and not method_name.native
- return 'wgpu' + type_name.CamelCase() + method_name.CamelCase()
-
-
-def as_cMethodDawn(type_name, method_name):
- assert not type_name.native and not method_name.native
- return 'dawn' + type_name.CamelCase() + method_name.CamelCase()
-
-
def as_MethodSuffix(type_name, method_name):
assert not type_name.native and not method_name.native
return type_name.CamelCase() + method_name.CamelCase()
-def as_cProc(type_name, method_name):
- assert not type_name.native and not method_name.native
- return 'WGPU' + 'Proc' + type_name.CamelCase() + method_name.CamelCase()
-
-
-def as_cProcDawn(type_name, method_name):
- assert not type_name.native and not method_name.native
- return 'Dawn' + 'Proc' + type_name.CamelCase() + method_name.CamelCase()
-
-
-def as_frontendType(typ):
+def as_frontendType(metadata, typ):
if typ.category == 'object':
return typ.name.CamelCase() + 'Base*'
elif typ.category in ['bitmask', 'enum']:
- return 'wgpu::' + typ.name.CamelCase()
+ return metadata.namespace + '::' + typ.name.CamelCase()
elif typ.category == 'structure':
return as_cppType(typ.name)
else:
- return as_cType(typ.name)
+ return as_cType(metadata.c_prefix, typ.name)
-def as_wireType(typ):
+def as_wireType(metadata, typ):
if typ.category == 'object':
return typ.name.CamelCase() + '*'
elif typ.category in ['bitmask', 'enum', 'structure']:
- return 'WGPU' + typ.name.CamelCase()
+ return metadata.c_prefix + typ.name.CamelCase()
else:
return as_cppType(typ.name)
@@ -660,6 +625,46 @@
return any(arg.type.category == 'callback' for arg in method.arguments)
+def make_base_render_params(metadata):
+ c_prefix = metadata.c_prefix
+
+ def as_cTypeEnumSpecialCase(typ):
+ if typ.category == 'bitmask':
+ return as_cType(c_prefix, typ.name) + 'Flags'
+ return as_cType(c_prefix, typ.name)
+
+ def as_cEnum(type_name, value_name):
+ 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):
+ assert not type_name.native and not method_name.native
+ return c_prefix.lower() + type_name.CamelCase() + method_name.CamelCase()
+
+ def as_cProc(type_name, method_name):
+ assert not type_name.native and not method_name.native
+ return c_prefix + 'Proc' + type_name.CamelCase() + method_name.CamelCase()
+
+ return {
+ 'Name': lambda name: Name(name),
+ 'as_annotated_cType': \
+ lambda arg: annotated(as_cTypeEnumSpecialCase(arg.type), arg),
+ 'as_annotated_cppType': \
+ lambda arg: annotated(as_cppType(arg.type.name), arg),
+ 'as_cEnum': as_cEnum,
+ 'as_cppEnum': as_cppEnum,
+ 'as_cMethod': as_cMethod,
+ 'as_MethodSuffix': as_MethodSuffix,
+ 'as_cProc': as_cProc,
+ 'as_cType': lambda name: as_cType(c_prefix, name),
+ 'as_cppType': as_cppType,
+ 'as_jsEnumValue': as_jsEnumValue,
+ 'convert_cType_to_cppType': convert_cType_to_cppType,
+ 'as_varName': as_varName,
+ 'decorate': decorate
+ }
+
+
class MultiGeneratorFromDawnJSON(Generator):
def get_description(self):
return 'Generates code for various target from Dawn.json.'
@@ -698,35 +703,15 @@
renders = []
- RENDER_PARAMS_BASE = {
- 'Name': lambda name: Name(name),
- 'as_annotated_cType': \
- lambda arg: annotated(as_cTypeEnumSpecialCase(arg.type), arg),
- 'as_annotated_cppType': \
- lambda arg: annotated(as_cppType(arg.type.name), arg),
- 'as_cEnum': as_cEnum,
- 'as_cEnumDawn': as_cEnumDawn,
- 'as_cppEnum': as_cppEnum,
- 'as_cMethod': as_cMethod,
- 'as_cMethodDawn': as_cMethodDawn,
- 'as_MethodSuffix': as_MethodSuffix,
- 'as_cProc': as_cProc,
- 'as_cProcDawn': as_cProcDawn,
- 'as_cType': as_cType,
- 'as_cTypeDawn': as_cTypeDawn,
- 'as_cppType': as_cppType,
- 'as_jsEnumValue': as_jsEnumValue,
- 'convert_cType_to_cppType': convert_cType_to_cppType,
- 'as_varName': as_varName,
- 'decorate': decorate,
- }
-
params_dawn = parse_json(loaded_json,
enabled_tags=['dawn', 'native', 'deprecated'])
+ metadata = params_dawn['metadata']
+ RENDER_PARAMS_BASE = make_base_render_params(metadata)
+ api_file_name = metadata.api.lower()
if 'dawn_headers' in targets:
renders.append(
- FileRender('webgpu.h', 'src/include/dawn/webgpu.h',
+ FileRender('api.h', 'src/include/dawn/' + api_file_name + '.h',
[RENDER_PARAMS_BASE, params_dawn]))
renders.append(
FileRender('dawn_proc_table.h',
@@ -761,14 +746,14 @@
params_upstream = parse_json(loaded_json,
enabled_tags=['upstream', 'native'])
renders.append(
- FileRender('webgpu.h', 'webgpu-headers/webgpu.h',
+ FileRender('api.h', 'webgpu-headers/' + api_file_name + '.h',
[RENDER_PARAMS_BASE, params_upstream]))
if 'emscripten_bits' in targets:
params_emscripten = parse_json(
loaded_json, enabled_tags=['upstream', 'emscripten'])
renders.append(
- FileRender('webgpu.h', 'emscripten-bits/webgpu.h',
+ FileRender('api.h', 'emscripten-bits/' + api_file_name + '.h',
[RENDER_PARAMS_BASE, params_emscripten]))
renders.append(
FileRender('webgpu_cpp.h', 'emscripten-bits/webgpu_cpp.h',
@@ -804,9 +789,9 @@
params_dawn,
{
# TODO: as_frontendType and co. take a Type, not a Name :(
- 'as_frontendType': lambda typ: as_frontendType(typ),
+ 'as_frontendType': lambda typ: as_frontendType(metadata, typ),
'as_annotated_frontendType': \
- lambda arg: annotated(as_frontendType(arg.type), arg),
+ lambda arg: annotated(as_frontendType(metadata, arg.type), arg),
}
]
@@ -863,9 +848,9 @@
wire_params = [
RENDER_PARAMS_BASE, params_dawn, {
- 'as_wireType': as_wireType,
+ 'as_wireType': lambda type : as_wireType(metadata, type),
'as_annotated_wireType': \
- lambda arg: annotated(as_wireType(arg.type), arg),
+ lambda arg: annotated(as_wireType(metadata, arg.type), arg),
}, additional_params
]
renders.append(
diff --git a/generator/templates/webgpu.h b/generator/templates/api.h
similarity index 78%
rename from generator/templates/webgpu.h
rename to generator/templates/api.h
index d305dd2..f03dbae 100644
--- a/generator/templates/webgpu.h
+++ b/generator/templates/api.h
@@ -14,14 +14,15 @@
//*
//*
//* This template itself is part of the Dawn source and follows Dawn's license
-//* but the generated file is used for "WebGPU native". The template comments
+//* but the generated file is used for "Web API native". The template comments
//* using //* at the top of the file are removed during generation such that
//* the resulting file starts with the BSD 3-Clause comment.
//*
//*
// BSD 3-Clause License
//
-// Copyright (c) 2019, "WebGPU native" developers
+{% set year = metadata.copyright_year if metadata.copyright_year else 2019 %}
+// Copyright (c) {{year}}, "{{metadata.api}} native" developers
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -48,26 +49,27 @@
// 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.
-#ifndef WEBGPU_H_
-#define WEBGPU_H_
+#ifndef {{metadata.api.upper()}}_H_
+#define {{metadata.api.upper()}}_H_
-#if defined(WGPU_SHARED_LIBRARY)
+{% set c_prefix = metadata.c_prefix %}
+#if defined({{c_prefix}}_SHARED_LIBRARY)
# if defined(_WIN32)
-# if defined(WGPU_IMPLEMENTATION)
-# define WGPU_EXPORT __declspec(dllexport)
+# if defined({{c_prefix}}_IMPLEMENTATION)
+# define {{c_prefix}}_EXPORT __declspec(dllexport)
# else
-# define WGPU_EXPORT __declspec(dllimport)
+# define {{c_prefix}}_EXPORT __declspec(dllimport)
# endif
# else // defined(_WIN32)
-# if defined(WGPU_IMPLEMENTATION)
-# define WGPU_EXPORT __attribute__((visibility("default")))
+# if defined({{c_prefix}}_IMPLEMENTATION)
+# define {{c_prefix}}_EXPORT __attribute__((visibility("default")))
# else
-# define WGPU_EXPORT
+# define {{c_prefix}}_EXPORT
# endif
# endif // defined(_WIN32)
-#else // defined(WGPU_SHARED_LIBRARY)
-# define WGPU_EXPORT
-#endif // defined(WGPU_SHARED_LIBRARY)
+#else // defined({{c_prefix}}_SHARED_LIBRARY)
+# define {{c_prefix}}_EXPORT
+#endif // defined({{c_prefix}}_SHARED_LIBRARY)
#include <stdint.h>
#include <stddef.h>
@@ -85,7 +87,7 @@
#define WGPU_ARRAY_LAYER_COUNT_UNDEFINED (0xffffffffUL)
#define WGPU_MIP_LEVEL_COUNT_UNDEFINED (0xffffffffUL)
-typedef uint32_t WGPUFlags;
+typedef uint32_t {{c_prefix}}Flags;
{% for type in by_category["object"] %}
typedef struct {{as_cType(type.name)}}Impl* {{as_cType(type.name)}};
@@ -99,30 +101,30 @@
{{as_cEnum(type.name, Name("force32"))}} = 0x7FFFFFFF
} {{as_cType(type.name)}};
{% if type.category == "bitmask" %}
- typedef WGPUFlags {{as_cType(type.name)}}Flags;
+ typedef {{c_prefix}}Flags {{as_cType(type.name)}}Flags;
{% endif %}
{% endfor -%}
-typedef struct WGPUChainedStruct {
- struct WGPUChainedStruct const * next;
- WGPUSType sType;
-} WGPUChainedStruct;
+typedef struct {{c_prefix}}ChainedStruct {
+ struct {{c_prefix}}ChainedStruct const * next;
+ {{c_prefix}}SType sType;
+} {{c_prefix}}ChainedStruct;
-typedef struct WGPUChainedStructOut {
- struct WGPUChainedStructOut * next;
- WGPUSType sType;
-} WGPUChainedStructOut;
+typedef struct {{c_prefix}}ChainedStructOut {
+ struct {{c_prefix}}ChainedStructOut * next;
+ {{c_prefix}}SType sType;
+} {{c_prefix}}ChainedStructOut;
{% for type in by_category["structure"] %}
typedef struct {{as_cType(type.name)}} {
{% set Out = "Out" if type.output else "" %}
{% set const = "const " if not type.output else "" %}
{% if type.extensible %}
- WGPUChainedStruct{{Out}} {{const}}* nextInChain;
+ {{c_prefix}}ChainedStruct{{Out}} {{const}}* nextInChain;
{% endif %}
{% if type.chained %}
- WGPUChainedStruct{{Out}} chain;
+ {{c_prefix}}ChainedStruct{{Out}} chain;
{% endif %}
{% for member in type.members %}
{{as_annotated_cType(member)}};
@@ -155,9 +157,9 @@
);
{% endfor %}
-typedef void (*WGPUProc)(void);
+typedef void (*{{c_prefix}}Proc)(void);
-#if !defined(WGPU_SKIP_PROCS)
+#if !defined({{c_prefix}}_SKIP_PROCS)
typedef WGPUInstance (*WGPUProcCreateInstance)(WGPUInstanceDescriptor const * descriptor);
typedef WGPUProc (*WGPUProcGetProcAddress)(WGPUDevice device, char const * procName);
@@ -174,9 +176,9 @@
{% endfor %}
{% endfor %}
-#endif // !defined(WGPU_SKIP_PROCS)
+#endif // !defined({{c_prefix}}_SKIP_PROCS)
-#if !defined(WGPU_SKIP_DECLARATIONS)
+#if !defined({{c_prefix}}_SKIP_DECLARATIONS)
WGPU_EXPORT WGPUInstance wgpuCreateInstance(WGPUInstanceDescriptor const * descriptor);
WGPU_EXPORT WGPUProc wgpuGetProcAddress(WGPUDevice device, char const * procName);
@@ -184,7 +186,7 @@
{% for type in by_category["object"] if len(c_methods(type)) > 0 %}
// Methods of {{type.name.CamelCase()}}
{% for method in c_methods(type) %}
- WGPU_EXPORT {{as_cType(method.return_type.name)}} {{as_cMethod(type.name, method.name)}}(
+ {{c_prefix}}_EXPORT {{as_cType(method.return_type.name)}} {{as_cMethod(type.name, method.name)}}(
{{-as_cType(type.name)}} {{as_varName(type.name)}}
{%- for arg in method.arguments -%}
, {{as_annotated_cType(arg)}}
@@ -193,10 +195,10 @@
{% endfor %}
{% endfor %}
-#endif // !defined(WGPU_SKIP_DECLARATIONS)
+#endif // !defined({{c_prefix}}_SKIP_DECLARATIONS)
#ifdef __cplusplus
} // extern "C"
#endif
-#endif // WEBGPU_H_
+#endif // {{metadata.api.upper()}}_H_