NXTTest: add -w to run the end2end tests through the wire

This will be useful to provide additional coverage of the wire in
addition to the very focused WireTests unittests. All tests pass except
the MapWriteAsync ones that aren't implemented in the wire yet. They can
be skipped with --gtest_filter=-*MapWrite*
This commit is contained in:
Corentin Wallez 2018-06-07 13:10:44 +02:00 committed by Corentin Wallez
parent 862f884a65
commit 419e9841a8
4 changed files with 151 additions and 58 deletions

View File

@ -90,5 +90,5 @@ add_executable(nxt_end2end_tests
${TESTS_DIR}/NXTTest.cpp
${TESTS_DIR}/NXTTest.h
)
target_link_libraries(nxt_end2end_tests nxt_common gtest utils)
target_link_libraries(nxt_end2end_tests nxt_common nxt_wire gtest utils)
NXTInternalTarget("tests" nxt_end2end_tests)

View File

@ -14,7 +14,23 @@
#include <gtest/gtest.h>
extern bool gTestUsesWire;
int main(int argc, char** argv) {
testing::InitGoogleTest(&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();
}

View File

@ -20,9 +20,12 @@
#include "utils/BackendBinding.h"
#include "utils/NXTHelpers.h"
#include "utils/SystemUtils.h"
#include "wire/TerribleCommandBuffer.h"
#include "wire/Wire.h"
#include <iostream>
#include "GLFW/glfw3.h"
namespace {
utils::BackendType ParamToBackendType(BackendType type) {
@ -122,6 +125,8 @@ bool NXTTest::IsVulkan() const {
return GetParam() == VulkanBackend;
}
bool gTestUsesWire = false;
void NXTTest::SetUp() {
mBinding = utils::CreateBinding(ParamToBackendType(GetParam()));
NXT_ASSERT(mBinding != nullptr);
@ -135,20 +140,50 @@ void NXTTest::SetUp() {
nxtProcTable backendProcs;
mBinding->GetProcAndDevice(&backendProcs, &backendDevice);
nxtSetProcs(&backendProcs);
device = nxt::Device::Acquire(backendDevice);
// Choose whether to use the backend procs and devices directly, or set up the wire.
nxtDevice cDevice = nullptr;
nxtProcTable procs;
if (gTestUsesWire) {
mC2sBuf = new nxt::wire::TerribleCommandBuffer();
mS2cBuf = new nxt::wire::TerribleCommandBuffer();
mWireServer = nxt::wire::NewServerCommandHandler(backendDevice, backendProcs, mS2cBuf);
mC2sBuf->SetHandler(mWireServer);
nxtDevice clientDevice;
nxtProcTable clientProcs;
mWireClient = nxt::wire::NewClientDevice(&clientProcs, &clientDevice, mC2sBuf);
mS2cBuf->SetHandler(mWireClient);
procs = clientProcs;
cDevice = clientDevice;
} else {
procs = backendProcs;
cDevice = backendDevice;
}
// Set up the device and queue because all tests need them, and NXTTest needs them too for the
// deferred expectations.
nxtSetProcs(&procs);
device = nxt::Device::Acquire(cDevice);
queue = device.CreateQueueBuilder().GetResult();
// The swapchain isn't used by tests but is useful when debugging with graphics debuggers that
// capture at frame boundaries.
swapchain = device.CreateSwapChainBuilder()
.SetImplementation(mBinding->GetSwapChainImplementation())
.GetResult();
swapchain.Configure(static_cast<nxt::TextureFormat>(mBinding->GetPreferredSwapChainTextureFormat()),
nxt::TextureUsageBit::OutputAttachment, 400, 400);
// The end2end tests should never cause validation errors. These should be tested in unittests.
device.SetErrorCallback(DeviceErrorCauseTestFailure, 0);
}
void NXTTest::TearDown() {
FlushWire();
MapSlotsSynchronously();
ResolveExpectations();
@ -160,6 +195,13 @@ void NXTTest::TearDown() {
delete expectation.expectation;
expectation.expectation = nullptr;
}
if (gTestUsesWire) {
delete mC2sBuf;
delete mS2cBuf;
delete mWireClient;
delete mWireServer;
}
}
std::ostringstream& NXTTest::AddBufferExpectation(const char* file, int line, const nxt::Buffer& buffer, uint32_t offset, uint32_t size, detail::Expectation* expectation) {
@ -226,6 +268,8 @@ std::ostringstream& NXTTest::AddTextureExpectation(const char* file, int line, c
void NXTTest::WaitABit() {
device.Tick();
FlushWire();
utils::USleep(100);
}
@ -236,6 +280,13 @@ void NXTTest::SwapBuffersForCapture() {
swapchain.Present(backBuffer);
}
void NXTTest::FlushWire() {
if (gTestUsesWire) {
mC2sBuf->Flush();
mS2cBuf->Flush();
}
}
NXTTest::ReadbackReservation NXTTest::ReserveReadback(uint32_t readbackSize) {
// For now create a new MapRead buffer for each readback
// TODO(cwallez@chromium.org): eventually make bigger buffers and allocate linearly?

View File

@ -66,6 +66,11 @@ namespace detail {
class Expectation;
}
namespace nxt { namespace wire {
class CommandHandler;
class TerribleCommandBuffer;
}} // namespace nxt::wire
class NXTTest : public ::testing::TestWithParam<BackendType> {
public:
~NXTTest();
@ -84,14 +89,35 @@ class NXTTest : public ::testing::TestWithParam<BackendType> {
nxt::SwapChain swapchain;
// Helper methods to implement the EXPECT_ macros
std::ostringstream& AddBufferExpectation(const char* file, int line, const nxt::Buffer& buffer, uint32_t offset, uint32_t size, detail::Expectation* expectation);
std::ostringstream& AddTextureExpectation(const char* file, int line, const nxt::Texture& texture, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t level, uint32_t pixelSize, detail::Expectation* expectation);
std::ostringstream& AddBufferExpectation(const char* file,
int line,
const nxt::Buffer& buffer,
uint32_t offset,
uint32_t size,
detail::Expectation* expectation);
std::ostringstream& AddTextureExpectation(const char* file,
int line,
const nxt::Texture& texture,
uint32_t x,
uint32_t y,
uint32_t width,
uint32_t height,
uint32_t level,
uint32_t pixelSize,
detail::Expectation* expectation);
void WaitABit();
void SwapBuffersForCapture();
private:
// Things used to set up testing through the Wire.
nxt::wire::CommandHandler* mWireServer = nullptr;
nxt::wire::CommandHandler* mWireClient = nullptr;
nxt::wire::TerribleCommandBuffer* mC2sBuf = nullptr;
nxt::wire::TerribleCommandBuffer* mS2cBuf = nullptr;
void FlushWire();
// MapRead buffers used to get data for the expectations
struct ReadbackSlot {
nxt::Buffer buffer;