xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/PersistentCommandPool.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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(Context * context,ProtectionType protectionType,uint32_t queueFamilyIndex)25 angle::Result PersistentCommandPool::init(Context *context,
26                                           ProtectionType protectionType,
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     ASSERT(protectionType == ProtectionType::Unprotected ||
39            protectionType == ProtectionType::Protected);
40     if (protectionType == ProtectionType::Protected)
41     {
42         commandPoolInfo.flags |= VK_COMMAND_POOL_CREATE_PROTECTED_BIT;
43     }
44     commandPoolInfo.queueFamilyIndex = queueFamilyIndex;
45 
46     ANGLE_VK_TRY(context, mCommandPool.init(context->getDevice(), commandPoolInfo));
47 
48     for (uint32_t i = 0; i < kInitBufferNum; i++)
49     {
50         ANGLE_TRY(allocateCommandBuffer(context));
51     }
52 
53     return angle::Result::Continue;
54 }
55 
destroy(VkDevice device)56 void PersistentCommandPool::destroy(VkDevice device)
57 {
58     if (!valid())
59         return;
60 
61     ASSERT(mCommandPool.valid());
62 
63     for (PrimaryCommandBuffer &cmdBuf : mFreeBuffers)
64     {
65         cmdBuf.destroy(device, mCommandPool);
66     }
67     mFreeBuffers.clear();
68 
69     mCommandPool.destroy(device);
70 }
71 
allocate(Context * context,PrimaryCommandBuffer * commandBufferOut)72 angle::Result PersistentCommandPool::allocate(Context *context,
73                                               PrimaryCommandBuffer *commandBufferOut)
74 {
75     if (mFreeBuffers.empty())
76     {
77         ANGLE_TRY(allocateCommandBuffer(context));
78         ASSERT(!mFreeBuffers.empty());
79     }
80 
81     *commandBufferOut = std::move(mFreeBuffers.back());
82     mFreeBuffers.pop_back();
83 
84     return angle::Result::Continue;
85 }
86 
collect(Context * context,PrimaryCommandBuffer && buffer)87 angle::Result PersistentCommandPool::collect(Context *context, PrimaryCommandBuffer &&buffer)
88 {
89     // VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT NOT set, The CommandBuffer
90     // can still hold the memory resource
91     ANGLE_VK_TRY(context, buffer.reset());
92 
93     mFreeBuffers.emplace_back(std::move(buffer));
94     return angle::Result::Continue;
95 }
96 
allocateCommandBuffer(Context * context)97 angle::Result PersistentCommandPool::allocateCommandBuffer(Context *context)
98 {
99     PrimaryCommandBuffer commandBuffer;
100     {
101         // Only used for primary CommandBuffer allocation
102         VkCommandBufferAllocateInfo commandBufferInfo = {};
103         commandBufferInfo.sType              = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
104         commandBufferInfo.commandPool        = mCommandPool.getHandle();
105         commandBufferInfo.level              = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
106         commandBufferInfo.commandBufferCount = 1;
107 
108         ANGLE_VK_TRY(context, commandBuffer.init(context->getDevice(), commandBufferInfo));
109     }
110 
111     mFreeBuffers.emplace_back(std::move(commandBuffer));
112 
113     return angle::Result::Continue;
114 }
115 
116 }  // namespace vk
117 
118 }  // namespace rx
119