dawn.node: Try to add support for compatibility mode
Also adds support for forceFallbackAdapter.
Change-Id: I088fba5b556ac5a5198bdc3c73673784eeea5cc8
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/147201
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Stephen White <senorblanco@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/node/binding/GPU.cpp b/src/dawn/node/binding/GPU.cpp
index eaf78ab..8c3d2bc 100644
--- a/src/dawn/node/binding/GPU.cpp
+++ b/src/dawn/node/binding/GPU.cpp
@@ -114,59 +114,48 @@
auto promise =
interop::Promise<std::optional<interop::Interface<interop::GPUAdapter>>>(env, PROMISE_INFO);
- if (options.forceFallbackAdapter) {
- // Software adapters are not currently supported.
- promise.Resolve({});
- return promise;
- }
-
RequestAdapterOptions nativeOptions;
+ nativeOptions.forceFallbackAdapter = options.forceFallbackAdapter;
+ nativeOptions.compatibilityMode = options.compatibilityMode;
+
+ // Convert the power preference.
+ nativeOptions.powerPreference = PowerPreference::Undefined;
if (options.powerPreference.has_value()) {
- // TODO(dneto): Assign power preference
+ switch (options.powerPreference.value()) {
+ case interop::GPUPowerPreference::kLowPower:
+ nativeOptions.powerPreference = PowerPreference::LowPower;
+ break;
+ case interop::GPUPowerPreference::kHighPerformance:
+ nativeOptions.powerPreference = PowerPreference::HighPerformance;
+ break;
+ }
}
- // Propagate toggles.
- TogglesLoader togglesLoader(flags_);
- DawnTogglesDescriptor togglesDescriptor = togglesLoader.GetDescriptor();
- nativeOptions.nextInChain = &togglesDescriptor;
-
- auto adapters = instance_.EnumerateAdapters(&nativeOptions);
- if (adapters.empty()) {
- promise.Resolve({});
- return promise;
- }
-
+ // Choose the backend to use.
#if defined(_WIN32)
- constexpr auto defaultBackendType = wgpu::BackendType::D3D12;
+ constexpr auto kDefaultBackendType = wgpu::BackendType::D3D12;
#elif defined(__linux__)
- constexpr auto defaultBackendType = wgpu::BackendType::Vulkan;
+ constexpr auto kDefaultBackendType = wgpu::BackendType::Vulkan;
#elif defined(__APPLE__)
- constexpr auto defaultBackendType = wgpu::BackendType::Metal;
+ constexpr auto kDefaultBackendType = wgpu::BackendType::Metal;
#else
#error "Unsupported platform"
#endif
+ nativeOptions.backendType = kDefaultBackendType;
- // Check for backend override from env var / flag
+ // Check for backend override from env var / flag.
std::string forceBackend;
if (auto f = flags_.Get("backend")) {
forceBackend = *f;
} else if (std::string envVar = GetEnvVar("DAWNNODE_BACKEND"); !envVar.empty()) {
forceBackend = envVar;
}
-
- // Check for specific adapter name
- std::string adapterName;
- if (auto f = flags_.Get("adapter")) {
- adapterName = *f;
- }
-
std::transform(forceBackend.begin(), forceBackend.end(), forceBackend.begin(),
[](char c) { return std::tolower(c); });
- auto targetBackendType = defaultBackendType;
if (!forceBackend.empty()) {
if (auto parsed = ParseBackend(forceBackend)) {
- targetBackendType = parsed.value();
+ nativeOptions.backendType = parsed.value();
} else {
std::stringstream msg;
msg << "unrecognised backend '" + forceBackend + "'" << std::endl
@@ -182,13 +171,27 @@
}
}
+ // Propagate toggles.
+ TogglesLoader togglesLoader(flags_);
+ DawnTogglesDescriptor togglesDescriptor = togglesLoader.GetDescriptor();
+ nativeOptions.nextInChain = &togglesDescriptor;
+
+ auto adapters = instance_.EnumerateAdapters(&nativeOptions);
+ if (adapters.empty()) {
+ promise.Resolve({});
+ return promise;
+ }
+
+ // Check for specific adapter name
+ std::string adapterName;
+ if (auto f = flags_.Get("adapter")) {
+ adapterName = *f;
+ }
+
dawn::native::Adapter* adapter = nullptr;
for (auto& a : adapters) {
wgpu::AdapterProperties props;
a.GetProperties(&props);
- if (props.backendType != targetBackendType) {
- continue;
- }
if (!adapterName.empty() && props.name &&
std::string(props.name).find(adapterName) == std::string::npos) {
continue;
diff --git a/src/dawn/node/binding/GPUAdapter.cpp b/src/dawn/node/binding/GPUAdapter.cpp
index de7d365..303ca38 100644
--- a/src/dawn/node/binding/GPUAdapter.cpp
+++ b/src/dawn/node/binding/GPUAdapter.cpp
@@ -99,6 +99,12 @@
return adapterProperties.adapterType == WGPUAdapterType_CPU;
}
+bool GPUAdapter::getIsCompatibilityMode(Napi::Env) {
+ WGPUAdapterProperties adapterProperties = {};
+ adapter_.GetProperties(&adapterProperties);
+ return adapterProperties.compatibilityMode;
+}
+
interop::Promise<interop::Interface<interop::GPUDevice>> GPUAdapter::requestDevice(
Napi::Env env,
interop::GPUDeviceDescriptor descriptor) {
diff --git a/src/dawn/node/binding/GPUAdapter.h b/src/dawn/node/binding/GPUAdapter.h
index 60b8436..8f0fdc4 100644
--- a/src/dawn/node/binding/GPUAdapter.h
+++ b/src/dawn/node/binding/GPUAdapter.h
@@ -41,6 +41,7 @@
interop::Interface<interop::GPUSupportedFeatures> getFeatures(Napi::Env) override;
interop::Interface<interop::GPUSupportedLimits> getLimits(Napi::Env) override;
bool getIsFallbackAdapter(Napi::Env) override;
+ bool getIsCompatibilityMode(Napi::Env) override;
private:
dawn::native::Adapter adapter_;
diff --git a/src/dawn/node/interop/DawnExtensions.idl b/src/dawn/node/interop/DawnExtensions.idl
index a24a9bb..da97b08 100644
--- a/src/dawn/node/interop/DawnExtensions.idl
+++ b/src/dawn/node/interop/DawnExtensions.idl
@@ -19,3 +19,11 @@
"chromium-experimental-subgroups",
"chromium-experimental-subgroup-uniform-control-flow",
};
+
+dictionary GPURequestAdapterOptions {
+ boolean compatibilityMode = false;
+};
+
+interface GPUAdapter {
+ readonly attribute boolean isCompatibilityMode;
+};
diff --git a/tools/src/cmd/idlgen/main.go b/tools/src/cmd/idlgen/main.go
index 2fd039c..451206a 100644
--- a/tools/src/cmd/idlgen/main.go
+++ b/tools/src/cmd/idlgen/main.go
@@ -206,6 +206,7 @@
mixins := map[string]*ast.Mixin{}
includes := []*ast.Includes{}
enums := map[string]*ast.Enum{}
+ dicts := map[string]*ast.Dictionary{}
for _, d := range in.Declarations {
switch d := d.(type) {
case *ast.Interface:
@@ -233,6 +234,16 @@
enums[d.Name] = d
s.declarations[d.Name] = d
}
+ case *ast.Dictionary:
+ if e, ok := dicts[d.Name]; ok {
+ // Merge partial dictionaries into one dictionary
+ e.Members = append(e.Members, d.Members...)
+ } else {
+ clone := *d
+ d := &clone
+ dicts[d.Name] = d
+ s.declarations[d.Name] = d
+ }
default:
if name := nameOf(d); name != "" {
s.declarations[nameOf(d)] = d