mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-03 11:46:09 +00:00
Add Buffer Destroyed state and validation tests
Adds Destroy() to the Buffer frontend but doesn't implement it in the backend yet. Bug: dawn:46, dawn:7 Change-Id: I2e6bdba1484fc5f49599801b4ffe3e9a6aaf60a5 Reviewed-on: https://dawn-review.googlesource.com/c/3720 Reviewed-by: Kai Ninomiya <kainino@chromium.org> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
1809ff7423
commit
446ab44ddb
@ -185,6 +185,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "unmap"
|
"name": "unmap"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "destroy"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -77,14 +77,18 @@ namespace dawn_native {
|
|||||||
// Buffer
|
// Buffer
|
||||||
|
|
||||||
BufferBase::BufferBase(DeviceBase* device, const BufferDescriptor* descriptor)
|
BufferBase::BufferBase(DeviceBase* device, const BufferDescriptor* descriptor)
|
||||||
: ObjectBase(device), mSize(descriptor->size), mUsage(descriptor->usage) {
|
: ObjectBase(device),
|
||||||
|
mSize(descriptor->size),
|
||||||
|
mUsage(descriptor->usage),
|
||||||
|
mState(BufferState::Unmapped) {
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferBase::BufferBase(DeviceBase* device, ObjectBase::ErrorTag tag) : ObjectBase(device, tag) {
|
BufferBase::BufferBase(DeviceBase* device, ObjectBase::ErrorTag tag)
|
||||||
|
: ObjectBase(device, tag), mState(BufferState::Unmapped) {
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferBase::~BufferBase() {
|
BufferBase::~BufferBase() {
|
||||||
if (mIsMapped) {
|
if (mState == BufferState::Mapped) {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
CallMapReadCallback(mMapSerial, DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr);
|
CallMapReadCallback(mMapSerial, DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr);
|
||||||
CallMapWriteCallback(mMapSerial, DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr);
|
CallMapWriteCallback(mMapSerial, DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr);
|
||||||
@ -109,11 +113,15 @@ namespace dawn_native {
|
|||||||
MaybeError BufferBase::ValidateCanUseInSubmitNow() const {
|
MaybeError BufferBase::ValidateCanUseInSubmitNow() const {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
|
|
||||||
if (mIsMapped) {
|
switch (mState) {
|
||||||
|
case BufferState::Destroyed:
|
||||||
|
return DAWN_VALIDATION_ERROR("Destroyed buffer used in a submit");
|
||||||
|
case BufferState::Mapped:
|
||||||
return DAWN_VALIDATION_ERROR("Buffer used in a submit while mapped");
|
return DAWN_VALIDATION_ERROR("Buffer used in a submit while mapped");
|
||||||
}
|
case BufferState::Unmapped:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BufferBase::CallMapReadCallback(uint32_t serial,
|
void BufferBase::CallMapReadCallback(uint32_t serial,
|
||||||
dawnBufferMapAsyncStatus status,
|
dawnBufferMapAsyncStatus status,
|
||||||
@ -172,7 +180,7 @@ namespace dawn_native {
|
|||||||
mMapSerial++;
|
mMapSerial++;
|
||||||
mMapReadCallback = callback;
|
mMapReadCallback = callback;
|
||||||
mMapUserdata = userdata;
|
mMapUserdata = userdata;
|
||||||
mIsMapped = true;
|
mState = BufferState::Mapped;
|
||||||
|
|
||||||
MapReadAsyncImpl(mMapSerial, start, size);
|
MapReadAsyncImpl(mMapSerial, start, size);
|
||||||
}
|
}
|
||||||
@ -193,11 +201,23 @@ namespace dawn_native {
|
|||||||
mMapSerial++;
|
mMapSerial++;
|
||||||
mMapWriteCallback = callback;
|
mMapWriteCallback = callback;
|
||||||
mMapUserdata = userdata;
|
mMapUserdata = userdata;
|
||||||
mIsMapped = true;
|
mState = BufferState::Mapped;
|
||||||
|
|
||||||
MapWriteAsyncImpl(mMapSerial, start, size);
|
MapWriteAsyncImpl(mMapSerial, start, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BufferBase::Destroy() {
|
||||||
|
if (GetDevice()->ConsumedError(ValidateDestroy())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ASSERT(!IsError());
|
||||||
|
|
||||||
|
if (mState == BufferState::Mapped) {
|
||||||
|
Unmap();
|
||||||
|
}
|
||||||
|
mState = BufferState::Destroyed;
|
||||||
|
}
|
||||||
|
|
||||||
void BufferBase::Unmap() {
|
void BufferBase::Unmap() {
|
||||||
if (GetDevice()->ConsumedError(ValidateUnmap())) {
|
if (GetDevice()->ConsumedError(ValidateUnmap())) {
|
||||||
return;
|
return;
|
||||||
@ -209,7 +229,7 @@ namespace dawn_native {
|
|||||||
CallMapReadCallback(mMapSerial, DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr);
|
CallMapReadCallback(mMapSerial, DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr);
|
||||||
CallMapWriteCallback(mMapSerial, DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr);
|
CallMapWriteCallback(mMapSerial, DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr);
|
||||||
UnmapImpl();
|
UnmapImpl();
|
||||||
mIsMapped = false;
|
mState = BufferState::Unmapped;
|
||||||
mMapReadCallback = nullptr;
|
mMapReadCallback = nullptr;
|
||||||
mMapWriteCallback = nullptr;
|
mMapWriteCallback = nullptr;
|
||||||
mMapUserdata = 0;
|
mMapUserdata = 0;
|
||||||
@ -218,6 +238,14 @@ namespace dawn_native {
|
|||||||
MaybeError BufferBase::ValidateSetSubData(uint32_t start, uint32_t count) const {
|
MaybeError BufferBase::ValidateSetSubData(uint32_t start, uint32_t count) const {
|
||||||
DAWN_TRY(GetDevice()->ValidateObject(this));
|
DAWN_TRY(GetDevice()->ValidateObject(this));
|
||||||
|
|
||||||
|
if (mState == BufferState::Destroyed) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Buffer is destroyed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mState == BufferState::Mapped) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Buffer is mapped");
|
||||||
|
}
|
||||||
|
|
||||||
if (count > GetSize()) {
|
if (count > GetSize()) {
|
||||||
return DAWN_VALIDATION_ERROR("Buffer subdata with too much data");
|
return DAWN_VALIDATION_ERROR("Buffer subdata with too much data");
|
||||||
}
|
}
|
||||||
@ -248,7 +276,11 @@ namespace dawn_native {
|
|||||||
return DAWN_VALIDATION_ERROR("Buffer mapping out of range");
|
return DAWN_VALIDATION_ERROR("Buffer mapping out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mIsMapped) {
|
if (mState == BufferState::Destroyed) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Buffer is destroyed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mState == BufferState::Mapped) {
|
||||||
return DAWN_VALIDATION_ERROR("Buffer already mapped");
|
return DAWN_VALIDATION_ERROR("Buffer already mapped");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,10 +294,20 @@ namespace dawn_native {
|
|||||||
MaybeError BufferBase::ValidateUnmap() const {
|
MaybeError BufferBase::ValidateUnmap() const {
|
||||||
DAWN_TRY(GetDevice()->ValidateObject(this));
|
DAWN_TRY(GetDevice()->ValidateObject(this));
|
||||||
|
|
||||||
if (!mIsMapped) {
|
if ((mUsage & (dawn::BufferUsageBit::MapRead | dawn::BufferUsageBit::MapWrite)) == 0) {
|
||||||
return DAWN_VALIDATION_ERROR("Buffer wasn't mapped");
|
return DAWN_VALIDATION_ERROR("Buffer does not have map usage");
|
||||||
|
}
|
||||||
|
switch (mState) {
|
||||||
|
case BufferState::Unmapped:
|
||||||
|
case BufferState::Mapped:
|
||||||
|
return {};
|
||||||
|
case BufferState::Destroyed:
|
||||||
|
return DAWN_VALIDATION_ERROR("Buffer is destroyed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaybeError BufferBase::ValidateDestroy() const {
|
||||||
|
DAWN_TRY(GetDevice()->ValidateObject(this));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,12 @@ namespace dawn_native {
|
|||||||
dawn::BufferUsageBit::Storage;
|
dawn::BufferUsageBit::Storage;
|
||||||
|
|
||||||
class BufferBase : public ObjectBase {
|
class BufferBase : public ObjectBase {
|
||||||
|
enum class BufferState {
|
||||||
|
Unmapped,
|
||||||
|
Mapped,
|
||||||
|
Destroyed,
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BufferBase(DeviceBase* device, const BufferDescriptor* descriptor);
|
BufferBase(DeviceBase* device, const BufferDescriptor* descriptor);
|
||||||
~BufferBase();
|
~BufferBase();
|
||||||
@ -57,6 +63,7 @@ namespace dawn_native {
|
|||||||
dawnBufferMapWriteCallback callback,
|
dawnBufferMapWriteCallback callback,
|
||||||
dawnCallbackUserdata userdata);
|
dawnCallbackUserdata userdata);
|
||||||
void Unmap();
|
void Unmap();
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BufferBase(DeviceBase* device, ObjectBase::ErrorTag tag);
|
BufferBase(DeviceBase* device, ObjectBase::ErrorTag tag);
|
||||||
@ -77,6 +84,7 @@ namespace dawn_native {
|
|||||||
uint32_t size,
|
uint32_t size,
|
||||||
dawn::BufferUsageBit requiredUsage) const;
|
dawn::BufferUsageBit requiredUsage) const;
|
||||||
MaybeError ValidateUnmap() const;
|
MaybeError ValidateUnmap() const;
|
||||||
|
MaybeError ValidateDestroy() const;
|
||||||
|
|
||||||
uint32_t mSize = 0;
|
uint32_t mSize = 0;
|
||||||
dawn::BufferUsageBit mUsage = dawn::BufferUsageBit::None;
|
dawn::BufferUsageBit mUsage = dawn::BufferUsageBit::None;
|
||||||
@ -86,7 +94,7 @@ namespace dawn_native {
|
|||||||
dawnCallbackUserdata mMapUserdata = 0;
|
dawnCallbackUserdata mMapUserdata = 0;
|
||||||
uint32_t mMapSerial = 0;
|
uint32_t mMapSerial = 0;
|
||||||
|
|
||||||
bool mIsMapped = false;
|
BufferState mState;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This builder class is kept around purely for testing but should not be used.
|
// This builder class is kept around purely for testing but should not be used.
|
||||||
|
@ -495,3 +495,234 @@ TEST_F(BufferValidationTest, SetSubDataWrongUsage) {
|
|||||||
uint8_t foo = 0;
|
uint8_t foo = 0;
|
||||||
ASSERT_DEVICE_ERROR(buf.SetSubData(0, sizeof(foo), &foo));
|
ASSERT_DEVICE_ERROR(buf.SetSubData(0, sizeof(foo), &foo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that it is valid to destroy an unmapped buffer
|
||||||
|
TEST_F(BufferValidationTest, DestroyUnmappedBuffer) {
|
||||||
|
{
|
||||||
|
dawn::Buffer buf = CreateMapReadBuffer(4);
|
||||||
|
buf.Destroy();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
dawn::Buffer buf = CreateMapWriteBuffer(4);
|
||||||
|
buf.Destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that it is valid to destroy a mapped buffer
|
||||||
|
TEST_F(BufferValidationTest, DestroyMappedBuffer) {
|
||||||
|
{
|
||||||
|
dawn::Buffer buf = CreateMapReadBuffer(4);
|
||||||
|
buf.MapReadAsync(0, 4, ToMockBufferMapReadCallback, 30303);
|
||||||
|
buf.Destroy();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
dawn::Buffer buf = CreateMapWriteBuffer(4);
|
||||||
|
buf.MapWriteAsync(0, 4, ToMockBufferMapWriteCallback, 30233);
|
||||||
|
buf.Destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that destroying a buffer implicitly unmaps it
|
||||||
|
TEST_F(BufferValidationTest, DestroyMappedBufferCausesImplicitUnmap) {
|
||||||
|
{
|
||||||
|
dawn::Buffer buf = CreateMapReadBuffer(4);
|
||||||
|
dawn::CallbackUserdata userdata = 40598;
|
||||||
|
buf.MapReadAsync(0, 4, ToMockBufferMapReadCallback, userdata);
|
||||||
|
// Buffer is destroyed. Callback should be called with UNKNOWN status
|
||||||
|
EXPECT_CALL(*mockBufferMapReadCallback,
|
||||||
|
Call(DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr, userdata))
|
||||||
|
.Times(1);
|
||||||
|
buf.Destroy();
|
||||||
|
queue.Submit(0, nullptr);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
dawn::Buffer buf = CreateMapWriteBuffer(4);
|
||||||
|
dawn::CallbackUserdata userdata = 23980;
|
||||||
|
buf.MapWriteAsync(0, 4, ToMockBufferMapWriteCallback, userdata);
|
||||||
|
// Buffer is destroyed. Callback should be called with UNKNOWN status
|
||||||
|
EXPECT_CALL(*mockBufferMapWriteCallback,
|
||||||
|
Call(DAWN_BUFFER_MAP_ASYNC_STATUS_UNKNOWN, nullptr, userdata))
|
||||||
|
.Times(1);
|
||||||
|
buf.Destroy();
|
||||||
|
queue.Submit(0, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that it is valid to Destroy a destroyed buffer
|
||||||
|
TEST_F(BufferValidationTest, DestroyDestroyedBuffer) {
|
||||||
|
dawn::Buffer buf = CreateSetSubDataBuffer(4);
|
||||||
|
buf.Destroy();
|
||||||
|
buf.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that it is invalid to Unmap a destroyed buffer
|
||||||
|
TEST_F(BufferValidationTest, UnmapDestroyedBuffer) {
|
||||||
|
{
|
||||||
|
dawn::Buffer buf = CreateMapReadBuffer(4);
|
||||||
|
buf.Destroy();
|
||||||
|
ASSERT_DEVICE_ERROR(buf.Unmap());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
dawn::Buffer buf = CreateMapWriteBuffer(4);
|
||||||
|
buf.Destroy();
|
||||||
|
ASSERT_DEVICE_ERROR(buf.Unmap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that it is invalid to map a destroyed buffer
|
||||||
|
TEST_F(BufferValidationTest, MapDestroyedBuffer) {
|
||||||
|
{
|
||||||
|
dawn::Buffer buf = CreateMapReadBuffer(4);
|
||||||
|
buf.Destroy();
|
||||||
|
ASSERT_DEVICE_ERROR(buf.MapReadAsync(0, 4, ToMockBufferMapReadCallback, 11303));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
dawn::Buffer buf = CreateMapWriteBuffer(4);
|
||||||
|
buf.Destroy();
|
||||||
|
ASSERT_DEVICE_ERROR(buf.MapWriteAsync(0, 4, ToMockBufferMapWriteCallback, 56303));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that it is invalid to call SetSubData on a destroyed buffer
|
||||||
|
TEST_F(BufferValidationTest, SetSubDataDestroyedBuffer) {
|
||||||
|
dawn::Buffer buf = CreateSetSubDataBuffer(4);
|
||||||
|
buf.Destroy();
|
||||||
|
uint8_t foo = 0;
|
||||||
|
ASSERT_DEVICE_ERROR(buf.SetSubData(0, sizeof(foo), &foo));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that is is invalid to Map a mapped buffer
|
||||||
|
TEST_F(BufferValidationTest, MapMappedbuffer) {
|
||||||
|
{
|
||||||
|
dawn::Buffer buf = CreateMapReadBuffer(4);
|
||||||
|
buf.MapReadAsync(0, 4, ToMockBufferMapReadCallback, 43309);
|
||||||
|
ASSERT_DEVICE_ERROR(buf.MapReadAsync(0, 4, ToMockBufferMapReadCallback, 34309));
|
||||||
|
queue.Submit(0, nullptr);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
dawn::Buffer buf = CreateMapWriteBuffer(4);
|
||||||
|
buf.MapWriteAsync(0, 4, ToMockBufferMapWriteCallback, 20301);
|
||||||
|
ASSERT_DEVICE_ERROR(buf.MapWriteAsync(0, 4, ToMockBufferMapWriteCallback, 40303));
|
||||||
|
queue.Submit(0, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that it is invalid to call SetSubData on a mapped buffer
|
||||||
|
TEST_F(BufferValidationTest, SetSubDataMappedBuffer) {
|
||||||
|
{
|
||||||
|
dawn::Buffer buf = CreateMapReadBuffer(4);
|
||||||
|
buf.MapReadAsync(0, 4, ToMockBufferMapReadCallback, 42899);
|
||||||
|
uint8_t foo = 0;
|
||||||
|
ASSERT_DEVICE_ERROR(buf.SetSubData(0, sizeof(foo), &foo));
|
||||||
|
queue.Submit(0, nullptr);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
dawn::Buffer buf = CreateMapWriteBuffer(4);
|
||||||
|
buf.MapWriteAsync(0, 4, ToMockBufferMapWriteCallback, 40329);
|
||||||
|
uint8_t foo = 0;
|
||||||
|
ASSERT_DEVICE_ERROR(buf.SetSubData(0, sizeof(foo), &foo));
|
||||||
|
queue.Submit(0, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that it is valid to submit a buffer in a queue with a map usage if it is unmapped
|
||||||
|
TEST_F(BufferValidationTest, SubmitBufferWithMapUsage) {
|
||||||
|
dawn::BufferDescriptor descriptorA;
|
||||||
|
descriptorA.size = 4;
|
||||||
|
descriptorA.usage = dawn::BufferUsageBit::TransferSrc | dawn::BufferUsageBit::MapWrite;
|
||||||
|
|
||||||
|
dawn::BufferDescriptor descriptorB;
|
||||||
|
descriptorB.size = 4;
|
||||||
|
descriptorB.usage = dawn::BufferUsageBit::TransferDst | dawn::BufferUsageBit::MapRead;
|
||||||
|
|
||||||
|
dawn::Buffer bufA = device.CreateBuffer(&descriptorA);
|
||||||
|
dawn::Buffer bufB = device.CreateBuffer(&descriptorB);
|
||||||
|
|
||||||
|
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
||||||
|
builder.CopyBufferToBuffer(bufA, 0, bufB, 0, 4);
|
||||||
|
dawn::CommandBuffer commands = builder.GetResult();
|
||||||
|
queue.Submit(1, &commands);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that it is invalid to submit a mapped buffer in a queue
|
||||||
|
TEST_F(BufferValidationTest, SubmitMappedBuffer) {
|
||||||
|
dawn::BufferDescriptor descriptorA;
|
||||||
|
descriptorA.size = 4;
|
||||||
|
descriptorA.usage = dawn::BufferUsageBit::TransferSrc | dawn::BufferUsageBit::MapWrite;
|
||||||
|
|
||||||
|
dawn::BufferDescriptor descriptorB;
|
||||||
|
descriptorB.size = 4;
|
||||||
|
descriptorB.usage = dawn::BufferUsageBit::TransferDst | dawn::BufferUsageBit::MapRead;
|
||||||
|
{
|
||||||
|
dawn::Buffer bufA = device.CreateBuffer(&descriptorA);
|
||||||
|
dawn::Buffer bufB = device.CreateBuffer(&descriptorB);
|
||||||
|
|
||||||
|
bufA.MapWriteAsync(0, 4, ToMockBufferMapWriteCallback, 40329);
|
||||||
|
|
||||||
|
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
||||||
|
builder.CopyBufferToBuffer(bufA, 0, bufB, 0, 4);
|
||||||
|
dawn::CommandBuffer commands = builder.GetResult();
|
||||||
|
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
||||||
|
queue.Submit(0, nullptr);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
dawn::Buffer bufA = device.CreateBuffer(&descriptorA);
|
||||||
|
dawn::Buffer bufB = device.CreateBuffer(&descriptorB);
|
||||||
|
|
||||||
|
bufB.MapReadAsync(0, 4, ToMockBufferMapReadCallback, 11329);
|
||||||
|
|
||||||
|
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
||||||
|
builder.CopyBufferToBuffer(bufA, 0, bufB, 0, 4);
|
||||||
|
dawn::CommandBuffer commands = builder.GetResult();
|
||||||
|
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
||||||
|
queue.Submit(0, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that it is invalid to submit a destroyed buffer in a queue
|
||||||
|
TEST_F(BufferValidationTest, SubmitDestroyedBuffer) {
|
||||||
|
dawn::BufferDescriptor descriptorA;
|
||||||
|
descriptorA.size = 4;
|
||||||
|
descriptorA.usage = dawn::BufferUsageBit::TransferSrc;
|
||||||
|
|
||||||
|
dawn::BufferDescriptor descriptorB;
|
||||||
|
descriptorB.size = 4;
|
||||||
|
descriptorB.usage = dawn::BufferUsageBit::TransferDst;
|
||||||
|
|
||||||
|
dawn::Buffer bufA = device.CreateBuffer(&descriptorA);
|
||||||
|
dawn::Buffer bufB = device.CreateBuffer(&descriptorB);
|
||||||
|
|
||||||
|
bufA.Destroy();
|
||||||
|
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
||||||
|
builder.CopyBufferToBuffer(bufA, 0, bufB, 0, 4);
|
||||||
|
dawn::CommandBuffer commands = builder.GetResult();
|
||||||
|
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that a map usage is required to call Unmap
|
||||||
|
TEST_F(BufferValidationTest, UnmapWithoutMapUsage) {
|
||||||
|
dawn::Buffer buf = CreateSetSubDataBuffer(4);
|
||||||
|
ASSERT_DEVICE_ERROR(buf.Unmap());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that it is valid to call Unmap on a buffer that is not mapped
|
||||||
|
TEST_F(BufferValidationTest, UnmapUnmappedBuffer) {
|
||||||
|
{
|
||||||
|
dawn::Buffer buf = CreateMapReadBuffer(4);
|
||||||
|
// Buffer starts unmapped. Unmap should succeed.
|
||||||
|
buf.Unmap();
|
||||||
|
buf.MapReadAsync(0, 4, ToMockBufferMapReadCallback, 30603);
|
||||||
|
buf.Unmap();
|
||||||
|
// Unmapping twice should succeed
|
||||||
|
buf.Unmap();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
dawn::Buffer buf = CreateMapWriteBuffer(4);
|
||||||
|
// Buffer starts unmapped. Unmap should succeed.
|
||||||
|
buf.Unmap();
|
||||||
|
buf.MapWriteAsync(0, 4, ToMockBufferMapWriteCallback, 23890);
|
||||||
|
// Unmapping twice should succeed
|
||||||
|
buf.Unmap();
|
||||||
|
buf.Unmap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user