• 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,bool hasProtectedContent,uint32_t queueFamilyIndex)25 angle::Result PersistentCommandPool::init(vk::Context *context,
26                                           bool hasProtectedContent,
27                                           uint32_t queueFamilyIndex)
28 {
29     ASSERT(!mCommandPool.valid());
30 
31     // Initialize the command pool now that we know the queue family index.
32     VkCommandPoolCreateInfo commandPoolInfo = {};
33     commandPoolInfo.sType                   = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
34     // TODO (https://issuetracker.google.com/issues/166793850) We currently reset individual
35     //  command buffers from this pool. Alternatively we could reset the entire command pool.
36     commandPoolInfo.flags =
37         VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
38     if (hasProtectedContent)
39     {
40         commandPoolInfo.flags |= VK_COMMAND_POOL_CREATE_PROTECTED_BIT;
41     }
42     commandPoolInfo.queueFamilyIndex = queueFamilyIndex;
43 
44     ANGLE_VK_TRY(context, mCommandPool.init(context->getDevice(), commandPoolInfo));
45 
46     for (uint32_t i = 0; i < kInitBufferNum; i++)
47     {
48         ANGLE_TRY(allocateCommandBuffer(context));
49     }
50 
51     return angle::Result::Continue;
52 }
53 
destroy(VkDevice device)54 void PersistentCommandPool::destroy(VkDevice device)
55 {
56     if (!valid())
57         return;
58 
59     ASSERT(mCommandPool.valid());
60 
61     for (vk::PrimaryCommandBuffer &cmdBuf : mFreeBuffers)
62     {
63         cmdBuf.destroy(device, mCommandPool);
64     }
65     mFreeBuffers.clear();
66 
67     mCommandPool.destroy(device);
68 }
69 
allocate(vk::Context * context,vk::PrimaryCommandBuffer * commandBufferOut)70 angle::Result PersistentCommandPool::allocate(vk::Context *context,
71                                               vk::PrimaryCommandBuffer *commandBufferOut)
72 {
73     if (mFreeBuffers.empty())
74     {
75         ANGLE_TRY(allocateCommandBuffer(context));
76         ASSERT(!mFreeBuffers.empty());
77     }
78 
79     *commandBufferOut = std::move(mFreeBuffers.back());
80     mFreeBuffers.pop_back();
81 
82     return angle::Result::Continue;
83 }
84 
collect(vk::Context * context,vk::PrimaryCommandBuffer && buffer)85 angle::Result PersistentCommandPool::collect(vk::Context *context,
86                                              vk::PrimaryCommandBuffer &&buffer)
87 {
88     // VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT NOT set, The CommandBuffer
89     // can still hold the memory resource
90     ANGLE_VK_TRY(context, vkResetCommandBuffer(buffer.getHandle(), 0));
91 
92     mFreeBuffers.emplace_back(std::move(buffer));
93     return angle::Result::Continue;
94 }
95 
allocateCommandBuffer(vk::Context * context)96 angle::Result PersistentCommandPool::allocateCommandBuffer(vk::Context *context)
97 {
98     vk::PrimaryCommandBuffer commandBuffer;
99     {
100         // Only used for primary CommandBuffer allocation
101         VkCommandBufferAllocateInfo commandBufferInfo = {};
102         commandBufferInfo.sType              = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
103         commandBufferInfo.commandPool        = mCommandPool.getHandle();
104         commandBufferInfo.level              = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
105         commandBufferInfo.commandBufferCount = 1;
106 
107         ANGLE_VK_TRY(context, commandBuffer.init(context->getDevice(), commandBufferInfo));
108     }
109 
110     mFreeBuffers.emplace_back(std::move(commandBuffer));
111 
112     return angle::Result::Continue;
113 }
114 
115 }  // namespace vk
116 
117 }  // namespace rx
118