diff --git a/src/backend/common/Buffer.cpp b/src/backend/common/Buffer.cpp index b1e5a6ab0a..0fa57db616 100644 --- a/src/backend/common/Buffer.cpp +++ b/src/backend/common/Buffer.cpp @@ -188,12 +188,25 @@ namespace backend { return nullptr; } + const nxt::BufferUsageBit kMapWriteAllowedUsages = nxt::BufferUsageBit::MapWrite | nxt::BufferUsageBit::TransferSrc; + if (allowedUsage & nxt::BufferUsageBit::MapWrite && + (allowedUsage & kMapWriteAllowedUsages) != allowedUsage) { + HandleError("Only TransferSrc is allowed with MapWrite"); + return nullptr; + } + + const nxt::BufferUsageBit kMapReadAllowedUsages = nxt::BufferUsageBit::MapRead | nxt::BufferUsageBit::TransferDst; + if (allowedUsage & nxt::BufferUsageBit::MapRead && + (allowedUsage & kMapReadAllowedUsages) != allowedUsage) { + HandleError("Only TransferDst is allowed with MapRead"); + return nullptr; + } + if (!BufferBase::IsUsagePossible(allowedUsage, currentUsage)) { HandleError("Initial buffer usage is not allowed"); return nullptr; } - // TODO(cwallez@chromium.org) disallow using MapRead with anything else than TransferDst return device->CreateBuffer(this); } diff --git a/src/tests/unittests/validation/BufferValidationTests.cpp b/src/tests/unittests/validation/BufferValidationTests.cpp index 5048a0cbac..928cee4ae2 100644 --- a/src/tests/unittests/validation/BufferValidationTests.cpp +++ b/src/tests/unittests/validation/BufferValidationTests.cpp @@ -142,6 +142,41 @@ TEST_F(BufferValidationTest, CreationMissingProperties) { } } +// Test restriction on usages allowed with MapRead and MapWrite +TEST_F(BufferValidationTest, CreationMapUsageRestrictions) { + // MapRead with TransferDst is ok + { + nxt::Buffer buf = AssertWillBeSuccess(device.CreateBufferBuilder(), "1") + .SetAllowedUsage(nxt::BufferUsageBit::MapRead | nxt::BufferUsageBit::TransferDst) + .SetSize(4) + .GetResult(); + } + + // MapRead with something else is an error + { + nxt::Buffer buf = AssertWillBeError(device.CreateBufferBuilder(), "2") + .SetAllowedUsage(nxt::BufferUsageBit::MapRead | nxt::BufferUsageBit::Uniform) + .SetSize(4) + .GetResult(); + } + + // MapWrite with TransferSrc is ok + { + nxt::Buffer buf = AssertWillBeSuccess(device.CreateBufferBuilder(), "3") + .SetAllowedUsage(nxt::BufferUsageBit::MapWrite | nxt::BufferUsageBit::TransferSrc) + .SetSize(4) + .GetResult(); + } + + // MapWrite with something else is an error + { + nxt::Buffer buf = AssertWillBeError(device.CreateBufferBuilder(), "4") + .SetAllowedUsage(nxt::BufferUsageBit::MapWrite | nxt::BufferUsageBit::Uniform) + .SetSize(4) + .GetResult(); + } +} + // Test the success cause for mapping buffer for reading TEST_F(BufferValidationTest, MapReadSuccess) { nxt::Buffer buf = CreateMapReadBuffer(4);