mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-17 17:05:31 +00:00
Implement CreateBufferMappedAsync in dawn_wire and dawn_native
Bug: dawn:7 Change-Id: I1a4e5eece53d83a4c5395ba6b41df2e20668c5bb Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/8120 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
d1b4b5cba5
commit
21eba761b5
@@ -226,6 +226,7 @@ DAWN_INSTANTIATE_TEST(BufferSetSubDataTests,
|
||||
OpenGLBackend,
|
||||
VulkanBackend);
|
||||
|
||||
// TODO(enga): These tests should use the testing toggle to initialize resources to 1.
|
||||
class CreateBufferMappedTests : public DawnTest {
|
||||
protected:
|
||||
static void MapReadCallback(DawnBufferMapAsyncStatus status,
|
||||
@@ -248,37 +249,97 @@ class CreateBufferMappedTests : public DawnTest {
|
||||
return mappedData;
|
||||
}
|
||||
|
||||
void CheckResultStartsZeroed(const dawn::CreateBufferMappedResult& result, uint64_t size) {
|
||||
ASSERT_EQ(result.dataLength, size);
|
||||
for (uint64_t i = 0; i < result.dataLength; ++i) {
|
||||
uint8_t value = *(reinterpret_cast<uint8_t*>(result.data) + i);
|
||||
ASSERT_EQ(value, 0u);
|
||||
}
|
||||
}
|
||||
|
||||
dawn::CreateBufferMappedResult CreateBufferMapped(dawn::BufferUsageBit usage, uint64_t size) {
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = size;
|
||||
descriptor.usage = usage;
|
||||
|
||||
dawn::CreateBufferMappedResult result = device.CreateBufferMapped(&descriptor);
|
||||
CheckResultStartsZeroed(result, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
dawn::CreateBufferMappedResult CreateBufferMappedWithData(dawn::BufferUsageBit usage,
|
||||
const std::vector<uint32_t>& data) {
|
||||
size_t byteLength = data.size() * sizeof(uint32_t);
|
||||
dawn::CreateBufferMappedResult result = CreateBufferMapped(usage, byteLength);
|
||||
memcpy(result.data, data.data(), byteLength);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <DawnBufferMapAsyncStatus expectedStatus = DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS>
|
||||
dawn::CreateBufferMappedResult CreateBufferMappedAsyncAndWait(dawn::BufferUsageBit usage,
|
||||
uint64_t size) {
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = size;
|
||||
descriptor.usage = usage;
|
||||
|
||||
struct ResultInfo {
|
||||
dawn::CreateBufferMappedResult result;
|
||||
bool done = false;
|
||||
} resultInfo;
|
||||
|
||||
device.CreateBufferMappedAsync(
|
||||
&descriptor,
|
||||
[](DawnBufferMapAsyncStatus status, DawnCreateBufferMappedResult result,
|
||||
void* userdata) {
|
||||
ASSERT_EQ(status, expectedStatus);
|
||||
auto* resultInfo = reinterpret_cast<ResultInfo*>(userdata);
|
||||
resultInfo->result.buffer = dawn::Buffer::Acquire(result.buffer);
|
||||
resultInfo->result.data = result.data;
|
||||
resultInfo->result.dataLength = result.dataLength;
|
||||
resultInfo->done = true;
|
||||
},
|
||||
&resultInfo);
|
||||
|
||||
while (!resultInfo.done) {
|
||||
WaitABit();
|
||||
}
|
||||
|
||||
CheckResultStartsZeroed(resultInfo.result, size);
|
||||
|
||||
return resultInfo.result;
|
||||
}
|
||||
|
||||
dawn::CreateBufferMappedResult CreateBufferMappedAsyncWithDataAndWait(
|
||||
dawn::BufferUsageBit usage,
|
||||
const std::vector<uint32_t>& data) {
|
||||
size_t byteLength = data.size() * sizeof(uint32_t);
|
||||
dawn::CreateBufferMappedResult result = CreateBufferMappedAsyncAndWait(usage, byteLength);
|
||||
memcpy(result.data, data.data(), byteLength);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
const void* mappedData = nullptr;
|
||||
};
|
||||
|
||||
// Test that the simplest CreateBufferMapped works for MapWrite buffers.
|
||||
TEST_P(CreateBufferMappedTests, MapWriteUsageSmall) {
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = 4;
|
||||
descriptor.usage = dawn::BufferUsageBit::MapWrite | dawn::BufferUsageBit::TransferSrc;
|
||||
|
||||
uint32_t myData = 230502;
|
||||
dawn::CreateBufferMappedResult result = device.CreateBufferMapped(&descriptor);
|
||||
ASSERT_EQ(result.dataLength, descriptor.size);
|
||||
memcpy(result.data, &myData, sizeof(myData));
|
||||
dawn::CreateBufferMappedResult result = CreateBufferMappedWithData(
|
||||
dawn::BufferUsageBit::MapWrite | dawn::BufferUsageBit::TransferSrc, {myData});
|
||||
result.buffer.Unmap();
|
||||
|
||||
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
|
||||
}
|
||||
|
||||
// Test that the simplest CreateBufferMapped works for MapRead buffers.
|
||||
TEST_P(CreateBufferMappedTests, MapReadUsageSmall) {
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = 4;
|
||||
descriptor.usage = dawn::BufferUsageBit::MapRead;
|
||||
|
||||
uint32_t myData = 230502;
|
||||
dawn::CreateBufferMappedResult result = device.CreateBufferMapped(&descriptor);
|
||||
ASSERT_EQ(result.dataLength, descriptor.size);
|
||||
memcpy(result.data, &myData, sizeof(myData));
|
||||
dawn::CreateBufferMappedResult result =
|
||||
CreateBufferMappedWithData(dawn::BufferUsageBit::MapRead, {myData});
|
||||
result.buffer.Unmap();
|
||||
|
||||
const void* mappedData = MapReadAsyncAndWait(result.buffer);
|
||||
@@ -288,15 +349,9 @@ TEST_P(CreateBufferMappedTests, MapReadUsageSmall) {
|
||||
|
||||
// Test that the simplest CreateBufferMapped works for non-mappable buffers.
|
||||
TEST_P(CreateBufferMappedTests, NonMappableUsageSmall) {
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = 4;
|
||||
descriptor.usage = dawn::BufferUsageBit::TransferSrc;
|
||||
|
||||
uint32_t myData = 4239;
|
||||
dawn::CreateBufferMappedResult result = device.CreateBufferMapped(&descriptor);
|
||||
ASSERT_EQ(result.dataLength, descriptor.size);
|
||||
memcpy(result.data, &myData, sizeof(myData));
|
||||
dawn::CreateBufferMappedResult result =
|
||||
CreateBufferMappedWithData(dawn::BufferUsageBit::TransferSrc, {myData});
|
||||
result.buffer.Unmap();
|
||||
|
||||
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
|
||||
@@ -310,14 +365,8 @@ TEST_P(CreateBufferMappedTests, MapWriteUsageLarge) {
|
||||
myData.push_back(i);
|
||||
}
|
||||
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = static_cast<uint64_t>(kDataSize * sizeof(uint32_t));
|
||||
descriptor.usage = dawn::BufferUsageBit::MapWrite | dawn::BufferUsageBit::TransferSrc;
|
||||
|
||||
dawn::CreateBufferMappedResult result = device.CreateBufferMapped(&descriptor);
|
||||
ASSERT_EQ(result.dataLength, descriptor.size);
|
||||
memcpy(result.data, myData.data(), kDataSize * sizeof(uint32_t));
|
||||
dawn::CreateBufferMappedResult result = CreateBufferMappedWithData(
|
||||
dawn::BufferUsageBit::MapWrite | dawn::BufferUsageBit::TransferSrc, {myData});
|
||||
result.buffer.Unmap();
|
||||
|
||||
EXPECT_BUFFER_U32_RANGE_EQ(myData.data(), result.buffer, 0, kDataSize);
|
||||
@@ -331,14 +380,8 @@ TEST_P(CreateBufferMappedTests, MapReadUsageLarge) {
|
||||
myData.push_back(i);
|
||||
}
|
||||
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = static_cast<uint64_t>(kDataSize * sizeof(uint32_t));
|
||||
descriptor.usage = dawn::BufferUsageBit::MapRead;
|
||||
|
||||
dawn::CreateBufferMappedResult result = device.CreateBufferMapped(&descriptor);
|
||||
ASSERT_EQ(result.dataLength, descriptor.size);
|
||||
memcpy(result.data, myData.data(), kDataSize * sizeof(uint32_t));
|
||||
dawn::CreateBufferMappedResult result =
|
||||
CreateBufferMappedWithData(dawn::BufferUsageBit::MapRead, myData);
|
||||
result.buffer.Unmap();
|
||||
|
||||
const void* mappedData = MapReadAsyncAndWait(result.buffer);
|
||||
@@ -354,59 +397,19 @@ TEST_P(CreateBufferMappedTests, NonMappableUsageLarge) {
|
||||
myData.push_back(i);
|
||||
}
|
||||
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = static_cast<uint64_t>(kDataSize * sizeof(uint32_t));
|
||||
descriptor.usage = dawn::BufferUsageBit::TransferSrc;
|
||||
|
||||
dawn::CreateBufferMappedResult result = device.CreateBufferMapped(&descriptor);
|
||||
ASSERT_EQ(result.dataLength, descriptor.size);
|
||||
memcpy(result.data, myData.data(), kDataSize * sizeof(uint32_t));
|
||||
dawn::CreateBufferMappedResult result =
|
||||
CreateBufferMappedWithData(dawn::BufferUsageBit::TransferSrc, {myData});
|
||||
result.buffer.Unmap();
|
||||
|
||||
EXPECT_BUFFER_U32_RANGE_EQ(myData.data(), result.buffer, 0, kDataSize);
|
||||
}
|
||||
|
||||
// Test that CreateBufferMapped returns zero-initialized data
|
||||
// TODO(enga): This should use the testing toggle to initialize resources to 1.
|
||||
TEST_P(CreateBufferMappedTests, MappableZeroInitialized) {
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = 4;
|
||||
descriptor.usage = dawn::BufferUsageBit::MapWrite | dawn::BufferUsageBit::TransferSrc;
|
||||
|
||||
dawn::CreateBufferMappedResult result = device.CreateBufferMapped(&descriptor);
|
||||
ASSERT_EQ(result.dataLength, descriptor.size);
|
||||
ASSERT_EQ(*reinterpret_cast<uint8_t*>(result.data), 0);
|
||||
result.buffer.Unmap();
|
||||
}
|
||||
|
||||
// Test that CreateBufferMapped returns zero-initialized data
|
||||
// TODO(enga): This should use the testing toggle to initialize resources to 1.
|
||||
TEST_P(CreateBufferMappedTests, NonMappableZeroInitialized) {
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = 4;
|
||||
descriptor.usage = dawn::BufferUsageBit::TransferSrc;
|
||||
|
||||
dawn::CreateBufferMappedResult result = device.CreateBufferMapped(&descriptor);
|
||||
ASSERT_EQ(result.dataLength, descriptor.size);
|
||||
ASSERT_EQ(*reinterpret_cast<uint8_t*>(result.data), 0);
|
||||
result.buffer.Unmap();
|
||||
}
|
||||
|
||||
// Test that mapping a buffer is valid after CreateBufferMapped and Unmap
|
||||
TEST_P(CreateBufferMappedTests, CreateThenMapSuccess) {
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = 4;
|
||||
descriptor.usage = dawn::BufferUsageBit::MapWrite | dawn::BufferUsageBit::TransferSrc;
|
||||
|
||||
static uint32_t myData = 230502;
|
||||
static uint32_t myData2 = 1337;
|
||||
dawn::CreateBufferMappedResult result = device.CreateBufferMapped(&descriptor);
|
||||
ASSERT_EQ(result.dataLength, descriptor.size);
|
||||
memcpy(result.data, &myData, sizeof(myData));
|
||||
dawn::CreateBufferMappedResult result = CreateBufferMappedWithData(
|
||||
dawn::BufferUsageBit::MapWrite | dawn::BufferUsageBit::TransferSrc, {myData});
|
||||
result.buffer.Unmap();
|
||||
|
||||
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
|
||||
@@ -432,15 +435,9 @@ TEST_P(CreateBufferMappedTests, CreateThenMapSuccess) {
|
||||
|
||||
// Test that is is invalid to map a buffer twice when using CreateBufferMapped
|
||||
TEST_P(CreateBufferMappedTests, CreateThenMapBeforeUnmapFailure) {
|
||||
dawn::BufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.size = 4;
|
||||
descriptor.usage = dawn::BufferUsageBit::MapWrite | dawn::BufferUsageBit::TransferSrc;
|
||||
|
||||
uint32_t myData = 230502;
|
||||
dawn::CreateBufferMappedResult result = device.CreateBufferMapped(&descriptor);
|
||||
ASSERT_EQ(result.dataLength, descriptor.size);
|
||||
memcpy(result.data, &myData, sizeof(myData));
|
||||
dawn::CreateBufferMappedResult result = CreateBufferMappedWithData(
|
||||
dawn::BufferUsageBit::MapWrite | dawn::BufferUsageBit::TransferSrc, {myData});
|
||||
|
||||
ASSERT_DEVICE_ERROR([&]() {
|
||||
bool done = false;
|
||||
@@ -463,6 +460,140 @@ TEST_P(CreateBufferMappedTests, CreateThenMapBeforeUnmapFailure) {
|
||||
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
|
||||
}
|
||||
|
||||
// Test that the simplest CreateBufferMappedAsync works for MapWrite buffers.
|
||||
TEST_P(CreateBufferMappedTests, MapWriteUsageSmallAsync) {
|
||||
uint32_t myData = 230502;
|
||||
dawn::CreateBufferMappedResult result = CreateBufferMappedAsyncWithDataAndWait(
|
||||
dawn::BufferUsageBit::MapWrite | dawn::BufferUsageBit::TransferSrc, {myData});
|
||||
result.buffer.Unmap();
|
||||
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
|
||||
}
|
||||
|
||||
// Test that the simplest CreateBufferMappedAsync works for MapRead buffers.
|
||||
TEST_P(CreateBufferMappedTests, MapReadUsageSmallAsync) {
|
||||
uint32_t myData = 230502;
|
||||
dawn::CreateBufferMappedResult result =
|
||||
CreateBufferMappedAsyncWithDataAndWait(dawn::BufferUsageBit::MapRead, {myData});
|
||||
result.buffer.Unmap();
|
||||
|
||||
const void* mappedData = MapReadAsyncAndWait(result.buffer);
|
||||
ASSERT_EQ(myData, *reinterpret_cast<const uint32_t*>(mappedData));
|
||||
result.buffer.Unmap();
|
||||
}
|
||||
|
||||
// Test that the simplest CreateBufferMappedAsync works for non-mappable buffers.
|
||||
TEST_P(CreateBufferMappedTests, NonMappableUsageSmallAsync) {
|
||||
uint32_t myData = 4239;
|
||||
dawn::CreateBufferMappedResult result =
|
||||
CreateBufferMappedAsyncWithDataAndWait(dawn::BufferUsageBit::TransferSrc, {myData});
|
||||
result.buffer.Unmap();
|
||||
|
||||
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
|
||||
}
|
||||
|
||||
// Test CreateBufferMappedAsync for a large MapWrite buffer
|
||||
TEST_P(CreateBufferMappedTests, MapWriteUsageLargeAsync) {
|
||||
constexpr uint64_t kDataSize = 1000 * 1000;
|
||||
std::vector<uint32_t> myData;
|
||||
for (uint32_t i = 0; i < kDataSize; ++i) {
|
||||
myData.push_back(i);
|
||||
}
|
||||
|
||||
dawn::CreateBufferMappedResult result = CreateBufferMappedAsyncWithDataAndWait(
|
||||
dawn::BufferUsageBit::MapWrite | dawn::BufferUsageBit::TransferSrc, {myData});
|
||||
result.buffer.Unmap();
|
||||
|
||||
EXPECT_BUFFER_U32_RANGE_EQ(myData.data(), result.buffer, 0, kDataSize);
|
||||
}
|
||||
|
||||
// Test CreateBufferMappedAsync for a large MapRead buffer
|
||||
TEST_P(CreateBufferMappedTests, MapReadUsageLargeAsync) {
|
||||
constexpr uint64_t kDataSize = 1000 * 1000;
|
||||
std::vector<uint32_t> myData;
|
||||
for (uint32_t i = 0; i < kDataSize; ++i) {
|
||||
myData.push_back(i);
|
||||
}
|
||||
|
||||
dawn::CreateBufferMappedResult result =
|
||||
CreateBufferMappedAsyncWithDataAndWait(dawn::BufferUsageBit::MapRead, {myData});
|
||||
result.buffer.Unmap();
|
||||
|
||||
const void* mappedData = MapReadAsyncAndWait(result.buffer);
|
||||
ASSERT_EQ(0, memcmp(mappedData, myData.data(), kDataSize * sizeof(uint32_t)));
|
||||
result.buffer.Unmap();
|
||||
}
|
||||
|
||||
// Test CreateBufferMappedAsync for a large non-mappable buffer
|
||||
TEST_P(CreateBufferMappedTests, NonMappableUsageLargeAsync) {
|
||||
constexpr uint64_t kDataSize = 1000 * 1000;
|
||||
std::vector<uint32_t> myData;
|
||||
for (uint32_t i = 0; i < kDataSize; ++i) {
|
||||
myData.push_back(i);
|
||||
}
|
||||
|
||||
dawn::CreateBufferMappedResult result =
|
||||
CreateBufferMappedAsyncWithDataAndWait(dawn::BufferUsageBit::TransferSrc, {myData});
|
||||
result.buffer.Unmap();
|
||||
|
||||
EXPECT_BUFFER_U32_RANGE_EQ(myData.data(), result.buffer, 0, kDataSize);
|
||||
}
|
||||
|
||||
// Test that mapping a buffer is valid after CreateBufferMappedAsync and Unmap
|
||||
TEST_P(CreateBufferMappedTests, CreateThenMapSuccessAsync) {
|
||||
static uint32_t myData = 230502;
|
||||
static uint32_t myData2 = 1337;
|
||||
dawn::CreateBufferMappedResult result = CreateBufferMappedAsyncWithDataAndWait(
|
||||
dawn::BufferUsageBit::MapWrite | dawn::BufferUsageBit::TransferSrc, {myData});
|
||||
result.buffer.Unmap();
|
||||
|
||||
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
|
||||
|
||||
bool done = false;
|
||||
result.buffer.MapWriteAsync(
|
||||
[](DawnBufferMapAsyncStatus status, void* data, uint64_t, void* userdata) {
|
||||
ASSERT_EQ(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, status);
|
||||
ASSERT_NE(nullptr, data);
|
||||
|
||||
*static_cast<uint32_t*>(data) = myData2;
|
||||
*static_cast<bool*>(userdata) = true;
|
||||
},
|
||||
&done);
|
||||
|
||||
while (!done) {
|
||||
WaitABit();
|
||||
}
|
||||
|
||||
result.buffer.Unmap();
|
||||
EXPECT_BUFFER_U32_EQ(myData2, result.buffer, 0);
|
||||
}
|
||||
|
||||
// Test that is is invalid to map a buffer twice when using CreateBufferMappedAsync
|
||||
TEST_P(CreateBufferMappedTests, CreateThenMapBeforeUnmapFailureAsync) {
|
||||
uint32_t myData = 230502;
|
||||
dawn::CreateBufferMappedResult result = CreateBufferMappedAsyncWithDataAndWait(
|
||||
dawn::BufferUsageBit::MapWrite | dawn::BufferUsageBit::TransferSrc, {myData});
|
||||
|
||||
ASSERT_DEVICE_ERROR([&]() {
|
||||
bool done = false;
|
||||
result.buffer.MapWriteAsync(
|
||||
[](DawnBufferMapAsyncStatus status, void* data, uint64_t, void* userdata) {
|
||||
ASSERT_EQ(DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, status);
|
||||
ASSERT_EQ(nullptr, data);
|
||||
|
||||
*static_cast<bool*>(userdata) = true;
|
||||
},
|
||||
&done);
|
||||
|
||||
while (!done) {
|
||||
WaitABit();
|
||||
}
|
||||
}());
|
||||
|
||||
// CreateBufferMappedAsync is unaffected by the MapWrite error.
|
||||
result.buffer.Unmap();
|
||||
EXPECT_BUFFER_U32_EQ(myData, result.buffer, 0);
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(CreateBufferMappedTests,
|
||||
D3D12Backend,
|
||||
MetalBackend,
|
||||
|
||||
@@ -59,6 +59,28 @@ namespace {
|
||||
mockBufferMapWriteCallback->Call(status, lastMapWritePointer, dataLength, userdata);
|
||||
}
|
||||
|
||||
class MockBufferCreateMappedCallback {
|
||||
public:
|
||||
MOCK_METHOD5(Call,
|
||||
void(DawnBufferMapAsyncStatus status,
|
||||
DawnBuffer buffer,
|
||||
uint32_t* ptr,
|
||||
uint64_t dataLength,
|
||||
void* userdata));
|
||||
};
|
||||
|
||||
std::unique_ptr<StrictMock<MockBufferCreateMappedCallback>> mockCreateBufferMappedCallback;
|
||||
uint32_t* lastCreateMappedPointer = nullptr;
|
||||
void ToMockCreateBufferMappedCallback(DawnBufferMapAsyncStatus status,
|
||||
DawnCreateBufferMappedResult result,
|
||||
void* userdata) {
|
||||
// Assume the data is uint32_t to make writing matchers easier
|
||||
lastCreateMappedPointer = static_cast<uint32_t*>(result.data);
|
||||
// Unpack DawnCreateBufferMappedResult to make writing matchers easier
|
||||
mockCreateBufferMappedCallback->Call(status, result.buffer, lastCreateMappedPointer,
|
||||
result.dataLength, userdata);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
class WireBufferMappingTests : public WireTest {
|
||||
@@ -72,6 +94,8 @@ class WireBufferMappingTests : public WireTest {
|
||||
|
||||
mockBufferMapReadCallback = std::make_unique<StrictMock<MockBufferMapReadCallback>>();
|
||||
mockBufferMapWriteCallback = std::make_unique<StrictMock<MockBufferMapWriteCallback>>();
|
||||
mockCreateBufferMappedCallback =
|
||||
std::make_unique<StrictMock<MockBufferCreateMappedCallback>>();
|
||||
|
||||
DawnBufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
@@ -91,6 +115,7 @@ class WireBufferMappingTests : public WireTest {
|
||||
// Delete mocks so that expectations are checked
|
||||
mockBufferMapReadCallback = nullptr;
|
||||
mockBufferMapWriteCallback = nullptr;
|
||||
mockCreateBufferMappedCallback = nullptr;
|
||||
}
|
||||
|
||||
void FlushServer() {
|
||||
@@ -98,6 +123,7 @@ class WireBufferMappingTests : public WireTest {
|
||||
|
||||
Mock::VerifyAndClearExpectations(&mockBufferMapReadCallback);
|
||||
Mock::VerifyAndClearExpectations(&mockBufferMapWriteCallback);
|
||||
Mock::VerifyAndClearExpectations(&mockCreateBufferMappedCallback);
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -612,3 +638,184 @@ TEST_F(WireBufferMappingTests, CreateBufferMappedThenMapFailure) {
|
||||
|
||||
FlushClient();
|
||||
}
|
||||
|
||||
// Test successful CreateBufferMappedAsync
|
||||
TEST_F(WireBufferMappingTests, CreateBufferMappedAsyncSuccess) {
|
||||
DawnBufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
|
||||
DawnCreateBufferMappedResult apiResult;
|
||||
uint32_t serverBufferContent = 31337;
|
||||
apiResult.buffer = apiBuffer;
|
||||
apiResult.data = reinterpret_cast<uint8_t*>(&serverBufferContent);
|
||||
apiResult.dataLength = 4;
|
||||
|
||||
uint32_t updatedContent = 4242;
|
||||
uint32_t zero = 0;
|
||||
|
||||
dawnDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback, nullptr);
|
||||
|
||||
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
|
||||
.WillOnce(Return(apiResult))
|
||||
.RetiresOnSaturation();
|
||||
|
||||
FlushClient();
|
||||
|
||||
DawnBuffer buffer;
|
||||
// The callback always gets a buffer full of zeroes.
|
||||
EXPECT_CALL(*mockCreateBufferMappedCallback, Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, _,
|
||||
Pointee(Eq(zero)), sizeof(uint32_t), _))
|
||||
.WillOnce(::testing::SaveArg<1>(&buffer));
|
||||
|
||||
FlushServer();
|
||||
|
||||
// Write something to the mapped pointer
|
||||
*lastCreateMappedPointer = updatedContent;
|
||||
|
||||
dawnBufferUnmap(buffer);
|
||||
EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);
|
||||
|
||||
FlushClient();
|
||||
|
||||
// After the buffer is unmapped, the content of the buffer is updated on the server
|
||||
ASSERT_EQ(serverBufferContent, updatedContent);
|
||||
}
|
||||
|
||||
// Test CreateBufferMappedAsync with map error
|
||||
TEST_F(WireBufferMappingTests, CreateBufferMappedAsyncMapError) {
|
||||
DawnBufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
|
||||
DawnCreateBufferMappedResult apiResult;
|
||||
apiResult.buffer = apiBuffer;
|
||||
apiResult.data = nullptr; // error mapping
|
||||
apiResult.dataLength = 4;
|
||||
|
||||
dawnDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback, nullptr);
|
||||
|
||||
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
|
||||
.WillOnce(Return(apiResult))
|
||||
.RetiresOnSaturation();
|
||||
|
||||
FlushClient();
|
||||
|
||||
DawnBuffer buffer;
|
||||
EXPECT_CALL(*mockCreateBufferMappedCallback,
|
||||
Call(DAWN_BUFFER_MAP_ASYNC_STATUS_ERROR, _, nullptr, 0, _))
|
||||
.WillOnce(::testing::SaveArg<1>(&buffer));
|
||||
|
||||
FlushServer();
|
||||
|
||||
dawnBufferUnmap(buffer);
|
||||
EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);
|
||||
|
||||
FlushClient();
|
||||
}
|
||||
|
||||
// Test that the CreateBufferMappedCallback isn't fired twice when unmap() is called inside the
|
||||
// callback
|
||||
TEST_F(WireBufferMappingTests, UnmapInsideCreateBufferMappedAsyncCallback) {
|
||||
DawnBufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
|
||||
DawnCreateBufferMappedResult apiResult;
|
||||
uint32_t serverBufferContent = 31337;
|
||||
apiResult.buffer = apiBuffer;
|
||||
apiResult.data = reinterpret_cast<uint8_t*>(&serverBufferContent);
|
||||
apiResult.dataLength = 4;
|
||||
|
||||
uint32_t zero = 0;
|
||||
|
||||
dawnDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback, nullptr);
|
||||
|
||||
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
|
||||
.WillOnce(Return(apiResult))
|
||||
.RetiresOnSaturation();
|
||||
|
||||
FlushClient();
|
||||
|
||||
DawnBuffer buffer;
|
||||
// The callback always gets a buffer full of zeroes.
|
||||
EXPECT_CALL(*mockCreateBufferMappedCallback, Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, _,
|
||||
Pointee(Eq(zero)), sizeof(uint32_t), _))
|
||||
.WillOnce(DoAll(::testing::SaveArg<1>(&buffer),
|
||||
InvokeWithoutArgs([&]() { dawnBufferUnmap(buffer); })));
|
||||
|
||||
FlushServer();
|
||||
|
||||
EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1);
|
||||
|
||||
FlushClient();
|
||||
}
|
||||
|
||||
// Test that the CreateBufferMappedCallback isn't fired twice when the buffer is deleted inside
|
||||
// the callback
|
||||
TEST_F(WireBufferMappingTests, ReleaseInsideCreateBufferMappedAsyncCallback) {
|
||||
DawnBufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
|
||||
DawnCreateBufferMappedResult apiResult;
|
||||
uint32_t serverBufferContent = 31337;
|
||||
apiResult.buffer = apiBuffer;
|
||||
apiResult.data = reinterpret_cast<uint8_t*>(&serverBufferContent);
|
||||
apiResult.dataLength = 4;
|
||||
|
||||
uint32_t zero = 0;
|
||||
|
||||
dawnDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback, nullptr);
|
||||
|
||||
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
|
||||
.WillOnce(Return(apiResult))
|
||||
.RetiresOnSaturation();
|
||||
|
||||
FlushClient();
|
||||
|
||||
DawnBuffer buffer;
|
||||
// The callback always gets a buffer full of zeroes.
|
||||
EXPECT_CALL(*mockCreateBufferMappedCallback, Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, _,
|
||||
Pointee(Eq(zero)), sizeof(uint32_t), _))
|
||||
.WillOnce(DoAll(::testing::SaveArg<1>(&buffer),
|
||||
InvokeWithoutArgs([&]() { dawnBufferRelease(buffer); })));
|
||||
|
||||
FlushServer();
|
||||
|
||||
EXPECT_CALL(api, BufferRelease(apiBuffer));
|
||||
|
||||
FlushClient();
|
||||
}
|
||||
|
||||
// Test that the CreateBufferMappedCallback isn't fired twice when the buffer is destroyed inside
|
||||
// the callback
|
||||
TEST_F(WireBufferMappingTests, DestroyInsideCreateBufferMappedAsyncCallback) {
|
||||
DawnBufferDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
|
||||
DawnCreateBufferMappedResult apiResult;
|
||||
uint32_t serverBufferContent = 31337;
|
||||
apiResult.buffer = apiBuffer;
|
||||
apiResult.data = reinterpret_cast<uint8_t*>(&serverBufferContent);
|
||||
apiResult.dataLength = 4;
|
||||
|
||||
uint32_t zero = 0;
|
||||
|
||||
dawnDeviceCreateBufferMappedAsync(device, &descriptor, ToMockCreateBufferMappedCallback, nullptr);
|
||||
|
||||
EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _))
|
||||
.WillOnce(Return(apiResult))
|
||||
.RetiresOnSaturation();
|
||||
|
||||
FlushClient();
|
||||
|
||||
DawnBuffer buffer;
|
||||
// The callback always gets a buffer full of zeroes.
|
||||
EXPECT_CALL(*mockCreateBufferMappedCallback, Call(DAWN_BUFFER_MAP_ASYNC_STATUS_SUCCESS, _,
|
||||
Pointee(Eq(zero)), sizeof(uint32_t), _))
|
||||
.WillOnce(DoAll(::testing::SaveArg<1>(&buffer),
|
||||
InvokeWithoutArgs([&]() { dawnBufferDestroy(buffer); })));
|
||||
|
||||
FlushServer();
|
||||
|
||||
EXPECT_CALL(api, BufferDestroy(apiBuffer));
|
||||
|
||||
FlushClient();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user