Commit 83c24aa8 by Jamie Madill Committed by Commit Bot

Vulkan: Reference Context fences in FenceSyncVk.

A particular test waits on a fence that was created in another Context. Then it immediately destroys all other resources. This triggered a bug where the VkEvent corresponding to the FenceSync was deleted while it was still in use by a command buffer. Fix this by referencing the other submit fence of the second ContextVk in the FenceSync class. Bug: angleproject:2464 Change-Id: I4ef096bf760aa8943db08d491006c68e36db993b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1757505Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 0aa11026
...@@ -28,7 +28,10 @@ void FenceSyncVk::onDestroy(ContextVk *contextVk) ...@@ -28,7 +28,10 @@ void FenceSyncVk::onDestroy(ContextVk *contextVk)
contextVk->releaseObject(contextVk->getCurrentQueueSerial(), &mEvent); contextVk->releaseObject(contextVk->getCurrentQueueSerial(), &mEvent);
} }
mFence.reset(contextVk->getDevice()); for (vk::Shared<vk::Fence> &fence : mFences)
{
fence.reset(contextVk->getDevice());
}
} }
void FenceSyncVk::onDestroy(DisplayVk *display) void FenceSyncVk::onDestroy(DisplayVk *display)
...@@ -36,7 +39,7 @@ void FenceSyncVk::onDestroy(DisplayVk *display) ...@@ -36,7 +39,7 @@ void FenceSyncVk::onDestroy(DisplayVk *display)
std::vector<vk::GarbageObjectBase> garbage; std::vector<vk::GarbageObjectBase> garbage;
mEvent.dumpResources(&garbage); mEvent.dumpResources(&garbage);
display->getRenderer()->addGarbage(std::move(mFence), std::move(garbage)); display->getRenderer()->addGarbage(std::move(mFences), std::move(garbage));
} }
angle::Result FenceSyncVk::initialize(ContextVk *contextVk) angle::Result FenceSyncVk::initialize(ContextVk *contextVk)
...@@ -53,9 +56,11 @@ angle::Result FenceSyncVk::initialize(ContextVk *contextVk) ...@@ -53,9 +56,11 @@ angle::Result FenceSyncVk::initialize(ContextVk *contextVk)
vk::Scoped<vk::Event> event(device); vk::Scoped<vk::Event> event(device);
ANGLE_VK_TRY(contextVk, event.get().init(device, eventCreateInfo)); ANGLE_VK_TRY(contextVk, event.get().init(device, eventCreateInfo));
ANGLE_TRY(contextVk->getNextSubmitFence(&mFence)); vk::Shared<vk::Fence> fence;
ANGLE_TRY(contextVk->getNextSubmitFence(&fence));
mEvent = event.release(); mEvent = event.release();
mFences.emplace_back(std::move(fence));
contextVk->getCommandGraph()->setFenceSync(mEvent); contextVk->getCommandGraph()->setFenceSync(mEvent);
return angle::Result::Continue; return angle::Result::Continue;
...@@ -91,8 +96,9 @@ angle::Result FenceSyncVk::clientWait(vk::Context *context, ...@@ -91,8 +96,9 @@ angle::Result FenceSyncVk::clientWait(vk::Context *context,
} }
// Wait on the fence that's expected to be signaled on the first vkQueueSubmit after // Wait on the fence that's expected to be signaled on the first vkQueueSubmit after
// `initialize` was called. // `initialize` was called. The first fence is the fence created to signal this sync.
VkResult status = mFence.get().wait(renderer->getDevice(), timeout); ASSERT(!mFences.empty());
VkResult status = mFences[0].get().wait(renderer->getDevice(), timeout);
// Check for errors, but don't consider timeout as such. // Check for errors, but don't consider timeout as such.
if (status != VK_TIMEOUT) if (status != VK_TIMEOUT)
...@@ -109,6 +115,11 @@ angle::Result FenceSyncVk::serverWait(vk::Context *context, ContextVk *contextVk ...@@ -109,6 +115,11 @@ angle::Result FenceSyncVk::serverWait(vk::Context *context, ContextVk *contextVk
if (contextVk) if (contextVk)
{ {
contextVk->getCommandGraph()->waitFenceSync(mEvent); contextVk->getCommandGraph()->waitFenceSync(mEvent);
// Track fences from Contexts that use this sync for garbage collection.
vk::Shared<vk::Fence> nextSubmitFence;
ANGLE_TRY(contextVk->getNextSubmitFence(&nextSubmitFence));
mFences.emplace_back(std::move(nextSubmitFence));
} }
return angle::Result::Continue; return angle::Result::Continue;
} }
......
...@@ -46,9 +46,9 @@ class FenceSyncVk ...@@ -46,9 +46,9 @@ class FenceSyncVk
// The vkEvent that's signaled on `init` and can be waited on in `serverWait`, or queried with // The vkEvent that's signaled on `init` and can be waited on in `serverWait`, or queried with
// `getStatus`. // `getStatus`.
vk::Event mEvent; vk::Event mEvent;
// The vkFence that's signaled once the command buffer including the `init` signal is executed. // The first fence in the list is signaled once the CB including the `init` signal is executed.
// `clientWait` waits on this fence. // `clientWait` waits on this fence. The other fences are referenced to prevent deletion.
vk::Shared<vk::Fence> mFence; std::vector<vk::Shared<vk::Fence>> mFences;
}; };
class SyncVk final : public SyncImpl class SyncVk final : public SyncImpl
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment