mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-08-10 22:19:09 +00:00
Validate that mapped buffers aren't used in submits.
Likewise "presented" textures won't be available for use in submits so this sets up state-tracking and validation for textures too. Command buffer resource usage is now stored in the frontend instead of done per-backend because it is used to validate resources are allowed in the submits. Also adds a test. BUG=dawn:9 Change-Id: I0537c5113bb33a089509b4f2af4ddf4eff8051ea Reviewed-on: https://dawn-review.googlesource.com/c/2142 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
b04c728d54
commit
679ff4ea86
1
BUILD.gn
1
BUILD.gn
@ -778,6 +778,7 @@ test("dawn_unittests") {
|
|||||||
"src/tests/unittests/validation/DynamicStateCommandValidationTests.cpp",
|
"src/tests/unittests/validation/DynamicStateCommandValidationTests.cpp",
|
||||||
"src/tests/unittests/validation/InputStateValidationTests.cpp",
|
"src/tests/unittests/validation/InputStateValidationTests.cpp",
|
||||||
"src/tests/unittests/validation/PushConstantsValidationTests.cpp",
|
"src/tests/unittests/validation/PushConstantsValidationTests.cpp",
|
||||||
|
"src/tests/unittests/validation/QueueSubmitValidationTests.cpp",
|
||||||
"src/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp",
|
"src/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp",
|
||||||
"src/tests/unittests/validation/RenderPipelineValidationTests.cpp",
|
"src/tests/unittests/validation/RenderPipelineValidationTests.cpp",
|
||||||
"src/tests/unittests/validation/ShaderModuleValidationTests.cpp",
|
"src/tests/unittests/validation/ShaderModuleValidationTests.cpp",
|
||||||
|
@ -72,6 +72,13 @@ namespace dawn_native {
|
|||||||
return mUsage;
|
return mUsage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaybeError BufferBase::ValidateCanUseInSubmitNow() const {
|
||||||
|
if (mIsMapped) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Buffer used in a submit while mapped");
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void BufferBase::CallMapReadCallback(uint32_t serial,
|
void BufferBase::CallMapReadCallback(uint32_t serial,
|
||||||
dawnBufferMapAsyncStatus status,
|
dawnBufferMapAsyncStatus status,
|
||||||
const void* pointer) {
|
const void* pointer) {
|
||||||
|
@ -42,6 +42,8 @@ namespace dawn_native {
|
|||||||
uint32_t GetSize() const;
|
uint32_t GetSize() const;
|
||||||
dawn::BufferUsageBit GetUsage() const;
|
dawn::BufferUsageBit GetUsage() const;
|
||||||
|
|
||||||
|
MaybeError ValidateCanUseInSubmitNow() const;
|
||||||
|
|
||||||
// Dawn API
|
// Dawn API
|
||||||
BufferViewBuilder* CreateBufferViewBuilder();
|
BufferViewBuilder* CreateBufferViewBuilder();
|
||||||
void SetSubData(uint32_t start, uint32_t count, const uint8_t* data);
|
void SetSubData(uint32_t start, uint32_t count, const uint8_t* data);
|
||||||
|
@ -286,7 +286,11 @@ namespace dawn_native {
|
|||||||
// CommandBuffer
|
// CommandBuffer
|
||||||
|
|
||||||
CommandBufferBase::CommandBufferBase(CommandBufferBuilder* builder)
|
CommandBufferBase::CommandBufferBase(CommandBufferBuilder* builder)
|
||||||
: ObjectBase(builder->GetDevice()) {
|
: ObjectBase(builder->GetDevice()), mResourceUsages(builder->AcquireResourceUsages()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
const CommandBufferResourceUsage& CommandBufferBase::GetResourceUsages() const {
|
||||||
|
return mResourceUsages;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandBufferBuilder
|
// CommandBufferBuilder
|
||||||
@ -308,10 +312,10 @@ namespace dawn_native {
|
|||||||
return std::move(mIterator);
|
return std::move(mIterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PassResourceUsage> CommandBufferBuilder::AcquirePassResourceUsage() {
|
CommandBufferResourceUsage CommandBufferBuilder::AcquireResourceUsages() {
|
||||||
ASSERT(!mWerePassUsagesAcquired);
|
ASSERT(!mWereResourceUsagesAcquired);
|
||||||
mWerePassUsagesAcquired = true;
|
mWereResourceUsagesAcquired = true;
|
||||||
return std::move(mPassResourceUsages);
|
return std::move(mResourceUsages);
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandBufferBase* CommandBufferBuilder::GetResultImpl() {
|
CommandBufferBase* CommandBufferBuilder::GetResultImpl() {
|
||||||
@ -372,6 +376,9 @@ namespace dawn_native {
|
|||||||
dawn::BufferUsageBit::TransferSrc));
|
dawn::BufferUsageBit::TransferSrc));
|
||||||
DAWN_TRY(ValidateCanUseAs(copy->destination.buffer.Get(),
|
DAWN_TRY(ValidateCanUseAs(copy->destination.buffer.Get(),
|
||||||
dawn::BufferUsageBit::TransferDst));
|
dawn::BufferUsageBit::TransferDst));
|
||||||
|
|
||||||
|
mResourceUsages.topLevelBuffers.insert(copy->source.buffer.Get());
|
||||||
|
mResourceUsages.topLevelBuffers.insert(copy->destination.buffer.Get());
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::CopyBufferToTexture: {
|
case Command::CopyBufferToTexture: {
|
||||||
@ -391,6 +398,9 @@ namespace dawn_native {
|
|||||||
dawn::BufferUsageBit::TransferSrc));
|
dawn::BufferUsageBit::TransferSrc));
|
||||||
DAWN_TRY(ValidateCanUseAs(copy->destination.texture.Get(),
|
DAWN_TRY(ValidateCanUseAs(copy->destination.texture.Get(),
|
||||||
dawn::TextureUsageBit::TransferDst));
|
dawn::TextureUsageBit::TransferDst));
|
||||||
|
|
||||||
|
mResourceUsages.topLevelBuffers.insert(copy->source.buffer.Get());
|
||||||
|
mResourceUsages.topLevelTextures.insert(copy->destination.texture.Get());
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::CopyTextureToBuffer: {
|
case Command::CopyTextureToBuffer: {
|
||||||
@ -410,6 +420,9 @@ namespace dawn_native {
|
|||||||
dawn::TextureUsageBit::TransferSrc));
|
dawn::TextureUsageBit::TransferSrc));
|
||||||
DAWN_TRY(ValidateCanUseAs(copy->destination.buffer.Get(),
|
DAWN_TRY(ValidateCanUseAs(copy->destination.buffer.Get(),
|
||||||
dawn::BufferUsageBit::TransferDst));
|
dawn::BufferUsageBit::TransferDst));
|
||||||
|
|
||||||
|
mResourceUsages.topLevelTextures.insert(copy->source.texture.Get());
|
||||||
|
mResourceUsages.topLevelBuffers.insert(copy->destination.buffer.Get());
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -431,7 +444,7 @@ namespace dawn_native {
|
|||||||
mIterator.NextCommand<EndComputePassCmd>();
|
mIterator.NextCommand<EndComputePassCmd>();
|
||||||
|
|
||||||
DAWN_TRY(usageTracker.ValidateUsages(PassType::Compute));
|
DAWN_TRY(usageTracker.ValidateUsages(PassType::Compute));
|
||||||
mPassResourceUsages.push_back(usageTracker.AcquireResourceUsage());
|
mResourceUsages.perPass.push_back(usageTracker.AcquireResourceUsage());
|
||||||
return {};
|
return {};
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -495,7 +508,7 @@ namespace dawn_native {
|
|||||||
mIterator.NextCommand<EndRenderPassCmd>();
|
mIterator.NextCommand<EndRenderPassCmd>();
|
||||||
|
|
||||||
DAWN_TRY(usageTracker.ValidateUsages(PassType::Render));
|
DAWN_TRY(usageTracker.ValidateUsages(PassType::Render));
|
||||||
mPassResourceUsages.push_back(usageTracker.AcquireResourceUsage());
|
mResourceUsages.perPass.push_back(usageTracker.AcquireResourceUsage());
|
||||||
return {};
|
return {};
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -42,6 +42,11 @@ namespace dawn_native {
|
|||||||
class CommandBufferBase : public ObjectBase {
|
class CommandBufferBase : public ObjectBase {
|
||||||
public:
|
public:
|
||||||
CommandBufferBase(CommandBufferBuilder* builder);
|
CommandBufferBase(CommandBufferBuilder* builder);
|
||||||
|
|
||||||
|
const CommandBufferResourceUsage& GetResourceUsages() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CommandBufferResourceUsage mResourceUsages;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CommandBufferBuilder : public Builder<CommandBufferBase> {
|
class CommandBufferBuilder : public Builder<CommandBufferBase> {
|
||||||
@ -52,7 +57,7 @@ namespace dawn_native {
|
|||||||
MaybeError ValidateGetResult();
|
MaybeError ValidateGetResult();
|
||||||
|
|
||||||
CommandIterator AcquireCommands();
|
CommandIterator AcquireCommands();
|
||||||
std::vector<PassResourceUsage> AcquirePassResourceUsage();
|
CommandBufferResourceUsage AcquireResourceUsages();
|
||||||
|
|
||||||
// Dawn API
|
// Dawn API
|
||||||
ComputePassEncoderBase* BeginComputePass();
|
ComputePassEncoderBase* BeginComputePass();
|
||||||
@ -116,9 +121,9 @@ namespace dawn_native {
|
|||||||
CommandIterator mIterator;
|
CommandIterator mIterator;
|
||||||
bool mWasMovedToIterator = false;
|
bool mWasMovedToIterator = false;
|
||||||
bool mWereCommandsAcquired = false;
|
bool mWereCommandsAcquired = false;
|
||||||
bool mWerePassUsagesAcquired = false;
|
|
||||||
|
|
||||||
std::vector<PassResourceUsage> mPassResourceUsages;
|
bool mWereResourceUsagesAcquired = false;
|
||||||
|
CommandBufferResourceUsage mResourceUsages;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dawn_native
|
} // namespace dawn_native
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "dawn_native/dawn_platform.h"
|
#include "dawn_native/dawn_platform.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace dawn_native {
|
namespace dawn_native {
|
||||||
@ -35,6 +36,12 @@ namespace dawn_native {
|
|||||||
std::vector<dawn::TextureUsageBit> textureUsages;
|
std::vector<dawn::TextureUsageBit> textureUsages;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CommandBufferResourceUsage {
|
||||||
|
std::vector<PassResourceUsage> perPass;
|
||||||
|
std::set<BufferBase*> topLevelBuffers;
|
||||||
|
std::set<TextureBase*> topLevelTextures;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace dawn_native
|
} // namespace dawn_native
|
||||||
|
|
||||||
#endif // DAWNNATIVE_PASSRESOURCEUSAGE_H
|
#endif // DAWNNATIVE_PASSRESOURCEUSAGE_H
|
||||||
|
@ -14,8 +14,10 @@
|
|||||||
|
|
||||||
#include "dawn_native/Queue.h"
|
#include "dawn_native/Queue.h"
|
||||||
|
|
||||||
|
#include "dawn_native/Buffer.h"
|
||||||
#include "dawn_native/CommandBuffer.h"
|
#include "dawn_native/CommandBuffer.h"
|
||||||
#include "dawn_native/Device.h"
|
#include "dawn_native/Device.h"
|
||||||
|
#include "dawn_native/Texture.h"
|
||||||
|
|
||||||
namespace dawn_native {
|
namespace dawn_native {
|
||||||
|
|
||||||
@ -32,7 +34,27 @@ namespace dawn_native {
|
|||||||
SubmitImpl(numCommands, commands);
|
SubmitImpl(numCommands, commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError QueueBase::ValidateSubmit(uint32_t, CommandBufferBase* const*) {
|
MaybeError QueueBase::ValidateSubmit(uint32_t numCommands, CommandBufferBase* const* commands) {
|
||||||
|
for (uint32_t i = 0; i < numCommands; ++i) {
|
||||||
|
const CommandBufferResourceUsage& usages = commands[i]->GetResourceUsages();
|
||||||
|
|
||||||
|
for (const PassResourceUsage& passUsages : usages.perPass) {
|
||||||
|
for (const BufferBase* buffer : passUsages.buffers) {
|
||||||
|
DAWN_TRY(buffer->ValidateCanUseInSubmitNow());
|
||||||
|
}
|
||||||
|
for (const TextureBase* texture : passUsages.textures) {
|
||||||
|
DAWN_TRY(texture->ValidateCanUseInSubmitNow());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const BufferBase* buffer : usages.topLevelBuffers) {
|
||||||
|
DAWN_TRY(buffer->ValidateCanUseInSubmitNow());
|
||||||
|
}
|
||||||
|
for (const TextureBase* texture : usages.topLevelTextures) {
|
||||||
|
DAWN_TRY(texture->ValidateCanUseInSubmitNow());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,6 +237,10 @@ namespace dawn_native {
|
|||||||
return mUsage;
|
return mUsage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaybeError TextureBase::ValidateCanUseInSubmitNow() const {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
TextureViewBase* TextureBase::CreateDefaultTextureView() {
|
TextureViewBase* TextureBase::CreateDefaultTextureView() {
|
||||||
TextureViewDescriptor descriptor = MakeDefaultTextureViewDescriptor(this);
|
TextureViewDescriptor descriptor = MakeDefaultTextureViewDescriptor(this);
|
||||||
return GetDevice()->CreateTextureView(this, &descriptor);
|
return GetDevice()->CreateTextureView(this, &descriptor);
|
||||||
|
@ -52,6 +52,8 @@ namespace dawn_native {
|
|||||||
uint32_t GetNumMipLevels() const;
|
uint32_t GetNumMipLevels() const;
|
||||||
dawn::TextureUsageBit GetUsage() const;
|
dawn::TextureUsageBit GetUsage() const;
|
||||||
|
|
||||||
|
MaybeError ValidateCanUseInSubmitNow() const;
|
||||||
|
|
||||||
// Dawn API
|
// Dawn API
|
||||||
TextureViewBase* CreateDefaultTextureView();
|
TextureViewBase* CreateDefaultTextureView();
|
||||||
TextureViewBase* CreateTextureView(const TextureViewDescriptor* descriptor);
|
TextureViewBase* CreateTextureView(const TextureViewDescriptor* descriptor);
|
||||||
|
@ -234,9 +234,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
CommandBuffer::CommandBuffer(CommandBufferBuilder* builder)
|
CommandBuffer::CommandBuffer(CommandBufferBuilder* builder)
|
||||||
: CommandBufferBase(builder),
|
: CommandBufferBase(builder), mCommands(builder->AcquireCommands()) {
|
||||||
mCommands(builder->AcquireCommands()),
|
|
||||||
mPassResourceUsages(builder->AcquirePassResourceUsage()) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandBuffer::~CommandBuffer() {
|
CommandBuffer::~CommandBuffer() {
|
||||||
@ -281,6 +279,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const std::vector<PassResourceUsage>& passResourceUsages = GetResourceUsages().perPass;
|
||||||
uint32_t nextPassNumber = 0;
|
uint32_t nextPassNumber = 0;
|
||||||
|
|
||||||
Command type;
|
Command type;
|
||||||
@ -289,7 +288,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
case Command::BeginComputePass: {
|
case Command::BeginComputePass: {
|
||||||
mCommands.NextCommand<BeginComputePassCmd>();
|
mCommands.NextCommand<BeginComputePassCmd>();
|
||||||
|
|
||||||
TransitionForPass(commandList, mPassResourceUsages[nextPassNumber]);
|
TransitionForPass(commandList, passResourceUsages[nextPassNumber]);
|
||||||
bindingTracker.SetInComputePass(true);
|
bindingTracker.SetInComputePass(true);
|
||||||
RecordComputePass(commandList, &bindingTracker);
|
RecordComputePass(commandList, &bindingTracker);
|
||||||
|
|
||||||
@ -300,7 +299,7 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
BeginRenderPassCmd* beginRenderPassCmd =
|
BeginRenderPassCmd* beginRenderPassCmd =
|
||||||
mCommands.NextCommand<BeginRenderPassCmd>();
|
mCommands.NextCommand<BeginRenderPassCmd>();
|
||||||
|
|
||||||
TransitionForPass(commandList, mPassResourceUsages[nextPassNumber]);
|
TransitionForPass(commandList, passResourceUsages[nextPassNumber]);
|
||||||
bindingTracker.SetInComputePass(false);
|
bindingTracker.SetInComputePass(false);
|
||||||
RecordRenderPass(commandList, &bindingTracker,
|
RecordRenderPass(commandList, &bindingTracker,
|
||||||
ToBackend(beginRenderPassCmd->info.Get()));
|
ToBackend(beginRenderPassCmd->info.Get()));
|
||||||
|
@ -42,7 +42,6 @@ namespace dawn_native { namespace d3d12 {
|
|||||||
RenderPassDescriptor* renderPass);
|
RenderPassDescriptor* renderPass);
|
||||||
|
|
||||||
CommandIterator mCommands;
|
CommandIterator mCommands;
|
||||||
std::vector<PassResourceUsage> mPassResourceUsages;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace dawn_native::d3d12
|
}} // namespace dawn_native::d3d12
|
||||||
|
@ -111,9 +111,7 @@ namespace dawn_native { namespace vulkan {
|
|||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
CommandBuffer::CommandBuffer(CommandBufferBuilder* builder)
|
CommandBuffer::CommandBuffer(CommandBufferBuilder* builder)
|
||||||
: CommandBufferBase(builder),
|
: CommandBufferBase(builder), mCommands(builder->AcquireCommands()) {
|
||||||
mCommands(builder->AcquireCommands()),
|
|
||||||
mPassResourceUsages(builder->AcquirePassResourceUsage()) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandBuffer::~CommandBuffer() {
|
CommandBuffer::~CommandBuffer() {
|
||||||
@ -135,6 +133,7 @@ namespace dawn_native { namespace vulkan {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const std::vector<PassResourceUsage>& passResourceUsages = GetResourceUsages().perPass;
|
||||||
size_t nextPassNumber = 0;
|
size_t nextPassNumber = 0;
|
||||||
|
|
||||||
Command type;
|
Command type;
|
||||||
@ -207,7 +206,7 @@ namespace dawn_native { namespace vulkan {
|
|||||||
case Command::BeginRenderPass: {
|
case Command::BeginRenderPass: {
|
||||||
BeginRenderPassCmd* cmd = mCommands.NextCommand<BeginRenderPassCmd>();
|
BeginRenderPassCmd* cmd = mCommands.NextCommand<BeginRenderPassCmd>();
|
||||||
|
|
||||||
TransitionForPass(commands, mPassResourceUsages[nextPassNumber]);
|
TransitionForPass(commands, passResourceUsages[nextPassNumber]);
|
||||||
RecordRenderPass(commands, ToBackend(cmd->info.Get()));
|
RecordRenderPass(commands, ToBackend(cmd->info.Get()));
|
||||||
|
|
||||||
nextPassNumber++;
|
nextPassNumber++;
|
||||||
@ -216,7 +215,7 @@ namespace dawn_native { namespace vulkan {
|
|||||||
case Command::BeginComputePass: {
|
case Command::BeginComputePass: {
|
||||||
mCommands.NextCommand<BeginComputePassCmd>();
|
mCommands.NextCommand<BeginComputePassCmd>();
|
||||||
|
|
||||||
TransitionForPass(commands, mPassResourceUsages[nextPassNumber]);
|
TransitionForPass(commands, passResourceUsages[nextPassNumber]);
|
||||||
RecordComputePass(commands);
|
RecordComputePass(commands);
|
||||||
|
|
||||||
nextPassNumber++;
|
nextPassNumber++;
|
||||||
|
@ -35,7 +35,6 @@ namespace dawn_native { namespace vulkan {
|
|||||||
void RecordRenderPass(VkCommandBuffer commands, RenderPassDescriptor* renderPass);
|
void RecordRenderPass(VkCommandBuffer commands, RenderPassDescriptor* renderPass);
|
||||||
|
|
||||||
CommandIterator mCommands;
|
CommandIterator mCommands;
|
||||||
std::vector<PassResourceUsage> mPassResourceUsages;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace dawn_native::vulkan
|
}} // namespace dawn_native::vulkan
|
||||||
|
@ -0,0 +1,69 @@
|
|||||||
|
// Copyright 2018 The Dawn Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "tests/unittests/validation/ValidationTest.h"
|
||||||
|
|
||||||
|
#include "utils/DawnHelpers.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class QueueSubmitValidationTest : public ValidationTest {
|
||||||
|
};
|
||||||
|
|
||||||
|
static void StoreTrueMapWriteCallback(dawnBufferMapAsyncStatus status, void*, dawnCallbackUserdata userdata) {
|
||||||
|
bool* userdataPtr = reinterpret_cast<bool*>(static_cast<intptr_t>(userdata));
|
||||||
|
*userdataPtr = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test submitting with a mapped buffer is disallowed
|
||||||
|
TEST_F(QueueSubmitValidationTest, SubmitWithMappedBuffer) {
|
||||||
|
// Create a map-write buffer.
|
||||||
|
dawn::BufferDescriptor descriptor;
|
||||||
|
descriptor.usage = dawn::BufferUsageBit::MapWrite | dawn::BufferUsageBit::TransferSrc;
|
||||||
|
descriptor.size = 4;
|
||||||
|
dawn::Buffer buffer = device.CreateBuffer(&descriptor);
|
||||||
|
|
||||||
|
// Create a fake copy destination buffer
|
||||||
|
descriptor.usage = dawn::BufferUsageBit::TransferDst;
|
||||||
|
dawn::Buffer targetBuffer = device.CreateBuffer(&descriptor);
|
||||||
|
|
||||||
|
// Create a command buffer that reads from the mappable buffer.
|
||||||
|
dawn::CommandBuffer commands;
|
||||||
|
{
|
||||||
|
dawn::RenderPassDescriptor renderpass = CreateSimpleRenderPass();
|
||||||
|
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
||||||
|
builder.CopyBufferToBuffer(buffer, 0, targetBuffer, 0, 4);
|
||||||
|
commands = builder.GetResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
dawn::Queue queue = device.CreateQueue();
|
||||||
|
|
||||||
|
// Submitting when the buffer has never been mapped should succeed
|
||||||
|
queue.Submit(1, &commands);
|
||||||
|
|
||||||
|
// Map the buffer, submitting when the buffer is mapped should fail
|
||||||
|
bool mapWriteFinished = false;
|
||||||
|
dawnCallbackUserdata userdata = static_cast<dawnCallbackUserdata>(reinterpret_cast<intptr_t>(&mapWriteFinished));
|
||||||
|
buffer.MapWriteAsync(0, 4, StoreTrueMapWriteCallback, userdata);
|
||||||
|
queue.Submit(0, nullptr);
|
||||||
|
ASSERT_TRUE(mapWriteFinished);
|
||||||
|
|
||||||
|
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
|
||||||
|
|
||||||
|
// Unmap the buffer, queue submit should succeed
|
||||||
|
buffer.Unmap();
|
||||||
|
queue.Submit(1, &commands);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
Loading…
x
Reference in New Issue
Block a user