mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-21 02:39:11 +00:00
Handle Device Lost for Buffer
Bug: dawn:68, chromium:1042998, chromium:1043468 Change-Id: I4faa46b0d2e8f814b9d353a75489d3c8ca0b2e89 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/15340 Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Natasha Lee <natlee@microsoft.com>
This commit is contained in:
committed by
Commit Bot service account
parent
f329c78b6c
commit
74f5054ec9
@@ -34,6 +34,8 @@ static void ToMockDeviceLostCallback(const char* message, void* userdata) {
|
||||
self->StartExpectDeviceError();
|
||||
}
|
||||
|
||||
static const int fakeUserData = 0;
|
||||
|
||||
class DeviceLostTest : public DawnTest {
|
||||
protected:
|
||||
void TestSetUp() override {
|
||||
@@ -52,6 +54,26 @@ class DeviceLostTest : public DawnTest {
|
||||
EXPECT_CALL(*mockDeviceLostCallback, Call(_, this)).Times(1);
|
||||
device.LoseForTesting();
|
||||
}
|
||||
|
||||
static void CheckMapWriteFail(WGPUBufferMapAsyncStatus status,
|
||||
void* data,
|
||||
uint64_t datalength,
|
||||
void* userdata) {
|
||||
EXPECT_EQ(WGPUBufferMapAsyncStatus_DeviceLost, status);
|
||||
EXPECT_EQ(nullptr, data);
|
||||
EXPECT_EQ(0u, datalength);
|
||||
EXPECT_EQ(&fakeUserData, userdata);
|
||||
}
|
||||
|
||||
static void CheckMapReadFail(WGPUBufferMapAsyncStatus status,
|
||||
const void* data,
|
||||
uint64_t datalength,
|
||||
void* userdata) {
|
||||
EXPECT_EQ(WGPUBufferMapAsyncStatus_DeviceLost, status);
|
||||
EXPECT_EQ(nullptr, data);
|
||||
EXPECT_EQ(0u, datalength);
|
||||
EXPECT_EQ(&fakeUserData, userdata);
|
||||
}
|
||||
};
|
||||
|
||||
// Test that DeviceLostCallback is invoked when LostForTestimg is called
|
||||
@@ -212,4 +234,127 @@ TEST_P(DeviceLostTest, TickFails) {
|
||||
ASSERT_DEVICE_ERROR(device.Tick());
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(DeviceLostTest, D3D12Backend, VulkanBackend);
|
||||
// Test that CreateBuffer fails when device is lost
|
||||
TEST_P(DeviceLostTest, CreateBufferFails) {
|
||||
SetCallbackAndLoseForTesting();
|
||||
|
||||
wgpu::BufferDescriptor bufferDescriptor;
|
||||
bufferDescriptor.size = sizeof(float);
|
||||
bufferDescriptor.usage = wgpu::BufferUsage::CopySrc;
|
||||
ASSERT_DEVICE_ERROR(device.CreateBuffer(&bufferDescriptor));
|
||||
}
|
||||
|
||||
// Test that buffer.MapWriteAsync fails after device is lost
|
||||
TEST_P(DeviceLostTest, BufferMapWriteAsyncFails) {
|
||||
wgpu::BufferDescriptor bufferDescriptor;
|
||||
bufferDescriptor.size = sizeof(float);
|
||||
bufferDescriptor.usage = wgpu::BufferUsage::MapWrite;
|
||||
wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
|
||||
|
||||
SetCallbackAndLoseForTesting();
|
||||
ASSERT_DEVICE_ERROR(buffer.MapWriteAsync(CheckMapWriteFail, const_cast<int*>(&fakeUserData)));
|
||||
}
|
||||
|
||||
// Test that buffer.MapWriteAsync calls back with device loss status
|
||||
TEST_P(DeviceLostTest, BufferMapWriteAsyncBeforeLossFails) {
|
||||
wgpu::BufferDescriptor bufferDescriptor;
|
||||
bufferDescriptor.size = sizeof(float);
|
||||
bufferDescriptor.usage = wgpu::BufferUsage::MapWrite;
|
||||
wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
|
||||
|
||||
buffer.MapWriteAsync(CheckMapWriteFail, const_cast<int*>(&fakeUserData));
|
||||
SetCallbackAndLoseForTesting();
|
||||
}
|
||||
|
||||
// Test that buffer.Unmap fails after device is lost
|
||||
TEST_P(DeviceLostTest, BufferUnmapFails) {
|
||||
wgpu::BufferDescriptor bufferDescriptor;
|
||||
bufferDescriptor.size = sizeof(float);
|
||||
bufferDescriptor.usage = wgpu::BufferUsage::MapWrite;
|
||||
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));
|
||||
}
|
||||
|
||||
// Test that CreateBufferMappedAsync fails after device is lost
|
||||
TEST_P(DeviceLostTest, CreateBufferMappedAsyncFails) {
|
||||
wgpu::BufferDescriptor bufferDescriptor;
|
||||
bufferDescriptor.size = sizeof(float);
|
||||
bufferDescriptor.usage = wgpu::BufferUsage::MapWrite;
|
||||
|
||||
SetCallbackAndLoseForTesting();
|
||||
struct ResultInfo {
|
||||
wgpu::CreateBufferMappedResult result;
|
||||
bool done = false;
|
||||
} resultInfo;
|
||||
|
||||
ASSERT_DEVICE_ERROR(device.CreateBufferMappedAsync(
|
||||
&bufferDescriptor,
|
||||
[](WGPUBufferMapAsyncStatus status, WGPUCreateBufferMappedResult result, void* userdata) {
|
||||
auto* resultInfo = static_cast<ResultInfo*>(userdata);
|
||||
EXPECT_EQ(WGPUBufferMapAsyncStatus_DeviceLost, status);
|
||||
EXPECT_NE(nullptr, result.data);
|
||||
resultInfo->result.buffer = wgpu::Buffer::Acquire(result.buffer);
|
||||
resultInfo->result.data = result.data;
|
||||
resultInfo->result.dataLength = result.dataLength;
|
||||
resultInfo->done = true;
|
||||
},
|
||||
&resultInfo));
|
||||
|
||||
while (!resultInfo.done) {
|
||||
ASSERT_DEVICE_ERROR(WaitABit());
|
||||
}
|
||||
|
||||
ASSERT_DEVICE_ERROR(resultInfo.result.buffer.Unmap());
|
||||
}
|
||||
|
||||
// Test that BufferMapReadAsync fails after device is lost
|
||||
TEST_P(DeviceLostTest, BufferMapReadAsyncFails) {
|
||||
wgpu::BufferDescriptor bufferDescriptor;
|
||||
bufferDescriptor.size = sizeof(float);
|
||||
bufferDescriptor.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
|
||||
|
||||
wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
|
||||
|
||||
SetCallbackAndLoseForTesting();
|
||||
ASSERT_DEVICE_ERROR(buffer.MapReadAsync(CheckMapReadFail, const_cast<int*>(&fakeUserData)));
|
||||
}
|
||||
|
||||
// Test that BufferMapReadAsync calls back with device lost status when device lost after map read
|
||||
TEST_P(DeviceLostTest, BufferMapReadAsyncBeforeLossFails) {
|
||||
wgpu::BufferDescriptor bufferDescriptor;
|
||||
bufferDescriptor.size = sizeof(float);
|
||||
bufferDescriptor.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
|
||||
|
||||
wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
|
||||
|
||||
buffer.MapReadAsync(CheckMapReadFail, const_cast<int*>(&fakeUserData));
|
||||
SetCallbackAndLoseForTesting();
|
||||
}
|
||||
|
||||
// Test that SetSubData fails after device is lost
|
||||
TEST_P(DeviceLostTest, SetSubDataFails) {
|
||||
wgpu::BufferDescriptor bufferDescriptor;
|
||||
bufferDescriptor.size = sizeof(float);
|
||||
bufferDescriptor.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
|
||||
|
||||
wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
|
||||
|
||||
SetCallbackAndLoseForTesting();
|
||||
std::array<float, 1> data = {12};
|
||||
ASSERT_DEVICE_ERROR(buffer.SetSubData(0, sizeof(float), data.data()));
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(DeviceLostTest, D3D12Backend, VulkanBackend);
|
||||
Reference in New Issue
Block a user