diff --git a/.github/workflows/dawn-ci.cmake b/.github/workflows/dawn-ci.cmake index 90c36d751fd..3e39337fd53 100644 --- a/.github/workflows/dawn-ci.cmake +++ b/.github/workflows/dawn-ci.cmake @@ -6,7 +6,9 @@ if (WIN32) set(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION "$ENV{WIN10_SDK_VERSION}" CACHE STRING "") endif () set(DAWN_FETCH_DEPENDENCIES ON CACHE BOOL "") -set(DAWN_ENABLE_INSTALL ON CACHE BOOL "") +# set(DAWN_ENABLE_INSTALL ON CACHE BOOL "") +set(DAWN_ENABLE_INSTALL OFF CACHE BOOL "") + if (CMAKE_SYTEM_NAME STREQUAL "Linux") # `sccache` seems effective only on linux. diff --git a/src/dawn/native/Buffer.cpp b/src/dawn/native/Buffer.cpp index 9b85cb99e43..3b338f0af79 100644 --- a/src/dawn/native/Buffer.cpp +++ b/src/dawn/native/Buffer.cpp @@ -566,17 +566,24 @@ Future BufferBase::APIMapAsync(wgpu::MapMode mode, size_t offset, size_t size, const WGPUBufferMapCallbackInfo& callbackInfo) { - // TODO(crbug.com/dawn/2052): Once we always return a future, change this to log to the instance - // (note, not raise a validation error to the device) and return the null future. DAWN_ASSERT(callbackInfo.nextInChain == nullptr); Ref event; { auto deviceGuard = GetDevice()->GetGuard(); - // Handle the defaulting of size required by WebGPU, even if in webgpu_cpp.h it is not - // possible to default the function argument (because there is the callback later in the - // argument list) + // Remove redundant early-exit validation. + // Let ValidateMapAsync and MapAsyncImpl handle invalid states, + // so errors are reported through the device's uncaptured error mechanism. + // We can still log a warning for developer visibility. + BufferState currentState = mState.load(std::memory_order::acquire); + if (currentState == BufferState::Mapped || currentState == BufferState::MappedAtCreation) { + dawn::EmitWarning(GetDevice(), + "Attempted to map a buffer that is already mapped. " + "Call Unmap() before calling MapAsync again."); + } + + // Handle the defaulting of size required by WebGPU if ((size == wgpu::kWholeMapSize) && (offset <= mSize)) { size = mSize - offset; } @@ -611,9 +618,13 @@ Future BufferBase::APIMapAsync(wgpu::MapMode mode, DAWN_ASSERT(event); FutureID futureID = GetInstance()->GetEventManager()->TrackEvent(std::move(event)); - return {futureID}; + return {futureID}; // Always return a valid FutureID } + + +//****************************************************************************************************** */ + void* BufferBase::APIGetMappedRange(size_t offset, size_t size) { return GetMappedRange(offset, size, true); } diff --git a/src/dawn/tests/end2end/BufferTests.cpp b/src/dawn/tests/end2end/BufferTests.cpp index 05186b5ff26..4027cac74f2 100644 --- a/src/dawn/tests/end2end/BufferTests.cpp +++ b/src/dawn/tests/end2end/BufferTests.cpp @@ -1230,6 +1230,45 @@ TEST_P(BufferTests, CreateErrorBuffer) { ASSERT_EQ(buffer, nullptr); } +// Test that MapAsync fails if called twice on the same buffer without unmapping. +TEST_P(BufferValidationTests, MapAsyncFailsWhenAlreadyMapped) { + // Create a writable buffer with MapWrite and CopyDst usage. + wgpu::BufferDescriptor desc; + desc.size = 64; + desc.usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopyDst; + + wgpu::Buffer buffer = device.CreateBuffer(&desc); + + // First call to MapAsync should succeed. + bool callback1Called = false; + buffer.MapAsync(wgpu::MapMode::Write, 0, 64, + [&](WGPUMapAsyncStatus status) { + // Expect the first mapping to succeed. + EXPECT_EQ(status, WGPUMapAsyncStatus_Success); + callback1Called = true; + }); + + // Immediately call MapAsync again without unmapping. + bool callback2Called = false; + buffer.MapAsync(wgpu::MapMode::Write, 0, 64, + [&](WGPUMapAsyncStatus status) { + // The second mapping should fail and return an error. + EXPECT_EQ(status, WGPUMapAsyncStatus_Error); + callback2Called = true; + }); + + // Process the commands and trigger callbacks. + device.Tick(); + + // Ensure both callbacks were actually called. + EXPECT_TRUE(callback1Called); + EXPECT_TRUE(callback2Called); + + // Cleanup: Unmap the buffer after use. + buffer.Unmap(); +} + + // Test that mapping an OOM buffer fails gracefully TEST_P(BufferTests, CreateBufferOOMMapAsync) { // TODO(crbug.com/346377856): fails on ANGLE/D3D11, but is likely a Dawn/GL bug that only