Add intermediate dawn_wire command handler to dump command traces
This adds an argument to Dawn tests to use an intermediate command handler which dumps command traces. In the near term, this will be useful to generate a seed corpus for fuzzing. In the future, we may be able to use the layer to produce reproducible traces of real applications. Bug: dawn:295 Change-Id: Ie36d10f4b46f4b16a3ad3ea34961fd38ba8041aa Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/14241 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
d1db0e94b0
commit
cbc206e84f
|
@ -19,6 +19,7 @@
|
||||||
#include "common/Log.h"
|
#include "common/Log.h"
|
||||||
#include "common/Math.h"
|
#include "common/Math.h"
|
||||||
#include "common/Platform.h"
|
#include "common/Platform.h"
|
||||||
|
#include "common/SystemUtils.h"
|
||||||
#include "dawn/dawn_proc.h"
|
#include "dawn/dawn_proc.h"
|
||||||
#include "dawn_native/DawnNative.h"
|
#include "dawn_native/DawnNative.h"
|
||||||
#include "dawn_wire/WireClient.h"
|
#include "dawn_wire/WireClient.h"
|
||||||
|
@ -28,6 +29,7 @@
|
||||||
#include "utils/WGPUHelpers.h"
|
#include "utils/WGPUHelpers.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -158,6 +160,19 @@ DawnTestEnvironment::DawnTestEnvironment(int argc, char** argv) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr const char kWireTraceDirArg[] = "--wire-trace-dir=";
|
||||||
|
if (strstr(argv[i], kWireTraceDirArg) == argv[i]) {
|
||||||
|
const char* wireTraceDir = argv[i] + strlen(kWireTraceDirArg);
|
||||||
|
if (wireTraceDir[0] != '\0') {
|
||||||
|
const char* sep = GetPathSeparator();
|
||||||
|
mWireTraceDir = wireTraceDir;
|
||||||
|
if (mWireTraceDir.back() != *sep) {
|
||||||
|
mWireTraceDir += sep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) {
|
if (strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) {
|
||||||
dawn::InfoLog()
|
dawn::InfoLog()
|
||||||
<< "\n\nUsage: " << argv[0]
|
<< "\n\nUsage: " << argv[0]
|
||||||
|
@ -264,6 +279,13 @@ uint32_t DawnTestEnvironment::GetVendorIdFilter() const {
|
||||||
return mVendorIdFilter;
|
return mVendorIdFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* DawnTestEnvironment::GetWireTraceDir() const {
|
||||||
|
if (mWireTraceDir.length() == 0) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return mWireTraceDir.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
void DawnTestEnvironment::DiscoverOpenGLAdapter() {
|
void DawnTestEnvironment::DiscoverOpenGLAdapter() {
|
||||||
#ifdef DAWN_ENABLE_BACKEND_OPENGL
|
#ifdef DAWN_ENABLE_BACKEND_OPENGL
|
||||||
if (!glfwInit()) {
|
if (!glfwInit()) {
|
||||||
|
@ -285,6 +307,23 @@ void DawnTestEnvironment::DiscoverOpenGLAdapter() {
|
||||||
#endif // DAWN_ENABLE_BACKEND_OPENGL
|
#endif // DAWN_ENABLE_BACKEND_OPENGL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class WireServerTraceLayer : public dawn_wire::CommandHandler {
|
||||||
|
public:
|
||||||
|
WireServerTraceLayer(const char* file, dawn_wire::WireServer* server)
|
||||||
|
: dawn_wire::CommandHandler(), mServer(server) {
|
||||||
|
mFile.open(file, std::ios_base::app | std::ios_base::binary | std::ios_base::trunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
const volatile char* HandleCommands(const volatile char* commands, size_t size) override {
|
||||||
|
mFile.write(const_cast<const char*>(commands), size);
|
||||||
|
return mServer->HandleCommands(commands, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
dawn_wire::WireServer* mServer;
|
||||||
|
std::ofstream mFile;
|
||||||
|
};
|
||||||
|
|
||||||
// Implementation of DawnTest
|
// Implementation of DawnTest
|
||||||
|
|
||||||
DawnTestBase::DawnTestBase(const DawnTestParam& param) : mParam(param) {
|
DawnTestBase::DawnTestBase(const DawnTestParam& param) : mParam(param) {
|
||||||
|
@ -497,6 +536,21 @@ void DawnTestBase::SetUp() {
|
||||||
mWireServer.reset(new dawn_wire::WireServer(serverDesc));
|
mWireServer.reset(new dawn_wire::WireServer(serverDesc));
|
||||||
mC2sBuf->SetHandler(mWireServer.get());
|
mC2sBuf->SetHandler(mWireServer.get());
|
||||||
|
|
||||||
|
if (gTestEnv->GetWireTraceDir() != nullptr) {
|
||||||
|
std::string file =
|
||||||
|
std::string(
|
||||||
|
::testing::UnitTest::GetInstance()->current_test_info()->test_suite_name()) +
|
||||||
|
"_" + ::testing::UnitTest::GetInstance()->current_test_info()->name();
|
||||||
|
// Replace slashes in gtest names with underscores so everything is in one directory.
|
||||||
|
std::replace(file.begin(), file.end(), '/', '_');
|
||||||
|
|
||||||
|
std::string fullPath = gTestEnv->GetWireTraceDir() + file;
|
||||||
|
|
||||||
|
mWireServerTraceLayer.reset(
|
||||||
|
new WireServerTraceLayer(fullPath.c_str(), mWireServer.get()));
|
||||||
|
mC2sBuf->SetHandler(mWireServerTraceLayer.get());
|
||||||
|
}
|
||||||
|
|
||||||
dawn_wire::WireClientDescriptor clientDesc = {};
|
dawn_wire::WireClientDescriptor clientDesc = {};
|
||||||
clientDesc.serializer = mC2sBuf.get();
|
clientDesc.serializer = mC2sBuf.get();
|
||||||
|
|
||||||
|
|
|
@ -117,6 +117,7 @@ namespace detail {
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
namespace dawn_wire {
|
namespace dawn_wire {
|
||||||
|
class CommandHandler;
|
||||||
class WireClient;
|
class WireClient;
|
||||||
class WireServer;
|
class WireServer;
|
||||||
} // namespace dawn_wire
|
} // namespace dawn_wire
|
||||||
|
@ -140,6 +141,7 @@ class DawnTestEnvironment : public testing::Environment {
|
||||||
dawn_native::Instance* GetInstance() const;
|
dawn_native::Instance* GetInstance() const;
|
||||||
bool HasVendorIdFilter() const;
|
bool HasVendorIdFilter() const;
|
||||||
uint32_t GetVendorIdFilter() const;
|
uint32_t GetVendorIdFilter() const;
|
||||||
|
const char* GetWireTraceDir() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::unique_ptr<dawn_native::Instance> mInstance;
|
std::unique_ptr<dawn_native::Instance> mInstance;
|
||||||
|
@ -154,6 +156,7 @@ class DawnTestEnvironment : public testing::Environment {
|
||||||
bool mBeginCaptureOnStartup = false;
|
bool mBeginCaptureOnStartup = false;
|
||||||
bool mHasVendorIdFilter = false;
|
bool mHasVendorIdFilter = false;
|
||||||
uint32_t mVendorIdFilter = 0;
|
uint32_t mVendorIdFilter = 0;
|
||||||
|
std::string mWireTraceDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DawnTestBase {
|
class DawnTestBase {
|
||||||
|
@ -242,6 +245,8 @@ class DawnTestBase {
|
||||||
std::unique_ptr<utils::TerribleCommandBuffer> mC2sBuf;
|
std::unique_ptr<utils::TerribleCommandBuffer> mC2sBuf;
|
||||||
std::unique_ptr<utils::TerribleCommandBuffer> mS2cBuf;
|
std::unique_ptr<utils::TerribleCommandBuffer> mS2cBuf;
|
||||||
|
|
||||||
|
std::unique_ptr<dawn_wire::CommandHandler> mWireServerTraceLayer;
|
||||||
|
|
||||||
// Tracking for validation errors
|
// Tracking for validation errors
|
||||||
static void OnDeviceError(WGPUErrorType type, const char* message, void* userdata);
|
static void OnDeviceError(WGPUErrorType type, const char* message, void* userdata);
|
||||||
bool mExpectError = false;
|
bool mExpectError = false;
|
||||||
|
|
Loading…
Reference in New Issue