blob: b345b3764cebc379ab3cc453656cb7a7edf35b5b [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 Daniel8daf3b72019-07-30 09:57:26 -040034 return new GrVkCommandPool(gpu, pool);
Ethan Nicholas8e265a72018-12-12 16:22:40 -050035}
36
37GrVkCommandPool::GrVkCommandPool(const GrVkGpu* gpu, VkCommandPool commandPool)
38 : fCommandPool(commandPool) {
Greg Daniel0addbdf2019-11-25 15:03:58 -050039 fPrimaryCommandBuffer.reset(GrVkPrimaryCommandBuffer::Create(gpu, fCommandPool));
Ethan Nicholas8e265a72018-12-12 16:22:40 -050040}
41
Greg Daniel8daf3b72019-07-30 09:57:26 -040042std::unique_ptr<GrVkSecondaryCommandBuffer> GrVkCommandPool::findOrCreateSecondaryCommandBuffer(
43 GrVkGpu* gpu) {
44 std::unique_ptr<GrVkSecondaryCommandBuffer> result;
Ethan Nicholas8e265a72018-12-12 16:22:40 -050045 if (fAvailableSecondaryBuffers.count()) {
Greg Daniel8daf3b72019-07-30 09:57:26 -040046 result = std::move(fAvailableSecondaryBuffers.back());
Ethan Nicholas8e265a72018-12-12 16:22:40 -050047 fAvailableSecondaryBuffers.pop_back();
Greg Daniel8daf3b72019-07-30 09:57:26 -040048 } else{
49 result.reset(GrVkSecondaryCommandBuffer::Create(gpu, this));
Ethan Nicholas8e265a72018-12-12 16:22:40 -050050 }
Greg Daniel8daf3b72019-07-30 09:57:26 -040051 return result;
Ethan Nicholas8e265a72018-12-12 16:22:40 -050052}
53
54void GrVkCommandPool::recycleSecondaryCommandBuffer(GrVkSecondaryCommandBuffer* buffer) {
Greg Daniel8daf3b72019-07-30 09:57:26 -040055 std::unique_ptr<GrVkSecondaryCommandBuffer> scb(buffer);
56 fAvailableSecondaryBuffers.push_back(std::move(scb));
Ethan Nicholas8e265a72018-12-12 16:22:40 -050057}
58
59void GrVkCommandPool::close() {
60 fOpen = false;
61}
62
63void GrVkCommandPool::reset(GrVkGpu* gpu) {
64 SkASSERT(!fOpen);
65 fOpen = true;
Greg Daniel95f0b162019-11-11 13:42:30 -050066 // We can't use the normal result macro calls here because we may call reset on a different
67 // thread and we can't be modifying the lost state on the GrVkGpu. We just call
68 // vkResetCommandPool and assume the "next" vulkan call will catch the lost device.
69 SkDEBUGCODE(VkResult result = )GR_VK_CALL(gpu->vkInterface(),
70 ResetCommandPool(gpu->device(), fCommandPool, 0));
71 SkASSERT(result == VK_SUCCESS || result == VK_ERROR_DEVICE_LOST);
Ethan Nicholas8e265a72018-12-12 16:22:40 -050072}
73
74void GrVkCommandPool::releaseResources(GrVkGpu* gpu) {
Brian Salomone39526b2019-06-24 16:35:53 -040075 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
Ethan Nicholas8e265a72018-12-12 16:22:40 -050076 SkASSERT(!fOpen);
77 fPrimaryCommandBuffer->releaseResources(gpu);
Greg Daniel7a32f1b2019-11-26 16:18:01 -050078 fPrimaryCommandBuffer->recycleSecondaryCommandBuffers(this);
Ethan Nicholas8e265a72018-12-12 16:22:40 -050079}
80
81void GrVkCommandPool::abandonGPUData() const {
Greg Daniel8daf3b72019-07-30 09:57:26 -040082 fPrimaryCommandBuffer->abandonGPUData();
83 for (const auto& buffer : fAvailableSecondaryBuffers) {
84 buffer->abandonGPUData();
Ethan Nicholas8e265a72018-12-12 16:22:40 -050085 }
86}
87
88void GrVkCommandPool::freeGPUData(GrVkGpu* gpu) const {
Greg Daniel0addbdf2019-11-25 15:03:58 -050089 // TODO: having freeGPUData virtual on GrVkResource be const seems like a bad restriction since
90 // we are changing the internal objects of these classes when it is called. We should go back a
91 // revisit how much of a headache it would be to make this function non-const
92 GrVkCommandPool* nonConstThis = const_cast<GrVkCommandPool*>(this);
93 nonConstThis->close();
94 nonConstThis->releaseResources(gpu);
95 fPrimaryCommandBuffer->freeGPUData(gpu, fCommandPool);
Greg Daniel8daf3b72019-07-30 09:57:26 -040096 for (const auto& buffer : fAvailableSecondaryBuffers) {
Greg Daniel0addbdf2019-11-25 15:03:58 -050097 buffer->freeGPUData(gpu, fCommandPool);
Ethan Nicholas8e265a72018-12-12 16:22:40 -050098 }
99 if (fCommandPool != VK_NULL_HANDLE) {
100 GR_VK_CALL(gpu->vkInterface(),
101 DestroyCommandPool(gpu->device(), fCommandPool, nullptr));
102 }
103}