Commit a6242e4d by Michael Spang Committed by Commit Bot

Vulkan: Support submitting multiple semaphores

With GL_EXT_semaphore, the client can create and submit semaphores to synchronize with an external vulkan instance. We need to be able to submit semaphores from both the current surface as well as the client. In order to support glWaitSemaphoreEXT, make ContextVk hold a vector of semaphores that will be submitted with the next batch. In order to support glSignalSemaphoreEXT, make ContextVk::flush() build a vector of semaphores to submit, rather than just one. Submissions that result from a client signal operation will need to signal both the client semaphore as well as a semaphore from the surface's semaphore chain. Bug: angleproject:3289 Change-Id: I52b07c4c2a7bf52300d3107f028aa64585c6c4db Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1623814 Commit-Queue: Michael Spang <spang@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 2008c8ff
......@@ -76,30 +76,20 @@ constexpr bool kEnableCommandGraphDiagnostics = false;
void InitializeSubmitInfo(VkSubmitInfo *submitInfo,
const vk::PrimaryCommandBuffer &commandBuffer,
const vk::Semaphore *waitSemaphore,
const std::vector<VkSemaphore> &waitSemaphores,
VkPipelineStageFlags *waitStageMask,
const vk::Semaphore *signalSemaphore)
const SignalSemaphoreVector &signalSemaphores)
{
// Verify that the submitInfo has been zero'd out.
ASSERT(submitInfo->waitSemaphoreCount == 0);
ASSERT(submitInfo->signalSemaphoreCount == 0);
submitInfo->sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo->commandBufferCount = 1;
submitInfo->pCommandBuffers = commandBuffer.ptr();
if (waitSemaphore)
{
submitInfo->waitSemaphoreCount = 1;
submitInfo->pWaitSemaphores = waitSemaphore->ptr();
submitInfo->pWaitDstStageMask = waitStageMask;
}
submitInfo->waitSemaphoreCount = waitSemaphores.size();
submitInfo->pWaitSemaphores = waitSemaphores.data();
submitInfo->pWaitDstStageMask = waitStageMask;
if (signalSemaphore)
{
submitInfo->signalSemaphoreCount = 1;
submitInfo->pSignalSemaphores = signalSemaphore->ptr();
}
submitInfo->signalSemaphoreCount = signalSemaphores.size();
submitInfo->pSignalSemaphores = signalSemaphores.data();
}
} // anonymous namespace
......@@ -310,7 +300,7 @@ angle::Result ContextVk::initialize()
// Calculate the difference between CPU and GPU clocks for GPU event reporting.
ANGLE_TRY(mGpuEventQueryPool.init(this, VK_QUERY_TYPE_TIMESTAMP,
vk::kDefaultTimestampQueryPoolSize));
ANGLE_TRY(synchronizeCpuGpuTime(nullptr, nullptr));
ANGLE_TRY(synchronizeCpuGpuTime());
}
return angle::Result::Continue;
......@@ -679,8 +669,7 @@ angle::Result ContextVk::flushCommandGraph(vk::PrimaryCommandBuffer *commandBatc
commandBatch);
}
angle::Result ContextVk::synchronizeCpuGpuTime(const vk::Semaphore *waitSemaphore,
const vk::Semaphore *signalSemaphore)
angle::Result ContextVk::synchronizeCpuGpuTime()
{
ASSERT(mGpuEventsEnabled);
......@@ -822,8 +811,8 @@ angle::Result ContextVk::synchronizeCpuGpuTime(const vk::Semaphore *waitSemaphor
// Submit the command buffer
VkSubmitInfo submitInfo = {};
VkPipelineStageFlags waitMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
InitializeSubmitInfo(&submitInfo, commandBatch.get(), waitSemaphore, &waitMask,
signalSemaphore);
InitializeSubmitInfo(&submitInfo, commandBatch.get(), {}, &waitMask,
{});
ANGLE_TRY(submitFrame(submitInfo, std::move(commandBuffer)));
......@@ -1991,21 +1980,18 @@ angle::Result ContextVk::flushImpl()
vk::Scoped<vk::PrimaryCommandBuffer> commandBatch(getDevice());
ANGLE_TRY(flushCommandGraph(&commandBatch.get()));
const vk::Semaphore *waitSemaphore = nullptr;
const vk::Semaphore *signalSemaphore = nullptr;
if (mCurrentWindowSurface)
{
ANGLE_TRY(mCurrentWindowSurface->generateSemaphoresForFlush(this, &waitSemaphore,
&signalSemaphore));
}
SignalSemaphoreVector signalSemaphores;
ANGLE_TRY(generateSurfaceSemaphores(&signalSemaphores));
VkSubmitInfo submitInfo = {};
VkPipelineStageFlags waitMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
InitializeSubmitInfo(&submitInfo, commandBatch.get(), waitSemaphore, &waitMask,
signalSemaphore);
InitializeSubmitInfo(&submitInfo, commandBatch.get(), mWaitSemaphores, &waitMask,
signalSemaphores);
ANGLE_TRY(submitFrame(submitInfo, commandBatch.release()));
mWaitSemaphores.clear();
return angle::Result::Continue;
}
......@@ -2030,7 +2016,7 @@ angle::Result ContextVk::finishImpl()
// multiple times towards the end of the application).
if (mGpuEvents.size() > 0)
{
ANGLE_TRY(synchronizeCpuGpuTime(nullptr, nullptr));
ANGLE_TRY(synchronizeCpuGpuTime());
}
}
......@@ -2325,4 +2311,21 @@ angle::Result ContextVk::updateDefaultAttribute(size_t attribIndex)
return angle::Result::Continue;
}
angle::Result ContextVk::generateSurfaceSemaphores(SignalSemaphoreVector *signalSemaphores)
{
if (mCurrentWindowSurface && !mCommandGraph.empty())
{
const vk::Semaphore *waitSemaphore = nullptr;
const vk::Semaphore *signalSemaphore = nullptr;
ANGLE_TRY(mCurrentWindowSurface->generateSemaphoresForFlush(this, &waitSemaphore,
&signalSemaphore));
mWaitSemaphores.push_back(waitSemaphore->getHandle());
ASSERT(signalSemaphores->empty());
signalSemaphores->push_back(signalSemaphore->getHandle());
}
return angle::Result::Continue;
}
} // namespace rx
......@@ -369,8 +369,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff
void freeAllInFlightResources();
angle::Result flushCommandGraph(vk::PrimaryCommandBuffer *commandBatch);
angle::Result synchronizeCpuGpuTime(const vk::Semaphore *waitSemaphore,
const vk::Semaphore *signalSemaphore);
angle::Result synchronizeCpuGpuTime();
angle::Result traceGpuEventImpl(vk::PrimaryCommandBuffer *commandBuffer,
char phase,
const char *name);
......@@ -379,6 +378,8 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff
void handleDeviceLost();
angle::Result generateSurfaceSemaphores(SignalSemaphoreVector *signalSemaphores);
vk::PipelineHelper *mCurrentPipeline;
gl::PrimitiveMode mCurrentDrawMode;
......@@ -533,6 +534,9 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff
// A list of gpu events since the last clock sync.
std::vector<GpuEvent> mGpuEvents;
// Semaphores that must be waited on in the next submission.
std::vector<VkSemaphore> mWaitSemaphores;
// Hold information from the last gpu clock sync for future gpu-to-cpu timestamp conversions.
struct GpuClockSyncInfo
{
......
......@@ -41,6 +41,10 @@ namespace vk
struct Format;
}
// Supports one semaphore from current surface, and one semaphore passed to
// glSignalSemaphoreEXT.
using SignalSemaphoreVector = angle::FixedVector<VkSemaphore, 2>;
class RendererVk : angle::NonCopyable
{
public:
......
......@@ -25,6 +25,8 @@ class SemaphoreVk : public SemaphoreImpl
angle::Result importFd(gl::Context *context, gl::HandleType handleType, GLint fd) override;
VkSemaphore getHandle() const { return mSemaphore.getHandle(); }
private:
angle::Result importOpaqueFd(gl::Context *context, GLint fd);
......
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