blob: 95b90d9293e1ea0ff78858080b2ffc09242aa3bb [file] [log] [blame]
Ethan Nicholas8e265a72018-12-12 16:22:40 -05001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/gpu/vk/GrVkCommandPool.h"
Ethan Nicholas8e265a72018-12-12 16:22:40 -05009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "src/gpu/GrContextPriv.h"
11#include "src/gpu/vk/GrVkCommandBuffer.h"
12#include "src/gpu/vk/GrVkGpu.h"
Ethan Nicholas8e265a72018-12-12 16:22:40 -050013
Greg Daniele643da62019-11-05 12:36:42 -050014GrVkCommandPool* GrVkCommandPool::Create(GrVkGpu* gpu) {
Greg Daniel8daf3b72019-07-30 09:57:26 -040015 VkCommandPoolCreateFlags cmdPoolCreateFlags =
16 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT |
17 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
18 if (gpu->protectedContext()) {
19 cmdPoolCreateFlags |= VK_COMMAND_POOL_CREATE_PROTECTED_BIT;
20 }
Emircan Uysaler23ca4e72019-06-24 10:53:09 -040021
Greg Daniel8daf3b72019-07-30 09:57:26 -040022 const VkCommandPoolCreateInfo cmdPoolInfo = {
23 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType
24 nullptr, // pNext
25 cmdPoolCreateFlags, // CmdPoolCreateFlags
26 gpu->queueIndex(), // queueFamilyIndex
27 };
Greg Daniel9b63dc82019-11-06 09:21:55 -050028 VkResult result;
Greg Daniel8daf3b72019-07-30 09:57:26 -040029 VkCommandPool pool;
Greg Daniel9b63dc82019-11-06 09:21:55 -050030 GR_VK_CALL_RESULT(gpu, result, CreateCommandPool(gpu->device(), &cmdPoolInfo, nullptr, &pool));
31 if (result != VK_SUCCESS) {
32 return nullptr;
33 }
Greg Daniel315c8dc2019-11-26 15:41:27 -050034
35 GrVkPrimaryCommandBuffer* primaryCmdBuffer = GrVkPrimaryCommandBuffer::Create(gpu, pool);
36 if (!primaryCmdBuffer) {
37 GR_VK_CALL(gpu->vkInterface(), DestroyCommandPool(gpu->device(), pool, nullptr));
38 return nullptr;
39 }
40
41 return new GrVkCommandPool(gpu, pool, primaryCmdBuffer);
Ethan Nicholas8e265a72018-12-12 16:22:40 -050042}
43
Greg Daniel315c8dc2019-11-26 15:41:27 -050044GrVkCommandPool::GrVkCommandPool(GrVkGpu* gpu, VkCommandPool commandPool,
45 GrVkPrimaryCommandBuffer* primaryCmdBuffer)
46 : fCommandPool(commandPool)
47 , fPrimaryCommandBuffer(primaryCmdBuffer) {
Ethan Nicholas8e265a72018-12-12 16:22:40 -050048}
49
Greg Daniel8daf3b72019-07-30 09:57:26 -040050std::unique_ptr<GrVkSecondaryCommandBuffer> GrVkCommandPool::findOrCreateSecondaryCommandBuffer(
51 GrVkGpu* gpu) {
52 std::unique_ptr<GrVkSecondaryCommandBuffer> result;
Ethan Nicholas8e265a72018-12-12 16:22:40 -050053 if (fAvailableSecondaryBuffers.count()) {
Greg Daniel8daf3b72019-07-30 09:57:26 -040054 result = std::move(fAvailableSecondaryBuffers.back());
Ethan Nicholas8e265a72018-12-12 16:22:40 -050055 fAvailableSecondaryBuffers.pop_back();
Greg Daniel8daf3b72019-07-30 09:57:26 -040056 } else{
57 result.reset(GrVkSecondaryCommandBuffer::Create(gpu, this));
Ethan Nicholas8e265a72018-12-12 16:22:40 -050058 }
Greg Daniel8daf3b72019-07-30 09:57:26 -040059 return result;
Ethan Nicholas8e265a72018-12-12 16:22:40 -050060}
61
62void GrVkCommandPool::recycleSecondaryCommandBuffer(GrVkSecondaryCommandBuffer* buffer) {
Greg Daniel8daf3b72019-07-30 09:57:26 -040063 std::unique_ptr<GrVkSecondaryCommandBuffer> scb(buffer);
64 fAvailableSecondaryBuffers.push_back(std::move(scb));
Ethan Nicholas8e265a72018-12-12 16:22:40 -050065}
66
67void GrVkCommandPool::close() {
68 fOpen = false;
69}
70
71void GrVkCommandPool::reset(GrVkGpu* gpu) {
72 SkASSERT(!fOpen);
73 fOpen = true;
Greg Daniel95f0b162019-11-11 13:42:30 -050074 // We can't use the normal result macro calls here because we may call reset on a different
75 // thread and we can't be modifying the lost state on the GrVkGpu. We just call
76 // vkResetCommandPool and assume the "next" vulkan call will catch the lost device.
77 SkDEBUGCODE(VkResult result = )GR_VK_CALL(gpu->vkInterface(),
78 ResetCommandPool(gpu->device(), fCommandPool, 0));
79 SkASSERT(result == VK_SUCCESS || result == VK_ERROR_DEVICE_LOST);
Ethan Nicholas8e265a72018-12-12 16:22:40 -050080}
81
82void GrVkCommandPool::releaseResources(GrVkGpu* gpu) {
Brian Salomone39526b2019-06-24 16:35:53 -040083 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
Ethan Nicholas8e265a72018-12-12 16:22:40 -050084 SkASSERT(!fOpen);
85 fPrimaryCommandBuffer->releaseResources(gpu);
Greg Daniel7a32f1b2019-11-26 16:18:01 -050086 fPrimaryCommandBuffer->recycleSecondaryCommandBuffers(this);
Ethan Nicholas8e265a72018-12-12 16:22:40 -050087}
88
Ethan Nicholas8e265a72018-12-12 16:22:40 -050089void GrVkCommandPool::freeGPUData(GrVkGpu* gpu) const {
Greg Daniel0addbdf2019-11-25 15:03:58 -050090 // TODO: having freeGPUData virtual on GrVkResource be const seems like a bad restriction since
91 // we are changing the internal objects of these classes when it is called. We should go back a
92 // revisit how much of a headache it would be to make this function non-const
93 GrVkCommandPool* nonConstThis = const_cast<GrVkCommandPool*>(this);
94 nonConstThis->close();
95 nonConstThis->releaseResources(gpu);
96 fPrimaryCommandBuffer->freeGPUData(gpu, fCommandPool);
Greg Daniel8daf3b72019-07-30 09:57:26 -040097 for (const auto& buffer : fAvailableSecondaryBuffers) {
Greg Daniel0addbdf2019-11-25 15:03:58 -050098 buffer->freeGPUData(gpu, fCommandPool);
Ethan Nicholas8e265a72018-12-12 16:22:40 -050099 }
100 if (fCommandPool != VK_NULL_HANDLE) {
101 GR_VK_CALL(gpu->vkInterface(),
102 DestroyCommandPool(gpu->device(), fCommandPool, nullptr));
103 }
104}