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; ...@@ -76,30 +76,20 @@ constexpr bool kEnableCommandGraphDiagnostics = false;
void InitializeSubmitInfo(VkSubmitInfo *submitInfo, void InitializeSubmitInfo(VkSubmitInfo *submitInfo,
const vk::PrimaryCommandBuffer &commandBuffer, const vk::PrimaryCommandBuffer &commandBuffer,
const vk::Semaphore *waitSemaphore, const std::vector<VkSemaphore> &waitSemaphores,
VkPipelineStageFlags *waitStageMask, 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->sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo->commandBufferCount = 1; submitInfo->commandBufferCount = 1;
submitInfo->pCommandBuffers = commandBuffer.ptr(); submitInfo->pCommandBuffers = commandBuffer.ptr();
if (waitSemaphore) submitInfo->waitSemaphoreCount = waitSemaphores.size();
{ submitInfo->pWaitSemaphores = waitSemaphores.data();
submitInfo->waitSemaphoreCount = 1; submitInfo->pWaitDstStageMask = waitStageMask;
submitInfo->pWaitSemaphores = waitSemaphore->ptr();
submitInfo->pWaitDstStageMask = waitStageMask;
}
if (signalSemaphore) submitInfo->signalSemaphoreCount = signalSemaphores.size();
{ submitInfo->pSignalSemaphores = signalSemaphores.data();
submitInfo->signalSemaphoreCount = 1;
submitInfo->pSignalSemaphores = signalSemaphore->ptr();
}
} }
} // anonymous namespace } // anonymous namespace
...@@ -310,7 +300,7 @@ angle::Result ContextVk::initialize() ...@@ -310,7 +300,7 @@ angle::Result ContextVk::initialize()
// Calculate the difference between CPU and GPU clocks for GPU event reporting. // Calculate the difference between CPU and GPU clocks for GPU event reporting.
ANGLE_TRY(mGpuEventQueryPool.init(this, VK_QUERY_TYPE_TIMESTAMP, ANGLE_TRY(mGpuEventQueryPool.init(this, VK_QUERY_TYPE_TIMESTAMP,
vk::kDefaultTimestampQueryPoolSize)); vk::kDefaultTimestampQueryPoolSize));
ANGLE_TRY(synchronizeCpuGpuTime(nullptr, nullptr)); ANGLE_TRY(synchronizeCpuGpuTime());
} }
return angle::Result::Continue; return angle::Result::Continue;
...@@ -679,8 +669,7 @@ angle::Result ContextVk::flushCommandGraph(vk::PrimaryCommandBuffer *commandBatc ...@@ -679,8 +669,7 @@ angle::Result ContextVk::flushCommandGraph(vk::PrimaryCommandBuffer *commandBatc
commandBatch); commandBatch);
} }
angle::Result ContextVk::synchronizeCpuGpuTime(const vk::Semaphore *waitSemaphore, angle::Result ContextVk::synchronizeCpuGpuTime()
const vk::Semaphore *signalSemaphore)
{ {
ASSERT(mGpuEventsEnabled); ASSERT(mGpuEventsEnabled);
...@@ -822,8 +811,8 @@ angle::Result ContextVk::synchronizeCpuGpuTime(const vk::Semaphore *waitSemaphor ...@@ -822,8 +811,8 @@ angle::Result ContextVk::synchronizeCpuGpuTime(const vk::Semaphore *waitSemaphor
// Submit the command buffer // Submit the command buffer
VkSubmitInfo submitInfo = {}; VkSubmitInfo submitInfo = {};
VkPipelineStageFlags waitMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; VkPipelineStageFlags waitMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
InitializeSubmitInfo(&submitInfo, commandBatch.get(), waitSemaphore, &waitMask, InitializeSubmitInfo(&submitInfo, commandBatch.get(), {}, &waitMask,
signalSemaphore); {});
ANGLE_TRY(submitFrame(submitInfo, std::move(commandBuffer))); ANGLE_TRY(submitFrame(submitInfo, std::move(commandBuffer)));
...@@ -1991,21 +1980,18 @@ angle::Result ContextVk::flushImpl() ...@@ -1991,21 +1980,18 @@ angle::Result ContextVk::flushImpl()
vk::Scoped<vk::PrimaryCommandBuffer> commandBatch(getDevice()); vk::Scoped<vk::PrimaryCommandBuffer> commandBatch(getDevice());
ANGLE_TRY(flushCommandGraph(&commandBatch.get())); ANGLE_TRY(flushCommandGraph(&commandBatch.get()));
const vk::Semaphore *waitSemaphore = nullptr; SignalSemaphoreVector signalSemaphores;
const vk::Semaphore *signalSemaphore = nullptr; ANGLE_TRY(generateSurfaceSemaphores(&signalSemaphores));
if (mCurrentWindowSurface)
{
ANGLE_TRY(mCurrentWindowSurface->generateSemaphoresForFlush(this, &waitSemaphore,
&signalSemaphore));
}
VkSubmitInfo submitInfo = {}; VkSubmitInfo submitInfo = {};
VkPipelineStageFlags waitMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; VkPipelineStageFlags waitMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
InitializeSubmitInfo(&submitInfo, commandBatch.get(), waitSemaphore, &waitMask, InitializeSubmitInfo(&submitInfo, commandBatch.get(), mWaitSemaphores, &waitMask,
signalSemaphore); signalSemaphores);
ANGLE_TRY(submitFrame(submitInfo, commandBatch.release())); ANGLE_TRY(submitFrame(submitInfo, commandBatch.release()));
mWaitSemaphores.clear();
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -2030,7 +2016,7 @@ angle::Result ContextVk::finishImpl() ...@@ -2030,7 +2016,7 @@ angle::Result ContextVk::finishImpl()
// multiple times towards the end of the application). // multiple times towards the end of the application).
if (mGpuEvents.size() > 0) if (mGpuEvents.size() > 0)
{ {
ANGLE_TRY(synchronizeCpuGpuTime(nullptr, nullptr)); ANGLE_TRY(synchronizeCpuGpuTime());
} }
} }
...@@ -2325,4 +2311,21 @@ angle::Result ContextVk::updateDefaultAttribute(size_t attribIndex) ...@@ -2325,4 +2311,21 @@ angle::Result ContextVk::updateDefaultAttribute(size_t attribIndex)
return angle::Result::Continue; 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 } // namespace rx
...@@ -369,8 +369,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff ...@@ -369,8 +369,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff
void freeAllInFlightResources(); void freeAllInFlightResources();
angle::Result flushCommandGraph(vk::PrimaryCommandBuffer *commandBatch); angle::Result flushCommandGraph(vk::PrimaryCommandBuffer *commandBatch);
angle::Result synchronizeCpuGpuTime(const vk::Semaphore *waitSemaphore, angle::Result synchronizeCpuGpuTime();
const vk::Semaphore *signalSemaphore);
angle::Result traceGpuEventImpl(vk::PrimaryCommandBuffer *commandBuffer, angle::Result traceGpuEventImpl(vk::PrimaryCommandBuffer *commandBuffer,
char phase, char phase,
const char *name); const char *name);
...@@ -379,6 +378,8 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff ...@@ -379,6 +378,8 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff
void handleDeviceLost(); void handleDeviceLost();
angle::Result generateSurfaceSemaphores(SignalSemaphoreVector *signalSemaphores);
vk::PipelineHelper *mCurrentPipeline; vk::PipelineHelper *mCurrentPipeline;
gl::PrimitiveMode mCurrentDrawMode; gl::PrimitiveMode mCurrentDrawMode;
...@@ -533,6 +534,9 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff ...@@ -533,6 +534,9 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::CommandBuff
// A list of gpu events since the last clock sync. // A list of gpu events since the last clock sync.
std::vector<GpuEvent> mGpuEvents; 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. // Hold information from the last gpu clock sync for future gpu-to-cpu timestamp conversions.
struct GpuClockSyncInfo struct GpuClockSyncInfo
{ {
......
...@@ -41,6 +41,10 @@ namespace vk ...@@ -41,6 +41,10 @@ namespace vk
struct Format; struct Format;
} }
// Supports one semaphore from current surface, and one semaphore passed to
// glSignalSemaphoreEXT.
using SignalSemaphoreVector = angle::FixedVector<VkSemaphore, 2>;
class RendererVk : angle::NonCopyable class RendererVk : angle::NonCopyable
{ {
public: public:
......
...@@ -25,6 +25,8 @@ class SemaphoreVk : public SemaphoreImpl ...@@ -25,6 +25,8 @@ class SemaphoreVk : public SemaphoreImpl
angle::Result importFd(gl::Context *context, gl::HandleType handleType, GLint fd) override; angle::Result importFd(gl::Context *context, gl::HandleType handleType, GLint fd) override;
VkSemaphore getHandle() const { return mSemaphore.getHandle(); }
private: private:
angle::Result importOpaqueFd(gl::Context *context, GLint fd); 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