Add offset and size to Get[Const]MappedRange.
Bug: dawn:445 Change-Id: I73758d95e61d1fbe69f328907a6170a1b27d785b Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/24983 Commit-Queue: Kai Ninomiya <kainino@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
4b7ca6bf96
commit
f6e7044697
12
dawn.json
12
dawn.json
|
@ -209,11 +209,19 @@
|
|||
},
|
||||
{
|
||||
"name": "get mapped range",
|
||||
"returns": "void *"
|
||||
"returns": "void *",
|
||||
"args": [
|
||||
{"name": "offset", "type": "size_t", "default": 0},
|
||||
{"name": "size", "type": "size_t", "default": 0}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "get const mapped range",
|
||||
"returns": "void const *"
|
||||
"returns": "void const *",
|
||||
"args": [
|
||||
{"name": "offset", "type": "size_t", "default": 0},
|
||||
{"name": "size", "type": "size_t", "default": 0}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "unmap"
|
||||
|
|
|
@ -140,6 +140,8 @@ namespace dawn_native {
|
|||
: ObjectBase(device, tag), mSize(descriptor->size), mState(BufferState::Unmapped) {
|
||||
if (descriptor->mappedAtCreation) {
|
||||
mState = BufferState::MappedAtCreation;
|
||||
mMapOffset = 0;
|
||||
mMapSize = mSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,6 +171,8 @@ namespace dawn_native {
|
|||
MaybeError BufferBase::MapAtCreation() {
|
||||
ASSERT(!IsError());
|
||||
mState = BufferState::MappedAtCreation;
|
||||
mMapOffset = 0;
|
||||
mMapSize = mSize;
|
||||
|
||||
// 0-sized buffers are not supposed to be written to, Return back any non-null pointer.
|
||||
// Handle 0-sized buffers first so we don't try to map them in the backend.
|
||||
|
@ -294,6 +298,7 @@ namespace dawn_native {
|
|||
mMapReadCallback = callback;
|
||||
mMapUserdata = userdata;
|
||||
mMapOffset = 0;
|
||||
mMapSize = mSize;
|
||||
mState = BufferState::Mapped;
|
||||
|
||||
if (GetDevice()->ConsumedError(MapReadAsyncImpl())) {
|
||||
|
@ -323,6 +328,7 @@ namespace dawn_native {
|
|||
mMapWriteCallback = callback;
|
||||
mMapUserdata = userdata;
|
||||
mMapOffset = 0;
|
||||
mMapSize = mSize;
|
||||
mState = BufferState::Mapped;
|
||||
|
||||
if (GetDevice()->ConsumedError(MapWriteAsyncImpl())) {
|
||||
|
@ -359,6 +365,7 @@ namespace dawn_native {
|
|||
mMapSerial++;
|
||||
mMapMode = mode;
|
||||
mMapOffset = offset;
|
||||
mMapSize = size;
|
||||
mMapCallback = callback;
|
||||
mMapUserdata = userdata;
|
||||
mState = BufferState::Mapped;
|
||||
|
@ -372,28 +379,28 @@ namespace dawn_native {
|
|||
tracker->Track(this, mMapSerial, MapType::Async);
|
||||
}
|
||||
|
||||
void* BufferBase::GetMappedRange() {
|
||||
return GetMappedRangeInternal(true);
|
||||
void* BufferBase::GetMappedRange(size_t offset, size_t size) {
|
||||
return GetMappedRangeInternal(true, offset, size);
|
||||
}
|
||||
|
||||
const void* BufferBase::GetConstMappedRange() {
|
||||
return GetMappedRangeInternal(false);
|
||||
const void* BufferBase::GetConstMappedRange(size_t offset, size_t size) {
|
||||
return GetMappedRangeInternal(false, offset, size);
|
||||
}
|
||||
|
||||
// TODO(dawn:445): When CreateBufferMapped is removed, make GetMappedRangeInternal also take
|
||||
// care of the validation of GetMappedRange.
|
||||
void* BufferBase::GetMappedRangeInternal(bool writable) {
|
||||
if (!CanGetMappedRange(writable)) {
|
||||
void* BufferBase::GetMappedRangeInternal(bool writable, size_t offset, size_t size) {
|
||||
if (!CanGetMappedRange(writable, offset, size)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mStagingBuffer != nullptr) {
|
||||
return static_cast<uint8_t*>(mStagingBuffer->GetMappedPointer()) + mMapOffset;
|
||||
return static_cast<uint8_t*>(mStagingBuffer->GetMappedPointer()) + offset;
|
||||
}
|
||||
if (mSize == 0) {
|
||||
return reinterpret_cast<uint8_t*>(intptr_t(0xCAFED00D));
|
||||
}
|
||||
return static_cast<uint8_t*>(GetMappedPointerImpl()) + mMapOffset;
|
||||
return static_cast<uint8_t*>(GetMappedPointerImpl()) + offset;
|
||||
}
|
||||
|
||||
void BufferBase::Destroy() {
|
||||
|
@ -554,7 +561,16 @@ namespace dawn_native {
|
|||
return {};
|
||||
}
|
||||
|
||||
bool BufferBase::CanGetMappedRange(bool writable) const {
|
||||
bool BufferBase::CanGetMappedRange(bool writable, size_t offset, size_t size) const {
|
||||
if (size > mMapSize || offset < mMapOffset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t offsetInMappedRange = offset - mMapOffset;
|
||||
if (offsetInMappedRange > mMapSize - size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note that:
|
||||
//
|
||||
// - We don't check that the device is alive because the application can ask for the
|
||||
|
@ -622,11 +638,11 @@ namespace dawn_native {
|
|||
switch (type) {
|
||||
case MapType::Read:
|
||||
CallMapReadCallback(mapSerial, WGPUBufferMapAsyncStatus_Success,
|
||||
GetMappedRangeInternal(false), GetSize());
|
||||
GetMappedRangeInternal(false, 0, mSize), GetSize());
|
||||
break;
|
||||
case MapType::Write:
|
||||
CallMapWriteCallback(mapSerial, WGPUBufferMapAsyncStatus_Success,
|
||||
GetMappedRangeInternal(true), GetSize());
|
||||
GetMappedRangeInternal(true, 0, mSize), GetSize());
|
||||
break;
|
||||
case MapType::Async:
|
||||
CallMapCallback(mapSerial, WGPUBufferMapAsyncStatus_Success);
|
||||
|
|
|
@ -67,8 +67,8 @@ namespace dawn_native {
|
|||
size_t size,
|
||||
WGPUBufferMapCallback callback,
|
||||
void* userdata);
|
||||
void* GetMappedRange();
|
||||
const void* GetConstMappedRange();
|
||||
void* GetMappedRange(size_t offset, size_t size);
|
||||
const void* GetConstMappedRange(size_t offset, size_t size);
|
||||
void Unmap();
|
||||
void Destroy();
|
||||
|
||||
|
@ -93,7 +93,7 @@ namespace dawn_native {
|
|||
|
||||
virtual bool IsMappableAtCreation() const = 0;
|
||||
MaybeError CopyFromStagingBuffer();
|
||||
void* GetMappedRangeInternal(bool writable);
|
||||
void* GetMappedRangeInternal(bool writable, size_t offset, size_t size);
|
||||
void CallMapReadCallback(uint32_t serial,
|
||||
WGPUBufferMapAsyncStatus status,
|
||||
const void* pointer,
|
||||
|
@ -112,7 +112,7 @@ namespace dawn_native {
|
|||
WGPUBufferMapAsyncStatus* status) const;
|
||||
MaybeError ValidateUnmap() const;
|
||||
MaybeError ValidateDestroy() const;
|
||||
bool CanGetMappedRange(bool writable) const;
|
||||
bool CanGetMappedRange(bool writable, size_t offset, size_t size) const;
|
||||
|
||||
uint64_t mSize = 0;
|
||||
wgpu::BufferUsage mUsage = wgpu::BufferUsage::None;
|
||||
|
@ -128,6 +128,7 @@ namespace dawn_native {
|
|||
uint32_t mMapSerial = 0;
|
||||
wgpu::MapMode mMapMode = wgpu::MapMode::None;
|
||||
size_t mMapOffset = 0;
|
||||
size_t mMapSize = 0;
|
||||
};
|
||||
|
||||
} // namespace dawn_native
|
||||
|
|
|
@ -624,7 +624,7 @@ namespace dawn_native {
|
|||
|
||||
WGPUCreateBufferMappedResult result = {};
|
||||
result.buffer = reinterpret_cast<WGPUBuffer>(buffer);
|
||||
result.data = buffer->GetMappedRange();
|
||||
result.data = buffer->GetMappedRange(0, descriptor->size);
|
||||
result.dataLength = descriptor->size;
|
||||
|
||||
if (result.data != nullptr) {
|
||||
|
|
|
@ -315,7 +315,7 @@ namespace dawn_native { namespace opengl {
|
|||
Ref<Buffer> srcBuffer = AcquireRef(ToBackend(device->CreateBuffer(&descriptor)));
|
||||
|
||||
// Fill the buffer with clear color
|
||||
memset(srcBuffer->GetMappedRange(), clearColor, descriptor.size);
|
||||
memset(srcBuffer->GetMappedRange(0, descriptor.size), clearColor, descriptor.size);
|
||||
srcBuffer->Unmap();
|
||||
|
||||
// Bind buffer and texture, and make the buffer to texture copy
|
||||
|
|
|
@ -273,6 +273,7 @@ namespace dawn_wire { namespace client {
|
|||
WGPUBufferMapCallback callback;
|
||||
void* userdata;
|
||||
size_t mapOffset;
|
||||
size_t mapSize;
|
||||
Buffer* self;
|
||||
};
|
||||
ProxyData* proxy = new ProxyData;
|
||||
|
@ -292,6 +293,7 @@ namespace dawn_wire { namespace client {
|
|||
proxy->callback(status, proxy->userdata);
|
||||
}
|
||||
proxy->self->mMapOffset = proxy->mapOffset;
|
||||
proxy->self->mMapSize = proxy->mapSize;
|
||||
delete proxy;
|
||||
},
|
||||
proxy);
|
||||
|
@ -304,6 +306,7 @@ namespace dawn_wire { namespace client {
|
|||
proxy->callback(status, proxy->userdata);
|
||||
}
|
||||
proxy->self->mMapOffset = proxy->mapOffset;
|
||||
proxy->self->mMapSize = proxy->mapSize;
|
||||
delete proxy;
|
||||
},
|
||||
proxy);
|
||||
|
@ -396,18 +399,19 @@ namespace dawn_wire { namespace client {
|
|||
return true;
|
||||
}
|
||||
|
||||
void* Buffer::GetMappedRange() {
|
||||
if (!IsMappedForWriting()) {
|
||||
void* Buffer::GetMappedRange(size_t offset, size_t size) {
|
||||
if (!IsMappedForWriting() || !CheckGetMappedRangeOffsetSize(offset, size)) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<uint8_t*>(mMappedData) + mMapOffset;
|
||||
return static_cast<uint8_t*>(mMappedData) + offset;
|
||||
}
|
||||
|
||||
const void* Buffer::GetConstMappedRange() {
|
||||
if (!IsMappedForWriting() && !IsMappedForReading()) {
|
||||
const void* Buffer::GetConstMappedRange(size_t offset, size_t size) {
|
||||
if (!(IsMappedForWriting() || IsMappedForReading()) ||
|
||||
!CheckGetMappedRangeOffsetSize(offset, size)) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<uint8_t*>(mMappedData) + mMapOffset;
|
||||
return static_cast<uint8_t*>(mMappedData) + offset;
|
||||
}
|
||||
|
||||
void Buffer::Unmap() {
|
||||
|
@ -446,6 +450,7 @@ namespace dawn_wire { namespace client {
|
|||
|
||||
mMappedData = nullptr;
|
||||
mMapOffset = 0;
|
||||
mMapSize = mSize;
|
||||
ClearMapRequests(WGPUBufferMapAsyncStatus_Unknown);
|
||||
|
||||
BufferUnmapCmd cmd;
|
||||
|
@ -483,4 +488,12 @@ namespace dawn_wire { namespace client {
|
|||
return mWriteHandle != nullptr;
|
||||
}
|
||||
|
||||
bool Buffer::CheckGetMappedRangeOffsetSize(size_t offset, size_t size) const {
|
||||
if (size > mMapSize || offset < mMapOffset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t offsetInMappedRange = offset - mMapOffset;
|
||||
return offsetInMappedRange <= mMapSize - size;
|
||||
}
|
||||
}} // namespace dawn_wire::client
|
||||
|
|
|
@ -47,18 +47,19 @@ namespace dawn_wire { namespace client {
|
|||
size_t size,
|
||||
WGPUBufferMapCallback callback,
|
||||
void* userdata);
|
||||
void* GetMappedRange();
|
||||
const void* GetConstMappedRange();
|
||||
void* GetMappedRange(size_t offset, size_t size);
|
||||
const void* GetConstMappedRange(size_t offset, size_t size);
|
||||
void Unmap();
|
||||
|
||||
void Destroy();
|
||||
|
||||
void SetSubData(uint64_t start, uint64_t count, const void* data);
|
||||
|
||||
private:
|
||||
bool IsMappedForReading() const;
|
||||
bool IsMappedForWriting() const;
|
||||
bool CheckGetMappedRangeOffsetSize(size_t offset, size_t size) const;
|
||||
|
||||
private:
|
||||
// We want to defer all the validation to the server, which means we could have multiple
|
||||
// map request in flight at a single time and need to track them separately.
|
||||
// On well-behaved applications, only one request should exist at a single time.
|
||||
|
@ -82,6 +83,7 @@ namespace dawn_wire { namespace client {
|
|||
std::unique_ptr<MemoryTransferService::WriteHandle> mWriteHandle = nullptr;
|
||||
void* mMappedData = nullptr;
|
||||
size_t mMapOffset = 0;
|
||||
size_t mMapSize = 0;
|
||||
};
|
||||
|
||||
}} // namespace dawn_wire::client
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace dawn_wire { namespace server {
|
|||
ObjectHandle buffer;
|
||||
WGPUBuffer bufferObj;
|
||||
uint32_t requestSerial;
|
||||
uint64_t offset;
|
||||
uint64_t size;
|
||||
WGPUMapModeFlags mode;
|
||||
// TODO(enga): Use a tagged pointer to save space.
|
||||
|
|
|
@ -82,6 +82,7 @@ namespace dawn_wire { namespace server {
|
|||
userdata->buffer = ObjectHandle{bufferId, buffer->generation};
|
||||
userdata->bufferObj = buffer->handle;
|
||||
userdata->requestSerial = requestSerial;
|
||||
userdata->offset = offset;
|
||||
userdata->size = size;
|
||||
userdata->mode = mode;
|
||||
|
||||
|
@ -248,7 +249,7 @@ namespace dawn_wire { namespace server {
|
|||
const void* readData = nullptr;
|
||||
if (isSuccess && isRead) {
|
||||
// Get the serialization size of the message to initialize ReadHandle data.
|
||||
readData = mProcs.bufferGetConstMappedRange(data->bufferObj);
|
||||
readData = mProcs.bufferGetConstMappedRange(data->bufferObj, data->offset, data->size);
|
||||
cmd.readInitialDataInfoLength =
|
||||
data->readHandle->SerializeInitialDataSize(readData, data->size);
|
||||
}
|
||||
|
@ -268,8 +269,9 @@ namespace dawn_wire { namespace server {
|
|||
bufferData->writeHandle = std::move(data->writeHandle);
|
||||
bufferData->mapWriteState = BufferMapWriteState::Mapped;
|
||||
// Set the target of the WriteHandle to the mapped buffer data.
|
||||
bufferData->writeHandle->SetTarget(mProcs.bufferGetMappedRange(data->bufferObj),
|
||||
data->size);
|
||||
bufferData->writeHandle->SetTarget(
|
||||
mProcs.bufferGetMappedRange(data->bufferObj, data->offset, data->size),
|
||||
data->size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -382,7 +382,7 @@ TEST_P(BufferMappingTests, MapRead_NonZeroOffset) {
|
|||
queue.WriteBuffer(buffer, 0, &myData, sizeof(myData));
|
||||
|
||||
MapAsyncAndWait(buffer, wgpu::MapMode::Read, 4, 4);
|
||||
ASSERT_EQ(myData[1], *static_cast<const uint32_t*>(buffer.GetConstMappedRange()));
|
||||
ASSERT_EQ(myData[1], *static_cast<const uint32_t*>(buffer.GetConstMappedRange(4)));
|
||||
buffer.Unmap();
|
||||
}
|
||||
|
||||
|
@ -451,7 +451,7 @@ TEST_P(BufferMappingTests, MapWrite_NonZeroOffset) {
|
|||
|
||||
uint32_t myData = 2934875;
|
||||
MapAsyncAndWait(buffer, wgpu::MapMode::Write, 4, 4);
|
||||
memcpy(buffer.GetMappedRange(), &myData, sizeof(myData));
|
||||
memcpy(buffer.GetMappedRange(4), &myData, sizeof(myData));
|
||||
buffer.Unmap();
|
||||
|
||||
EXPECT_BUFFER_U32_EQ(myData, buffer, 4);
|
||||
|
@ -518,7 +518,7 @@ TEST_P(BufferMappingTests, OffsetNotUpdatedOnError) {
|
|||
}
|
||||
|
||||
// mMapOffset has not been updated so it should still be 4, which is data[1]
|
||||
ASSERT_EQ(0, memcmp(buffer.GetConstMappedRange(), &data[1], sizeof(uint32_t)));
|
||||
ASSERT_EQ(0, memcmp(buffer.GetConstMappedRange(4), &data[1], sizeof(uint32_t)));
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(BufferMappingTests,
|
||||
|
|
|
@ -252,6 +252,46 @@ TEST_F(BufferValidationTest, MapAsync_OffsetSizeAlignment) {
|
|||
}
|
||||
}
|
||||
|
||||
// Test map async with an invalid offset and size OOB checks
|
||||
TEST_F(BufferValidationTest, MapAsync_OffsetSizeOOB) {
|
||||
// Valid case: full buffer is ok.
|
||||
{
|
||||
wgpu::Buffer buffer = CreateMapReadBuffer(8);
|
||||
buffer.MapAsync(wgpu::MapMode::Read, 0, 8, nullptr, nullptr);
|
||||
}
|
||||
|
||||
// Valid case: range in the middle of the buffer is ok.
|
||||
{
|
||||
wgpu::Buffer buffer = CreateMapReadBuffer(12);
|
||||
buffer.MapAsync(wgpu::MapMode::Read, 4, 4, nullptr, nullptr);
|
||||
}
|
||||
|
||||
// Valid case: empty range at the end of the buffer is ok.
|
||||
{
|
||||
wgpu::Buffer buffer = CreateMapReadBuffer(8);
|
||||
buffer.MapAsync(wgpu::MapMode::Read, 8, 0, nullptr, nullptr);
|
||||
}
|
||||
|
||||
// Error case, offset is larger than the buffer size (even if size is 0).
|
||||
{
|
||||
wgpu::Buffer buffer = CreateMapReadBuffer(8);
|
||||
AssertMapAsyncError(buffer, wgpu::MapMode::Read, 12, 0);
|
||||
}
|
||||
|
||||
// Error case, offset + size is larger than the buffer
|
||||
{
|
||||
wgpu::Buffer buffer = CreateMapReadBuffer(12);
|
||||
AssertMapAsyncError(buffer, wgpu::MapMode::Read, 8, 8);
|
||||
}
|
||||
|
||||
// Error case, offset + size is larger than the buffer, overflow case.
|
||||
{
|
||||
wgpu::Buffer buffer = CreateMapReadBuffer(12);
|
||||
AssertMapAsyncError(buffer, wgpu::MapMode::Read, 4,
|
||||
std::numeric_limits<size_t>::max() & ~size_t(3));
|
||||
}
|
||||
}
|
||||
|
||||
// Test map async with a buffer that has the wrong usage
|
||||
TEST_F(BufferValidationTest, MapAsync_WrongUsage) {
|
||||
{
|
||||
|
@ -1051,7 +1091,7 @@ TEST_F(BufferValidationTest, UnmapUnmappedBuffer) {
|
|||
}
|
||||
|
||||
// Test that it is invalid to call GetMappedRange on an unmapped buffer.
|
||||
TEST_F(BufferValidationTest, GetMappedRangeOnUnmappedBuffer) {
|
||||
TEST_F(BufferValidationTest, GetMappedRange_OnUnmappedBuffer) {
|
||||
// Unmapped at creation case.
|
||||
{
|
||||
wgpu::BufferDescriptor desc;
|
||||
|
@ -1138,7 +1178,7 @@ TEST_F(BufferValidationTest, GetMappedRangeOnUnmappedBuffer) {
|
|||
}
|
||||
|
||||
// Test that it is invalid to call GetMappedRange on a destroyed buffer.
|
||||
TEST_F(BufferValidationTest, GetMappedRangeOnDestroyedBuffer) {
|
||||
TEST_F(BufferValidationTest, GetMappedRange_OnDestroyedBuffer) {
|
||||
// Destroyed after creation case.
|
||||
{
|
||||
wgpu::BufferDescriptor desc;
|
||||
|
@ -1225,8 +1265,8 @@ TEST_F(BufferValidationTest, GetMappedRangeOnDestroyedBuffer) {
|
|||
}
|
||||
}
|
||||
|
||||
// Test that it is invalid to call GetMappedRange on a buffer afterMapReadAsync
|
||||
TEST_F(BufferValidationTest, GetMappedRangeOnMappedForReading) {
|
||||
// Test that it is invalid to call GetMappedRange on a buffer after MapReadAsync
|
||||
TEST_F(BufferValidationTest, GetMappedRange_OnMappedForReading) {
|
||||
{
|
||||
wgpu::Buffer buf = CreateMapReadBuffer(4);
|
||||
|
||||
|
@ -1251,7 +1291,7 @@ TEST_F(BufferValidationTest, GetMappedRangeOnMappedForReading) {
|
|||
}
|
||||
|
||||
// Test valid cases to call GetMappedRange on a buffer.
|
||||
TEST_F(BufferValidationTest, GetMappedRangeValidCases) {
|
||||
TEST_F(BufferValidationTest, GetMappedRange_ValidBufferStateCases) {
|
||||
// GetMappedRange after CreateBufferMapped case.
|
||||
{
|
||||
wgpu::CreateBufferMappedResult result = CreateBufferMapped(4, wgpu::BufferUsage::CopySrc);
|
||||
|
@ -1303,7 +1343,7 @@ TEST_F(BufferValidationTest, GetMappedRangeValidCases) {
|
|||
}
|
||||
|
||||
// Test valid cases to call GetMappedRange on an error buffer.
|
||||
TEST_F(BufferValidationTest, GetMappedRangeOnErrorBuffer) {
|
||||
TEST_F(BufferValidationTest, GetMappedRange_OnErrorBuffer) {
|
||||
wgpu::BufferDescriptor desc;
|
||||
desc.size = 4;
|
||||
desc.usage = wgpu::BufferUsage::Storage | wgpu::BufferUsage::MapRead;
|
||||
|
@ -1377,3 +1417,62 @@ TEST_F(BufferValidationTest, GetMappedRangeOnErrorBuffer) {
|
|||
ASSERT_EQ(buffer.GetConstMappedRange(), buffer.GetMappedRange());
|
||||
}
|
||||
}
|
||||
|
||||
// Test validation of the GetMappedRange parameters
|
||||
TEST_F(BufferValidationTest, GetMappedRange_OffsetSizeOOB) {
|
||||
// Valid case: full range is ok
|
||||
{
|
||||
wgpu::Buffer buffer = CreateMapWriteBuffer(8);
|
||||
buffer.MapAsync(wgpu::MapMode::Write, 0, 8, nullptr, nullptr);
|
||||
EXPECT_NE(buffer.GetMappedRange(0, 8), nullptr);
|
||||
}
|
||||
|
||||
// Valid case: full range is ok with defaulted MapAsync size
|
||||
{
|
||||
wgpu::Buffer buffer = CreateMapWriteBuffer(8);
|
||||
buffer.MapAsync(wgpu::MapMode::Write, 0, 0, nullptr, nullptr);
|
||||
EXPECT_NE(buffer.GetMappedRange(0, 8), nullptr);
|
||||
}
|
||||
|
||||
// Valid case: empty range at the end is ok
|
||||
{
|
||||
wgpu::Buffer buffer = CreateMapWriteBuffer(8);
|
||||
buffer.MapAsync(wgpu::MapMode::Write, 0, 8, nullptr, nullptr);
|
||||
EXPECT_NE(buffer.GetMappedRange(8, 0), nullptr);
|
||||
}
|
||||
|
||||
// Valid case: range in the middle is ok.
|
||||
{
|
||||
wgpu::Buffer buffer = CreateMapWriteBuffer(12);
|
||||
buffer.MapAsync(wgpu::MapMode::Write, 0, 12, nullptr, nullptr);
|
||||
EXPECT_NE(buffer.GetMappedRange(4, 4), nullptr);
|
||||
}
|
||||
|
||||
// Error case: offset is larger than the mapped range (even with size = 0)
|
||||
{
|
||||
wgpu::Buffer buffer = CreateMapWriteBuffer(8);
|
||||
buffer.MapAsync(wgpu::MapMode::Write, 0, 8, nullptr, nullptr);
|
||||
EXPECT_EQ(buffer.GetMappedRange(9, 0), nullptr);
|
||||
}
|
||||
|
||||
// Error case: offset + size is larger than the mapped range
|
||||
{
|
||||
wgpu::Buffer buffer = CreateMapWriteBuffer(12);
|
||||
buffer.MapAsync(wgpu::MapMode::Write, 0, 12, nullptr, nullptr);
|
||||
EXPECT_EQ(buffer.GetMappedRange(8, 5), nullptr);
|
||||
}
|
||||
|
||||
// Error case: offset + size is larger than the mapped range, overflow case
|
||||
{
|
||||
wgpu::Buffer buffer = CreateMapWriteBuffer(12);
|
||||
buffer.MapAsync(wgpu::MapMode::Write, 0, 12, nullptr, nullptr);
|
||||
EXPECT_EQ(buffer.GetMappedRange(8, std::numeric_limits<size_t>::max()), nullptr);
|
||||
}
|
||||
|
||||
// Error case: offset is before the start of the range
|
||||
{
|
||||
wgpu::Buffer buffer = CreateMapWriteBuffer(12);
|
||||
buffer.MapAsync(wgpu::MapMode::Write, 4, 4, nullptr, nullptr);
|
||||
EXPECT_EQ(buffer.GetMappedRange(3, 4), nullptr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,7 +128,8 @@ TEST_F(WireBufferMappingTests, MappingForReadSuccessBuffer) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer)).WillOnce(Return(&bufferContent));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&bufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
@ -171,7 +172,8 @@ TEST_F(WireBufferMappingTests, DestroyBeforeReadRequestEnd) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer)).WillOnce(Return(&bufferContent));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.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, _))
|
||||
|
@ -192,7 +194,8 @@ TEST_F(WireBufferMappingTests, UnmapCalledTooEarlyForRead) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer)).WillOnce(Return(&bufferContent));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&bufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
@ -214,7 +217,8 @@ TEST_F(WireBufferMappingTests, MappingForReadingErrorWhileAlreadyMappedGetsNullp
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer)).WillOnce(Return(&bufferContent));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&bufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
@ -246,7 +250,8 @@ TEST_F(WireBufferMappingTests, UnmapInsideMapReadCallback) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer)).WillOnce(Return(&bufferContent));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&bufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
@ -270,7 +275,8 @@ TEST_F(WireBufferMappingTests, DestroyInsideMapReadCallback) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer)).WillOnce(Return(&bufferContent));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&bufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
@ -298,7 +304,8 @@ TEST_F(WireBufferMappingTests, MappingForWriteSuccessBuffer) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer)).WillOnce(Return(&serverBufferContent));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&serverBufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
@ -348,7 +355,8 @@ TEST_F(WireBufferMappingTests, DestroyBeforeWriteRequestEnd) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer)).WillOnce(Return(&bufferContent));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.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, _))
|
||||
|
@ -369,7 +377,8 @@ TEST_F(WireBufferMappingTests, UnmapCalledTooEarlyForWrite) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer)).WillOnce(Return(&bufferContent));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&bufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
@ -392,7 +401,8 @@ TEST_F(WireBufferMappingTests, MappingForWritingErrorWhileAlreadyMappedGetsNullp
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer)).WillOnce(Return(&bufferContent));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&bufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
@ -425,7 +435,8 @@ TEST_F(WireBufferMappingTests, UnmapInsideMapWriteCallback) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer)).WillOnce(Return(&bufferContent));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&bufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
@ -450,7 +461,8 @@ TEST_F(WireBufferMappingTests, DestroyInsideMapWriteCallback) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer)).WillOnce(Return(&bufferContent));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&bufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
@ -548,7 +560,8 @@ TEST_F(WireBufferMappingTests, CreateBufferMappedThenMapSuccess) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer)).WillOnce(Return(&apiBufferData));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&apiBufferData));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ class WireMemoryTransferServiceTests : public WireTest {
|
|||
|
||||
std::pair<WGPUBuffer, WGPUBuffer> CreateBuffer() {
|
||||
WGPUBufferDescriptor descriptor = {};
|
||||
descriptor.size = sizeof(mBufferContent);
|
||||
descriptor.size = kBufferSize;
|
||||
|
||||
WGPUBuffer apiBuffer = api.GetNewBuffer();
|
||||
WGPUBuffer buffer = wgpuDeviceCreateBuffer(device, &descriptor);
|
||||
|
@ -349,6 +349,8 @@ class WireMemoryTransferServiceTests : public WireTest {
|
|||
// Represents the buffer contents for the test.
|
||||
static uint32_t mBufferContent;
|
||||
|
||||
static constexpr size_t kBufferSize = sizeof(mBufferContent);
|
||||
|
||||
// The client's zero-initialized buffer for writing.
|
||||
uint32_t mMappedBufferContent = 0;
|
||||
|
||||
|
@ -389,7 +391,8 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapReadSuccess) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer)).WillOnce(Return(&mBufferContent));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&mBufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
@ -521,7 +524,8 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapReadDeserializeInitialDataFailur
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer)).WillOnce(Return(&mBufferContent));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&mBufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
@ -565,7 +569,8 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapReadDestroyBeforeUnmap) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer)).WillOnce(Return(&mBufferContent));
|
||||
EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&mBufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
@ -616,7 +621,8 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteSuccess) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer)).WillOnce(Return(&mMappedBufferContent));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&mMappedBufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
@ -755,7 +761,8 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteHandleOpenFailure) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer)).WillOnce(Return(&mMappedBufferContent));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&mMappedBufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
@ -795,7 +802,8 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteDeserializeFlushFailure) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer)).WillOnce(Return(&mMappedBufferContent));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&mMappedBufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
@ -846,7 +854,8 @@ TEST_F(WireMemoryTransferServiceTests, BufferMapWriteDestroyBeforeUnmap) {
|
|||
EXPECT_CALL(api, OnBufferMapAsyncCallback(apiBuffer, _, _)).WillOnce(InvokeWithoutArgs([&]() {
|
||||
api.CallMapAsyncCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success);
|
||||
}));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer)).WillOnce(Return(&mMappedBufferContent));
|
||||
EXPECT_CALL(api, BufferGetMappedRange(apiBuffer, 0, kBufferSize))
|
||||
.WillOnce(Return(&mMappedBufferContent));
|
||||
|
||||
FlushClient();
|
||||
|
||||
|
|
Loading…
Reference in New Issue