From b2fdd6402df4a59ce4fbdafaa171fa06bb776c0c Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Tue, 12 Apr 2022 16:46:01 +0000 Subject: [PATCH] Rework dawn/native/ProcTable.cpp's template to better handle functions. This is a small rework to try to make the template better handle functions that aren't associated with an object, when during an unrelated patch I got confused that APICreateInstance didn't appear in dawn::native. Change-Id: If5a2aa3f9e348d1847e48fec4e90e5966ddd489d Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/86530 Reviewed-by: Austin Eng Kokoro: Kokoro Reviewed-by: Loko Kung Commit-Queue: Corentin Wallez --- generator/templates/dawn/native/ProcTable.cpp | 98 ++++++++++++------- .../templates/dawn/wire/client/ApiProcs.cpp | 2 +- src/dawn/native/DawnNative.cpp | 2 +- src/dawn/native/Instance.cpp | 8 +- src/dawn/native/Instance.h | 4 +- 5 files changed, 71 insertions(+), 43 deletions(-) diff --git a/generator/templates/dawn/native/ProcTable.cpp b/generator/templates/dawn/native/ProcTable.cpp index 47ac2f52e2..cd829e3031 100644 --- a/generator/templates/dawn/native/ProcTable.cpp +++ b/generator/templates/dawn/native/ProcTable.cpp @@ -76,6 +76,43 @@ namespace {{native_namespace}} { {% endfor %} {% endfor %} + {% for function in by_category["function"] if function.name.canonical_case() != "get proc address" %} + {{as_cType(function.return_type.name)}} Native{{function.name.CamelCase()}}( + {%- for arg in function.arguments -%} + {%- if not loop.first %}, {% endif -%} + {{as_annotated_cType(arg)}} + {%- endfor -%} + ) { + {% for arg in function.arguments %} + {% set varName = as_varName(arg.name) %} + {% if arg.type.category in ["enum", "bitmask"] and arg.annotation == "value" %} + auto {{varName}}_ = static_cast<{{as_frontendType(arg.type)}}>({{varName}}); + {% elif arg.annotation != "value" or arg.type.category == "object" %} + auto {{varName}}_ = reinterpret_cast<{{decorate("", as_frontendType(arg.type), arg)}}>({{varName}}); + {% else %} + auto {{varName}}_ = {{as_varName(arg.name)}}; + {% endif %} + {%- endfor-%} + + {% if function.return_type.name.canonical_case() != "void" %} + auto result = + {%- endif %} + API{{function.name.CamelCase()}}( + {%- for arg in function.arguments -%} + {%- if not loop.first %}, {% endif -%} + {{as_varName(arg.name)}}_ + {%- endfor -%} + ); + {% if function.return_type.name.canonical_case() != "void" %} + {% if function.return_type.category == "object" %} + return ToAPI(result); + {% else %} + return result; + {% endif %} + {% endif %} + } + {% endfor %} + namespace { {% set c_prefix = metadata.c_prefix %} @@ -92,46 +129,31 @@ namespace {{native_namespace}} { } // anonymous namespace - {% for function in by_category["function"] %} - {{as_cType(function.return_type.name)}} Native{{as_cppType(function.name)}}( - {%- for arg in function.arguments -%} - {% if not loop.first %}, {% endif %}{{as_annotated_cType(arg)}} - {%- endfor -%} - ) { - {% if function.name.canonical_case() == "get proc address" %} - 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<{{c_prefix}}Proc>(Native{{as_cppType(function.name)}}); - } - - {% endfor %} - return nullptr; - {% else %} - return ToAPI({{as_cppType(function.return_type.name)}}Base::Create( - {%- for arg in function.arguments -%} - FromAPI({% if not loop.first %}, {% endif %}{{as_varName(arg.name)}}) - {%- endfor -%} - )); - {% endif %} + WGPUProc NativeGetProcAddress(WGPUDevice, const char* procName) { + if (procName == nullptr) { + return nullptr; } - {% endfor %} + 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<{{c_prefix}}Proc>(Native{{as_cppType(function.name)}}); + } + + {% endfor %} + return nullptr; + } std::vector GetProcMapNamesForTestingInternal() { std::vector result; diff --git a/generator/templates/dawn/wire/client/ApiProcs.cpp b/generator/templates/dawn/wire/client/ApiProcs.cpp index d6e5279099..f9b4ccf46f 100644 --- a/generator/templates/dawn/wire/client/ApiProcs.cpp +++ b/generator/templates/dawn/wire/client/ApiProcs.cpp @@ -12,7 +12,6 @@ //* See the License for the specific language governing permissions and //* limitations under the License. -#include "dawn/common/Log.h" #include "dawn/wire/client/ApiObjects.h" #include "dawn/wire/client/Client.h" @@ -172,6 +171,7 @@ namespace dawn::wire::client { {% endfor %} {% endfor %} }; + const {{Prefix}}ProcTable& GetProcs() { return gProcTable; } diff --git a/src/dawn/native/DawnNative.cpp b/src/dawn/native/DawnNative.cpp index ca46df8db3..6a139a5cff 100644 --- a/src/dawn/native/DawnNative.cpp +++ b/src/dawn/native/DawnNative.cpp @@ -188,7 +188,7 @@ namespace dawn::native { // Instance Instance::Instance(const WGPUInstanceDescriptor* desc) - : mImpl(InstanceBase::Create(reinterpret_cast(desc))) { + : mImpl(APICreateInstance(reinterpret_cast(desc))) { } Instance::~Instance() { diff --git a/src/dawn/native/Instance.cpp b/src/dawn/native/Instance.cpp index 48bf74064d..92842f519d 100644 --- a/src/dawn/native/Instance.cpp +++ b/src/dawn/native/Instance.cpp @@ -93,10 +93,14 @@ namespace dawn::native { } // anonymous namespace + InstanceBase* APICreateInstance(const InstanceDescriptor* descriptor) { + return InstanceBase::Create().Detach(); + } + // InstanceBase // static - InstanceBase* InstanceBase::Create(const InstanceDescriptor* descriptor) { + Ref InstanceBase::Create(const InstanceDescriptor* descriptor) { Ref instance = AcquireRef(new InstanceBase); static constexpr InstanceDescriptor kDefaultDesc = {}; if (descriptor == nullptr) { @@ -105,7 +109,7 @@ namespace dawn::native { if (instance->ConsumedError(instance->Initialize(descriptor))) { return nullptr; } - return instance.Detach(); + return instance; } // TODO(crbug.com/dawn/832): make the platform an initialization parameter of the instance. diff --git a/src/dawn/native/Instance.h b/src/dawn/native/Instance.h index 7dfaf51c9e..b574f6335e 100644 --- a/src/dawn/native/Instance.h +++ b/src/dawn/native/Instance.h @@ -39,11 +39,13 @@ namespace dawn::native { using BackendsBitset = ityp::bitset>; + InstanceBase* APICreateInstance(const InstanceDescriptor* descriptor); + // This is called InstanceBase for consistency across the frontend, even if the backends don't // specialize this class. class InstanceBase final : public RefCounted { public: - static InstanceBase* Create(const InstanceDescriptor* descriptor = nullptr); + static Ref Create(const InstanceDescriptor* descriptor = nullptr); void APIRequestAdapter(const RequestAdapterOptions* options, WGPURequestAdapterCallback callback,