- add vk_submit_multithread for doing command buffer submit calls on a worker thread
- add vk_submit_size for testing various command buffer sizes before flushing them - add submitted command buffer count to renderstats
This commit is contained in:
parent
3957a19bd0
commit
458da39c39
4 changed files with 121 additions and 22 deletions
|
|
@ -68,7 +68,11 @@ EXTERN_CVAR(Int, screenblocks)
|
|||
EXTERN_CVAR(Bool, cl_capfps)
|
||||
EXTERN_CVAR(Bool, gl_no_skyclear)
|
||||
|
||||
CVAR(Bool, vk_submit_multithread, false, 0)
|
||||
|
||||
extern bool NoInterpolateView;
|
||||
extern int rendered_commandbuffers;
|
||||
int current_rendered_commandbuffers;
|
||||
|
||||
VulkanFrameBuffer::VulkanFrameBuffer(void *hMonitor, bool fullscreen, VulkanDevice *dev) :
|
||||
Super(hMonitor, fullscreen)
|
||||
|
|
@ -91,6 +95,8 @@ VulkanFrameBuffer::VulkanFrameBuffer(void *hMonitor, bool fullscreen, VulkanDevi
|
|||
|
||||
VulkanFrameBuffer::~VulkanFrameBuffer()
|
||||
{
|
||||
StopSubmitThread();
|
||||
|
||||
// All descriptors must be destroyed before the descriptor pool in renderpass manager is destroyed
|
||||
for (VkHardwareTexture *cur = VkHardwareTexture::First; cur; cur = cur->Next)
|
||||
cur->Reset();
|
||||
|
|
@ -189,42 +195,112 @@ void VulkanFrameBuffer::DeleteFrameObjects()
|
|||
FrameDeleteList.CommandBuffers.clear();
|
||||
}
|
||||
|
||||
void VulkanFrameBuffer::StartSubmitThread()
|
||||
{
|
||||
if (!mSubmitThread.joinable())
|
||||
{
|
||||
mSubmitThread = std::thread([this] { SubmitThreadMain(); });
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanFrameBuffer::StopSubmitThread()
|
||||
{
|
||||
if (mSubmitThread.joinable())
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mSubmitMutex);
|
||||
mSubmitExitFlag = true;
|
||||
lock.unlock();
|
||||
mSubmitCondVar.notify_all();
|
||||
mSubmitThread.join();
|
||||
mSubmitThread = {};
|
||||
lock.lock();
|
||||
mSubmitExitFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanFrameBuffer::SubmitThreadMain()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mSubmitMutex);
|
||||
mSubmitCondVar.wait(lock, [&]() { return mSubmitExitFlag || !mSubmitQueue.empty(); });
|
||||
|
||||
std::vector<VulkanCommandBuffer*> commands;
|
||||
commands.swap(mSubmitQueue);
|
||||
mSubmitItemsActive = commands.size();
|
||||
lock.unlock();
|
||||
|
||||
FlushCommands(commands.data(), commands.size());
|
||||
|
||||
lock.lock();
|
||||
mSubmitItemsActive = 0;
|
||||
if (mSubmitQueue.empty())
|
||||
mSubmitDone.notify_all();
|
||||
if (mSubmitExitFlag)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanFrameBuffer::FlushCommands(VulkanCommandBuffer **commands, size_t count)
|
||||
{
|
||||
int currentIndex = nextSubmitQueue % submitQueueSize;
|
||||
|
||||
if (nextSubmitQueue >= submitQueueSize)
|
||||
{
|
||||
vkWaitForFences(device->device, 1, &mSubmitFence[currentIndex]->fence, VK_TRUE, std::numeric_limits<uint64_t>::max());
|
||||
vkResetFences(device->device, 1, &mSubmitFence[currentIndex]->fence);
|
||||
}
|
||||
|
||||
QueueSubmit submit;
|
||||
|
||||
for (size_t i = 0; i < count; i++)
|
||||
submit.addCommandBuffer(commands[i]);
|
||||
|
||||
if (nextSubmitQueue > 0)
|
||||
submit.addWait(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, mSubmitSemaphore[(nextSubmitQueue - 1) % submitQueueSize].get());
|
||||
|
||||
submit.addSignal(mSubmitSemaphore[currentIndex].get());
|
||||
submit.execute(device, device->graphicsQueue, mSubmitFence[currentIndex].get());
|
||||
nextSubmitQueue++;
|
||||
}
|
||||
|
||||
void VulkanFrameBuffer::FlushCommands()
|
||||
{
|
||||
if (mDrawCommands || mTransferCommands)
|
||||
{
|
||||
int currentIndex = nextSubmitQueue % submitQueueSize;
|
||||
|
||||
if (nextSubmitQueue >= submitQueueSize)
|
||||
{
|
||||
vkWaitForFences(device->device, 1, &mSubmitFence[currentIndex]->fence, VK_TRUE, std::numeric_limits<uint64_t>::max());
|
||||
vkResetFences(device->device, 1, &mSubmitFence[currentIndex]->fence);
|
||||
}
|
||||
|
||||
QueueSubmit submit;
|
||||
VulkanCommandBuffer *commands[2];
|
||||
size_t count = 0;
|
||||
|
||||
if (mTransferCommands)
|
||||
{
|
||||
mTransferCommands->end();
|
||||
submit.addCommandBuffer(mTransferCommands.get());
|
||||
|
||||
commands[count++] = mTransferCommands.get();
|
||||
FrameDeleteList.CommandBuffers.push_back(std::move(mTransferCommands));
|
||||
}
|
||||
|
||||
if (mDrawCommands)
|
||||
{
|
||||
mDrawCommands->end();
|
||||
submit.addCommandBuffer(mDrawCommands.get());
|
||||
|
||||
commands[count++] = mDrawCommands.get();
|
||||
FrameDeleteList.CommandBuffers.push_back(std::move(mDrawCommands));
|
||||
}
|
||||
|
||||
if (nextSubmitQueue > 0)
|
||||
submit.addWait(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, mSubmitSemaphore[(nextSubmitQueue - 1) % submitQueueSize].get());
|
||||
current_rendered_commandbuffers += (int)count;
|
||||
|
||||
submit.addSignal(mSubmitSemaphore[currentIndex].get());
|
||||
submit.execute(device, device->graphicsQueue, mSubmitFence[currentIndex].get());
|
||||
nextSubmitQueue++;
|
||||
if (vk_submit_multithread)
|
||||
{
|
||||
StartSubmitThread();
|
||||
std::unique_lock<std::mutex> lock(mSubmitMutex);
|
||||
for (size_t i = 0; i < count; i++)
|
||||
mSubmitQueue.push_back(commands[i]);
|
||||
lock.unlock();
|
||||
mSubmitCondVar.notify_all();
|
||||
}
|
||||
else
|
||||
{
|
||||
StopSubmitThread();
|
||||
FlushCommands(commands, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -242,6 +318,10 @@ void VulkanFrameBuffer::WaitForCommands(bool finish)
|
|||
|
||||
FlushCommands();
|
||||
|
||||
std::unique_lock<std::mutex> lock(mSubmitMutex);
|
||||
mSubmitDone.wait(lock, [&]() { return mSubmitQueue.empty() && mSubmitItemsActive == 0; });
|
||||
lock.unlock();
|
||||
|
||||
QueueSubmit submit;
|
||||
|
||||
if (nextSubmitQueue > 0)
|
||||
|
|
@ -280,6 +360,8 @@ void VulkanFrameBuffer::WaitForCommands(bool finish)
|
|||
if (finish)
|
||||
{
|
||||
Finish.Unclock();
|
||||
rendered_commandbuffers = current_rendered_commandbuffers;
|
||||
current_rendered_commandbuffers = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue