Corentin Wallez | 4a9ef4e | 2018-07-18 11:40:26 +0200 | [diff] [blame] | 1 | //* Copyright 2017 The Dawn Authors |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 2 | //* |
| 3 | //* Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | //* you may not use this file except in compliance with the License. |
| 5 | //* You may obtain a copy of the License at |
| 6 | //* |
| 7 | //* http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | //* |
| 9 | //* Unless required by applicable law or agreed to in writing, software |
| 10 | //* distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | //* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | //* See the License for the specific language governing permissions and |
| 13 | //* limitations under the License. |
fujunwei | c7d4f2c | 2021-12-07 00:46:35 +0000 | [diff] [blame] | 14 | {% set API = metadata.api.upper() %} |
| 15 | {% set api = API.lower() %} |
Loko Kung | 14ed533 | 2023-05-16 04:50:32 +0000 | [diff] [blame] | 16 | {% if 'dawn' in enabled_tags %} |
Shrek Shao | 71a363b | 2022-02-09 19:42:51 +0000 | [diff] [blame] | 17 | #ifdef __EMSCRIPTEN__ |
| 18 | #error "Do not include this header. Emscripten already provides headers needed for {{metadata.api}}." |
| 19 | #endif |
| 20 | {% endif %} |
fujunwei | c7d4f2c | 2021-12-07 00:46:35 +0000 | [diff] [blame] | 21 | #ifndef {{API}}_CPP_H_ |
| 22 | #define {{API}}_CPP_H_ |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 23 | |
fujunwei | c7d4f2c | 2021-12-07 00:46:35 +0000 | [diff] [blame] | 24 | #include "dawn/{{api}}.h" |
Loko Kung | 14ed533 | 2023-05-16 04:50:32 +0000 | [diff] [blame] | 25 | #include "dawn/{{api}}_cpp_chained_struct.h" |
Corentin Wallez | 3e371b1 | 2018-07-18 14:32:45 +0200 | [diff] [blame] | 26 | #include "dawn/EnumClassBitmasks.h" |
Brandon Jones | 6e8c473 | 2022-02-19 00:44:12 +0000 | [diff] [blame] | 27 | #include <cmath> |
Loko Kung | 6f5515a | 2023-05-25 23:19:48 +0000 | [diff] [blame] | 28 | #include <cstddef> |
| 29 | #include <cstdint> |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 30 | |
fujunwei | c7d4f2c | 2021-12-07 00:46:35 +0000 | [diff] [blame] | 31 | namespace {{metadata.namespace}} { |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 32 | |
fujunwei | 4e87690 | 2021-11-25 08:44:01 +0000 | [diff] [blame] | 33 | {% set c_prefix = metadata.c_prefix %} |
| 34 | {% for constant in by_category["constant"] %} |
| 35 | {% set type = as_cppType(constant.type.name) %} |
| 36 | {% set value = c_prefix + "_" + constant.name.SNAKE_CASE() %} |
| 37 | static constexpr {{type}} k{{as_cppType(constant.name)}} = {{ value }}; |
| 38 | {% endfor %} |
François Beaufort | 0326b80 | 2019-07-17 08:54:19 +0000 | [diff] [blame] | 39 | |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 40 | {% for type in by_category["enum"] %} |
| 41 | enum class {{as_cppType(type.name)}} : uint32_t { |
| 42 | {% for value in type.values %} |
| 43 | {{as_cppEnum(value.name)}} = 0x{{format(value.value, "08X")}}, |
| 44 | {% endfor %} |
| 45 | }; |
| 46 | |
| 47 | {% endfor %} |
| 48 | |
| 49 | {% for type in by_category["bitmask"] %} |
| 50 | enum class {{as_cppType(type.name)}} : uint32_t { |
| 51 | {% for value in type.values %} |
| 52 | {{as_cppEnum(value.name)}} = 0x{{format(value.value, "08X")}}, |
| 53 | {% endfor %} |
| 54 | }; |
| 55 | |
| 56 | {% endfor %} |
| 57 | |
fujunwei | 23f7162 | 2021-12-02 07:41:21 +0000 | [diff] [blame] | 58 | {% for type in by_category["function pointer"] %} |
Corentin Wallez | 4b410a3 | 2017-04-20 14:42:36 -0400 | [diff] [blame] | 59 | using {{as_cppType(type.name)}} = {{as_cType(type.name)}}; |
| 60 | {% endfor %} |
| 61 | |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 62 | {% for type in by_category["object"] %} |
| 63 | class {{as_cppType(type.name)}}; |
| 64 | {% endfor %} |
| 65 | |
Corentin Wallez | a641654 | 2018-05-17 16:55:53 -0400 | [diff] [blame] | 66 | {% for type in by_category["structure"] %} |
Corentin Wallez | 8e335a5 | 2018-08-27 23:12:56 +0200 | [diff] [blame] | 67 | struct {{as_cppType(type.name)}}; |
Corentin Wallez | a641654 | 2018-05-17 16:55:53 -0400 | [diff] [blame] | 68 | {% endfor %} |
| 69 | |
Brandon Jones | 58a471a | 2021-02-08 19:48:06 +0000 | [diff] [blame] | 70 | {% for typeDef in by_category["typedef"] %} |
| 71 | // {{as_cppType(typeDef.name)}} is deprecated. |
| 72 | // Use {{as_cppType(typeDef.type.name)}} instead. |
| 73 | using {{as_cppType(typeDef.name)}} = {{as_cppType(typeDef.type.name)}}; |
| 74 | |
| 75 | {% endfor %} |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 76 | template<typename Derived, typename CType> |
| 77 | class ObjectBase { |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 78 | public: |
| 79 | ObjectBase() = default; |
| 80 | ObjectBase(CType handle): mHandle(handle) { |
fujunwei | c7d4f2c | 2021-12-07 00:46:35 +0000 | [diff] [blame] | 81 | if (mHandle) Derived::{{c_prefix}}Reference(mHandle); |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 82 | } |
| 83 | ~ObjectBase() { |
fujunwei | c7d4f2c | 2021-12-07 00:46:35 +0000 | [diff] [blame] | 84 | if (mHandle) Derived::{{c_prefix}}Release(mHandle); |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 85 | } |
| 86 | |
| 87 | ObjectBase(ObjectBase const& other) |
| 88 | : ObjectBase(other.Get()) { |
| 89 | } |
| 90 | Derived& operator=(ObjectBase const& other) { |
| 91 | if (&other != this) { |
fujunwei | c7d4f2c | 2021-12-07 00:46:35 +0000 | [diff] [blame] | 92 | if (mHandle) Derived::{{c_prefix}}Release(mHandle); |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 93 | mHandle = other.mHandle; |
fujunwei | c7d4f2c | 2021-12-07 00:46:35 +0000 | [diff] [blame] | 94 | if (mHandle) Derived::{{c_prefix}}Reference(mHandle); |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 95 | } |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 96 | |
| 97 | return static_cast<Derived&>(*this); |
| 98 | } |
| 99 | |
| 100 | ObjectBase(ObjectBase&& other) { |
| 101 | mHandle = other.mHandle; |
| 102 | other.mHandle = 0; |
| 103 | } |
| 104 | Derived& operator=(ObjectBase&& other) { |
| 105 | if (&other != this) { |
fujunwei | c7d4f2c | 2021-12-07 00:46:35 +0000 | [diff] [blame] | 106 | if (mHandle) Derived::{{c_prefix}}Release(mHandle); |
Corentin Wallez | 42dbde1 | 2017-11-23 16:04:26 -0500 | [diff] [blame] | 107 | mHandle = other.mHandle; |
| 108 | other.mHandle = 0; |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 109 | } |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 110 | |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 111 | return static_cast<Derived&>(*this); |
| 112 | } |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 113 | |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 114 | ObjectBase(std::nullptr_t) {} |
| 115 | Derived& operator=(std::nullptr_t) { |
| 116 | if (mHandle != nullptr) { |
fujunwei | c7d4f2c | 2021-12-07 00:46:35 +0000 | [diff] [blame] | 117 | Derived::{{c_prefix}}Release(mHandle); |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 118 | mHandle = nullptr; |
Corentin Wallez | f48e6b7 | 2018-12-04 12:13:03 +0000 | [diff] [blame] | 119 | } |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 120 | return static_cast<Derived&>(*this); |
| 121 | } |
Corentin Wallez | f48e6b7 | 2018-12-04 12:13:03 +0000 | [diff] [blame] | 122 | |
Austin Eng | f6eb890 | 2019-11-22 17:02:22 +0000 | [diff] [blame] | 123 | bool operator==(std::nullptr_t) const { |
| 124 | return mHandle == nullptr; |
| 125 | } |
| 126 | bool operator!=(std::nullptr_t) const { |
| 127 | return mHandle != nullptr; |
| 128 | } |
| 129 | |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 130 | explicit operator bool() const { |
| 131 | return mHandle != nullptr; |
| 132 | } |
| 133 | CType Get() const { |
| 134 | return mHandle; |
| 135 | } |
Loko Kung | 0214a30 | 2023-05-10 23:48:22 +0000 | [diff] [blame] | 136 | // TODO(dawn:1639) Deprecate Release after uses have been removed. |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 137 | CType Release() { |
| 138 | CType result = mHandle; |
| 139 | mHandle = 0; |
| 140 | return result; |
| 141 | } |
Loko Kung | 0214a30 | 2023-05-10 23:48:22 +0000 | [diff] [blame] | 142 | CType MoveToCHandle() { |
| 143 | CType result = mHandle; |
| 144 | mHandle = 0; |
| 145 | return result; |
| 146 | } |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 147 | static Derived Acquire(CType handle) { |
| 148 | Derived result; |
| 149 | result.mHandle = handle; |
| 150 | return result; |
| 151 | } |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 152 | |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 153 | protected: |
| 154 | CType mHandle = nullptr; |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 155 | }; |
| 156 | |
Corentin Wallez | 9d6265b | 2020-11-04 10:04:17 +0000 | [diff] [blame] | 157 | {% macro render_cpp_default_value(member, is_struct=True) -%} |
Corentin Wallez | 1260a53 | 2022-07-26 17:36:44 +0000 | [diff] [blame] | 158 | {%- if member.json_data.get("no_default", false) -%} |
| 159 | {%- elif member.annotation in ["*", "const*"] and member.optional or member.default_value == "nullptr" -%} |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 160 | {{" "}}= nullptr |
Corentin Wallez | 9d6265b | 2020-11-04 10:04:17 +0000 | [diff] [blame] | 161 | {%- elif member.type.category == "object" and member.optional and is_struct -%} |
Corentin Wallez | b0789fd | 2020-10-29 13:09:12 +0000 | [diff] [blame] | 162 | {{" "}}= nullptr |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 163 | {%- elif member.type.category in ["enum", "bitmask"] and member.default_value != None -%} |
| 164 | {{" "}}= {{as_cppType(member.type.name)}}::{{as_cppEnum(Name(member.default_value))}} |
| 165 | {%- elif member.type.category == "native" and member.default_value != None -%} |
| 166 | {{" "}}= {{member.default_value}} |
Brandon Jones | 6e8c473 | 2022-02-19 00:44:12 +0000 | [diff] [blame] | 167 | {%- elif member.default_value != None -%} |
| 168 | {{" "}}= {{member.default_value}} |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 169 | {%- else -%} |
| 170 | {{assert(member.default_value == None)}} |
| 171 | {%- endif -%} |
| 172 | {%- endmacro %} |
| 173 | |
| 174 | {% macro render_cpp_method_declaration(type, method) %} |
| 175 | {% set CppType = as_cppType(type.name) %} |
Corentin Wallez | 9649682 | 2019-10-15 11:44:38 +0000 | [diff] [blame] | 176 | {{as_cppType(method.return_type.name)}} {{method.name.CamelCase()}}( |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 177 | {%- for arg in method.arguments -%} |
| 178 | {%- if not loop.first %}, {% endif -%} |
| 179 | {%- if arg.type.category == "object" and arg.annotation == "value" -%} |
| 180 | {{as_cppType(arg.type.name)}} const& {{as_varName(arg.name)}} |
| 181 | {%- else -%} |
| 182 | {{as_annotated_cppType(arg)}} |
| 183 | {%- endif -%} |
Corentin Wallez | 9d6265b | 2020-11-04 10:04:17 +0000 | [diff] [blame] | 184 | {{render_cpp_default_value(arg, False)}} |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 185 | {%- endfor -%} |
| 186 | ) const |
| 187 | {%- endmacro %} |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 188 | |
| 189 | {% for type in by_category["object"] %} |
| 190 | {% set CppType = as_cppType(type.name) %} |
| 191 | {% set CType = as_cType(type.name) %} |
Corentin Wallez | bd48385 | 2019-01-09 09:05:18 +0000 | [diff] [blame] | 192 | class {{CppType}} : public ObjectBase<{{CppType}}, {{CType}}> { |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 193 | public: |
| 194 | using ObjectBase::ObjectBase; |
| 195 | using ObjectBase::operator=; |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 196 | |
Corentin Wallez | aca8c4a | 2019-11-22 14:02:52 +0000 | [diff] [blame] | 197 | {% for method in type.methods %} |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 198 | {{render_cpp_method_declaration(type, method)}}; |
| 199 | {% endfor %} |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 200 | |
Corentin Wallez | 8f93871 | 2019-07-08 19:20:22 +0000 | [diff] [blame] | 201 | private: |
| 202 | friend ObjectBase<{{CppType}}, {{CType}}>; |
fujunwei | c7d4f2c | 2021-12-07 00:46:35 +0000 | [diff] [blame] | 203 | static void {{c_prefix}}Reference({{CType}} handle); |
| 204 | static void {{c_prefix}}Release({{CType}} handle); |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 205 | }; |
| 206 | |
| 207 | {% endfor %} |
| 208 | |
fujunwei | c7d4f2c | 2021-12-07 00:46:35 +0000 | [diff] [blame] | 209 | {% for function in by_category["function"] %} |
fujunwei | d3cac11 | 2021-12-14 02:20:15 +0000 | [diff] [blame] | 210 | {{as_cppType(function.return_type.name)}} {{as_cppType(function.name)}}( |
fujunwei | c7d4f2c | 2021-12-07 00:46:35 +0000 | [diff] [blame] | 211 | {%- for arg in function.arguments -%} |
fujunwei | d3cac11 | 2021-12-14 02:20:15 +0000 | [diff] [blame] | 212 | {%- if not loop.first %}, {% endif -%} |
| 213 | {{as_annotated_cppType(arg)}}{{render_cpp_default_value(arg, False)}} |
fujunwei | c7d4f2c | 2021-12-07 00:46:35 +0000 | [diff] [blame] | 214 | {%- endfor -%} |
| 215 | ); |
| 216 | {% endfor %} |
Corentin Wallez | c57b180 | 2019-10-15 12:08:48 +0000 | [diff] [blame] | 217 | |
Corentin Wallez | 8e335a5 | 2018-08-27 23:12:56 +0200 | [diff] [blame] | 218 | {% for type in by_category["structure"] %} |
Austin Eng | bffc966 | 2021-09-17 15:36:00 +0000 | [diff] [blame] | 219 | {% set Out = "Out" if type.output else "" %} |
| 220 | {% set const = "const" if not type.output else "" %} |
Corentin Wallez | 2b24c3d | 2020-01-15 09:54:42 +0000 | [diff] [blame] | 221 | {% if type.chained %} |
Corentin Wallez | a45561b | 2022-07-14 12:58:25 +0000 | [diff] [blame] | 222 | {% for root in type.chain_roots %} |
| 223 | // Can be chained in {{as_cppType(root.name)}} |
| 224 | {% endfor %} |
Austin Eng | bffc966 | 2021-09-17 15:36:00 +0000 | [diff] [blame] | 225 | struct {{as_cppType(type.name)}} : ChainedStruct{{Out}} { |
Corentin Wallez | 2b24c3d | 2020-01-15 09:54:42 +0000 | [diff] [blame] | 226 | {{as_cppType(type.name)}}() { |
| 227 | sType = SType::{{type.name.CamelCase()}}; |
| 228 | } |
| 229 | {% else %} |
| 230 | struct {{as_cppType(type.name)}} { |
| 231 | {% endif %} |
Corentin Wallez | 8e335a5 | 2018-08-27 23:12:56 +0200 | [diff] [blame] | 232 | {% if type.extensible %} |
Austin Eng | bffc966 | 2021-09-17 15:36:00 +0000 | [diff] [blame] | 233 | ChainedStruct{{Out}} {{const}} * nextInChain = nullptr; |
Corentin Wallez | 8e335a5 | 2018-08-27 23:12:56 +0200 | [diff] [blame] | 234 | {% endif %} |
| 235 | {% for member in type.members %} |
Austin Eng | 76a8d0b | 2020-04-03 17:37:48 +0000 | [diff] [blame] | 236 | {% set member_declaration = as_annotated_cppType(member) + render_cpp_default_value(member) %} |
| 237 | {% if type.chained and loop.first %} |
Corentin Wallez | 7a64127 | 2022-06-29 17:37:41 +0000 | [diff] [blame] | 238 | //* Align the first member after ChainedStruct to match the C struct layout. |
| 239 | //* It has to be aligned both to its natural and ChainedStruct's alignment. |
| 240 | static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct{{out}}), alignof({{decorate("", as_cppType(member.type.name), member)}})); |
| 241 | alignas(kFirstMemberAlignment) {{member_declaration}}; |
Austin Eng | 76a8d0b | 2020-04-03 17:37:48 +0000 | [diff] [blame] | 242 | {% else %} |
| 243 | {{member_declaration}}; |
| 244 | {% endif %} |
Corentin Wallez | 8e335a5 | 2018-08-27 23:12:56 +0200 | [diff] [blame] | 245 | {% endfor %} |
| 246 | }; |
| 247 | |
| 248 | {% endfor %} |
fujunwei | ed33e05 | 2021-12-08 05:46:17 +0000 | [diff] [blame] | 249 | |
| 250 | // The operators of EnumClassBitmmasks in the dawn:: namespace need to be imported |
| 251 | // in the {{metadata.namespace}} namespace for Argument Dependent Lookup. |
| 252 | DAWN_IMPORT_BITMASK_OPERATORS |
fujunwei | c7d4f2c | 2021-12-07 00:46:35 +0000 | [diff] [blame] | 253 | } // namespace {{metadata.namespace}} |
Corentin Wallez | f07e3bd | 2017-04-20 14:38:20 -0400 | [diff] [blame] | 254 | |
fujunwei | ed33e05 | 2021-12-08 05:46:17 +0000 | [diff] [blame] | 255 | namespace dawn { |
| 256 | {% for type in by_category["bitmask"] %} |
| 257 | template<> |
| 258 | struct IsDawnBitmask<{{metadata.namespace}}::{{as_cppType(type.name)}}> { |
| 259 | static constexpr bool enable = true; |
| 260 | }; |
| 261 | |
| 262 | {% endfor %} |
| 263 | } // namespace dawn |
| 264 | |
fujunwei | c7d4f2c | 2021-12-07 00:46:35 +0000 | [diff] [blame] | 265 | #endif // {{API}}_CPP_H_ |