dawn/node: Allow picking of the adapter by name

Add the "--adapter" flag to run-cts as a helper for setting this.

Make "--verbose" print the picked adapter.

Rename "dawn-backend" flag to just "backend" - this is already specific to the "gpu provider" (dawn).

Change-Id: Idc8d0eb3ccf5fa23325c06f0f9520aa9b528d9dd
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/116295
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Auto-Submit: Ben Clayton <bclayton@google.com>
Kokoro: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ben Clayton
2023-01-10 19:15:42 +00:00
committed by Dawn LUCI CQ
parent c6236de7c2
commit c9c937cc3e
3 changed files with 117 additions and 51 deletions

View File

@@ -69,7 +69,8 @@ VK_ICD_FILENAMES=<swiftshader-cmake-build>/Linux/vk_swiftshader_icd.json ./src/t
```
The `--flag` parameter must be passed in multiple times, once for each flag begin set. Here are some common arguments:
* `dawn-backend=<null|webgpu|d3d11|d3d12|metal|vulkan|opengl|opengles>`
* `backend=<null|webgpu|d3d11|d3d12|metal|vulkan|opengl|opengles>`
* `adapter=<name-of-adapter>` - specifies the adapter to use. May be a substring of the full adapter name. Pass an invalid adapter name and `--verbose` to see all possible adapters.
* `dlldir=<path>` - used to add an extra DLL search path on Windows, primarily to load the right d3dcompiler_47.dll
* `enable-dawn-features=<features>` - enable [Dawn toggles](https://dawn.googlesource.com/dawn/+/refs/heads/main/src/dawn/native/Toggles.cpp), e.g. `dump_shaders`
* `disable-dawn-features=<features>` - disable [Dawn toggles](https://dawn.googlesource.com/dawn/+/refs/heads/main/src/dawn/native/Toggles.cpp)

View File

@@ -52,6 +52,41 @@ void SetDllDir(const char* dir) {
#endif
}
struct BackendInfo {
const char* const name;
const char* const alias; // may be nullptr
wgpu::BackendType const backend;
};
constexpr BackendInfo kBackends[] = {
{"null", nullptr, wgpu::BackendType::Null}, //
{"webgpu", nullptr, wgpu::BackendType::WebGPU}, //
{"d3d11", nullptr, wgpu::BackendType::D3D11}, //
{"d3d12", "d3d", wgpu::BackendType::D3D12}, //
{"metal", nullptr, wgpu::BackendType::Metal}, //
{"vulkan", "vk", wgpu::BackendType::Vulkan}, //
{"opengl", "gl", wgpu::BackendType::OpenGL}, //
{"opengles", "gles", wgpu::BackendType::OpenGLES}, //
};
std::optional<wgpu::BackendType> ParseBackend(std::string_view name) {
for (auto& info : kBackends) {
if (info.name == name || (info.alias && info.alias == name)) {
return info.backend;
}
}
return std::nullopt;
}
const char* BackendName(wgpu::BackendType backend) {
for (auto& info : kBackends) {
if (info.backend == backend) {
return info.name;
}
}
return "<unknown>";
}
} // namespace
namespace wgpu::binding {
@@ -99,69 +134,93 @@ interop::Promise<std::optional<interop::Interface<interop::GPUAdapter>>> GPU::re
#error "Unsupported platform"
#endif
auto targetBackendType = defaultBackendType;
// Check for backend override from env var / flag
std::string forceBackend;
// Check for override from env var
if (std::string envVar = GetEnvVar("DAWNNODE_BACKEND"); !envVar.empty()) {
if (auto f = flags_.Get("backend")) {
forceBackend = *f;
} else if (std::string envVar = GetEnvVar("DAWNNODE_BACKEND"); !envVar.empty()) {
forceBackend = envVar;
}
// Check for override from flag
if (auto f = flags_.Get("dawn-backend")) {
forceBackend = *f;
// 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); });
// Default to first adapter if a backend is not specified
size_t adapterIndex = 0;
auto targetBackendType = defaultBackendType;
if (!forceBackend.empty()) {
if (forceBackend == "null") {
targetBackendType = wgpu::BackendType::Null;
} else if (forceBackend == "webgpu") {
targetBackendType = wgpu::BackendType::WebGPU;
} else if (forceBackend == "d3d11") {
targetBackendType = wgpu::BackendType::D3D11;
} else if (forceBackend == "d3d12" || forceBackend == "d3d") {
targetBackendType = wgpu::BackendType::D3D12;
} else if (forceBackend == "metal") {
targetBackendType = wgpu::BackendType::Metal;
} else if (forceBackend == "vulkan" || forceBackend == "vk") {
targetBackendType = wgpu::BackendType::Vulkan;
} else if (forceBackend == "opengl" || forceBackend == "gl") {
targetBackendType = wgpu::BackendType::OpenGL;
} else if (forceBackend == "opengles" || forceBackend == "gles") {
targetBackendType = wgpu::BackendType::OpenGLES;
if (auto parsed = ParseBackend(forceBackend)) {
targetBackendType = parsed.value();
} else {
promise.Reject("unknown backend '" + forceBackend + "'");
std::stringstream msg;
msg << "unrecognised backend '" + forceBackend + "'" << std::endl
<< "Possible backends: ";
for (auto& info : kBackends) {
if (&info != &kBackends[0]) {
msg << ", ";
}
msg << "'" << info.name << "'";
}
promise.Reject(msg.str());
return promise;
}
}
bool found = false;
for (size_t i = 0; i < adapters.size(); ++i) {
dawn::native::Adapter* adapter = nullptr;
for (auto& a : adapters) {
wgpu::AdapterProperties props;
adapters[i].GetProperties(&props);
if (props.backendType == targetBackendType) {
adapterIndex = i;
found = true;
break;
a.GetProperties(&props);
if (props.backendType != targetBackendType) {
continue;
}
if (!adapterName.empty() && props.name &&
std::string(props.name).find(adapterName) == std::string::npos) {
continue;
}
adapter = &a;
break;
}
if (!found) {
if (!forceBackend.empty()) {
promise.Reject("backend '" + forceBackend + "' not found");
if (!adapter) {
std::stringstream msg;
if (!forceBackend.empty() || adapterName.empty()) {
msg << "no adapter ";
if (!forceBackend.empty()) {
msg << "with backend '" << forceBackend << "'";
if (!adapterName.empty()) {
msg << " and name '" << adapterName << "'";
}
} else {
msg << " with name '" << adapterName << "'";
}
msg << " found";
} else {
promise.Reject("no suitable backends found");
msg << "no suitable backends found";
}
msg << std::endl << "Available adapters:";
for (auto& a : adapters) {
wgpu::AdapterProperties props;
a.GetProperties(&props);
msg << std::endl
<< " * backend: '" << BackendName(props.backendType) << "', name: '" << props.name
<< "'";
}
promise.Reject(msg.str());
return promise;
}
auto adapter = GPUAdapter::Create<GPUAdapter>(env, adapters[adapterIndex], flags_);
promise.Resolve(std::optional<interop::Interface<interop::GPUAdapter>>(adapter));
if (flags_.Get("verbose")) {
wgpu::AdapterProperties props;
adapter->GetProperties(&props);
printf("using GPU adapter: %s\n", props.name);
}
auto gpuAdapter = GPUAdapter::Create<GPUAdapter>(env, *adapter, flags_);
promise.Resolve(std::optional<interop::Interface<interop::GPUAdapter>>(gpuAdapter));
return promise;
}