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>
This commit is contained in:
fujunwei 2021-11-23 08:47:35 +00:00 committed by Dawn LUCI CQ
parent aaaf70aee2
commit 76bda371ef
4 changed files with 114 additions and 114 deletions

View File

@ -17,6 +17,12 @@
"_doc": "See docs/codegen.md",
"_metadata": {
"api": "WebGPU",
"c_prefix": "WGPU",
"namespace": "wgpu"
},
"request adapter options": {
"category": "structure",
"extensible": "in",

View File

@ -23,6 +23,13 @@ At this time it is used to generate:
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.

View File

@ -23,6 +23,14 @@ from generator_lib import Generator, run_generator, FileRender
############################################################
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 @@ def parse_json(json, enabled_tags):
'enabled_tags': enabled_tags,
}
return {
'metadata': Metadata(json['_metadata']),
'types': types,
'by_category': by_category,
'enabled_tags': enabled_tags,
@ -494,24 +503,11 @@ def as_varName(*names):
[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 @@ def item_is_enabled(enabled_tags, json_data):
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 @@ def as_cppEnum(value_name):
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 @@ def has_callback_arguments(method):
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 @@ class MultiGeneratorFromDawnJSON(Generator):
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 @@ class MultiGeneratorFromDawnJSON(Generator):
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 @@ class MultiGeneratorFromDawnJSON(Generator):
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 @@ class MultiGeneratorFromDawnJSON(Generator):
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(

View File

@ -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 @@ typedef uint32_t WGPUFlags;
{{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 @@ extern "C" {
);
{% 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 @@ typedef WGPUProc (*WGPUProcGetProcAddress)(WGPUDevice device, char const * procN
{% 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 @@ WGPU_EXPORT WGPUProc wgpuGetProcAddress(WGPUDevice device, char const * procName
{% 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 @@ WGPU_EXPORT WGPUProc wgpuGetProcAddress(WGPUDevice device, char const * procName
{% 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_