Commit 65ee5168 by Jamie Madill Committed by Commit Bot

Vulkan: Align submit and serial management code.

This progresses the goal of merging TaskProcessor and CommandQueue. Moving the serial management out of RendererVk allows these classes to have finer control over when thread synchronization locks happen. Note: device lost handling seems untested currently. Bug: b/172704839 Change-Id: I0cc61e1ffe41aad0b898d4146c8dbd08a2cebd3c Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2525140 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com>
parent 453a113a
...@@ -76,11 +76,12 @@ class CommandProcessorTask ...@@ -76,11 +76,12 @@ class CommandProcessorTask
const Semaphore *semaphore, const Semaphore *semaphore,
egl::ContextPriority priority, egl::ContextPriority priority,
GarbageList &&currentGarbage, GarbageList &&currentGarbage,
ResourceUseList &&currentResources); Serial submitQueueSerial);
void initOneOffQueueSubmit(VkCommandBuffer oneOffCommandBufferVk, void initOneOffQueueSubmit(VkCommandBuffer oneOffCommandBufferVk,
egl::ContextPriority priority, egl::ContextPriority priority,
const Fence *fence); const Fence *fence,
Serial submitQueueSerial);
CommandProcessorTask &operator=(CommandProcessorTask &&rhs); CommandProcessorTask &operator=(CommandProcessorTask &&rhs);
...@@ -91,7 +92,6 @@ class CommandProcessorTask ...@@ -91,7 +92,6 @@ class CommandProcessorTask
void setQueueSerial(Serial serial) { mSerial = serial; } void setQueueSerial(Serial serial) { mSerial = serial; }
Serial getQueueSerial() const { return mSerial; } Serial getQueueSerial() const { return mSerial; }
ResourceUseList &getResourceUseList() { return mResourceUseList; }
CustomTask getTaskCommand() { return mTask; } CustomTask getTaskCommand() { return mTask; }
std::vector<VkSemaphore> &getWaitSemaphores() { return mWaitSemaphores; } std::vector<VkSemaphore> &getWaitSemaphores() { return mWaitSemaphores; }
std::vector<VkPipelineStageFlags> &getWaitSemaphoreStageMasks() std::vector<VkPipelineStageFlags> &getWaitSemaphoreStageMasks()
...@@ -123,7 +123,6 @@ class CommandProcessorTask ...@@ -123,7 +123,6 @@ class CommandProcessorTask
std::vector<VkPipelineStageFlags> mWaitSemaphoreStageMasks; std::vector<VkPipelineStageFlags> mWaitSemaphoreStageMasks;
const Semaphore *mSemaphore; const Semaphore *mSemaphore;
GarbageList mGarbage; GarbageList mGarbage;
ResourceUseList mResourceUseList;
// FinishToSerial & Flush command data // FinishToSerial & Flush command data
Serial mSerial; Serial mSerial;
...@@ -169,22 +168,30 @@ class CommandQueue final : angle::NonCopyable ...@@ -169,22 +168,30 @@ class CommandQueue final : angle::NonCopyable
~CommandQueue(); ~CommandQueue();
angle::Result init(Context *context); angle::Result init(Context *context);
void destroy(VkDevice device); void destroy(RendererVk *renderer);
void handleDeviceLost(RendererVk *renderer); void handleDeviceLost(RendererVk *renderer);
void clearAllGarbage(RendererVk *renderer); void clearAllGarbage(RendererVk *renderer);
angle::Result finishToSerial(Context *context, Serial finishSerial, uint64_t timeout); angle::Result finishToSerial(Context *context, Serial finishSerial, uint64_t timeout);
Serial reserveSubmitSerial();
angle::Result submitFrame(Context *context, angle::Result submitFrame(Context *context,
egl::ContextPriority priority, egl::ContextPriority priority,
const std::vector<VkSemaphore> &waitSemaphores, const std::vector<VkSemaphore> &waitSemaphores,
const std::vector<VkPipelineStageFlags> &waitSemaphoreStageMasks, const std::vector<VkPipelineStageFlags> &waitSemaphoreStageMasks,
const Semaphore *signalSemaphore, const Semaphore *signalSemaphore,
Shared<Fence> &&sharedFence, Shared<Fence> &&sharedFence,
ResourceUseList &&resourceList,
GarbageList &&currentGarbage, GarbageList &&currentGarbage,
CommandPool *commandPool); CommandPool *commandPool,
Serial submitQueueSerial);
angle::Result queueSubmit(Context *context,
egl::ContextPriority contextPriority,
const VkSubmitInfo &submitInfo,
const Fence *fence,
Serial submitQueueSerial);
angle::Result waitForSerialWithUserTimeout(vk::Context *context, angle::Result waitForSerialWithUserTimeout(vk::Context *context,
Serial serial, Serial serial,
...@@ -202,6 +209,10 @@ class CommandQueue final : angle::NonCopyable ...@@ -202,6 +209,10 @@ class CommandQueue final : angle::NonCopyable
const RenderPass &renderPass, const RenderPass &renderPass,
CommandBufferHelper *renderPassCommands); CommandBufferHelper *renderPassCommands);
ANGLE_INLINE Serial getLastSubmittedQueueSerial() const { return mLastSubmittedQueueSerial; }
ANGLE_INLINE Serial getLastCompletedQueueSerial() const { return mLastCompletedQueueSerial; }
ANGLE_INLINE Serial getCurrentQueueSerial() const { return mCurrentQueueSerial; }
private: private:
angle::Result releaseToCommandBatch(Context *context, angle::Result releaseToCommandBatch(Context *context,
PrimaryCommandBuffer &&commandBuffer, PrimaryCommandBuffer &&commandBuffer,
...@@ -222,6 +233,12 @@ class CommandQueue final : angle::NonCopyable ...@@ -222,6 +233,12 @@ class CommandQueue final : angle::NonCopyable
// Keeps a free list of reusable primary command buffers. // Keeps a free list of reusable primary command buffers.
PrimaryCommandBuffer mPrimaryCommands; PrimaryCommandBuffer mPrimaryCommands;
PersistentCommandPool mPrimaryCommandPool; PersistentCommandPool mPrimaryCommandPool;
// Queue serial management.
AtomicSerialFactory mQueueSerialFactory;
Serial mLastCompletedQueueSerial;
Serial mLastSubmittedQueueSerial;
Serial mCurrentQueueSerial;
}; };
class TaskProcessor : angle::NonCopyable class TaskProcessor : angle::NonCopyable
...@@ -249,11 +266,12 @@ class TaskProcessor : angle::NonCopyable ...@@ -249,11 +266,12 @@ class TaskProcessor : angle::NonCopyable
GarbageList *currentGarbage, GarbageList *currentGarbage,
CommandPool *commandPool, CommandPool *commandPool,
PrimaryCommandBuffer &&commandBuffer, PrimaryCommandBuffer &&commandBuffer,
const Serial &queueSerial); Serial submitQueueSerial);
angle::Result queueSubmit(Context *context, angle::Result queueSubmit(Context *context,
VkQueue queue, VkQueue queue,
const VkSubmitInfo &submitInfo, const VkSubmitInfo &submitInfo,
const Fence *fence); const Fence *fence,
Serial submitQueueSerial);
void handleDeviceLost(Context *context); void handleDeviceLost(Context *context);
...@@ -261,6 +279,12 @@ class TaskProcessor : angle::NonCopyable ...@@ -261,6 +279,12 @@ class TaskProcessor : angle::NonCopyable
VkResult getLastAndClearPresentResult(VkSwapchainKHR swapchain); VkResult getLastAndClearPresentResult(VkSwapchainKHR swapchain);
Serial reserveSubmitSerial();
ANGLE_INLINE Serial getLastSubmittedQueueSerial() const { return mLastSubmittedQueueSerial; }
ANGLE_INLINE Serial getLastCompletedQueueSerial() const { return mLastCompletedQueueSerial; }
ANGLE_INLINE Serial getCurrentQueueSerial() const { return mCurrentQueueSerial; }
private: private:
bool isValidWorkerThread(Context *context) const; bool isValidWorkerThread(Context *context) const;
...@@ -276,12 +300,19 @@ class TaskProcessor : angle::NonCopyable ...@@ -276,12 +300,19 @@ class TaskProcessor : angle::NonCopyable
PersistentCommandPool mPrimaryCommandPool; PersistentCommandPool mPrimaryCommandPool;
std::thread::id mThreadId; std::thread::id mThreadId;
// Queue serial management.
AtomicSerialFactory mQueueSerialFactory;
Serial mLastCompletedQueueSerial;
Serial mLastSubmittedQueueSerial;
Serial mCurrentQueueSerial;
// Track present info // Track present info
std::mutex mSwapchainStatusMutex; std::mutex mSwapchainStatusMutex;
std::condition_variable mSwapchainStatusCondition; std::condition_variable mSwapchainStatusCondition;
std::map<VkSwapchainKHR, VkResult> mSwapchainStatus; std::map<VkSwapchainKHR, VkResult> mSwapchainStatus;
}; };
// TODO(jmadill): Give this the same API as CommandQueue. b/172704839
class CommandProcessor : public Context class CommandProcessor : public Context
{ {
public: public:
...@@ -307,8 +338,11 @@ class CommandProcessor : public Context ...@@ -307,8 +338,11 @@ class CommandProcessor : public Context
// Used by main thread to wait for worker thread to complete all outstanding work. // Used by main thread to wait for worker thread to complete all outstanding work.
void waitForWorkComplete(Context *context); void waitForWorkComplete(Context *context);
Serial getLastCompletedQueueSerial();
Serial getLastSubmittedQueueSerial();
Serial getCurrentQueueSerial(); Serial getCurrentQueueSerial();
Serial getLastSubmittedSerial(); Serial reserveSubmitSerial();
// Wait until desired serial has been processed. // Wait until desired serial has been processed.
void finishToSerial(Context *context, Serial serial); void finishToSerial(Context *context, Serial serial);
...@@ -353,10 +387,7 @@ class CommandProcessor : public Context ...@@ -353,10 +387,7 @@ class CommandProcessor : public Context
PrimaryCommandBuffer mPrimaryCommandBuffer; PrimaryCommandBuffer mPrimaryCommandBuffer;
TaskProcessor mTaskProcessor; TaskProcessor mTaskProcessor;
AtomicSerialFactory mQueueSerialFactory; std::mutex mQueueSerialMutex;
std::mutex mCommandProcessorQueueSerialMutex;
Serial mCommandProcessorLastSubmittedSerial;
Serial mCommandProcessorCurrentQueueSerial;
mutable std::mutex mErrorMutex; mutable std::mutex mErrorMutex;
std::queue<Error> mErrors; std::queue<Error> mErrors;
......
...@@ -517,7 +517,7 @@ void ContextVk::onDestroy(const gl::Context *context) ...@@ -517,7 +517,7 @@ void ContextVk::onDestroy(const gl::Context *context)
mCommandPool.destroy(device); mCommandPool.destroy(device);
// This will clean up any outstanding buffer allocations // This will clean up any outstanding buffer allocations
(void)mRenderer->cleanupGarbage(false); (void)mRenderer->clearAllGarbage(this);
} }
angle::Result ContextVk::getIncompleteTexture(const gl::Context *context, angle::Result ContextVk::getIncompleteTexture(const gl::Context *context,
......
...@@ -47,7 +47,7 @@ void DisplayVk::terminate() ...@@ -47,7 +47,7 @@ void DisplayVk::terminate()
mRenderer->reloadVolkIfNeeded(); mRenderer->reloadVolkIfNeeded();
ASSERT(mRenderer); ASSERT(mRenderer);
mRenderer->onDestroy(); mRenderer->onDestroy(this);
} }
egl::Error DisplayVk::makeCurrent(egl::Display * /*display*/, egl::Error DisplayVk::makeCurrent(egl::Display * /*display*/,
......
...@@ -64,8 +64,6 @@ constexpr uint32_t kPipelineCacheVkUpdatePeriod = 60; ...@@ -64,8 +64,6 @@ constexpr uint32_t kPipelineCacheVkUpdatePeriod = 60;
// version of Vulkan. // version of Vulkan.
constexpr uint32_t kPreferredVulkanAPIVersion = VK_API_VERSION_1_1; constexpr uint32_t kPreferredVulkanAPIVersion = VK_API_VERSION_1_1;
constexpr bool kOutputVmaStatsString = false;
angle::vk::ICD ChooseICDFromAttribs(const egl::AttributeMap &attribs) angle::vk::ICD ChooseICDFromAttribs(const egl::AttributeMap &attribs)
{ {
#if !defined(ANGLE_PLATFORM_ANDROID) #if !defined(ANGLE_PLATFORM_ANDROID)
...@@ -465,8 +463,6 @@ RendererVk::RendererVk() ...@@ -465,8 +463,6 @@ RendererVk::RendererVk()
mMinImportedHostPointerAlignment(1), mMinImportedHostPointerAlignment(1),
mDefaultUniformBufferSize(kPreferredDefaultUniformBufferSize), mDefaultUniformBufferSize(kPreferredDefaultUniformBufferSize),
mDevice(VK_NULL_HANDLE), mDevice(VK_NULL_HANDLE),
mLastCompletedQueueSerial(mQueueSerialFactory.generate()),
mCurrentQueueSerial(mQueueSerialFactory.generate()),
mDeviceLost(false), mDeviceLost(false),
mPipelineCacheVkUpdateTimeout(kPipelineCacheVkUpdatePeriod), mPipelineCacheVkUpdateTimeout(kPipelineCacheVkUpdatePeriod),
mPipelineCacheDirty(false), mPipelineCacheDirty(false),
...@@ -504,15 +500,8 @@ void RendererVk::releaseSharedResources(vk::ResourceUseList *resourceList) ...@@ -504,15 +500,8 @@ void RendererVk::releaseSharedResources(vk::ResourceUseList *resourceList)
resourceList->releaseResourceUses(); resourceList->releaseResourceUses();
} }
void RendererVk::onDestroy() void RendererVk::onDestroy(vk::Context *context)
{ {
if (getFeatures().commandProcessor.enabled)
{
// Shutdown worker thread
mCommandProcessor.shutdown(&mCommandProcessorThread);
}
mCommandQueue.destroy(mDevice);
// Force all commands to finish by flushing all queues. // Force all commands to finish by flushing all queues.
for (VkQueue queue : mQueues) for (VkQueue queue : mQueues)
{ {
...@@ -522,13 +511,19 @@ void RendererVk::onDestroy() ...@@ -522,13 +511,19 @@ void RendererVk::onDestroy()
} }
} }
// Then assign an infinite "last completed" serial to force garbage to delete. if (getFeatures().commandProcessor.enabled)
{ {
std::lock_guard<std::mutex> lock(mQueueSerialMutex); // Shutdown worker thread
mLastCompletedQueueSerial = Serial::Infinite(); mCommandProcessor.shutdown(&mCommandProcessorThread);
}
else
{
std::lock_guard<std::mutex> lock(mCommandQueueMutex);
mCommandQueue.destroy(this);
} }
(void)cleanupGarbage(true); // Assigns an infinite "last completed" serial to force garbage to delete.
(void)cleanupGarbage(Serial::Infinite());
ASSERT(!hasSharedGarbage()); ASSERT(!hasSharedGarbage());
for (PendingOneOffCommands &pending : mPendingOneOffCommands) for (PendingOneOffCommands &pending : mPendingOneOffCommands)
...@@ -588,10 +583,6 @@ void RendererVk::onDestroy() ...@@ -588,10 +583,6 @@ void RendererVk::onDestroy()
void RendererVk::notifyDeviceLost() void RendererVk::notifyDeviceLost()
{ {
{
std::lock_guard<std::mutex> lock(mQueueSerialMutex);
mLastCompletedQueueSerial = getLastSubmittedQueueSerial();
}
mDeviceLost = true; mDeviceLost = true;
mDisplay->notifyDeviceLost(); mDisplay->notifyDeviceLost();
} }
...@@ -2242,38 +2233,6 @@ void RendererVk::outputVmaStatString() ...@@ -2242,38 +2233,6 @@ void RendererVk::outputVmaStatString()
mAllocator.freeStatsString(statsString); mAllocator.freeStatsString(statsString);
} }
angle::Result RendererVk::queueSubmit(vk::Context *context,
egl::ContextPriority priority,
const VkSubmitInfo &submitInfo,
vk::ResourceUseList &&resourceUseList,
const vk::Fence *fence,
Serial *serialOut)
{
if (kOutputVmaStatsString)
{
outputVmaStatString();
}
ASSERT(!getFeatures().commandProcessor.enabled);
{
std::lock_guard<decltype(mQueueMutex)> lock(mQueueMutex);
std::lock_guard<std::mutex> serialLock(mQueueSerialMutex);
VkFence handle = fence ? fence->getHandle() : VK_NULL_HANDLE;
ANGLE_VK_TRY(context, vkQueueSubmit(mQueues[priority], 1, &submitInfo, handle));
resourceUseList.releaseResourceUsesAndUpdateSerials(mCurrentQueueSerial);
*serialOut = mCurrentQueueSerial;
mLastSubmittedQueueSerial = mCurrentQueueSerial;
mCurrentQueueSerial = mQueueSerialFactory.generate();
}
ANGLE_TRY(cleanupGarbage(false));
return angle::Result::Continue;
}
angle::Result RendererVk::queueSubmitOneOff(vk::Context *context, angle::Result RendererVk::queueSubmitOneOff(vk::Context *context,
vk::PrimaryCommandBuffer &&primary, vk::PrimaryCommandBuffer &&primary,
egl::ContextPriority priority, egl::ContextPriority priority,
...@@ -2282,10 +2241,16 @@ angle::Result RendererVk::queueSubmitOneOff(vk::Context *context, ...@@ -2282,10 +2241,16 @@ angle::Result RendererVk::queueSubmitOneOff(vk::Context *context,
{ {
ANGLE_TRACE_EVENT0("gpu.angle", "RendererVk::queueSubmitOneOff"); ANGLE_TRACE_EVENT0("gpu.angle", "RendererVk::queueSubmitOneOff");
Serial submitQueueSerial;
if (getFeatures().commandProcessor.enabled) if (getFeatures().commandProcessor.enabled)
{ {
std::lock_guard<std::mutex> commandQueueLock(mCommandQueueMutex);
submitQueueSerial = mCommandProcessor.reserveSubmitSerial();
vk::CommandProcessorTask oneOffQueueSubmit; vk::CommandProcessorTask oneOffQueueSubmit;
oneOffQueueSubmit.initOneOffQueueSubmit(primary.getHandle(), priority, fence); oneOffQueueSubmit.initOneOffQueueSubmit(primary.getHandle(), priority, fence,
submitQueueSerial);
queueCommand(context, &oneOffQueueSubmit); queueCommand(context, &oneOffQueueSubmit);
// TODO: https://issuetracker.google.com/170312581 - should go away with improved fence // TODO: https://issuetracker.google.com/170312581 - should go away with improved fence
// management // management
...@@ -2293,20 +2258,32 @@ angle::Result RendererVk::queueSubmitOneOff(vk::Context *context, ...@@ -2293,20 +2258,32 @@ angle::Result RendererVk::queueSubmitOneOff(vk::Context *context,
{ {
waitForCommandProcessorIdle(context); waitForCommandProcessorIdle(context);
} }
*serialOut = getLastSubmittedQueueSerial();
} }
else else
{ {
VkSubmitInfo submitInfo = {}; std::lock_guard<std::mutex> commandQueueLock(mCommandQueueMutex);
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; std::lock_guard<std::mutex> queueLock(mQueueMutex);
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = primary.ptr();
VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
if (primary.valid())
{
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = primary.ptr();
}
submitQueueSerial = mCommandQueue.reserveSubmitSerial();
ANGLE_TRY( ANGLE_TRY(
queueSubmit(context, priority, submitInfo, vk::ResourceUseList(), fence, serialOut)); mCommandQueue.queueSubmit(context, priority, submitInfo, fence, submitQueueSerial));
} }
mPendingOneOffCommands.push_back({*serialOut, std::move(primary)}); *serialOut = submitQueueSerial;
if (primary.valid())
{
mPendingOneOffCommands.push_back({*serialOut, std::move(primary)});
}
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -2414,9 +2391,8 @@ bool RendererVk::hasFormatFeatureBits(VkFormat format, const VkFormatFeatureFlag ...@@ -2414,9 +2391,8 @@ bool RendererVk::hasFormatFeatureBits(VkFormat format, const VkFormatFeatureFlag
return IsMaskFlagSet(getFormatFeatureBits<features>(format, featureBits), featureBits); return IsMaskFlagSet(getFormatFeatureBits<features>(format, featureBits), featureBits);
} }
angle::Result RendererVk::cleanupGarbage(bool block) angle::Result RendererVk::cleanupGarbage(Serial lastCompletedQueueSerial)
{ {
Serial lastCompletedQueueSerial = getLastCompletedQueueSerial();
std::lock_guard<std::mutex> lock(mGarbageMutex); std::lock_guard<std::mutex> lock(mGarbageMutex);
for (auto garbageIter = mSharedGarbage.begin(); garbageIter != mSharedGarbage.end();) for (auto garbageIter = mSharedGarbage.begin(); garbageIter != mSharedGarbage.end();)
...@@ -2457,15 +2433,6 @@ uint64_t RendererVk::getMaxFenceWaitTimeNs() const ...@@ -2457,15 +2433,6 @@ uint64_t RendererVk::getMaxFenceWaitTimeNs() const
return kMaxFenceWaitTimeNs; return kMaxFenceWaitTimeNs;
} }
void RendererVk::onCompletedSerial(Serial serial)
{
std::lock_guard<std::mutex> lock(mQueueSerialMutex);
if (serial > mLastCompletedQueueSerial)
{
mLastCompletedQueueSerial = serial;
}
}
void RendererVk::setGlobalDebugAnnotator() void RendererVk::setGlobalDebugAnnotator()
{ {
// If the vkCmd*DebugUtilsLabelEXT functions exist, and if the kEnableDebugMarkersVarName // If the vkCmd*DebugUtilsLabelEXT functions exist, and if the kEnableDebugMarkersVarName
...@@ -2581,29 +2548,39 @@ angle::Result RendererVk::submitFrame(vk::Context *context, ...@@ -2581,29 +2548,39 @@ angle::Result RendererVk::submitFrame(vk::Context *context,
vk::GarbageList &&currentGarbage, vk::GarbageList &&currentGarbage,
vk::CommandPool *commandPool) vk::CommandPool *commandPool)
{ {
Serial submitQueueSerial;
if (mFeatures.commandProcessor.enabled) if (mFeatures.commandProcessor.enabled)
{ {
std::lock_guard<std::mutex> commandQueueLock(mCommandQueueMutex);
submitQueueSerial = mCommandProcessor.reserveSubmitSerial();
vk::CommandProcessorTask flushAndQueueSubmit; vk::CommandProcessorTask flushAndQueueSubmit;
flushAndQueueSubmit.initFlushAndQueueSubmit( flushAndQueueSubmit.initFlushAndQueueSubmit(
std::move(waitSemaphores), std::move(waitSemaphoreStageMasks), signalSemaphore, std::move(waitSemaphores), std::move(waitSemaphoreStageMasks), signalSemaphore,
contextPriority, std::move(currentGarbage), std::move(resourceUseList)); contextPriority, std::move(currentGarbage), submitQueueSerial);
commandProcessorSyncErrorsAndQueueCommand(context, &flushAndQueueSubmit); commandProcessorSyncErrorsAndQueueCommand(context, &flushAndQueueSubmit);
} }
else else
{ {
std::lock_guard<std::mutex> lock(mCommandQueueMutex); std::lock_guard<std::mutex> commandQueueLock(mCommandQueueMutex);
std::lock_guard<std::mutex> queueLock(mQueueMutex);
submitQueueSerial = mCommandQueue.reserveSubmitSerial();
vk::Shared<vk::Fence> submitFence; vk::Shared<vk::Fence> submitFence;
ANGLE_TRY(newSharedFence(context, &submitFence)); ANGLE_TRY(newSharedFence(context, &submitFence));
ANGLE_TRY(mCommandQueue.submitFrame(context, contextPriority, waitSemaphores, ANGLE_TRY(mCommandQueue.submitFrame(
waitSemaphoreStageMasks, signalSemaphore, context, contextPriority, waitSemaphores, waitSemaphoreStageMasks, signalSemaphore,
std::move(submitFence), std::move(resourceUseList), std::move(submitFence), std::move(currentGarbage), commandPool, submitQueueSerial));
std::move(currentGarbage), commandPool));
waitSemaphores.clear(); waitSemaphores.clear();
waitSemaphoreStageMasks.clear(); waitSemaphoreStageMasks.clear();
} }
resourceUseList.releaseResourceUsesAndUpdateSerials(submitQueueSerial);
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -2672,8 +2649,7 @@ angle::Result RendererVk::waitForSerialWithUserTimeout(vk::Context *context, ...@@ -2672,8 +2649,7 @@ angle::Result RendererVk::waitForSerialWithUserTimeout(vk::Context *context,
angle::Result RendererVk::finish(vk::Context *context) angle::Result RendererVk::finish(vk::Context *context)
{ {
ANGLE_TRY(finishToSerial(context, mLastSubmittedQueueSerial)); return finishToSerial(context, getLastSubmittedQueueSerial());
return angle::Result::Continue;
} }
angle::Result RendererVk::checkCompletedCommands(vk::Context *context) angle::Result RendererVk::checkCompletedCommands(vk::Context *context)
......
...@@ -83,7 +83,7 @@ class RendererVk : angle::NonCopyable ...@@ -83,7 +83,7 @@ class RendererVk : angle::NonCopyable
const char *wsiLayer); const char *wsiLayer);
// Reload volk vk* function ptrs if needed for an already initialized RendererVk // Reload volk vk* function ptrs if needed for an already initialized RendererVk
void reloadVolkIfNeeded() const; void reloadVolkIfNeeded() const;
void onDestroy(); void onDestroy(vk::Context *context);
void notifyDeviceLost(); void notifyDeviceLost();
bool isDeviceLost() const; bool isDeviceLost() const;
...@@ -172,12 +172,6 @@ class RendererVk : angle::NonCopyable ...@@ -172,12 +172,6 @@ class RendererVk : angle::NonCopyable
} }
// Queue submit that originates from the main thread // Queue submit that originates from the main thread
angle::Result queueSubmit(vk::Context *context,
egl::ContextPriority priority,
const VkSubmitInfo &submitInfo,
vk::ResourceUseList &&resourceList,
const vk::Fence *fence,
Serial *serialOut);
VkResult queuePresent(egl::ContextPriority priority, const VkPresentInfoKHR &presentInfo); VkResult queuePresent(egl::ContextPriority priority, const VkPresentInfoKHR &presentInfo);
// This command buffer should be submitted immediately via queueSubmitOneOff. // This command buffer should be submitted immediately via queueSubmitOneOff.
...@@ -246,26 +240,39 @@ class RendererVk : angle::NonCopyable ...@@ -246,26 +240,39 @@ class RendererVk : angle::NonCopyable
{ {
return mCommandProcessor.getCurrentQueueSerial(); return mCommandProcessor.getCurrentQueueSerial();
} }
std::lock_guard<std::mutex> lock(mQueueSerialMutex); else
return mCurrentQueueSerial; {
std::lock_guard<std::mutex> lock(mCommandQueueMutex);
return mCommandQueue.getCurrentQueueSerial();
}
} }
ANGLE_INLINE Serial getLastSubmittedQueueSerial() ANGLE_INLINE Serial getLastSubmittedQueueSerial()
{ {
if (getFeatures().commandProcessor.enabled) if (getFeatures().commandProcessor.enabled)
{ {
return mCommandProcessor.getLastSubmittedSerial(); return mCommandProcessor.getLastSubmittedQueueSerial();
}
else
{
std::lock_guard<std::mutex> lock(mCommandQueueMutex);
return mCommandQueue.getLastSubmittedQueueSerial();
} }
std::lock_guard<std::mutex> lock(mQueueSerialMutex);
return mLastSubmittedQueueSerial;
} }
ANGLE_INLINE Serial getLastCompletedQueueSerial() ANGLE_INLINE Serial getLastCompletedQueueSerial()
{ {
std::lock_guard<std::mutex> lock(mQueueSerialMutex); if (mFeatures.commandProcessor.enabled)
return mLastCompletedQueueSerial; {
return mCommandProcessor.getLastCompletedQueueSerial();
}
else
{
std::lock_guard<std::mutex> lock(mCommandQueueMutex);
return mCommandQueue.getLastCompletedQueueSerial();
}
} }
void onCompletedSerial(Serial serial);
VkResult getLastPresentResult(VkSwapchainKHR swapchain) VkResult getLastPresentResult(VkSwapchainKHR swapchain)
{ {
return mCommandProcessor.getLastPresentResult(swapchain); return mCommandProcessor.getLastPresentResult(swapchain);
...@@ -301,7 +308,7 @@ class RendererVk : angle::NonCopyable ...@@ -301,7 +308,7 @@ class RendererVk : angle::NonCopyable
void outputVmaStatString(); void outputVmaStatString();
angle::Result cleanupGarbage(bool block); angle::Result cleanupGarbage(Serial lastCompletedQueueSerial);
angle::Result submitFrame(vk::Context *context, angle::Result submitFrame(vk::Context *context,
egl::ContextPriority contextPriority, egl::ContextPriority contextPriority,
...@@ -396,14 +403,8 @@ class RendererVk : angle::NonCopyable ...@@ -396,14 +403,8 @@ class RendererVk : angle::NonCopyable
VkDeviceSize mMinImportedHostPointerAlignment; VkDeviceSize mMinImportedHostPointerAlignment;
uint32_t mDefaultUniformBufferSize; uint32_t mDefaultUniformBufferSize;
VkDevice mDevice; VkDevice mDevice;
AtomicSerialFactory mQueueSerialFactory;
AtomicSerialFactory mShaderSerialFactory; AtomicSerialFactory mShaderSerialFactory;
std::mutex mQueueSerialMutex;
Serial mLastCompletedQueueSerial;
Serial mLastSubmittedQueueSerial;
Serial mCurrentQueueSerial;
bool mDeviceLost; bool mDeviceLost;
std::mutex mFenceRecyclerMutex; std::mutex mFenceRecyclerMutex;
......
...@@ -202,28 +202,9 @@ angle::Result SyncHelperNativeFence::initializeWithFd(ContextVk *contextVk, int ...@@ -202,28 +202,9 @@ angle::Result SyncHelperNativeFence::initializeWithFd(ContextVk *contextVk, int
retain(&contextVk->getResourceUseList()); retain(&contextVk->getResourceUseList());
if (renderer->getFeatures().commandProcessor.enabled) Serial serialOut;
{ ANGLE_TRY(renderer->queueSubmitOneOff(contextVk, vk::PrimaryCommandBuffer(),
CommandProcessorTask oneOffQueueSubmit; contextVk->getPriority(), &fence.get(), &serialOut));
oneOffQueueSubmit.initOneOffQueueSubmit(VK_NULL_HANDLE, contextVk->getPriority(),
&fence.get());
renderer->queueCommand(contextVk, &oneOffQueueSubmit);
// TODO: https://issuetracker.google.com/170312581 - wait for now
if (renderer->getFeatures().asynchronousCommandProcessing.enabled)
{
ANGLE_TRACE_EVENT0("gpu.angle", "SyncHelperNativeFence::initializeWithFd");
renderer->waitForCommandProcessorIdle(contextVk);
}
}
else
{
Serial serialOut;
VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
ANGLE_TRY(renderer->queueSubmit(contextVk, contextVk->getPriority(), submitInfo,
vk::ResourceUseList(), &fence.get(), &serialOut));
}
VkFenceGetFdInfoKHR fenceGetFdInfo = {}; VkFenceGetFdInfoKHR fenceGetFdInfo = {};
fenceGetFdInfo.sType = VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR; fenceGetFdInfo.sType = VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR;
......
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