• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/vk/GrVkCommandPool.h"
9 
10 #include "src/core/SkTraceEvent.h"
11 #include "src/gpu/GrDirectContextPriv.h"
12 #include "src/gpu/vk/GrVkCommandBuffer.h"
13 #include "src/gpu/vk/GrVkGpu.h"
14 
Create(GrVkGpu * gpu)15 GrVkCommandPool* GrVkCommandPool::Create(GrVkGpu* gpu) {
16     VkCommandPoolCreateFlags cmdPoolCreateFlags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
17     if (gpu->protectedContext()) {
18         cmdPoolCreateFlags |= VK_COMMAND_POOL_CREATE_PROTECTED_BIT;
19     }
20 
21     const VkCommandPoolCreateInfo cmdPoolInfo = {
22         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,  // sType
23         nullptr,                                     // pNext
24         cmdPoolCreateFlags,                          // CmdPoolCreateFlags
25         gpu->queueIndex(),                           // queueFamilyIndex
26     };
27     VkResult result;
28     VkCommandPool pool;
29     GR_VK_CALL_RESULT(gpu, result, CreateCommandPool(gpu->device(), &cmdPoolInfo, nullptr, &pool));
30     if (result != VK_SUCCESS) {
31         return nullptr;
32     }
33 
34     GrVkPrimaryCommandBuffer* primaryCmdBuffer = GrVkPrimaryCommandBuffer::Create(gpu, pool);
35     if (!primaryCmdBuffer) {
36         GR_VK_CALL(gpu->vkInterface(), DestroyCommandPool(gpu->device(), pool, nullptr));
37         return nullptr;
38     }
39 
40     return new GrVkCommandPool(gpu, pool, primaryCmdBuffer);
41 }
42 
GrVkCommandPool(GrVkGpu * gpu,VkCommandPool commandPool,GrVkPrimaryCommandBuffer * primaryCmdBuffer)43 GrVkCommandPool::GrVkCommandPool(GrVkGpu* gpu, VkCommandPool commandPool,
44                                  GrVkPrimaryCommandBuffer* primaryCmdBuffer)
45         : GrVkManagedResource(gpu)
46         , fCommandPool(commandPool)
47         , fPrimaryCommandBuffer(primaryCmdBuffer)
48         , fMaxCachedSecondaryCommandBuffers(
49                 gpu->vkCaps().maxPerPoolCachedSecondaryCommandBuffers()) {
50 }
51 
findOrCreateSecondaryCommandBuffer(GrVkGpu * gpu)52 std::unique_ptr<GrVkSecondaryCommandBuffer> GrVkCommandPool::findOrCreateSecondaryCommandBuffer(
53         GrVkGpu* gpu) {
54     std::unique_ptr<GrVkSecondaryCommandBuffer> result;
55     if (fAvailableSecondaryBuffers.count()) {
56         result = std::move(fAvailableSecondaryBuffers.back());
57         fAvailableSecondaryBuffers.pop_back();
58     } else{
59         result.reset(GrVkSecondaryCommandBuffer::Create(gpu, this));
60     }
61     return result;
62 }
63 
recycleSecondaryCommandBuffer(GrVkSecondaryCommandBuffer * buffer)64 void GrVkCommandPool::recycleSecondaryCommandBuffer(GrVkSecondaryCommandBuffer* buffer) {
65     std::unique_ptr<GrVkSecondaryCommandBuffer> scb(buffer);
66     if (fAvailableSecondaryBuffers.count() < fMaxCachedSecondaryCommandBuffers) {
67         fAvailableSecondaryBuffers.push_back(std::move(scb));
68     } else {
69         VkCommandBuffer vkBuffer = buffer->vkCommandBuffer();
70         GR_VK_CALL(fGpu->vkInterface(),
71                    FreeCommandBuffers(fGpu->device(), fCommandPool, 1, &vkBuffer));
72     }
73 }
74 
close()75 void GrVkCommandPool::close() {
76     fOpen = false;
77 }
78 
reset(GrVkGpu * gpu)79 void GrVkCommandPool::reset(GrVkGpu* gpu) {
80     SkASSERT(!fOpen);
81     fOpen = true;
82     // We can't use the normal result macro calls here because we may call reset on a different
83     // thread and we can't be modifying the lost state on the GrVkGpu. We just call
84     // vkResetCommandPool and assume the "next" vulkan call will catch the lost device.
85     SkDEBUGCODE(VkResult result = )GR_VK_CALL(gpu->vkInterface(),
86                                               ResetCommandPool(gpu->device(), fCommandPool, 0));
87     SkASSERT(result == VK_SUCCESS || result == VK_ERROR_DEVICE_LOST);
88 }
89 
releaseResources()90 void GrVkCommandPool::releaseResources() {
91     TRACE_EVENT0("skia.gpu", TRACE_FUNC);
92     SkASSERT(!fOpen);
93     fPrimaryCommandBuffer->releaseResources();
94     fPrimaryCommandBuffer->recycleSecondaryCommandBuffers(this);
95 }
96 
freeGPUData() const97 void GrVkCommandPool::freeGPUData() const {
98     // TODO: having freeGPUData virtual on GrManagedResource be const seems like a bad restriction since
99     // we are changing the internal objects of these classes when it is called. We should go back a
100     // revisit how much of a headache it would be to make this function non-const
101     GrVkCommandPool* nonConstThis = const_cast<GrVkCommandPool*>(this);
102     nonConstThis->close();
103     nonConstThis->releaseResources();
104     fPrimaryCommandBuffer->freeGPUData(fGpu, fCommandPool);
105     for (const auto& buffer : fAvailableSecondaryBuffers) {
106         buffer->freeGPUData(fGpu, fCommandPool);
107     }
108     if (fCommandPool != VK_NULL_HANDLE) {
109         GR_VK_CALL(fGpu->vkInterface(),
110                    DestroyCommandPool(fGpu->device(), fCommandPool, nullptr));
111     }
112 }
113