Add support for submitting command buffers from worker threads
This commit is contained in:
parent
9067d7529d
commit
83254204ff
5 changed files with 85 additions and 30 deletions
|
|
@ -731,6 +731,9 @@ public:
|
|||
|
||||
// API-dependent render interface
|
||||
|
||||
// Worker threads
|
||||
virtual void FlushCommands() { }
|
||||
|
||||
// Vertices
|
||||
virtual std::pair<FFlatVertex*, unsigned int> AllocVertices(unsigned int count) = 0;
|
||||
virtual void SetShadowData(const TArray<FFlatVertex>& vertices, const TArray<uint32_t>& indexes) = 0;
|
||||
|
|
|
|||
|
|
@ -71,24 +71,43 @@ VulkanCommandBuffer* VkCommandBufferManager::GetTransferCommands()
|
|||
{
|
||||
if (!mTransferCommands)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
mTransferCommands = mCommandPool->createBuffer();
|
||||
mTransferCommands->SetDebugName("VulkanRenderDevice.mTransferCommands");
|
||||
mTransferCommands->SetDebugName("TransferCommands");
|
||||
mTransferCommands->begin();
|
||||
}
|
||||
return mTransferCommands.get();
|
||||
}
|
||||
|
||||
VulkanCommandBuffer* VkCommandBufferManager::GetDrawCommands(int threadIndex)
|
||||
VulkanCommandBuffer* VkCommandBufferManager::GetDrawCommands()
|
||||
{
|
||||
if (!mDrawCommands)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
mDrawCommands = mCommandPool->createBuffer();
|
||||
mDrawCommands->SetDebugName("VulkanRenderDevice.mDrawCommands");
|
||||
mDrawCommands->SetDebugName("DrawCommands");
|
||||
mDrawCommands->begin();
|
||||
}
|
||||
return mDrawCommands.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<VulkanCommandBuffer> VkCommandBufferManager::BeginThreadCommands()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
auto commands = mCommandPool->createBuffer();
|
||||
commands->SetDebugName("ThreadCommands");
|
||||
lock.unlock();
|
||||
commands->begin();
|
||||
return commands;
|
||||
}
|
||||
|
||||
void VkCommandBufferManager::EndThreadCommands(std::unique_ptr<VulkanCommandBuffer> commands)
|
||||
{
|
||||
commands->end();
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
mThreadCommands.push_back(std::move(commands));
|
||||
}
|
||||
|
||||
void VkCommandBufferManager::BeginFrame()
|
||||
{
|
||||
if (mNextTimestampQuery > 0)
|
||||
|
|
@ -134,28 +153,37 @@ void VkCommandBufferManager::FlushCommands(bool finish, bool lastsubmit, bool up
|
|||
if (!uploadOnly)
|
||||
fb->GetRenderState()->EndRenderPass();
|
||||
|
||||
if ((!uploadOnly && mDrawCommands) || mTransferCommands)
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
|
||||
if (mTransferCommands)
|
||||
{
|
||||
VulkanCommandBuffer* commands[2];
|
||||
size_t count = 0;
|
||||
mTransferCommands->end();
|
||||
mFlushCommands.push_back(mTransferCommands.get());
|
||||
TransferDeleteList->Add(std::move(mTransferCommands));
|
||||
}
|
||||
|
||||
if (mTransferCommands)
|
||||
{
|
||||
mTransferCommands->end();
|
||||
commands[count++] = mTransferCommands.get();
|
||||
TransferDeleteList->Add(std::move(mTransferCommands));
|
||||
}
|
||||
|
||||
if (!uploadOnly && mDrawCommands)
|
||||
if (!uploadOnly)
|
||||
{
|
||||
if (mDrawCommands)
|
||||
{
|
||||
mDrawCommands->end();
|
||||
commands[count++] = mDrawCommands.get();
|
||||
mFlushCommands.push_back(mDrawCommands.get());
|
||||
DrawDeleteList->Add(std::move(mDrawCommands));
|
||||
}
|
||||
|
||||
FlushCommands(commands, count, finish, lastsubmit);
|
||||
for (auto& buffer : mThreadCommands)
|
||||
{
|
||||
mFlushCommands.push_back(buffer.get());
|
||||
DrawDeleteList->Add(std::move(buffer));
|
||||
}
|
||||
mThreadCommands.clear();
|
||||
}
|
||||
|
||||
current_rendered_commandbuffers += (int)count;
|
||||
if (!mFlushCommands.empty())
|
||||
{
|
||||
FlushCommands(mFlushCommands.data(), mFlushCommands.size(), finish, lastsubmit);
|
||||
current_rendered_commandbuffers += (int)mFlushCommands.size();
|
||||
mFlushCommands.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,10 @@ public:
|
|||
void BeginFrame();
|
||||
|
||||
VulkanCommandBuffer* GetTransferCommands();
|
||||
VulkanCommandBuffer* GetDrawCommands(int threadIndex = 0);
|
||||
VulkanCommandBuffer* GetDrawCommands();
|
||||
|
||||
std::unique_ptr<VulkanCommandBuffer> BeginThreadCommands();
|
||||
void EndThreadCommands(std::unique_ptr<VulkanCommandBuffer> commands);
|
||||
|
||||
void FlushCommands(bool finish, bool lastsubmit = false, bool uploadOnly = false);
|
||||
|
||||
|
|
@ -67,6 +70,7 @@ private:
|
|||
|
||||
std::unique_ptr<VulkanCommandBuffer> mTransferCommands;
|
||||
std::unique_ptr<VulkanCommandBuffer> mDrawCommands;
|
||||
std::vector<std::unique_ptr<VulkanCommandBuffer>> mThreadCommands;
|
||||
|
||||
enum { maxConcurrentSubmitCount = 8 };
|
||||
std::unique_ptr<VulkanSemaphore> mSubmitSemaphore[maxConcurrentSubmitCount];
|
||||
|
|
@ -86,4 +90,6 @@ private:
|
|||
int mNextTimestampQuery = 0;
|
||||
std::vector<size_t> mGroupStack;
|
||||
std::vector<TimestampQuery> timeElapsedQueries;
|
||||
std::mutex mMutex;
|
||||
std::vector<VulkanCommandBuffer*> mFlushCommands;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ void VkRenderState::Apply(int dt)
|
|||
drawcalls.Clock();
|
||||
|
||||
mApplyCount++;
|
||||
if (mApplyCount >= vk_submit_size)
|
||||
if (threadIndex == 0 && mApplyCount >= vk_submit_size)
|
||||
{
|
||||
fb->GetCommands()->FlushCommands(false);
|
||||
mApplyCount = 0;
|
||||
|
|
@ -310,7 +310,16 @@ void VkRenderState::ApplyRenderPass(int dt)
|
|||
|
||||
if (!inRenderPass)
|
||||
{
|
||||
mCommandBuffer = fb->GetCommands()->GetDrawCommands(threadIndex);
|
||||
if (threadIndex == 0)
|
||||
{
|
||||
mCommandBuffer = fb->GetCommands()->GetDrawCommands();
|
||||
}
|
||||
else
|
||||
{
|
||||
mThreadCommandBuffer = fb->GetCommands()->BeginThreadCommands();
|
||||
mCommandBuffer = mThreadCommandBuffer.get();
|
||||
}
|
||||
|
||||
mScissorChanged = true;
|
||||
mViewportChanged = true;
|
||||
mStencilRefChanged = true;
|
||||
|
|
@ -711,13 +720,18 @@ void VkRenderState::EndRenderPass()
|
|||
{
|
||||
mCommandBuffer->endRenderPass();
|
||||
mCommandBuffer = nullptr;
|
||||
mPipelineKey = {};
|
||||
|
||||
// Force rebind of all buffers
|
||||
mLastViewpointOffset = 0xffffffff;
|
||||
mLastVertexOffsets[0] = 0xffffffff;
|
||||
mIndexBufferNeedsBind = true;
|
||||
}
|
||||
|
||||
if (mThreadCommandBuffer)
|
||||
{
|
||||
fb->GetCommands()->EndThreadCommands(std::move(mThreadCommandBuffer));
|
||||
}
|
||||
|
||||
// Force rebind of everything on next draw
|
||||
mPipelineKey = {};
|
||||
mLastViewpointOffset = 0xffffffff;
|
||||
mLastVertexOffsets[0] = 0xffffffff;
|
||||
mIndexBufferNeedsBind = true;
|
||||
}
|
||||
|
||||
void VkRenderState::EndFrame()
|
||||
|
|
|
|||
|
|
@ -42,11 +42,6 @@ public:
|
|||
void EnableLineSmooth(bool on) override;
|
||||
void EnableDrawBuffers(int count, bool apply) override;
|
||||
|
||||
void BeginFrame();
|
||||
void SetRenderTarget(VkTextureImage *image, VulkanImageView *depthStencilView, int width, int height, VkFormat Format, VkSampleCountFlagBits samples);
|
||||
void EndRenderPass();
|
||||
void EndFrame();
|
||||
|
||||
// Buffers
|
||||
int SetViewpoint(const HWViewpointUniforms& vp) override;
|
||||
void SetViewpoint(int index) override;
|
||||
|
|
@ -61,6 +56,14 @@ public:
|
|||
void UpdateShadowData(unsigned int index, const FFlatVertex* vertices, unsigned int count) override;
|
||||
void ResetVertices() override;
|
||||
|
||||
// Worker threads
|
||||
void FlushCommands() override { EndRenderPass(); }
|
||||
|
||||
void BeginFrame();
|
||||
void SetRenderTarget(VkTextureImage* image, VulkanImageView* depthStencilView, int width, int height, VkFormat Format, VkSampleCountFlagBits samples);
|
||||
void EndRenderPass();
|
||||
void EndFrame();
|
||||
|
||||
protected:
|
||||
void Apply(int dt);
|
||||
void ApplyRenderPass(int dt);
|
||||
|
|
@ -144,6 +147,7 @@ protected:
|
|||
|
||||
std::map<VkRenderPassKey, std::unique_ptr<VkThreadRenderPassSetup>> mRenderPassSetups;
|
||||
std::vector<VulkanPipelineLayout*> mPipelineLayouts;
|
||||
std::unique_ptr<VulkanCommandBuffer> mThreadCommandBuffer;
|
||||
};
|
||||
|
||||
class VkThreadRenderPassSetup
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue