119 lines
3.6 KiB
C++
119 lines
3.6 KiB
C++
|
|
//
|
||
|
|
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
|
||
|
|
// Use of this source code is governed by a BSD-style license that can be
|
||
|
|
// found in the LICENSE file.
|
||
|
|
//
|
||
|
|
// PersistentCommandPool.cpp:
|
||
|
|
// Implements the class methods for PersistentCommandPool
|
||
|
|
//
|
||
|
|
|
||
|
|
#include "libANGLE/renderer/vulkan/PersistentCommandPool.h"
|
||
|
|
|
||
|
|
namespace rx
|
||
|
|
{
|
||
|
|
|
||
|
|
namespace vk
|
||
|
|
{
|
||
|
|
|
||
|
|
PersistentCommandPool::PersistentCommandPool() {}
|
||
|
|
|
||
|
|
PersistentCommandPool::~PersistentCommandPool()
|
||
|
|
{
|
||
|
|
ASSERT(!mCommandPool.valid() && mFreeBuffers.empty());
|
||
|
|
}
|
||
|
|
|
||
|
|
angle::Result PersistentCommandPool::init(Context *context,
|
||
|
|
ProtectionType protectionType,
|
||
|
|
uint32_t queueFamilyIndex)
|
||
|
|
{
|
||
|
|
ASSERT(!mCommandPool.valid());
|
||
|
|
|
||
|
|
// Initialize the command pool now that we know the queue family index.
|
||
|
|
VkCommandPoolCreateInfo commandPoolInfo = {};
|
||
|
|
commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||
|
|
// TODO (https://issuetracker.google.com/issues/166793850) We currently reset individual
|
||
|
|
// command buffers from this pool. Alternatively we could reset the entire command pool.
|
||
|
|
commandPoolInfo.flags =
|
||
|
|
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
|
||
|
|
ASSERT(protectionType == ProtectionType::Unprotected ||
|
||
|
|
protectionType == ProtectionType::Protected);
|
||
|
|
if (protectionType == ProtectionType::Protected)
|
||
|
|
{
|
||
|
|
commandPoolInfo.flags |= VK_COMMAND_POOL_CREATE_PROTECTED_BIT;
|
||
|
|
}
|
||
|
|
commandPoolInfo.queueFamilyIndex = queueFamilyIndex;
|
||
|
|
|
||
|
|
ANGLE_VK_TRY(context, mCommandPool.init(context->getDevice(), commandPoolInfo));
|
||
|
|
|
||
|
|
for (uint32_t i = 0; i < kInitBufferNum; i++)
|
||
|
|
{
|
||
|
|
ANGLE_TRY(allocateCommandBuffer(context));
|
||
|
|
}
|
||
|
|
|
||
|
|
return angle::Result::Continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
void PersistentCommandPool::destroy(VkDevice device)
|
||
|
|
{
|
||
|
|
if (!valid())
|
||
|
|
return;
|
||
|
|
|
||
|
|
ASSERT(mCommandPool.valid());
|
||
|
|
|
||
|
|
for (PrimaryCommandBuffer &cmdBuf : mFreeBuffers)
|
||
|
|
{
|
||
|
|
cmdBuf.destroy(device, mCommandPool);
|
||
|
|
}
|
||
|
|
mFreeBuffers.clear();
|
||
|
|
|
||
|
|
mCommandPool.destroy(device);
|
||
|
|
}
|
||
|
|
|
||
|
|
angle::Result PersistentCommandPool::allocate(Context *context,
|
||
|
|
PrimaryCommandBuffer *commandBufferOut)
|
||
|
|
{
|
||
|
|
if (mFreeBuffers.empty())
|
||
|
|
{
|
||
|
|
ANGLE_TRY(allocateCommandBuffer(context));
|
||
|
|
ASSERT(!mFreeBuffers.empty());
|
||
|
|
}
|
||
|
|
|
||
|
|
*commandBufferOut = std::move(mFreeBuffers.back());
|
||
|
|
mFreeBuffers.pop_back();
|
||
|
|
|
||
|
|
return angle::Result::Continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
angle::Result PersistentCommandPool::collect(Context *context, PrimaryCommandBuffer &&buffer)
|
||
|
|
{
|
||
|
|
// VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT NOT set, The CommandBuffer
|
||
|
|
// can still hold the memory resource
|
||
|
|
ANGLE_VK_TRY(context, buffer.reset());
|
||
|
|
|
||
|
|
mFreeBuffers.emplace_back(std::move(buffer));
|
||
|
|
return angle::Result::Continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
angle::Result PersistentCommandPool::allocateCommandBuffer(Context *context)
|
||
|
|
{
|
||
|
|
PrimaryCommandBuffer commandBuffer;
|
||
|
|
{
|
||
|
|
// Only used for primary CommandBuffer allocation
|
||
|
|
VkCommandBufferAllocateInfo commandBufferInfo = {};
|
||
|
|
commandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||
|
|
commandBufferInfo.commandPool = mCommandPool.getHandle();
|
||
|
|
commandBufferInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||
|
|
commandBufferInfo.commandBufferCount = 1;
|
||
|
|
|
||
|
|
ANGLE_VK_TRY(context, commandBuffer.init(context->getDevice(), commandBufferInfo));
|
||
|
|
}
|
||
|
|
|
||
|
|
mFreeBuffers.emplace_back(std::move(commandBuffer));
|
||
|
|
|
||
|
|
return angle::Result::Continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace vk
|
||
|
|
|
||
|
|
} // namespace rx
|