Add backend and toggle options to ManualSurfaceTests
Bug: 346802084
Bug: 42241992
Change-Id: I66da6dc06eefbb0e28f9363b8a84387a0ace262f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/194561
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/samples/ManualSurfaceTest.cpp b/src/dawn/samples/ManualSurfaceTest.cpp
index c9ef652..4e686a6 100644
--- a/src/dawn/samples/ManualSurfaceTest.cpp
+++ b/src/dawn/samples/ManualSurfaceTest.cpp
@@ -78,6 +78,7 @@
// - Check with GLFW transparency on / off.
#include <algorithm>
+#include <iostream>
#include <memory>
#include <string>
#include <unordered_map>
@@ -90,6 +91,7 @@
#include "dawn/dawn_proc.h"
#include "dawn/native/DawnNative.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
+#include "dawn/utils/CommandLineParser.h"
#include "dawn/utils/WGPUHelpers.h"
#include "dawn/webgpu_cpp.h"
#include "dawn/webgpu_cpp_print.h"
@@ -136,7 +138,7 @@
static std::unordered_map<GLFWwindow*, std::unique_ptr<WindowData>> windows;
static uint64_t windowSerial = 0;
-static std::unique_ptr<dawn::native::Instance> instance;
+static wgpu::Instance instance;
static wgpu::Adapter adapter;
static wgpu::Device device;
static wgpu::Queue queue;
@@ -200,7 +202,7 @@
GLFWwindow* window = glfwCreateWindow(400, 400, "", nullptr, nullptr);
glfwSetKeyCallback(window, OnKeyPress);
- wgpu::Surface surface = wgpu::glfw::CreateSurfaceForWindow(instance->Get(), window);
+ wgpu::Surface surface = wgpu::glfw::CreateSurfaceForWindow(instance, window);
wgpu::SurfaceCapabilities caps;
surface.GetCapabilities(adapter, &caps);
@@ -343,7 +345,41 @@
}
int main(int argc, const char* argv[]) {
- // Setup GLFW
+ // Parse command line options.
+ dawn::utils::CommandLineParser parser;
+ auto& helpOpt = parser.AddHelp();
+ auto& enableTogglesOpt = parser.AddStringList("enable-toggles", "Toggles to enable in Dawn")
+ .ShortName('e')
+ .Parameter("comma separated list");
+ auto& disableTogglesOpt = parser.AddStringList("disable-toggles", "Toggles to disable in Dawn")
+ .ShortName('d')
+ .Parameter("comma separated list");
+ auto& backendOpt =
+ parser
+ .AddEnum<wgpu::BackendType>({{"d3d11", wgpu::BackendType::D3D11},
+ {"d3d12", wgpu::BackendType::D3D12},
+ {"metal", wgpu::BackendType::Metal},
+ {"null", wgpu::BackendType::Null},
+ {"opengl", wgpu::BackendType::OpenGL},
+ {"opengles", wgpu::BackendType::OpenGLES},
+ {"vulkan", wgpu::BackendType::Vulkan}},
+ "backend", "The backend to get an adapter from")
+ .ShortName('b')
+ .Default(wgpu::BackendType::Undefined);
+
+ auto parserResult = parser.Parse(argc, argv);
+ if (!parserResult.success) {
+ std::cerr << parserResult.errorMessage << "\n";
+ return 1;
+ }
+
+ if (helpOpt.GetValue()) {
+ std::cout << "Usage: " << argv[0] << " <options>\n\noptions\n";
+ parser.PrintHelp(std::cout);
+ return 0;
+ }
+
+ // Setup GLFW, Dawn procs
glfwSetErrorCallback([](int code, const char* message) {
dawn::ErrorLog() << "GLFW error " << code << " " << message;
});
@@ -351,19 +387,74 @@
return 1;
}
- // Choose an adapter we like.
- // TODO(dawn:269): allow switching the window between devices.
DawnProcTable procs = dawn::native::GetProcs();
dawnProcSetProcs(&procs);
- instance = std::make_unique<dawn::native::Instance>();
+ // Make an instance with the toggles.
+ std::vector<const char*> enableToggleNames;
+ std::vector<const char*> disabledToggleNames;
+ for (auto toggle : enableTogglesOpt.GetValue()) {
+ enableToggleNames.push_back(toggle.c_str());
+ }
- dawn::native::Adapter chosenAdapter = instance->EnumerateAdapters()[0];
- DAWN_ASSERT(chosenAdapter);
- adapter = wgpu::Adapter(chosenAdapter.Get());
+ for (auto toggle : disableTogglesOpt.GetValue()) {
+ disabledToggleNames.push_back(toggle.c_str());
+ }
+ wgpu::DawnTogglesDescriptor toggles;
+ toggles.enabledToggles = enableToggleNames.data();
+ toggles.enabledToggleCount = enableToggleNames.size();
+ toggles.disabledToggles = disabledToggleNames.data();
+ toggles.disabledToggleCount = disabledToggleNames.size();
+
+ wgpu::InstanceDescriptor instanceDescriptor{};
+ instanceDescriptor.nextInChain = &toggles;
+ instanceDescriptor.features.timedWaitAnyEnable = true;
+ instance = wgpu::CreateInstance(&instanceDescriptor);
+
+ // Choose an adapter we like.
+ // TODO(dawn:269): allow switching the window between devices.
+ wgpu::RequestAdapterOptions options = {};
+ options.backendType = backendOpt.GetValue();
+ if (options.backendType != wgpu::BackendType::Undefined) {
+ options.compatibilityMode = dawn::utils::BackendRequiresCompat(options.backendType);
+ }
+
+ wgpu::Future adapterFuture = instance.RequestAdapter(
+ &options, wgpu::CallbackMode::WaitAnyOnly,
+ [&](wgpu::RequestAdapterStatus status, wgpu::Adapter adapterIn, const char* message) {
+ if (status != wgpu::RequestAdapterStatus::Success) {
+ dawn::ErrorLog() << "Failed to get an adapter: " << message;
+ return;
+ }
+ adapter = adapterIn;
+ });
+ instance.WaitAny(adapterFuture, UINT64_MAX);
+
+ if (adapter == nullptr) {
+ return 1;
+ }
+
+ wgpu::AdapterInfo adapterInfo;
+ adapter.GetInfo(&adapterInfo);
+ std::cout << "Using adapter \"" << adapterInfo.device << "\" on " << adapterInfo.backendType
+ << ".\n";
// Setup the device on that adapter.
- device = wgpu::Device::Acquire(chosenAdapter.CreateDevice());
+ wgpu::Future deviceFuture = adapter.RequestDevice(
+ nullptr, wgpu::CallbackMode::WaitAnyOnly,
+ [&](wgpu::RequestDeviceStatus status, wgpu::Device deviceIn, const char* message) {
+ if (status != wgpu::RequestDeviceStatus::Success) {
+ dawn::ErrorLog() << "Failed to get a device:" << message;
+ return;
+ }
+ device = deviceIn;
+ });
+ instance.WaitAny(deviceFuture, UINT64_MAX);
+
+ if (device == nullptr) {
+ return 1;
+ }
+
device.SetUncapturedErrorCallback(
[](WGPUErrorType errorType, const char* message, void*) {
const char* errorTypeName = "";
@@ -395,7 +486,7 @@
while (windows.size() != 0) {
glfwPollEvents();
- wgpuInstanceProcessEvents(instance->Get());
+ instance.ProcessEvents();
for (auto it = windows.begin(); it != windows.end();) {
GLFWwindow* window = it->first;
diff --git a/src/dawn/tests/unittests/CommandLineParserTests.cpp b/src/dawn/tests/unittests/CommandLineParserTests.cpp
index 9d8cc62..5640b93 100644
--- a/src/dawn/tests/unittests/CommandLineParserTests.cpp
+++ b/src/dawn/tests/unittests/CommandLineParserTests.cpp
@@ -429,7 +429,7 @@
}
// Tests for the generation of the help strings for the options.
-TEST(CommandLineParserTest, OptionHelp) {
+TEST(CommandLineParserTest, PrintHelp) {
// A test with a few options, checks that they are sorted.
{
CLP opts;
@@ -438,7 +438,7 @@
opts.AddString("baz");
std::stringstream s;
- opts.AddHelp(s);
+ opts.PrintHelp(s);
EXPECT_EQ(s.str(), R"(--bar <value>
--baz <value>
--foo <value>
@@ -451,7 +451,7 @@
opts.AddString("foo").Parameter("bar");
std::stringstream s;
- opts.AddHelp(s);
+ opts.PrintHelp(s);
EXPECT_EQ(s.str(), R"(--foo <bar>
)");
}
@@ -462,7 +462,7 @@
opts.AddBool("foo", "enable fooing");
std::stringstream s;
- opts.AddHelp(s);
+ opts.PrintHelp(s);
EXPECT_EQ(s.str(), R"(--foo enable fooing
)");
}
@@ -479,7 +479,7 @@
opts.AddEnum(conversions, "cell", "which story to get");
std::stringstream s;
- opts.AddHelp(s);
+ opts.PrintHelp(s);
EXPECT_EQ(s.str(), R"(--cell <pop|six|uh-uh> which story to get
)");
}
@@ -490,12 +490,27 @@
opts.AddString("foo").ShortName('f');
std::stringstream s;
- opts.AddHelp(s);
+ opts.PrintHelp(s);
EXPECT_EQ(s.str(), R"(--foo <value>
-f alias for --foo
)");
}
}
+// Tests that AddHelp() add the correct option.
+TEST(CommandLineParserTest, HelpOption) {
+ CLP opts;
+ CLP::BoolOption& helpOpt = opts.AddHelp();
+
+ std::stringstream s;
+ opts.PrintHelp(s);
+ EXPECT_EQ(s.str(), R"(--help Shows the help
+-h alias for --help
+)");
+
+ ExpectSuccess(opts.Parse(Split("-h")));
+ EXPECT_TRUE(helpOpt.GetValue());
+}
+
} // anonymous namespace
} // namespace dawn
diff --git a/src/dawn/utils/CommandLineParser.cpp b/src/dawn/utils/CommandLineParser.cpp
index b8c0c2d..eca9e03 100644
--- a/src/dawn/utils/CommandLineParser.cpp
+++ b/src/dawn/utils/CommandLineParser.cpp
@@ -198,6 +198,10 @@
return absl::StrJoin(names, separator);
}
+CommandLineParser::BoolOption& CommandLineParser::AddHelp() {
+ return AddBool("help", "Shows the help").ShortName('h');
+}
+
// static
const CommandLineParser::ParseOptions CommandLineParser::kDefaultParseOptions = {};
@@ -307,7 +311,7 @@
return Parse(args, parseOptions);
}
-void CommandLineParser::AddHelp(std::ostream& s) {
+void CommandLineParser::PrintHelp(std::ostream& s) {
// Sort options in alphabetical order using a trick that std::tuple is sorted lexicographically.
std::vector<std::tuple<std::string_view, OptionBase*>> sortedOptions;
for (auto& option : mOptions) {
diff --git a/src/dawn/utils/CommandLineParser.h b/src/dawn/utils/CommandLineParser.h
index 457b07d..a8759b9 100644
--- a/src/dawn/utils/CommandLineParser.h
+++ b/src/dawn/utils/CommandLineParser.h
@@ -45,7 +45,7 @@
// CommandLineParser parser;
// auto& dryRun = parser.AddBool("dry-run", "fake operations").ShortName('d');
// auto& input = parser.AddString("input", "the input file to process").ShortName('i');
-// auto& help = opts.AddBool("help", "Shows the help").ShortName('h');
+// auto& help = opts.AddHelp();
//
// auto result = parser.Parse(argc, argv);
// if (!result.success) {
@@ -55,7 +55,7 @@
//
// if (help.GetValue()) {
// std::cout << "Usage: " << argv[0] << " <options>\n\noptions\n";
-// parser.AddHelp(std::cout);
+// parser.PrintHelp(std::cout);
// return 0;
// }
//
@@ -196,6 +196,9 @@
return AddOption(std::make_unique<EnumOption<E>>(std::move(conversions), name, desc));
}
+ // Helper to add a --help option.
+ BoolOption& AddHelp();
+
// Helper structs for the Parse calls.
struct ParseResult {
bool success;
@@ -219,7 +222,7 @@
const ParseOptions& parseOptions = kDefaultParseOptions);
// Generate summary of options for a --help and add it to the stream.
- void AddHelp(std::ostream& s);
+ void PrintHelp(std::ostream& s);
private:
template <typename T>
diff --git a/src/dawn/utils/WGPUHelpers.cpp b/src/dawn/utils/WGPUHelpers.cpp
index 7086096..297fee4 100644
--- a/src/dawn/utils/WGPUHelpers.cpp
+++ b/src/dawn/utils/WGPUHelpers.cpp
@@ -452,4 +452,21 @@
return info;
}
+bool BackendRequiresCompat(wgpu::BackendType backend) {
+ switch (backend) {
+ case wgpu::BackendType::D3D12:
+ case wgpu::BackendType::Metal:
+ case wgpu::BackendType::Vulkan:
+ case wgpu::BackendType::WebGPU:
+ case wgpu::BackendType::Null:
+ return false;
+ case wgpu::BackendType::D3D11:
+ case wgpu::BackendType::OpenGL:
+ case wgpu::BackendType::OpenGLES:
+ return true;
+ case wgpu::BackendType::Undefined:
+ DAWN_UNREACHABLE();
+ }
+}
+
} // namespace dawn::utils
diff --git a/src/dawn/utils/WGPUHelpers.h b/src/dawn/utils/WGPUHelpers.h
index fcd8f42..1d341bd 100644
--- a/src/dawn/utils/WGPUHelpers.h
+++ b/src/dawn/utils/WGPUHelpers.h
@@ -207,6 +207,8 @@
ColorSpaceConversionInfo GetYUVBT709ToRGBSRGBColorSpaceConversionInfo();
ColorSpaceConversionInfo GetNoopRGBColorSpaceConversionInfo();
+bool BackendRequiresCompat(wgpu::BackendType backend);
+
} // namespace dawn::utils
#endif // SRC_DAWN_UTILS_WGPUHELPERS_H_