DawnTest: add a test environment to contain global data.

This move the "use wire" option as well as instance and window creation
to the test environment. The environment will later be used to print
system information before running the tests for debugging.

BUG=dawn:109

Change-Id: Ice2f40bd5506cc69927287f9f8d51dac85f4472b
Reviewed-on: https://dawn-review.googlesource.com/c/4823
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2019-02-21 16:29:12 +00:00 committed by Commit Bot service account
parent e30d5e17e4
commit 0b2f55257a
3 changed files with 105 additions and 57 deletions

View File

@ -50,32 +50,6 @@ namespace {
} }
} }
// Windows don't usually like to be bound to one API than the other, for example switching
// from Vulkan to OpenGL causes crashes on some drivers. Because of this, we lazily created
// a window for each backing API.
std::unordered_map<dawn_native::BackendType, GLFWwindow*> windows;
// Creates a GLFW window set up for use with a given backend.
GLFWwindow* GetWindowForBackend(dawn_native::BackendType type) {
GLFWwindow** window = &windows[type];
if (*window != nullptr) {
return *window;
}
if (!glfwInit()) {
return nullptr;
}
glfwDefaultWindowHints();
utils::SetupGLFWWindowHintsForBackend(type);
std::string windowName = "Dawn " + ParamName(type) + " test window";
*window = glfwCreateWindow(400, 400, windowName.c_str(), nullptr, nullptr);
return *window;
}
// End2end tests should test valid commands produce the expected result so no error // End2end tests should test valid commands produce the expected result so no error
// should happen. Failure cases should be tested in the validation tests. // should happen. Failure cases should be tested in the validation tests.
void DeviceErrorCauseTestFailure(const char* message, dawnCallbackUserdata) { void DeviceErrorCauseTestFailure(const char* message, dawnCallbackUserdata) {
@ -94,11 +68,78 @@ namespace {
constexpr uint32_t kVendorID_Nvidia = 0x10DE; constexpr uint32_t kVendorID_Nvidia = 0x10DE;
constexpr uint32_t kVendorID_Qualcomm = 0x5143; constexpr uint32_t kVendorID_Qualcomm = 0x5143;
DawnTestEnvironment* gTestEnv = nullptr;
} // namespace } // namespace
void InitDawnEnd2EndTestEnvironment(int, char**) { // Implementation of DawnTestEnvironment
void InitDawnEnd2EndTestEnvironment(int argc, char** argv) {
gTestEnv = new DawnTestEnvironment(argc, argv);
testing::AddGlobalTestEnvironment(gTestEnv);
} }
DawnTestEnvironment::DawnTestEnvironment(int argc, char** argv) {
for (int i = 1; i < argc; ++i) {
if (strcmp("-w", argv[i]) == 0 || strcmp("--use-wire", argv[i]) == 0) {
mUseWire = true;
continue;
}
if (strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) {
std::cout << "\n\nUsage: " << argv[0] << " [GTEST_FLAGS...] [-w] \n";
std::cout << " -w, --use-wire: Run the tests through the wire (defaults to no wire)";
std::cout << std::endl;
continue;
}
}
}
void DawnTestEnvironment::SetUp() {
ASSERT_TRUE(glfwInit());
mInstance = std::make_unique<dawn_native::Instance>();
static constexpr dawn_native::BackendType kAllBackends[] = {
D3D12Backend,
MetalBackend,
OpenGLBackend,
VulkanBackend,
};
// Create a test window for each backend and discover an adapter using it.
for (dawn_native::BackendType backend : kAllBackends) {
if (detail::IsBackendAvailable(backend)) {
CreateBackendWindow(backend);
utils::DiscoverAdapter(mInstance.get(), mWindows[backend], backend);
}
}
}
bool DawnTestEnvironment::UseWire() const {
return mUseWire;
}
dawn_native::Instance* DawnTestEnvironment::GetInstance() const {
return mInstance.get();
}
GLFWwindow* DawnTestEnvironment::GetWindowForBackend(dawn_native::BackendType type) const {
return mWindows.at(type);
}
void DawnTestEnvironment::CreateBackendWindow(dawn_native::BackendType type) {
glfwDefaultWindowHints();
utils::SetupGLFWWindowHintsForBackend(type);
std::string windowName = "Dawn " + ParamName(type) + " test window";
GLFWwindow* window = glfwCreateWindow(400, 400, windowName.c_str(), nullptr, nullptr);
mWindows[type] = window;
}
// Implementation of DawnTest
DawnTest::DawnTest() = default; DawnTest::DawnTest() = default;
DawnTest::~DawnTest() { DawnTest::~DawnTest() {
@ -175,20 +216,12 @@ bool DawnTest::IsMacOS() const {
#endif #endif
} }
bool gTestUsesWire = false;
void DawnTest::SetUp() { void DawnTest::SetUp() {
// Create the test window and discover adapters using it (esp. for OpenGL)
GLFWwindow* testWindow = GetWindowForBackend(GetParam());
DAWN_ASSERT(testWindow != nullptr);
mInstance = std::make_unique<dawn_native::Instance>();
utils::DiscoverAdapter(mInstance.get(), testWindow, GetParam());
// Get an adapter for the backend to use, and create the device. // Get an adapter for the backend to use, and create the device.
dawn_native::Adapter backendAdapter; dawn_native::Adapter backendAdapter;
{ {
std::vector<dawn_native::Adapter> adapters = mInstance->GetAdapters(); dawn_native::Instance* instance = gTestEnv->GetInstance();
std::vector<dawn_native::Adapter> adapters = instance->GetAdapters();
auto adapterIt = std::find_if(adapters.begin(), adapters.end(), auto adapterIt = std::find_if(adapters.begin(), adapters.end(),
[this](const dawn_native::Adapter adapter) -> bool { [this](const dawn_native::Adapter adapter) -> bool {
// Chromium's GTest harness has GetParam() as a regular // Chromium's GTest harness has GetParam() as a regular
@ -204,6 +237,9 @@ void DawnTest::SetUp() {
dawnDevice backendDevice = backendAdapter.CreateDevice(); dawnDevice backendDevice = backendAdapter.CreateDevice();
dawnProcTable backendProcs = dawn_native::GetProcs(); dawnProcTable backendProcs = dawn_native::GetProcs();
// Get the test window and create the device using it (esp. for OpenGL)
GLFWwindow* testWindow = gTestEnv->GetWindowForBackend(GetParam());
DAWN_ASSERT(testWindow != nullptr);
mBinding.reset(utils::CreateBinding(GetParam(), testWindow, backendDevice)); mBinding.reset(utils::CreateBinding(GetParam(), testWindow, backendDevice));
DAWN_ASSERT(mBinding != nullptr); DAWN_ASSERT(mBinding != nullptr);
@ -211,7 +247,7 @@ void DawnTest::SetUp() {
dawnDevice cDevice = nullptr; dawnDevice cDevice = nullptr;
dawnProcTable procs; dawnProcTable procs;
if (gTestUsesWire) { if (gTestEnv->UseWire()) {
mC2sBuf = std::make_unique<utils::TerribleCommandBuffer>(); mC2sBuf = std::make_unique<utils::TerribleCommandBuffer>();
mS2cBuf = std::make_unique<utils::TerribleCommandBuffer>(); mS2cBuf = std::make_unique<utils::TerribleCommandBuffer>();
@ -350,7 +386,7 @@ void DawnTest::SwapBuffersForCapture() {
} }
void DawnTest::FlushWire() { void DawnTest::FlushWire() {
if (gTestUsesWire) { if (gTestEnv->UseWire()) {
bool C2SFlushed = mC2sBuf->Flush(); bool C2SFlushed = mC2sBuf->Flush();
bool S2CFlushed = mS2cBuf->Flush(); bool S2CFlushed = mS2cBuf->Flush();
ASSERT(C2SFlushed); ASSERT(C2SFlushed);

View File

@ -17,6 +17,7 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <memory> #include <memory>
#include <unordered_map>
// Getting data back from Dawn is done in an async manners so all expectations are "deferred" // Getting data back from Dawn is done in an async manners so all expectations are "deferred"
// until the end of the test. Also expectations use a copy to a MapRead buffer to get the data // until the end of the test. Also expectations use a copy to a MapRead buffer to get the data
@ -62,6 +63,8 @@ static constexpr dawn_native::BackendType MetalBackend = dawn_native::BackendTyp
static constexpr dawn_native::BackendType OpenGLBackend = dawn_native::BackendType::OpenGL; static constexpr dawn_native::BackendType OpenGLBackend = dawn_native::BackendType::OpenGL;
static constexpr dawn_native::BackendType VulkanBackend = dawn_native::BackendType::Vulkan; static constexpr dawn_native::BackendType VulkanBackend = dawn_native::BackendType::Vulkan;
struct GLFWwindow;
namespace utils { namespace utils {
class BackendBinding; class BackendBinding;
class TerribleCommandBuffer; class TerribleCommandBuffer;
@ -76,6 +79,31 @@ namespace dawn_wire {
class WireServer; class WireServer;
} // namespace dawn_wire } // namespace dawn_wire
void InitDawnEnd2EndTestEnvironment(int argc, char** argv);
class DawnTestEnvironment : public testing::Environment {
public:
DawnTestEnvironment(int argc, char** argv);
~DawnTestEnvironment() = default;
void SetUp() override;
bool UseWire() const;
dawn_native::Instance* GetInstance() const;
GLFWwindow* GetWindowForBackend(dawn_native::BackendType type) const;
private:
void CreateBackendWindow(dawn_native::BackendType type);
bool mUseWire = false;
std::unique_ptr<dawn_native::Instance> mInstance;
// Windows don't usually like to be bound to one API than the other, for example switching
// from Vulkan to OpenGL causes crashes on some drivers. Because of this, we lazily created
// a window for each backing API.
std::unordered_map<dawn_native::BackendType, GLFWwindow*> mWindows;
};
class DawnTest : public ::testing::TestWithParam<dawn_native::BackendType> { class DawnTest : public ::testing::TestWithParam<dawn_native::BackendType> {
public: public:
DawnTest(); DawnTest();
@ -178,7 +206,6 @@ class DawnTest : public ::testing::TestWithParam<dawn_native::BackendType> {
// Assuming the data is mapped, checks all expectations // Assuming the data is mapped, checks all expectations
void ResolveExpectations(); void ResolveExpectations();
std::unique_ptr<dawn_native::Instance> mInstance;
std::unique_ptr<utils::BackendBinding> mBinding; std::unique_ptr<utils::BackendBinding> mBinding;
dawn_native::PCIInfo mPCIInfo; dawn_native::PCIInfo mPCIInfo;

View File

@ -12,25 +12,10 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include <gtest/gtest.h> #include "tests/DawnTest.h"
extern bool gTestUsesWire;
int main(int argc, char** argv) { int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
InitDawnEnd2EndTestEnvironment(argc, argv);
for (int i = 1; i < argc; ++i) {
if (strcmp("-w", argv[i]) == 0 || strcmp("--use-wire", argv[i]) == 0) {
gTestUsesWire = true;
continue;
}
if (strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) {
printf("\n\nUsage: %s [GTEST_FLAGS...] [-w] \n", argv[0]);
printf(" -w, --use-wire: Run the tests through the wire (defaults to no wire)\n");
return 0;
}
}
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }