Update tests to use new mapping APIs

This CL updates all tests not specific to the old mapping API to use the
new mapping APIs. (a couple old tests that caused difficult diffs were
removed early).

Also fix an issue where the mapAsync callback wasn't fired with Unknown
when the buffer was destroyed.

Bug: dawn:445

Change-Id: I0101f533ecb1fd995066742b60a833dc2ad522aa
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/26300
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2020-08-12 19:32:25 +00:00 committed by Commit Bot service account
parent 1aff02d444
commit 2088cdec66
8 changed files with 231 additions and 357 deletions

View File

@ -151,6 +151,7 @@ namespace dawn_native {
ASSERT(!IsError());
CallMapReadCallback(mMapSerial, WGPUBufferMapAsyncStatus_Unknown, nullptr, 0u);
CallMapWriteCallback(mMapSerial, WGPUBufferMapAsyncStatus_Unknown, nullptr, 0u);
CallMapCallback(mMapSerial, WGPUBufferMapAsyncStatus_Unknown);
}
}
@ -468,6 +469,7 @@ namespace dawn_native {
mMapReadCallback = nullptr;
mMapWriteCallback = nullptr;
mMapCallback = nullptr;
mMapUserdata = 0;
} else if (mState == BufferState::MappedAtCreation) {

View File

@ -14,6 +14,7 @@
#include "tests/DawnTest.h"
#include <array>
#include <cstring>
class BufferMapReadTests : public DawnTest {
@ -575,6 +576,51 @@ TEST_P(BufferMappingTests, MapWrite_Large) {
EXPECT_BUFFER_U32_RANGE_EQ(myData.data(), buffer, 12, kDataSize - 5);
}
// Stress test mapping many buffers.
TEST_P(BufferMappingTests, MapWrite_ManySimultaneous) {
constexpr uint32_t kDataSize = 1000;
std::vector<uint32_t> myData;
for (uint32_t i = 0; i < kDataSize; ++i) {
myData.push_back(i);
}
constexpr uint32_t kBuffers = 100;
std::array<wgpu::Buffer, kBuffers> buffers;
uint32_t mapCompletedCount = 0;
// Create buffers and request mapping them.
wgpu::BufferDescriptor descriptor;
descriptor.size = static_cast<uint32_t>(kDataSize * sizeof(uint32_t));
descriptor.usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc;
for (uint32_t i = 0; i < kBuffers; ++i) {
buffers[i] = device.CreateBuffer(&descriptor);
buffers[i].MapAsync(
wgpu::MapMode::Write, 0, descriptor.size,
[](WGPUBufferMapAsyncStatus status, void* userdata) {
ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
(*static_cast<uint32_t*>(userdata))++;
},
&mapCompletedCount);
}
// Wait for all mappings to complete
while (mapCompletedCount != kBuffers) {
WaitABit();
}
// All buffers are mapped, write into them and unmap them all.
for (uint32_t i = 0; i < kBuffers; ++i) {
memcpy(buffers[i].GetMappedRange(0, descriptor.size), myData.data(), descriptor.size);
buffers[i].Unmap();
}
// Check the content of the buffers.
for (uint32_t i = 0; i < kBuffers; ++i) {
EXPECT_BUFFER_U32_RANGE_EQ(myData.data(), buffers[i], 0, kDataSize);
}
}
// Test that the map offset isn't updated when the call is an error.
TEST_P(BufferMappingTests, OffsetNotUpdatedOnError) {
uint32_t data[3] = {0xCA7, 0xB0A7, 0xBA7};
@ -977,29 +1023,24 @@ DAWN_INSTANTIATE_TEST(CreateBufferMappedTests,
class BufferMappedAtCreationTests : public DawnTest {
protected:
static void MapReadCallback(WGPUBufferMapAsyncStatus status,
const void* data,
uint64_t,
void* userdata) {
ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
ASSERT_NE(nullptr, data);
static_cast<BufferMappedAtCreationTests*>(userdata)->mappedData = data;
static void MapCallback(WGPUBufferMapAsyncStatus status, void* userdata) {
EXPECT_EQ(WGPUBufferMapAsyncStatus_Success, status);
*static_cast<bool*>(userdata) = true;
}
const void* MapReadAsyncAndWait(const wgpu::Buffer& buffer) {
buffer.MapReadAsync(MapReadCallback, this);
const void* MapAsyncAndWait(const wgpu::Buffer& buffer, wgpu::MapMode mode, size_t size) {
bool done = false;
buffer.MapAsync(mode, 0, size, MapCallback, &done);
while (mappedData == nullptr) {
while (!done) {
WaitABit();
}
return mappedData;
return buffer.GetConstMappedRange(0, size);
}
void UnmapBuffer(const wgpu::Buffer& buffer) {
buffer.Unmap();
mappedData = nullptr;
}
wgpu::Buffer BufferMappedAtCreation(wgpu::BufferUsage usage, uint64_t size) {
@ -1017,9 +1058,6 @@ class BufferMappedAtCreationTests : public DawnTest {
memcpy(buffer.GetMappedRange(), data.data(), byteLength);
return buffer;
}
private:
const void* mappedData = nullptr;
};
// Test that the simplest mappedAtCreation works for MapWrite buffers.
@ -1037,7 +1075,7 @@ TEST_P(BufferMappedAtCreationTests, MapReadUsageSmall) {
wgpu::Buffer buffer = BufferMappedAtCreationWithData(wgpu::BufferUsage::MapRead, {myData});
UnmapBuffer(buffer);
const void* mappedData = MapReadAsyncAndWait(buffer);
const void* mappedData = MapAsyncAndWait(buffer, wgpu::MapMode::Read, 4);
ASSERT_EQ(myData, *reinterpret_cast<const uint32_t*>(mappedData));
UnmapBuffer(buffer);
}
@ -1077,7 +1115,8 @@ TEST_P(BufferMappedAtCreationTests, MapReadUsageLarge) {
wgpu::Buffer buffer = BufferMappedAtCreationWithData(wgpu::BufferUsage::MapRead, myData);
UnmapBuffer(buffer);
const void* mappedData = MapReadAsyncAndWait(buffer);
const void* mappedData =
MapAsyncAndWait(buffer, wgpu::MapMode::Read, kDataSize * sizeof(uint32_t));
ASSERT_EQ(0, memcmp(mappedData, myData.data(), kDataSize * sizeof(uint32_t)));
UnmapBuffer(buffer);
}
@ -1114,7 +1153,6 @@ TEST_P(BufferMappedAtCreationTests, DestroyMappableWhileMappedForCreation) {
// Test that mapping a buffer is valid after mappedAtCreation and Unmap
TEST_P(BufferMappedAtCreationTests, CreateThenMapSuccess) {
static uint32_t myData = 230502;
static uint32_t myData2 = 1337;
wgpu::Buffer buffer = BufferMappedAtCreationWithData(
wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc, {myData});
UnmapBuffer(buffer);
@ -1122,12 +1160,10 @@ TEST_P(BufferMappedAtCreationTests, CreateThenMapSuccess) {
EXPECT_BUFFER_U32_EQ(myData, buffer, 0);
bool done = false;
buffer.MapWriteAsync(
[](WGPUBufferMapAsyncStatus status, void* data, uint64_t, void* userdata) {
buffer.MapAsync(
wgpu::MapMode::Write, 0, 4,
[](WGPUBufferMapAsyncStatus status, void* userdata) {
ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
ASSERT_NE(nullptr, data);
*static_cast<uint32_t*>(data) = myData2;
*static_cast<bool*>(userdata) = true;
},
&done);
@ -1137,7 +1173,6 @@ TEST_P(BufferMappedAtCreationTests, CreateThenMapSuccess) {
}
UnmapBuffer(buffer);
EXPECT_BUFFER_U32_EQ(myData2, buffer, 0);
}
// Test that is is invalid to map a buffer twice when using mappedAtCreation
@ -1148,11 +1183,10 @@ TEST_P(BufferMappedAtCreationTests, CreateThenMapBeforeUnmapFailure) {
ASSERT_DEVICE_ERROR([&]() {
bool done = false;
buffer.MapWriteAsync(
[](WGPUBufferMapAsyncStatus status, void* data, uint64_t, void* userdata) {
buffer.MapAsync(
wgpu::MapMode::Write, 0, 4,
[](WGPUBufferMapAsyncStatus status, void* userdata) {
ASSERT_EQ(WGPUBufferMapAsyncStatus_Error, status);
ASSERT_EQ(nullptr, data);
*static_cast<bool*>(userdata) = true;
},
&done);
@ -1164,7 +1198,6 @@ TEST_P(BufferMappedAtCreationTests, CreateThenMapBeforeUnmapFailure) {
// mappedAtCreation is unaffected by the MapWrite error.
UnmapBuffer(buffer);
EXPECT_BUFFER_U32_EQ(myData, buffer, 0);
}
// Test that creating a zero-sized buffer mapped is allowed.

View File

@ -74,14 +74,9 @@ class DeviceLostTest : public DawnTest {
device.LoseForTesting();
}
template <typename T>
static void MapFailCallback(WGPUBufferMapAsyncStatus status,
T* data,
uint64_t datalength,
void* userdata) {
EXPECT_EQ(WGPUBufferMapAsyncStatus_DeviceLost, status);
EXPECT_EQ(nullptr, data);
EXPECT_EQ(0u, datalength);
EXPECT_EQ(&fakeUserData, userdata);
}
};
@ -251,25 +246,27 @@ TEST_P(DeviceLostTest, CreateBufferFails) {
ASSERT_DEVICE_ERROR(device.CreateBuffer(&bufferDescriptor));
}
// Test that buffer.MapWriteAsync fails after device is lost
TEST_P(DeviceLostTest, BufferMapWriteAsyncFails) {
// Test that buffer.MapAsync for writing fails after device is lost
TEST_P(DeviceLostTest, BufferMapAsyncFailsForWriting) {
wgpu::BufferDescriptor bufferDescriptor;
bufferDescriptor.size = sizeof(float);
bufferDescriptor.size = 4;
bufferDescriptor.usage = wgpu::BufferUsage::MapWrite;
wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
SetCallbackAndLoseForTesting();
ASSERT_DEVICE_ERROR(buffer.MapWriteAsync(MapFailCallback, const_cast<int*>(&fakeUserData)));
ASSERT_DEVICE_ERROR(buffer.MapAsync(wgpu::MapMode::Write, 0, 4, MapFailCallback,
const_cast<int*>(&fakeUserData)));
}
// Test that buffer.MapWriteAsync calls back with device loss status
TEST_P(DeviceLostTest, BufferMapWriteAsyncBeforeLossFails) {
// Test that BufferMapAsync for writing calls back with device lost status when device lost after
// mapping
TEST_P(DeviceLostTest, BufferMapAsyncBeforeLossFailsForWriting) {
wgpu::BufferDescriptor bufferDescriptor;
bufferDescriptor.size = sizeof(float);
bufferDescriptor.size = 4;
bufferDescriptor.usage = wgpu::BufferUsage::MapWrite;
wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
buffer.MapWriteAsync(MapFailCallback, const_cast<int*>(&fakeUserData));
buffer.MapAsync(wgpu::MapMode::Write, 0, 4, MapFailCallback, const_cast<int*>(&fakeUserData));
SetCallbackAndLoseForTesting();
}
@ -278,21 +275,11 @@ TEST_P(DeviceLostTest, BufferUnmapFails) {
wgpu::BufferDescriptor bufferDescriptor;
bufferDescriptor.size = sizeof(float);
bufferDescriptor.usage = wgpu::BufferUsage::MapWrite;
bufferDescriptor.mappedAtCreation = true;
wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
wgpu::CreateBufferMappedResult result = device.CreateBufferMapped(&bufferDescriptor);
SetCallbackAndLoseForTesting();
ASSERT_DEVICE_ERROR(result.buffer.Unmap());
}
// Test that CreateBufferMapped fails after device is lost
TEST_P(DeviceLostTest, CreateBufferMappedFails) {
wgpu::BufferDescriptor bufferDescriptor;
bufferDescriptor.size = sizeof(float);
bufferDescriptor.usage = wgpu::BufferUsage::MapWrite;
SetCallbackAndLoseForTesting();
ASSERT_DEVICE_ERROR(device.CreateBufferMapped(&bufferDescriptor));
ASSERT_DEVICE_ERROR(buffer.Unmap());
}
// Test that mappedAtCreation fails after device is lost
@ -306,27 +293,29 @@ TEST_P(DeviceLostTest, CreateBufferMappedAtCreationFails) {
ASSERT_DEVICE_ERROR(device.CreateBuffer(&bufferDescriptor));
}
// Test that BufferMapReadAsync fails after device is lost
TEST_P(DeviceLostTest, BufferMapReadAsyncFails) {
// Test that BufferMapAsync for reading fails after device is lost
TEST_P(DeviceLostTest, BufferMapAsyncFailsForReading) {
wgpu::BufferDescriptor bufferDescriptor;
bufferDescriptor.size = sizeof(float);
bufferDescriptor.size = 4;
bufferDescriptor.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
SetCallbackAndLoseForTesting();
ASSERT_DEVICE_ERROR(buffer.MapReadAsync(MapFailCallback, const_cast<int*>(&fakeUserData)));
ASSERT_DEVICE_ERROR(buffer.MapAsync(wgpu::MapMode::Read, 0, 4, MapFailCallback,
const_cast<int*>(&fakeUserData)));
}
// Test that BufferMapReadAsync calls back with device lost status when device lost after map read
TEST_P(DeviceLostTest, BufferMapReadAsyncBeforeLossFails) {
// Test that BufferMapAsync for reading calls back with device lost status when device lost after
// mapping
TEST_P(DeviceLostTest, BufferMapAsyncBeforeLossFailsForReading) {
wgpu::BufferDescriptor bufferDescriptor;
bufferDescriptor.size = sizeof(float);
bufferDescriptor.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
buffer.MapReadAsync(MapFailCallback, const_cast<int*>(&fakeUserData));
buffer.MapAsync(wgpu::MapMode::Read, 0, 4, MapFailCallback, const_cast<int*>(&fakeUserData));
SetCallbackAndLoseForTesting();
}
@ -399,14 +388,14 @@ TEST_P(DeviceLostTest, GetMappedRange_CreateBufferMappedAtCreationBeforeLoss) {
ASSERT_EQ(buffer.GetMappedRange(), rangeBeforeLoss);
}
// Test that device loss doesn't change the result of GetMappedRange, mapReadAsync version.
TEST_P(DeviceLostTest, GetMappedRange_MapReadAsync) {
// Test that device loss doesn't change the result of GetMappedRange, mapping for reading version.
TEST_P(DeviceLostTest, GetMappedRange_MapAsyncReading) {
wgpu::BufferDescriptor desc;
desc.size = 4;
desc.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
wgpu::Buffer buffer = device.CreateBuffer(&desc);
buffer.MapReadAsync(nullptr, nullptr);
buffer.MapAsync(wgpu::MapMode::Read, 0, 4, nullptr, nullptr);
queue.Submit(0, nullptr);
const void* rangeBeforeLoss = buffer.GetConstMappedRange();
@ -416,14 +405,14 @@ TEST_P(DeviceLostTest, GetMappedRange_MapReadAsync) {
ASSERT_EQ(buffer.GetConstMappedRange(), rangeBeforeLoss);
}
// Test that device loss doesn't change the result of GetMappedRange, mapReadAsync version.
TEST_P(DeviceLostTest, GetMappedRange_MapWriteAsync) {
// Test that device loss doesn't change the result of GetMappedRange, mapping for writing version.
TEST_P(DeviceLostTest, GetMappedRange_MapAsyncWriting) {
wgpu::BufferDescriptor desc;
desc.size = 4;
desc.usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc;
wgpu::Buffer buffer = device.CreateBuffer(&desc);
buffer.MapWriteAsync(nullptr, nullptr);
buffer.MapAsync(wgpu::MapMode::Write, 0, 4, nullptr, nullptr);
queue.Submit(0, nullptr);
const void* rangeBeforeLoss = buffer.GetConstMappedRange();

View File

@ -23,7 +23,7 @@ namespace {
enum class UploadMethod {
WriteBuffer,
CreateBufferMapped,
MappedAtCreation,
};
// Perf delta exists between ranges [0, 1MB] vs [1MB, MAX_SIZE).
@ -55,8 +55,8 @@ namespace {
case UploadMethod::WriteBuffer:
ostream << "_WriteBuffer";
break;
case UploadMethod::CreateBufferMapped:
ostream << "_CreateBufferMapped";
case UploadMethod::MappedAtCreation:
ostream << "_MappedAtCreation";
break;
}
@ -122,18 +122,19 @@ void BufferUploadPerf::Step() {
break;
}
case UploadMethod::CreateBufferMapped: {
case UploadMethod::MappedAtCreation: {
wgpu::BufferDescriptor desc = {};
desc.size = data.size();
desc.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::MapWrite;
desc.mappedAtCreation = true;
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
for (unsigned int i = 0; i < kNumIterations; ++i) {
auto result = device.CreateBufferMapped(&desc);
memcpy(result.data, data.data(), data.size());
result.buffer.Unmap();
encoder.CopyBufferToBuffer(result.buffer, 0, dst, 0, data.size());
wgpu::Buffer buffer = device.CreateBuffer(&desc);
memcpy(buffer.GetMappedRange(0, data.size()), data.data(), data.size());
buffer.Unmap();
encoder.CopyBufferToBuffer(buffer, 0, dst, 0, data.size());
}
wgpu::CommandBuffer commands = encoder.Finish();
@ -150,7 +151,7 @@ TEST_P(BufferUploadPerf, Run) {
DAWN_INSTANTIATE_PERF_TEST_SUITE_P(BufferUploadPerf,
{D3D12Backend(), MetalBackend(), OpenGLBackend(),
VulkanBackend()},
{UploadMethod::WriteBuffer, UploadMethod::CreateBufferMapped},
{UploadMethod::WriteBuffer, UploadMethod::MappedAtCreation},
{UploadSize::BufferSize_1KB, UploadSize::BufferSize_64KB,
UploadSize::BufferSize_1MB, UploadSize::BufferSize_4MB,
UploadSize::BufferSize_16MB});

View File

@ -1265,29 +1265,15 @@ TEST_F(BufferValidationTest, GetMappedRange_OnDestroyedBuffer) {
}
}
// Test that it is invalid to call GetMappedRange on a buffer after MapReadAsync
TEST_F(BufferValidationTest, GetMappedRange_OnMappedForReading) {
{
wgpu::Buffer buf = CreateMapReadBuffer(4);
buf.MapReadAsync(ToMockBufferMapReadCallback, nullptr);
EXPECT_CALL(*mockBufferMapReadCallback,
Call(WGPUBufferMapAsyncStatus_Success, Ne(nullptr), 4u, _))
.Times(1);
WaitForAllOperations(device);
ASSERT_EQ(nullptr, buf.GetMappedRange());
}
{
// Test that it is invalid to call GetMappedRange on a buffer after MapAsync for reading
TEST_F(BufferValidationTest, GetMappedRange_NonConstOnMappedForReading) {
wgpu::Buffer buf = CreateMapReadBuffer(4);
buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
.Times(1);
EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _)).Times(1);
WaitForAllOperations(device);
ASSERT_EQ(nullptr, buf.GetMappedRange());
}
}
// Test valid cases to call GetMappedRange on a buffer.
@ -1307,38 +1293,25 @@ TEST_F(BufferValidationTest, GetMappedRange_ValidBufferStateCases) {
ASSERT_EQ(buffer.GetConstMappedRange(), buffer.GetMappedRange());
}
// GetMappedRange after MapReadAsync case.
// GetMappedRange after MapAsync for reading case.
{
wgpu::Buffer buf = CreateMapReadBuffer(4);
buf.MapReadAsync(ToMockBufferMapReadCallback, nullptr);
const void* mappedPointer = nullptr;
EXPECT_CALL(*mockBufferMapReadCallback,
Call(WGPUBufferMapAsyncStatus_Success, Ne(nullptr), 4u, _))
.WillOnce(SaveArg<1>(&mappedPointer));
buf.MapAsync(wgpu::MapMode::Read, 0, 4, nullptr, nullptr);
WaitForAllOperations(device);
ASSERT_NE(buf.GetConstMappedRange(), nullptr);
ASSERT_EQ(buf.GetConstMappedRange(), mappedPointer);
}
// GetMappedRange after MapWriteAsync case.
// GetMappedRange after MapAsync for writing case.
{
wgpu::Buffer buf = CreateMapWriteBuffer(4);
buf.MapWriteAsync(ToMockBufferMapWriteCallback, nullptr);
const void* mappedPointer = nullptr;
EXPECT_CALL(*mockBufferMapWriteCallback,
Call(WGPUBufferMapAsyncStatus_Success, Ne(nullptr), 4u, _))
.WillOnce(SaveArg<1>(&mappedPointer));
buf.MapAsync(wgpu::MapMode::Write, 0, 4, nullptr, nullptr);
WaitForAllOperations(device);
ASSERT_NE(buf.GetConstMappedRange(), nullptr);
ASSERT_EQ(buf.GetConstMappedRange(), buf.GetMappedRange());
ASSERT_EQ(buf.GetConstMappedRange(), mappedPointer);
}
}

View File

@ -169,26 +169,14 @@ namespace {
ASSERT_DEVICE_ERROR(queue.WriteBuffer(buffer, 0, &value, sizeof(value)));
}
// MapReadAsync
// MapAsync
{
wgpu::BufferDescriptor descriptor;
descriptor.size = 4;
descriptor.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::MapRead;
wgpu::Buffer buf = device.CreateBuffer(&descriptor);
buf.MapReadAsync(nullptr, nullptr);
uint32_t value = 0;
ASSERT_DEVICE_ERROR(queue.WriteBuffer(buf, 0, &value, sizeof(value)));
}
// MapWriteAsync
{
wgpu::BufferDescriptor descriptor;
descriptor.size = 4;
descriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::MapWrite;
wgpu::Buffer buf = device.CreateBuffer(&descriptor);
buf.MapWriteAsync(nullptr, nullptr);
buf.MapAsync(wgpu::MapMode::Read, 0, 4, nullptr, nullptr);
uint32_t value = 0;
ASSERT_DEVICE_ERROR(queue.WriteBuffer(buf, 0, &value, sizeof(value)));
}

View File

@ -19,57 +19,20 @@ using namespace dawn_wire;
namespace {
// Mock classes to add expectations on the wire calling callbacks
class MockBufferMapReadCallback {
// Mock class to add expectations on the wire calling callbacks
class MockBufferMapCallback {
public:
MOCK_METHOD(void,
Call,
(WGPUBufferMapAsyncStatus status,
const uint32_t* ptr,
uint64_t dataLength,
void* userdata));
};
std::unique_ptr<StrictMock<MockBufferMapReadCallback>> mockBufferMapReadCallback;
void ToMockBufferMapReadCallback(WGPUBufferMapAsyncStatus status,
const void* ptr,
uint64_t dataLength,
void* userdata) {
// Assume the data is uint32_t to make writing matchers easier
mockBufferMapReadCallback->Call(status, static_cast<const uint32_t*>(ptr), dataLength,
userdata);
std::unique_ptr<StrictMock<MockBufferMapCallback>> mockBufferMapCallback;
void ToMockBufferMapCallback(WGPUBufferMapAsyncStatus status, void* userdata) {
mockBufferMapCallback->Call(status, userdata);
}
class MockBufferMapWriteCallback {
public:
MOCK_METHOD(
void,
Call,
(WGPUBufferMapAsyncStatus status, uint32_t* ptr, uint64_t dataLength, void* userdata));
};
std::unique_ptr<StrictMock<MockBufferMapWriteCallback>> mockBufferMapWriteCallback;
uint32_t* lastMapWritePointer = nullptr;
void ToMockBufferMapWriteCallback(WGPUBufferMapAsyncStatus status,
void* ptr,
uint64_t dataLength,
void* userdata) {
// Assume the data is uint32_t to make writing matchers easier
lastMapWritePointer = static_cast<uint32_t*>(ptr);
mockBufferMapWriteCallback->Call(status, lastMapWritePointer, dataLength, userdata);
}
class MockBufferCreateMappedCallback {
public:
MOCK_METHOD(void,
Call,
(WGPUBufferMapAsyncStatus status,
WGPUBuffer buffer,
uint32_t* ptr,
uint64_t dataLength,
void* userdata));
};
} // anonymous namespace
class WireBufferMappingTests : public WireTest {
@ -81,8 +44,7 @@ class WireBufferMappingTests : public WireTest {
void SetUp() override {
WireTest::SetUp();
mockBufferMapReadCallback = std::make_unique<StrictMock<MockBufferMapReadCallback>>();
mockBufferMapWriteCallback = std::make_unique<StrictMock<MockBufferMapWriteCallback>>();
mockBufferMapCallback = std::make_unique<StrictMock<MockBufferMapCallback>>();
WGPUBufferDescriptor descriptor = {};
descriptor.size = kBufferSize;
@ -99,16 +61,14 @@ class WireBufferMappingTests : public WireTest {
void TearDown() override {
WireTest::TearDown();
// Delete mocks so that expectations are checked
mockBufferMapReadCallback = nullptr;
mockBufferMapWriteCallback = nullptr;
// Delete mock so that expectations are checked
mockBufferMapCallback = nullptr;
}
void FlushServer() {
WireTest::FlushServer();
Mock::VerifyAndClearExpectations(&mockBufferMapReadCallback);
Mock::VerifyAndClearExpectations(&mockBufferMapWriteCallback);
Mock::VerifyAndClearExpectations(&mockBufferMapCallback);
}
protected:
@ -118,11 +78,11 @@ class WireBufferMappingTests : public WireTest {
WGPUBuffer apiBuffer;
};
// MapRead-specific tests
// Tests specific to mapping for reading
// Check mapping for reading a succesfully created buffer
TEST_F(WireBufferMappingTests, MappingForReadSuccessBuffer) {
wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Read, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
uint32_t bufferContent = 31337;
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
@ -133,12 +93,13 @@ TEST_F(WireBufferMappingTests, MappingForReadSuccessBuffer) {
FlushClient();
EXPECT_CALL(*mockBufferMapReadCallback,
Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(bufferContent)), kBufferSize, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Success, _)).Times(1);
FlushServer();
EXPECT_EQ(bufferContent,
*static_cast<const uint32_t*>(wgpuBufferGetConstMappedRange(buffer, 0, kBufferSize)));
wgpuBufferUnmap(buffer);
EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);
@ -148,7 +109,7 @@ TEST_F(WireBufferMappingTests, MappingForReadSuccessBuffer) {
// Check that things work correctly when a validation error happens when mapping the buffer for
// reading
TEST_F(WireBufferMappingTests, ErrorWhileMappingForRead) {
wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Read, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Error);
@ -156,16 +117,17 @@ TEST_F(WireBufferMappingTests, ErrorWhileMappingForRead) {
FlushClient();
EXPECT_CALL(*mockBufferMapReadCallback, Call(WGPUBufferMapAsyncStatus_Error, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Error, _)).Times(1);
FlushServer();
EXPECT_EQ(nullptr, wgpuBufferGetConstMappedRange(buffer, 0, kBufferSize));
}
// Check that the map read callback is called with UNKNOWN when the buffer is destroyed before the
// request is finished
TEST_F(WireBufferMappingTests, DestroyBeforeReadRequestEnd) {
wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Read, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
// Return success
uint32_t bufferContent = 0;
@ -176,8 +138,7 @@ TEST_F(WireBufferMappingTests, DestroyBeforeReadRequestEnd) {
.WillOnce(Return(&bufferContent));
// Destroy before the client gets the success, so the callback is called with unknown.
EXPECT_CALL(*mockBufferMapReadCallback, Call(WGPUBufferMapAsyncStatus_Unknown, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Unknown, _)).Times(1);
wgpuBufferRelease(buffer);
EXPECT_CALL(api, BufferRelease(apiBuffer));
@ -188,7 +149,7 @@ TEST_F(WireBufferMappingTests, DestroyBeforeReadRequestEnd) {
// Check the map read callback is called with UNKNOWN when the map request would have worked, but
// Unmap was called
TEST_F(WireBufferMappingTests, UnmapCalledTooEarlyForRead) {
wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Read, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
uint32_t bufferContent = 31337;
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
@ -200,8 +161,7 @@ TEST_F(WireBufferMappingTests, UnmapCalledTooEarlyForRead) {
FlushClient();
// Oh no! We are calling Unmap too early!
EXPECT_CALL(*mockBufferMapReadCallback, Call(WGPUBufferMapAsyncStatus_Unknown, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Unknown, _)).Times(1);
wgpuBufferUnmap(buffer);
// The callback shouldn't get called, even when the request succeeded on the server side
@ -211,7 +171,7 @@ TEST_F(WireBufferMappingTests, UnmapCalledTooEarlyForRead) {
// Check that an error map read callback gets nullptr while a buffer is already mapped
TEST_F(WireBufferMappingTests, MappingForReadingErrorWhileAlreadyMappedGetsNullptr) {
// Successful map
wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Read, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
uint32_t bufferContent = 31337;
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
@ -222,29 +182,28 @@ TEST_F(WireBufferMappingTests, MappingForReadingErrorWhileAlreadyMappedGetsNullp
FlushClient();
EXPECT_CALL(*mockBufferMapReadCallback,
Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(bufferContent)), kBufferSize, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Success, _)).Times(1);
FlushServer();
// Map failure while the buffer is already mapped
wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Read, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Error);
}));
FlushClient();
EXPECT_CALL(*mockBufferMapReadCallback, Call(WGPUBufferMapAsyncStatus_Error, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Error, _)).Times(1);
FlushServer();
EXPECT_EQ(nullptr, wgpuBufferGetConstMappedRange(buffer, 0, kBufferSize));
}
// Test that the MapReadCallback isn't fired twice when unmap() is called inside the callback
TEST_F(WireBufferMappingTests, UnmapInsideMapReadCallback) {
wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Read, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
uint32_t bufferContent = 31337;
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
@ -255,8 +214,7 @@ TEST_F(WireBufferMappingTests, UnmapInsideMapReadCallback) {
FlushClient();
EXPECT_CALL(*mockBufferMapReadCallback,
Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(bufferContent)), kBufferSize, _))
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
.WillOnce(InvokeWithoutArgs([&]() { wgpuBufferUnmap(buffer); }));
FlushServer();
@ -269,7 +227,7 @@ TEST_F(WireBufferMappingTests, UnmapInsideMapReadCallback) {
// Test that the MapReadCallback isn't fired twice the buffer external refcount reaches 0 in the
// callback
TEST_F(WireBufferMappingTests, DestroyInsideMapReadCallback) {
wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Read, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
uint32_t bufferContent = 31337;
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
@ -280,8 +238,7 @@ TEST_F(WireBufferMappingTests, DestroyInsideMapReadCallback) {
FlushClient();
EXPECT_CALL(*mockBufferMapReadCallback,
Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(bufferContent)), kBufferSize, _))
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
.WillOnce(InvokeWithoutArgs([&]() { wgpuBufferRelease(buffer); }));
FlushServer();
@ -291,15 +248,14 @@ TEST_F(WireBufferMappingTests, DestroyInsideMapReadCallback) {
FlushClient();
}
// MapWrite-specific tests
// Tests specific to mapping for writing
// Check mapping for writing a succesfully created buffer
TEST_F(WireBufferMappingTests, MappingForWriteSuccessBuffer) {
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
uint32_t serverBufferContent = 31337;
uint32_t updatedContent = 4242;
uint32_t zero = 0;
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
@ -310,12 +266,14 @@ TEST_F(WireBufferMappingTests, MappingForWriteSuccessBuffer) {
FlushClient();
// The map write callback always gets a buffer full of zeroes.
EXPECT_CALL(*mockBufferMapWriteCallback,
Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(zero)), kBufferSize, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Success, _)).Times(1);
FlushServer();
uint32_t* lastMapWritePointer =
static_cast<uint32_t*>(wgpuBufferGetMappedRange(buffer, 0, kBufferSize));
ASSERT_EQ(0u, *lastMapWritePointer);
// Write something to the mapped pointer
*lastMapWritePointer = updatedContent;
@ -331,7 +289,7 @@ TEST_F(WireBufferMappingTests, MappingForWriteSuccessBuffer) {
// Check that things work correctly when a validation error happens when mapping the buffer for
// writing
TEST_F(WireBufferMappingTests, ErrorWhileMappingForWrite) {
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Error);
@ -339,16 +297,17 @@ TEST_F(WireBufferMappingTests, ErrorWhileMappingForWrite) {
FlushClient();
EXPECT_CALL(*mockBufferMapWriteCallback, Call(WGPUBufferMapAsyncStatus_Error, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Error, _)).Times(1);
FlushServer();
EXPECT_EQ(nullptr, wgpuBufferGetMappedRange(buffer, 0, kBufferSize));
}
// Check that the map write callback is called with UNKNOWN when the buffer is destroyed before the
// request is finished
TEST_F(WireBufferMappingTests, DestroyBeforeWriteRequestEnd) {
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
// Return success
uint32_t bufferContent = 31337;
@ -359,8 +318,7 @@ TEST_F(WireBufferMappingTests, DestroyBeforeWriteRequestEnd) {
.WillOnce(Return(&bufferContent));
// Destroy before the client gets the success, so the callback is called with unknown.
EXPECT_CALL(*mockBufferMapWriteCallback, Call(WGPUBufferMapAsyncStatus_Unknown, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Unknown, _)).Times(1);
wgpuBufferRelease(buffer);
EXPECT_CALL(api, BufferRelease(apiBuffer));
@ -371,7 +329,7 @@ TEST_F(WireBufferMappingTests, DestroyBeforeWriteRequestEnd) {
// Check the map read callback is called with UNKNOWN when the map request would have worked, but
// Unmap was called
TEST_F(WireBufferMappingTests, UnmapCalledTooEarlyForWrite) {
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
uint32_t bufferContent = 31337;
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
@ -383,8 +341,7 @@ TEST_F(WireBufferMappingTests, UnmapCalledTooEarlyForWrite) {
FlushClient();
// Oh no! We are calling Unmap too early!
EXPECT_CALL(*mockBufferMapWriteCallback, Call(WGPUBufferMapAsyncStatus_Unknown, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Unknown, _)).Times(1);
wgpuBufferUnmap(buffer);
// The callback shouldn't get called, even when the request succeeded on the server side
@ -394,10 +351,9 @@ TEST_F(WireBufferMappingTests, UnmapCalledTooEarlyForWrite) {
// Check that an error map read callback gets nullptr while a buffer is already mapped
TEST_F(WireBufferMappingTests, MappingForWritingErrorWhileAlreadyMappedGetsNullptr) {
// Successful map
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
uint32_t bufferContent = 31337;
uint32_t zero = 0;
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
}));
@ -406,32 +362,30 @@ TEST_F(WireBufferMappingTests, MappingForWritingErrorWhileAlreadyMappedGetsNullp
FlushClient();
EXPECT_CALL(*mockBufferMapWriteCallback,
Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(zero)), kBufferSize, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Success, _)).Times(1);
FlushServer();
// Map failure while the buffer is already mapped
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Error);
}));
FlushClient();
EXPECT_CALL(*mockBufferMapWriteCallback, Call(WGPUBufferMapAsyncStatus_Error, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Error, _)).Times(1);
FlushServer();
EXPECT_EQ(nullptr, wgpuBufferGetMappedRange(buffer, 0, kBufferSize));
}
// Test that the MapWriteCallback isn't fired twice when unmap() is called inside the callback
TEST_F(WireBufferMappingTests, UnmapInsideMapWriteCallback) {
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
uint32_t bufferContent = 31337;
uint32_t zero = 0;
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
}));
@ -440,8 +394,7 @@ TEST_F(WireBufferMappingTests, UnmapInsideMapWriteCallback) {
FlushClient();
EXPECT_CALL(*mockBufferMapWriteCallback,
Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(zero)), kBufferSize, _))
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
.WillOnce(InvokeWithoutArgs([&]() { wgpuBufferUnmap(buffer); }));
FlushServer();
@ -454,10 +407,9 @@ TEST_F(WireBufferMappingTests, UnmapInsideMapWriteCallback) {
// Test that the MapWriteCallback isn't fired twice the buffer external refcount reaches 0 in the
// callback
TEST_F(WireBufferMappingTests, DestroyInsideMapWriteCallback) {
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
uint32_t bufferContent = 31337;
uint32_t zero = 0;
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
}));
@ -466,8 +418,7 @@ TEST_F(WireBufferMappingTests, DestroyInsideMapWriteCallback) {
FlushClient();
EXPECT_CALL(*mockBufferMapWriteCallback,
Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(zero)), kBufferSize, _))
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
.WillOnce(InvokeWithoutArgs([&]() { wgpuBufferRelease(buffer); }));
FlushServer();
@ -542,9 +493,8 @@ TEST_F(WireBufferMappingTests, MappedAtCreationThenMapSuccess) {
FlushClient();
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
uint32_t zero = 0;
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
}));
@ -553,9 +503,7 @@ TEST_F(WireBufferMappingTests, MappedAtCreationThenMapSuccess) {
FlushClient();
EXPECT_CALL(*mockBufferMapWriteCallback,
Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(zero)), kBufferSize, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Success, _)).Times(1);
FlushServer();
}
@ -576,7 +524,7 @@ TEST_F(WireBufferMappingTests, MappedAtCreationThenMapFailure) {
FlushClient();
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Error);
@ -584,11 +532,12 @@ TEST_F(WireBufferMappingTests, MappedAtCreationThenMapFailure) {
FlushClient();
EXPECT_CALL(*mockBufferMapWriteCallback, Call(WGPUBufferMapAsyncStatus_Error, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Error, _)).Times(1);
FlushServer();
EXPECT_EQ(nullptr, wgpuBufferGetConstMappedRange(buffer, 0, kBufferSize));
wgpuBufferUnmap(buffer);
EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);

View File

@ -22,55 +22,20 @@ using namespace dawn_wire;
namespace {
// Mock classes to add expectations on the wire calling callbacks
class MockBufferMapReadCallback {
// Mock class to add expectations on the wire calling callbacks
class MockBufferMapCallback {
public:
MOCK_METHOD(void,
Call,
(WGPUBufferMapAsyncStatus status,
const uint32_t* ptr,
uint64_t dataLength,
void* userdata));
};
std::unique_ptr<StrictMock<MockBufferMapReadCallback>> mockBufferMapReadCallback;
void ToMockBufferMapReadCallback(WGPUBufferMapAsyncStatus status,
const void* ptr,
uint64_t dataLength,
void* userdata) {
// Assume the data is uint32_t to make writing matchers easier
mockBufferMapReadCallback->Call(status, static_cast<const uint32_t*>(ptr), dataLength,
userdata);
std::unique_ptr<StrictMock<MockBufferMapCallback>> mockBufferMapCallback;
void ToMockBufferMapCallback(WGPUBufferMapAsyncStatus status, void* userdata) {
mockBufferMapCallback->Call(status, userdata);
}
class MockBufferMapWriteCallback {
public:
MOCK_METHOD(
void,
Call,
(WGPUBufferMapAsyncStatus status, uint32_t* ptr, uint64_t dataLength, void* userdata));
};
std::unique_ptr<StrictMock<MockBufferMapWriteCallback>> mockBufferMapWriteCallback;
void ToMockBufferMapWriteCallback(WGPUBufferMapAsyncStatus status,
void* ptr,
uint64_t dataLength,
void* userdata) {
// Assume the data is uint32_t to make writing matchers easier
mockBufferMapWriteCallback->Call(status, static_cast<uint32_t*>(ptr), dataLength, userdata);
}
class MockBufferCreateMappedCallback {
public:
MOCK_METHOD(void,
Call,
(WGPUBufferMapAsyncStatus status,
WGPUBuffer buffer,
uint32_t* ptr,
uint64_t dataLength,
void* userdata));
};
} // anonymous namespace
// WireMemoryTransferServiceTests test the MemoryTransferService with buffer mapping.
@ -102,8 +67,7 @@ class WireMemoryTransferServiceTests : public WireTest {
void SetUp() override {
WireTest::SetUp();
mockBufferMapReadCallback = std::make_unique<StrictMock<MockBufferMapReadCallback>>();
mockBufferMapWriteCallback = std::make_unique<StrictMock<MockBufferMapWriteCallback>>();
mockBufferMapCallback = std::make_unique<StrictMock<MockBufferMapCallback>>();
// TODO(enga): Make this thread-safe.
mBufferContent++;
@ -117,9 +81,8 @@ class WireMemoryTransferServiceTests : public WireTest {
void TearDown() override {
WireTest::TearDown();
// Delete mocks so that expectations are checked
mockBufferMapReadCallback = nullptr;
mockBufferMapWriteCallback = nullptr;
// Delete mock so that expectations are checked
mockBufferMapCallback = nullptr;
}
void FlushClient(bool success = true) {
@ -130,8 +93,7 @@ class WireMemoryTransferServiceTests : public WireTest {
void FlushServer(bool success = true) {
WireTest::FlushServer(success);
Mock::VerifyAndClearExpectations(&mockBufferMapReadCallback);
Mock::VerifyAndClearExpectations(&mockBufferMapWriteCallback);
Mock::VerifyAndClearExpectations(&mockBufferMapCallback);
Mock::VerifyAndClearExpectations(&clientMemoryTransferService);
}
@ -365,20 +327,20 @@ uint32_t WireMemoryTransferServiceTests::mSerializeCreateInfo = 4242;
uint32_t WireMemoryTransferServiceTests::mSerializeInitialDataInfo = 1394;
uint32_t WireMemoryTransferServiceTests::mSerializeFlushInfo = 1235;
// Test successful MapRead.
// Test successful mapping for reading.
TEST_F(WireMemoryTransferServiceTests, BufferMapReadSuccess) {
WGPUBuffer buffer;
WGPUBuffer apiBuffer;
std::tie(apiBuffer, buffer) = CreateBuffer();
FlushClient();
// The client should create and serialize a ReadHandle on mapReadAsync.
// The client should create and serialize a ReadHandle on mapAsync for reading.
ClientReadHandle* clientHandle = ExpectReadHandleCreation();
ExpectReadHandleSerialization(clientHandle);
wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Read, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
// The server should deserialize the MapRead handle from the client and then serialize
// The server should deserialize the read handle from the client and then serialize
// an initialization message.
ServerReadHandle* serverHandle = ExpectServerReadHandleDeserialize();
ExpectServerReadHandleInitialize(serverHandle);
@ -393,9 +355,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapReadSuccess) {
FlushClient();
// The client receives a successful callback.
EXPECT_CALL(*mockBufferMapReadCallback,
Call(WGPUBufferMapAsyncStatus_Success, &mBufferContent, sizeof(mBufferContent), _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Success, _)).Times(1);
// The client should receive the handle initialization message from the server.
ExpectClientReadHandleDeserializeInitialize(clientHandle, &mBufferContent);
@ -412,18 +372,18 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapReadSuccess) {
FlushClient();
}
// Test unsuccessful MapRead.
// Test unsuccessful mapping for reading.
TEST_F(WireMemoryTransferServiceTests, BufferMapReadError) {
WGPUBuffer buffer;
WGPUBuffer apiBuffer;
std::tie(apiBuffer, buffer) = CreateBuffer();
FlushClient();
// The client should create and serialize a ReadHandle on mapReadAsync.
// The client should create and serialize a ReadHandle on mapAsync.
ClientReadHandle* clientHandle = ExpectReadHandleCreation();
ExpectReadHandleSerialization(clientHandle);
wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Read, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
// The server should deserialize the ReadHandle from the client.
ServerReadHandle* serverHandle = ExpectServerReadHandleDeserialize();
@ -439,8 +399,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapReadError) {
FlushClient();
// The client receives an error callback.
EXPECT_CALL(*mockBufferMapReadCallback, Call(WGPUBufferMapAsyncStatus_Error, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Error, _)).Times(1);
// The client receives the map failure and destroys the handle.
EXPECT_CALL(clientMemoryTransferService, OnReadHandleDestroy(clientHandle)).Times(1);
@ -454,7 +413,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapReadError) {
FlushClient();
}
// Test MapRead ReadHandle creation failure.
// Test ReadHandle creation failure.
TEST_F(WireMemoryTransferServiceTests, BufferMapReadHandleCreationFailure) {
WGPUBuffer buffer;
WGPUBuffer apiBuffer;
@ -466,10 +425,9 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapReadHandleCreationFailure) {
// Failed creation of a ReadHandle is a mapping failure and the client synchronously receives
// an error callback.
EXPECT_CALL(*mockBufferMapReadCallback, Call(WGPUBufferMapAsyncStatus_Error, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Error, _)).Times(1);
wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Read, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
}
// Test MapRead DeserializeReadHandle failure.
@ -479,11 +437,11 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapReadDeserializeReadHandleFailure
std::tie(apiBuffer, buffer) = CreateBuffer();
FlushClient();
// The client should create and serialize a ReadHandle on mapReadAsync.
// The client should create and serialize a ReadHandle on mapping for reading..
ClientReadHandle* clientHandle = ExpectReadHandleCreation();
ExpectReadHandleSerialization(clientHandle);
wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Read, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
// Mock a Deserialization failure.
MockServerReadHandleDeserializeFailure();
@ -492,26 +450,25 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapReadDeserializeReadHandleFailure
// The server received a fatal failure and the client callback was never returned.
// It is called when the wire is destructed.
EXPECT_CALL(*mockBufferMapReadCallback, Call(WGPUBufferMapAsyncStatus_Unknown, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Unknown, _)).Times(1);
EXPECT_CALL(clientMemoryTransferService, OnReadHandleDestroy(clientHandle)).Times(1);
}
// Test MapRead DeserializeInitialData failure.
// Test read handle DeserializeInitialData failure.
TEST_F(WireMemoryTransferServiceTests, BufferMapReadDeserializeInitialDataFailure) {
WGPUBuffer buffer;
WGPUBuffer apiBuffer;
std::tie(apiBuffer, buffer) = CreateBuffer();
FlushClient();
// The client should create and serialize a ReadHandle on mapReadAsync.
// The client should create and serialize a ReadHandle on mapping for reading.
ClientReadHandle* clientHandle = ExpectReadHandleCreation();
ExpectReadHandleSerialization(clientHandle);
wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Read, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
// The server should deserialize the MapRead handle from the client and then serialize
// The server should deserialize the read handle from the client and then serialize
// an initialization message.
ServerReadHandle* serverHandle = ExpectServerReadHandleDeserialize();
ExpectServerReadHandleInitialize(serverHandle);
@ -531,9 +488,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapReadDeserializeInitialDataFailur
// Failed deserialization is a fatal failure and the client synchronously receives a
// DEVICE_LOST callback.
EXPECT_CALL(*mockBufferMapReadCallback,
Call(WGPUBufferMapAsyncStatus_DeviceLost, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_DeviceLost, _)).Times(1);
// The handle will be destroyed since deserializing failed.
EXPECT_CALL(clientMemoryTransferService, OnReadHandleDestroy(clientHandle)).Times(1);
@ -543,20 +498,20 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapReadDeserializeInitialDataFailur
EXPECT_CALL(serverMemoryTransferService, OnReadHandleDestroy(serverHandle)).Times(1);
}
// Test MapRead destroying the buffer before unmapping on the client side.
// Test mapping for reading destroying the buffer before unmapping on the client side.
TEST_F(WireMemoryTransferServiceTests, BufferMapReadDestroyBeforeUnmap) {
WGPUBuffer buffer;
WGPUBuffer apiBuffer;
std::tie(apiBuffer, buffer) = CreateBuffer();
FlushClient();
// The client should create and serialize a ReadHandle on mapReadAsync.
// The client should create and serialize a ReadHandle on mapping for reading.
ClientReadHandle* clientHandle = ExpectReadHandleCreation();
ExpectReadHandleSerialization(clientHandle);
wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Read, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
// The server should deserialize the MapRead handle from the client and then serialize
// The server should deserialize the read handle from the client and then serialize
// an initialization message.
ServerReadHandle* serverHandle = ExpectServerReadHandleDeserialize();
ExpectServerReadHandleInitialize(serverHandle);
@ -571,9 +526,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapReadDestroyBeforeUnmap) {
FlushClient();
// The client receives a successful callback.
EXPECT_CALL(*mockBufferMapReadCallback,
Call(WGPUBufferMapAsyncStatus_Success, &mBufferContent, sizeof(mBufferContent), _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Success, _)).Times(1);
// The client should receive the handle initialization message from the server.
ExpectClientReadHandleDeserializeInitialize(clientHandle, &mBufferContent);
@ -598,7 +551,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapReadDestroyBeforeUnmap) {
}
}
// Test successful MapWrite.
// Test successful mapping for writing.
TEST_F(WireMemoryTransferServiceTests, BufferMapWriteSuccess) {
WGPUBuffer buffer;
WGPUBuffer apiBuffer;
@ -608,7 +561,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteSuccess) {
ClientWriteHandle* clientHandle = ExpectWriteHandleCreation();
ExpectWriteHandleSerialization(clientHandle);
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
// The server should then deserialize the WriteHandle from the client.
ServerWriteHandle* serverHandle = ExpectServerWriteHandleDeserialization();
@ -623,10 +576,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteSuccess) {
FlushClient();
// The client receives a successful callback.
EXPECT_CALL(*mockBufferMapWriteCallback,
Call(WGPUBufferMapAsyncStatus_Success, &mMappedBufferContent,
sizeof(mMappedBufferContent), _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Success, _)).Times(1);
// Since the mapping succeeds, the client opens the WriteHandle.
ExpectClientWriteHandleOpen(clientHandle, &mMappedBufferContent);
@ -659,11 +609,11 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteError) {
std::tie(apiBuffer, buffer) = CreateBuffer();
FlushClient();
// The client should create and serialize a WriteHandle on mapWriteAsync.
// The client should create and serialize a WriteHandle on mapping for writing.
ClientWriteHandle* clientHandle = ExpectWriteHandleCreation();
ExpectWriteHandleSerialization(clientHandle);
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
// The server should then deserialize the WriteHandle from the client.
ServerWriteHandle* serverHandle = ExpectServerWriteHandleDeserialization();
@ -679,8 +629,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteError) {
FlushClient();
// The client receives an error callback.
EXPECT_CALL(*mockBufferMapWriteCallback, Call(WGPUBufferMapAsyncStatus_Error, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Error, _)).Times(1);
// Client receives the map failure and destroys the handle.
EXPECT_CALL(clientMemoryTransferService, OnWriteHandleDestroy(clientHandle)).Times(1);
@ -694,7 +643,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteError) {
FlushClient();
}
// Test MapRead WriteHandle creation failure.
// Test WriteHandle creation failure.
TEST_F(WireMemoryTransferServiceTests, BufferMapWriteHandleCreationFailure) {
WGPUBuffer buffer;
WGPUBuffer apiBuffer;
@ -706,10 +655,9 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteHandleCreationFailure) {
// Failed creation of a WriteHandle is a mapping failure and the client synchronously receives
// an error callback.
EXPECT_CALL(*mockBufferMapWriteCallback, Call(WGPUBufferMapAsyncStatus_Error, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Error, _)).Times(1);
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
}
// Test MapWrite DeserializeWriteHandle failure.
@ -719,11 +667,11 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteDeserializeWriteHandleFailu
std::tie(apiBuffer, buffer) = CreateBuffer();
FlushClient();
// The client should create and serialize a WriteHandle on mapWriteAsync.
// The client should create and serialize a WriteHandle on mapping for writing.
ClientWriteHandle* clientHandle = ExpectWriteHandleCreation();
ExpectWriteHandleSerialization(clientHandle);
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
// Mock a deserialization failure.
MockServerWriteHandleDeserializeFailure();
@ -732,8 +680,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteDeserializeWriteHandleFailu
// The server hit a fatal failure and never returned the callback. The client callback is
// called when the wire is destructed.
EXPECT_CALL(*mockBufferMapWriteCallback, Call(WGPUBufferMapAsyncStatus_Unknown, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Unknown, _)).Times(1);
EXPECT_CALL(clientMemoryTransferService, OnWriteHandleDestroy(clientHandle)).Times(1);
}
@ -748,7 +695,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteHandleOpenFailure) {
ClientWriteHandle* clientHandle = ExpectWriteHandleCreation();
ExpectWriteHandleSerialization(clientHandle);
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
// The server should then deserialize the WriteHandle from the client.
ServerWriteHandle* serverHandle = ExpectServerWriteHandleDeserialization();
@ -767,9 +714,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteHandleOpenFailure) {
MockClientWriteHandleOpenFailure(clientHandle);
// Failing to open a handle is a fatal failure and the client receives a DEVICE_LOST callback.
EXPECT_CALL(*mockBufferMapWriteCallback,
Call(WGPUBufferMapAsyncStatus_DeviceLost, nullptr, 0, _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_DeviceLost, _)).Times(1);
// Since opening the handle fails, it gets destroyed immediately.
EXPECT_CALL(clientMemoryTransferService, OnWriteHandleDestroy(clientHandle)).Times(1);
@ -789,7 +734,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteDeserializeFlushFailure) {
ClientWriteHandle* clientHandle = ExpectWriteHandleCreation();
ExpectWriteHandleSerialization(clientHandle);
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
// The server should then deserialize the WriteHandle from the client.
ServerWriteHandle* serverHandle = ExpectServerWriteHandleDeserialization();
@ -804,10 +749,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteDeserializeFlushFailure) {
FlushClient();
// The client receives a success callback.
EXPECT_CALL(*mockBufferMapWriteCallback,
Call(WGPUBufferMapAsyncStatus_Success, &mMappedBufferContent,
sizeof(mMappedBufferContent), _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Success, _)).Times(1);
// Since the mapping succeeds, the client opens the WriteHandle.
ExpectClientWriteHandleOpen(clientHandle, &mMappedBufferContent);
@ -841,7 +783,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteDestroyBeforeUnmap) {
ClientWriteHandle* clientHandle = ExpectWriteHandleCreation();
ExpectWriteHandleSerialization(clientHandle);
wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr);
wgpuBufferMapAsync(buffer, WGPUMapMode_Write, 0, kBufferSize, ToMockBufferMapCallback, nullptr);
// The server should then deserialize the WriteHandle from the client.
ServerWriteHandle* serverHandle = ExpectServerWriteHandleDeserialization();
@ -856,10 +798,7 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteDestroyBeforeUnmap) {
FlushClient();
// The client receives a successful callback.
EXPECT_CALL(*mockBufferMapWriteCallback,
Call(WGPUBufferMapAsyncStatus_Success, &mMappedBufferContent,
sizeof(mMappedBufferContent), _))
.Times(1);
EXPECT_CALL(*mockBufferMapCallback, Call(WGPUBufferMapAsyncStatus_Success, _)).Times(1);
// Since the mapping succeeds, the client opens the WriteHandle.
ExpectClientWriteHandleOpen(clientHandle, &mMappedBufferContent);