• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // PersistentCommandPool.cpp:
7 //    Implements the class methods for PersistentCommandPool
8 //
9 
10 #include "libANGLE/renderer/vulkan/PersistentCommandPool.h"
11 
12 namespace rx
13 {
14 
15 namespace vk
16 {
17 
PersistentCommandPool()18 PersistentCommandPool::PersistentCommandPool() {}
19 
~PersistentCommandPool()20 PersistentCommandPool::~PersistentCommandPool()
21 {
22     ASSERT(!mCommandPool.valid() && mFreeBuffers.empty());
23 }
24 
init(vk::Context * context,uint32_t queueFamilyIndex)25 angle::Result PersistentCommandPool::init(vk::Context *context, uint32_t queueFamilyIndex)
26 {
27     ASSERT(!mCommandPool.valid());
28 
29     // Initialize the command pool now that we know the queue family index.
30     VkCommandPoolCreateInfo commandPoolInfo = {};
31     commandPoolInfo.sType                   = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
32     commandPoolInfo.flags                   = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
33     commandPoolInfo.queueFamilyIndex        = queueFamilyIndex;
34 
35     ANGLE_VK_TRY(context, mCommandPool.init(context->getDevice(), commandPoolInfo));
36 
37     for (uint32_t i = 0; i < kInitBufferNum; i++)
38     {
39         ANGLE_TRY(allocateCommandBuffer(context));
40     }
41 
42     return angle::Result::Continue;
43 }
44 
destroy(VkDevice device)45 void PersistentCommandPool::destroy(VkDevice device)
46 {
47     if (!valid())
48         return;
49 
50     ASSERT(mCommandPool.valid());
51 
52     for (vk::PrimaryCommandBuffer &cmdBuf : mFreeBuffers)
53     {
54         cmdBuf.destroy(device, mCommandPool);
55     }
56     mFreeBuffers.clear();
57 
58     mCommandPool.destroy(device);
59 }
60 
allocate(vk::Context * context,vk::PrimaryCommandBuffer * commandBufferOut)61 angle::Result PersistentCommandPool::allocate(vk::Context *context,
62                                               vk::PrimaryCommandBuffer *commandBufferOut)
63 {
64     if (mFreeBuffers.empty())
65     {
66         ANGLE_TRY(allocateCommandBuffer(context));
67         ASSERT(!mFreeBuffers.empty());
68     }
69 
70     *commandBufferOut = std::move(mFreeBuffers.back());
71     mFreeBuffers.pop_back();
72 
73     return angle::Result::Continue;
74 }
75 
collect(vk::Context * context,vk::PrimaryCommandBuffer && buffer)76 angle::Result PersistentCommandPool::collect(vk::Context *context,
77                                              vk::PrimaryCommandBuffer &&buffer)
78 {
79     // VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT NOT set, The CommandBuffer
80     // can still hold the memory resource
81     ANGLE_VK_TRY(context, vkResetCommandBuffer(buffer.getHandle(), 0));
82 
83     mFreeBuffers.emplace_back(std::move(buffer));
84     return angle::Result::Continue;
85 }
86 
allocateCommandBuffer(vk::Context * context)87 angle::Result PersistentCommandPool::allocateCommandBuffer(vk::Context *context)
88 {
89     vk::PrimaryCommandBuffer commandBuffer;
90     {
91         // Only used for primary CommandBuffer allocation
92         VkCommandBufferAllocateInfo commandBufferInfo = {};
93         commandBufferInfo.sType              = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
94         commandBufferInfo.commandPool        = mCommandPool.getHandle();
95         commandBufferInfo.level              = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
96         commandBufferInfo.commandBufferCount = 1;
97 
98         ANGLE_VK_TRY(context, commandBuffer.init(context->getDevice(), commandBufferInfo));
99     }
100 
101     mFreeBuffers.emplace_back(std::move(commandBuffer));
102 
103     return angle::Result::Continue;
104 }
105 
106 }  // namespace vk
107 
108 }  // namespace rx
109