@@ -1230,6 +1230,45 @@ TEST_P(BufferTests, CreateErrorBuffer) {
12301230 ASSERT_EQ (buffer, nullptr );
12311231}
12321232
1233+ // Test that MapAsync fails if called twice on the same buffer without unmapping.
1234+ TEST_P (BufferValidationTests, MapAsyncFailsWhenAlreadyMapped) {
1235+ // Create a writable buffer with MapWrite and CopyDst usage.
1236+ wgpu::BufferDescriptor desc;
1237+ desc.size = 64 ;
1238+ desc.usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopyDst;
1239+
1240+ wgpu::Buffer buffer = device.CreateBuffer (&desc);
1241+
1242+ // First call to MapAsync should succeed.
1243+ bool callback1Called = false ;
1244+ buffer.MapAsync (wgpu::MapMode::Write, 0 , 64 ,
1245+ [&](WGPUMapAsyncStatus status) {
1246+ // Expect the first mapping to succeed.
1247+ EXPECT_EQ (status, WGPUMapAsyncStatus_Success);
1248+ callback1Called = true ;
1249+ });
1250+
1251+ // Immediately call MapAsync again without unmapping.
1252+ bool callback2Called = false ;
1253+ buffer.MapAsync (wgpu::MapMode::Write, 0 , 64 ,
1254+ [&](WGPUMapAsyncStatus status) {
1255+ // The second mapping should fail and return an error.
1256+ EXPECT_EQ (status, WGPUMapAsyncStatus_Error);
1257+ callback2Called = true ;
1258+ });
1259+
1260+ // Process the commands and trigger callbacks.
1261+ device.Tick ();
1262+
1263+ // Ensure both callbacks were actually called.
1264+ EXPECT_TRUE (callback1Called);
1265+ EXPECT_TRUE (callback2Called);
1266+
1267+ // Cleanup: Unmap the buffer after use.
1268+ buffer.Unmap ();
1269+ }
1270+
1271+
12331272// Test that mapping an OOM buffer fails gracefully
12341273TEST_P (BufferTests, CreateBufferOOMMapAsync) {
12351274 // TODO(crbug.com/346377856): fails on ANGLE/D3D11, but is likely a Dawn/GL bug that only
0 commit comments