Updates DawnInstanceDescriptor to pass in the Platform.
Notes:
- Separates ChainedStruct to be reusable without cpp header. (Also
updates native structs to directly use it.)
- Manually implements the descriptor in DawnNative.
- Reworks ChainUtils with mapping from struct to STypes.
- Updates the tests to use either SetPlatformForTesting which is still
required because DawnTest uses a "global" instance for all tests and
some tests require setting (and cleaning up) a test specific platform.
Bug: dawn:1374
Change-Id: I078c78f22c5137030cf3cf0e8358fe4373ee9c6c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/132268
Reviewed-by: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Loko Kung <lokokung@google.com>
diff --git a/generator/dawn_json_generator.py b/generator/dawn_json_generator.py
index 16207fc..d0d502a 100644
--- a/generator/dawn_json_generator.py
+++ b/generator/dawn_json_generator.py
@@ -965,6 +965,11 @@
'include/dawn/' + api + '_cpp_print.h',
[RENDER_PARAMS_BASE, params_dawn]))
+ renders.append(
+ FileRender('api_cpp_chained_struct.h',
+ 'include/dawn/' + api + '_cpp_chained_struct.h',
+ [RENDER_PARAMS_BASE, params_dawn]))
+
if 'proc' in targets:
renders.append(
FileRender('dawn_proc.c', 'src/dawn/' + prefix + '_proc.c',
diff --git a/generator/templates/api_cpp.h b/generator/templates/api_cpp.h
index 54bf66d..4d2a072 100644
--- a/generator/templates/api_cpp.h
+++ b/generator/templates/api_cpp.h
@@ -13,7 +13,7 @@
//* limitations under the License.
{% set API = metadata.api.upper() %}
{% set api = API.lower() %}
-{% if 'dawn' not in enabled_tags %}
+{% if 'dawn' in enabled_tags %}
#ifdef __EMSCRIPTEN__
#error "Do not include this header. Emscripten already provides headers needed for {{metadata.api}}."
#endif
@@ -22,17 +22,12 @@
#define {{API}}_CPP_H_
#include "dawn/{{api}}.h"
+#include "dawn/{{api}}_cpp_chained_struct.h"
#include "dawn/EnumClassBitmasks.h"
#include <cmath>
namespace {{metadata.namespace}} {
- namespace detail {
- constexpr size_t ConstexprMax(size_t a, size_t b) {
- return a > b ? a : b;
- }
- } // namespace detail
-
{% set c_prefix = metadata.c_prefix %}
{% for constant in by_category["constant"] %}
{% set type = as_cppType(constant.type.name) %}
@@ -218,16 +213,6 @@
);
{% endfor %}
- struct ChainedStruct {
- ChainedStruct const * nextInChain = nullptr;
- SType sType = SType::Invalid;
- };
-
- struct ChainedStructOut {
- ChainedStruct * nextInChain = nullptr;
- SType sType = SType::Invalid;
- };
-
{% for type in by_category["structure"] %}
{% set Out = "Out" if type.output else "" %}
{% set const = "const" if not type.output else "" %}
diff --git a/generator/templates/api_cpp_chained_struct.h b/generator/templates/api_cpp_chained_struct.h
new file mode 100644
index 0000000..59a0fd0
--- /dev/null
+++ b/generator/templates/api_cpp_chained_struct.h
@@ -0,0 +1,48 @@
+//* Copyright 2023 The Dawn Authors
+//*
+//* Licensed under the Apache License, Version 2.0 (the "License");
+//* you may not use this file except in compliance with the License.
+//* You may obtain a copy of the License at
+//*
+//* http://www.apache.org/licenses/LICENSE-2.0
+//*
+//* Unless required by applicable law or agreed to in writing, software
+//* distributed under the License is distributed on an "AS IS" BASIS,
+//* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//* See the License for the specific language governing permissions and
+//* limitations under the License.
+{% set API = metadata.api.upper() %}
+{% if 'dawn' in enabled_tags %}
+ #ifdef __EMSCRIPTEN__
+ #error "Do not include this header. Emscripten already provides headers needed for {{metadata.api}}."
+ #endif
+{% endif %}
+#ifndef {{API}}_CPP_CHAINED_STRUCT_H_
+#define {{API}}_CPP_CHAINED_STRUCT_H_
+
+// This header file declares the ChainedStruct structures separately from the {{metadata.api}}
+// headers so that dependencies can directly extend structures without including the larger header
+// which exposes capabilities that may require correctly set proc tables.
+namespace {{metadata.namespace}} {
+
+ namespace detail {
+ constexpr size_t ConstexprMax(size_t a, size_t b) {
+ return a > b ? a : b;
+ }
+ } // namespace detail
+
+ enum class SType : uint32_t;
+
+ struct ChainedStruct {
+ ChainedStruct const * nextInChain = nullptr;
+ SType sType = SType(0u);
+ };
+
+ struct ChainedStructOut {
+ ChainedStructOut * nextInChain = nullptr;
+ SType sType = SType(0u);
+ };
+
+} // namespace {{metadata.namespace}}}
+
+#endif // {{API}}_CPP_CHAINED_STRUCT_H_
diff --git a/generator/templates/dawn/native/ChainUtils.cpp b/generator/templates/dawn/native/ChainUtils.cpp
index 95f5e43..1600c41 100644
--- a/generator/templates/dawn/native/ChainUtils.cpp
+++ b/generator/templates/dawn/native/ChainUtils.cpp
@@ -23,21 +23,6 @@
namespace {{native_namespace}} {
{% set namespace = metadata.namespace %}
-{% for value in types["s type"].values %}
- {% if value.valid %}
- {% set const_qualifier = "const " if types[value.name.get()].chained == "in" else "" %}
- {% set chained_struct_type = "ChainedStruct" if types[value.name.get()].chained == "in" else "ChainedStructOut" %}
- void FindInChain({{const_qualifier}}{{chained_struct_type}}* chain, {{const_qualifier}}{{as_cppEnum(value.name)}}** out) {
- for (; chain; chain = chain->nextInChain) {
- if (chain->sType == {{namespace}}::SType::{{as_cppEnum(value.name)}}) {
- *out = static_cast<{{const_qualifier}}{{as_cppEnum(value.name)}}*>(chain);
- break;
- }
- }
- }
- {% endif %}
-{% endfor %}
-
MaybeError ValidateSTypes(const ChainedStruct* chain,
std::vector<std::vector<{{namespace}}::SType>> oneOfConstraints) {
std::unordered_set<{{namespace}}::SType> allSTypes;
diff --git a/generator/templates/dawn/native/ChainUtils.h b/generator/templates/dawn/native/ChainUtils.h
index 3b5a926..1495f7b 100644
--- a/generator/templates/dawn/native/ChainUtils.h
+++ b/generator/templates/dawn/native/ChainUtils.h
@@ -18,6 +18,7 @@
#define {{DIR}}_CHAIN_UTILS_H_
{% set impl_dir = metadata.impl_dir + "/" if metadata.impl_dir else "" %}
+{% set namespace = metadata.namespace %}
{% set namespace_name = Name(metadata.native_namespace) %}
{% set native_namespace = namespace_name.namespace_case() %}
{% set native_dir = impl_dir + namespace_name.Dirs() %}
@@ -26,13 +27,44 @@
#include "{{native_dir}}/Error.h"
namespace {{native_namespace}} {
+namespace detail {
+ // Mapping from native types to the expected STypes is implemented as template specializations.
+ template <typename T>
+ struct STypeForImpl;
{% for value in types["s type"].values %}
- {% if value.valid %}
- {% set const_qualifier = "const " if types[value.name.get()].chained == "in" else "" %}
- {% set chained_struct_type = "ChainedStruct" if types[value.name.get()].chained == "in" else "ChainedStructOut" %}
- void FindInChain({{const_qualifier}}{{chained_struct_type}}* chain, {{const_qualifier}}{{as_cppEnum(value.name)}}** out);
+ {% if value.valid and value.name.get() in types %}
+ template <>
+ struct STypeForImpl<{{as_cppEnum(value.name)}}> {
+ static constexpr {{namespace}}::SType value = {{namespace}}::SType::{{as_cppEnum(value.name)}};
+ };
{% endif %}
{% endfor %}
+ template <>
+ struct STypeForImpl<DawnInstanceDescriptor> {
+ static constexpr {{namespace}}::SType value = {{namespace}}::SType::DawnInstanceDescriptor;
+ };
+} // namespace detail
+
+ template <typename T>
+ constexpr {{namespace}}::SType STypeFor = detail::STypeForImpl<T>::value;
+ template <typename T>
+ void FindInChain(const ChainedStruct* chain, const T** out) {
+ for (; chain; chain = chain->nextInChain) {
+ if (chain->sType == STypeFor<T>) {
+ *out = static_cast<const T*>(chain);
+ break;
+ }
+ }
+ }
+ template <typename T>
+ void FindInChain(ChainedStructOut* chain, T** out) {
+ for (; chain; chain = chain->nextInChain) {
+ if (chain->sType == STypeFor<T>) {
+ *out = static_cast<T*>(chain);
+ break;
+ }
+ }
+ }
// Verifies that |chain| only contains ChainedStructs of types enumerated in
// |oneOfConstraints| and contains no duplicate sTypes. Each vector in
@@ -40,7 +72,6 @@
// For example:
// ValidateSTypes(chain, { { ShaderModuleSPIRVDescriptor, ShaderModuleWGSLDescriptor } }))
// ValidateSTypes(chain, { { Extension1 }, { Extension2 } })
- {% set namespace = metadata.namespace %}
MaybeError ValidateSTypes(const ChainedStruct* chain,
std::vector<std::vector<{{namespace}}::SType>> oneOfConstraints);
MaybeError ValidateSTypes(const ChainedStructOut* chain,
diff --git a/generator/templates/dawn/native/api_structs.h b/generator/templates/dawn/native/api_structs.h
index 84a6404..2de5805 100644
--- a/generator/templates/dawn/native/api_structs.h
+++ b/generator/templates/dawn/native/api_structs.h
@@ -44,15 +44,8 @@
{%- endif -%}
{%- endmacro %}
- struct ChainedStruct {
- ChainedStruct const * nextInChain = nullptr;
- {{namespace}}::SType sType = {{namespace}}::SType::Invalid;
- };
-
- struct ChainedStructOut {
- ChainedStructOut * nextInChain = nullptr;
- {{namespace}}::SType sType = {{namespace}}::SType::Invalid;
- };
+ using {{namespace}}::ChainedStruct;
+ using {{namespace}}::ChainedStructOut;
{% for type in by_category["structure"] %}
{% if type.chained %}