From ceb46e788ca3e9b8f32a3a155689afcdc063764a Mon Sep 17 00:00:00 2001 From: Antonio Maiorano Date: Thu, 21 Oct 2021 23:02:34 +0000 Subject: [PATCH] dawn_node: add "enable/disable-dawn-features=" Same as Chrome's args, this allows us to set the DeviceDescriptor::forceEnabledToggles and forceDisabledToggles when creating the GPUDevice. Example: node cmdline.ts ... --gpu-provider-flag=enable-dawn-features=dump_shaders ... Bug: dawn:1163 Change-Id: Ib5db71355f72e5d08f8fe87313c5e3d63ee236c3 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/66963 Commit-Queue: Antonio Maiorano Reviewed-by: Ben Clayton --- src/dawn_node/binding/GPU.cpp | 2 +- src/dawn_node/binding/GPUAdapter.cpp | 51 +++++++++++++++++++++++++++- src/dawn_node/binding/GPUAdapter.h | 4 ++- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/dawn_node/binding/GPU.cpp b/src/dawn_node/binding/GPU.cpp index 5f1d4e7ba0..50eb020195 100644 --- a/src/dawn_node/binding/GPU.cpp +++ b/src/dawn_node/binding/GPU.cpp @@ -143,7 +143,7 @@ namespace wgpu { namespace binding { } } - auto adapter = GPUAdapter::Create(env, adapters[adapterIndex]); + auto adapter = GPUAdapter::Create(env, adapters[adapterIndex], flags_); promise.Resolve(std::optional>(adapter)); return promise; } diff --git a/src/dawn_node/binding/GPUAdapter.cpp b/src/dawn_node/binding/GPUAdapter.cpp index c49e442537..9ddca1ea16 100644 --- a/src/dawn_node/binding/GPUAdapter.cpp +++ b/src/dawn_node/binding/GPUAdapter.cpp @@ -16,9 +16,38 @@ #include +#include "src/dawn_node/binding/Flags.h" #include "src/dawn_node/binding/GPUDevice.h" #include "src/dawn_node/binding/GPUSupportedLimits.h" +namespace { + // TODO(amaiorano): Move to utility header + std::vector Split(const std::string& s, char delim) { + if (s.empty()) + return {}; + + std::vector result; + const size_t lastIndex = s.length() - 1; + size_t startIndex = 0; + size_t i = startIndex; + + while (i <= lastIndex) { + if (s[i] == delim) { + auto token = s.substr(startIndex, i - startIndex); + if (!token.empty()) // Discard empty tokens + result.push_back(token); + startIndex = i + 1; + } else if (i == lastIndex) { + auto token = s.substr(startIndex, i - startIndex + 1); + if (!token.empty()) // Discard empty tokens + result.push_back(token); + } + ++i; + } + return result; + } +} // namespace + namespace wgpu { namespace binding { namespace { @@ -79,7 +108,8 @@ namespace wgpu { namespace binding { // wgpu::bindings::GPUAdapter // TODO(crbug.com/dawn/1133): This is a stub implementation. Properly implement. //////////////////////////////////////////////////////////////////////////////// - GPUAdapter::GPUAdapter(dawn_native::Adapter a) : adapter_(a) { + GPUAdapter::GPUAdapter(dawn_native::Adapter a, const Flags& flags) + : adapter_(a), flags_(flags) { } std::string GPUAdapter::getName(Napi::Env) { @@ -163,6 +193,25 @@ namespace wgpu { namespace binding { UNIMPLEMENTED("required: ", required); } + // Propogate enabled/disabled dawn features + // Note: DeviceDescriptor::forceEnabledToggles and forceDisabledToggles are vectors of + // 'const char*', so we make sure the parsed strings survive the CreateDevice() call by + // storing them on the stack. + std::vector enabledToggles; + std::vector disabledToggles; + if (auto values = flags_.Get("enable-dawn-features")) { + enabledToggles = Split(*values, ','); + for (auto& t : enabledToggles) { + desc.forceEnabledToggles.emplace_back(t.c_str()); + } + } + if (auto values = flags_.Get("disable-dawn-features")) { + disabledToggles = Split(*values, ','); + for (auto& t : disabledToggles) { + desc.forceDisabledToggles.emplace_back(t.c_str()); + } + } + auto wgpu_device = adapter_.CreateDevice(&desc); if (wgpu_device) { promise.Resolve(interop::GPUDevice::Create(env, env, wgpu_device)); diff --git a/src/dawn_node/binding/GPUAdapter.h b/src/dawn_node/binding/GPUAdapter.h index 1b44f57993..6f837c86be 100644 --- a/src/dawn_node/binding/GPUAdapter.h +++ b/src/dawn_node/binding/GPUAdapter.h @@ -21,11 +21,12 @@ #include "src/dawn_node/interop/WebGPU.h" namespace wgpu { namespace binding { + class Flags; // GPUAdapter is an implementation of interop::GPUAdapter that wraps a dawn_native::Adapter. class GPUAdapter final : public interop::GPUAdapter { public: - GPUAdapter(dawn_native::Adapter a); + GPUAdapter(dawn_native::Adapter a, const Flags& flags); // interop::GPUAdapter interface compliance std::string getName(Napi::Env) override; @@ -38,6 +39,7 @@ namespace wgpu { namespace binding { private: dawn_native::Adapter adapter_; + const Flags& flags_; }; }} // namespace wgpu::binding