xref: /aosp_15_r20/external/skia/src/gpu/ganesh/vk/GrVkCommandPool.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2018 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "src/gpu/ganesh/vk/GrVkCommandPool.h"
9 
10 #include "include/private/base/SkAssert.h"
11 #include "src/core/SkTraceEvent.h"
12 #include "src/gpu/ganesh/vk/GrVkCaps.h"
13 #include "src/gpu/ganesh/vk/GrVkCommandBuffer.h"
14 #include "src/gpu/ganesh/vk/GrVkGpu.h"
15 #include "src/gpu/ganesh/vk/GrVkUtil.h"
16 
17 #include <utility>
18 
Create(GrVkGpu * gpu)19 GrVkCommandPool* GrVkCommandPool::Create(GrVkGpu* gpu) {
20     VkCommandPoolCreateFlags cmdPoolCreateFlags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
21     if (gpu->protectedContext()) {
22         cmdPoolCreateFlags |= VK_COMMAND_POOL_CREATE_PROTECTED_BIT;
23     }
24 
25     const VkCommandPoolCreateInfo cmdPoolInfo = {
26         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,  // sType
27         nullptr,                                     // pNext
28         cmdPoolCreateFlags,                          // CmdPoolCreateFlags
29         gpu->queueIndex(),                           // queueFamilyIndex
30     };
31     VkResult result;
32     VkCommandPool pool;
33     GR_VK_CALL_RESULT(gpu, result, CreateCommandPool(gpu->device(), &cmdPoolInfo, nullptr, &pool));
34     if (result != VK_SUCCESS) {
35         return nullptr;
36     }
37 
38     GrVkPrimaryCommandBuffer* primaryCmdBuffer = GrVkPrimaryCommandBuffer::Create(gpu, pool);
39     if (!primaryCmdBuffer) {
40         GR_VK_CALL(gpu->vkInterface(), DestroyCommandPool(gpu->device(), pool, nullptr));
41         return nullptr;
42     }
43 
44     return new GrVkCommandPool(gpu, pool, primaryCmdBuffer);
45 }
46 
GrVkCommandPool(GrVkGpu * gpu,VkCommandPool commandPool,GrVkPrimaryCommandBuffer * primaryCmdBuffer)47 GrVkCommandPool::GrVkCommandPool(GrVkGpu* gpu, VkCommandPool commandPool,
48                                  GrVkPrimaryCommandBuffer* primaryCmdBuffer)
49         : GrVkManagedResource(gpu)
50         , fCommandPool(commandPool)
51         , fPrimaryCommandBuffer(primaryCmdBuffer)
52         , fMaxCachedSecondaryCommandBuffers(
53                 gpu->vkCaps().maxPerPoolCachedSecondaryCommandBuffers()) {
54 }
55 
findOrCreateSecondaryCommandBuffer(GrVkGpu * gpu)56 std::unique_ptr<GrVkSecondaryCommandBuffer> GrVkCommandPool::findOrCreateSecondaryCommandBuffer(
57         GrVkGpu* gpu) {
58     std::unique_ptr<GrVkSecondaryCommandBuffer> result;
59     if (!fAvailableSecondaryBuffers.empty()) {
60         result = std::move(fAvailableSecondaryBuffers.back());
61         fAvailableSecondaryBuffers.pop_back();
62     } else{
63         result.reset(GrVkSecondaryCommandBuffer::Create(gpu, this));
64     }
65     return result;
66 }
67 
recycleSecondaryCommandBuffer(GrVkSecondaryCommandBuffer * buffer)68 void GrVkCommandPool::recycleSecondaryCommandBuffer(GrVkSecondaryCommandBuffer* buffer) {
69     std::unique_ptr<GrVkSecondaryCommandBuffer> scb(buffer);
70     if (fAvailableSecondaryBuffers.size() < fMaxCachedSecondaryCommandBuffers) {
71         fAvailableSecondaryBuffers.push_back(std::move(scb));
72     } else {
73         VkCommandBuffer vkBuffer = buffer->vkCommandBuffer();
74         GR_VK_CALL(fGpu->vkInterface(),
75                    FreeCommandBuffers(fGpu->device(), fCommandPool, 1, &vkBuffer));
76     }
77 }
78 
close()79 void GrVkCommandPool::close() {
80     fOpen = false;
81 }
82 
reset(GrVkGpu * gpu)83 void GrVkCommandPool::reset(GrVkGpu* gpu) {
84     TRACE_EVENT0("skia.gpu", TRACE_FUNC);
85     SkASSERT(!fOpen);
86     // We can't use the normal result macro calls here because we may call reset on a different
87     // thread and we can't be modifying the lost state on the GrVkGpu. We just call
88     // vkResetCommandPool and assume the "next" vulkan call will catch the lost device.
89     SkDEBUGCODE(VkResult result = )GR_VK_CALL(gpu->vkInterface(),
90                                               ResetCommandPool(gpu->device(), fCommandPool, 0));
91     SkASSERT(result == VK_SUCCESS || result == VK_ERROR_DEVICE_LOST);
92 
93     // It should be safe to release the resources before actually resetting the VkCommandPool.
94     // However, on qualcomm devices running R drivers there was a few months period where the driver
95     // had a bug which it incorrectly was accessing objects on the command buffer while it was being
96     // reset. If these objects were already destroyed (which is a valid thing to do) it would crash.
97     // So to be safe we do the reset first since it doesn't really matter when single threaded. If
98     // we ever add back in threaded resets we'll want to add checks to make sure everything happens
99     // in the right order (and probably do single threaded resets on bad devices).
100     this->releaseResources();
101 
102     fOpen = true;
103 }
104 
releaseResources()105 void GrVkCommandPool::releaseResources() {
106     TRACE_EVENT0("skia.gpu", TRACE_FUNC);
107     SkASSERT(!fOpen);
108     fPrimaryCommandBuffer->releaseResources();
109     fPrimaryCommandBuffer->recycleSecondaryCommandBuffers(this);
110 }
111 
freeGPUData() const112 void GrVkCommandPool::freeGPUData() const {
113     // TODO: having freeGPUData virtual on GrManagedResource be const seems like a bad restriction since
114     // we are changing the internal objects of these classes when it is called. We should go back a
115     // revisit how much of a headache it would be to make this function non-const
116     GrVkCommandPool* nonConstThis = const_cast<GrVkCommandPool*>(this);
117     nonConstThis->close();
118     nonConstThis->releaseResources();
119     fPrimaryCommandBuffer->freeGPUData(fGpu, fCommandPool);
120     for (const auto& buffer : fAvailableSecondaryBuffers) {
121         buffer->freeGPUData(fGpu, fCommandPool);
122     }
123     if (fCommandPool != VK_NULL_HANDLE) {
124         GR_VK_CALL(fGpu->vkInterface(),
125                    DestroyCommandPool(fGpu->device(), fCommandPool, nullptr));
126     }
127 }
128