blob: fe467e009a6e7726b82b5ea8ba95801cd439b8a3 [file] [log] [blame]
Alexis Hetu9c4ecae2018-11-20 16:26:10 -05001// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "VkCommandPool.hpp"
Alexis Hetucd610c92019-02-01 16:47:51 -050016#include "VkCommandBuffer.hpp"
Alexis Hetubffee5e2018-11-19 11:30:43 -050017#include "VkDestroy.h"
18#include <algorithm>
Alexis Hetu1a9714a2019-04-12 11:48:12 -040019#include <new>
Alexis Hetu9c4ecae2018-11-20 16:26:10 -050020
Nicolas Capens157ba262019-12-10 17:49:14 -050021namespace vk {
Alexis Hetu9c4ecae2018-11-20 16:26:10 -050022
Ben Clayton2ed93ab2019-12-17 20:38:03 +000023CommandPool::CommandPool(const VkCommandPoolCreateInfo *pCreateInfo, void *mem)
Alexis Hetu9c4ecae2018-11-20 16:26:10 -050024{
Alexis Hetubffee5e2018-11-19 11:30:43 -050025 // FIXME (b/119409619): use an allocator here so we can control all memory allocations
Ben Clayton2ed93ab2019-12-17 20:38:03 +000026 void *deviceMemory = vk::allocate(sizeof(std::set<VkCommandBuffer>), REQUIRED_MEMORY_ALIGNMENT,
Alexis Hetu1a9714a2019-04-12 11:48:12 -040027 DEVICE_MEMORY, GetAllocationScope());
28 ASSERT(deviceMemory);
Ben Clayton2ed93ab2019-12-17 20:38:03 +000029 commandBuffers = new(deviceMemory) std::set<VkCommandBuffer>();
Alexis Hetu9c4ecae2018-11-20 16:26:10 -050030}
31
Ben Clayton2ed93ab2019-12-17 20:38:03 +000032void CommandPool::destroy(const VkAllocationCallbacks *pAllocator)
Alexis Hetu9c4ecae2018-11-20 16:26:10 -050033{
Alexis Hetubffee5e2018-11-19 11:30:43 -050034 // Free command Buffers allocated in allocateCommandBuffers
35 for(auto commandBuffer : *commandBuffers)
36 {
37 vk::destroy(commandBuffer, DEVICE_MEMORY);
38 }
39
40 // FIXME (b/119409619): use an allocator here so we can control all memory allocations
Alexis Hetu1a9714a2019-04-12 11:48:12 -040041 vk::deallocate(commandBuffers, DEVICE_MEMORY);
Alexis Hetu9c4ecae2018-11-20 16:26:10 -050042}
43
Ben Clayton2ed93ab2019-12-17 20:38:03 +000044size_t CommandPool::ComputeRequiredAllocationSize(const VkCommandPoolCreateInfo *pCreateInfo)
Alexis Hetu9c4ecae2018-11-20 16:26:10 -050045{
46 return 0;
47}
48
Ben Claytona4e06ca2019-12-03 12:38:14 +000049VkResult CommandPool::allocateCommandBuffers(Device *device, VkCommandBufferLevel level, uint32_t commandBufferCount, VkCommandBuffer *pCommandBuffers)
Alexis Hetubffee5e2018-11-19 11:30:43 -050050{
51 for(uint32_t i = 0; i < commandBufferCount; i++)
52 {
Alexis Hetu1a9714a2019-04-12 11:48:12 -040053 // FIXME (b/119409619): use an allocator here so we can control all memory allocations
Ben Clayton2ed93ab2019-12-17 20:38:03 +000054 void *deviceMemory = vk::allocate(sizeof(DispatchableCommandBuffer), REQUIRED_MEMORY_ALIGNMENT,
Alexis Hetu1a9714a2019-04-12 11:48:12 -040055 DEVICE_MEMORY, DispatchableCommandBuffer::GetAllocationScope());
56 ASSERT(deviceMemory);
Ben Claytona4e06ca2019-12-03 12:38:14 +000057 DispatchableCommandBuffer *commandBuffer = new(deviceMemory) DispatchableCommandBuffer(device, level);
Alexis Hetubffee5e2018-11-19 11:30:43 -050058 if(commandBuffer)
59 {
60 pCommandBuffers[i] = *commandBuffer;
61 }
62 else
63 {
64 for(uint32_t j = 0; j < i; j++)
65 {
66 vk::destroy(pCommandBuffers[j], DEVICE_MEMORY);
67 }
68 for(uint32_t j = 0; j < commandBufferCount; j++)
69 {
70 pCommandBuffers[j] = VK_NULL_HANDLE;
71 }
72 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
73 }
74 }
75
76 commandBuffers->insert(pCommandBuffers, pCommandBuffers + commandBufferCount);
77
78 return VK_SUCCESS;
79}
80
Ben Clayton2ed93ab2019-12-17 20:38:03 +000081void CommandPool::freeCommandBuffers(uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers)
Alexis Hetubffee5e2018-11-19 11:30:43 -050082{
83 for(uint32_t i = 0; i < commandBufferCount; ++i)
84 {
85 commandBuffers->erase(pCommandBuffers[i]);
86 vk::destroy(pCommandBuffers[i], DEVICE_MEMORY);
87 }
88}
89
Alexis Hetucd610c92019-02-01 16:47:51 -050090VkResult CommandPool::reset(VkCommandPoolResetFlags flags)
91{
92 // According the Vulkan 1.1 spec:
93 // "All command buffers that have been allocated from
94 // the command pool are put in the initial state."
95 for(auto commandBuffer : *commandBuffers)
96 {
Alexis Hetubd4cf812019-06-14 15:14:07 -040097 vk::Cast(commandBuffer)->reset(flags);
Alexis Hetucd610c92019-02-01 16:47:51 -050098 }
99
100 // According the Vulkan 1.1 spec:
101 // "Resetting a command pool recycles all of the
102 // resources from all of the command buffers allocated
103 // from the command pool back to the command pool."
104 commandBuffers->clear();
105
106 return VK_SUCCESS;
107}
108
109void CommandPool::trim(VkCommandPoolTrimFlags flags)
110{
111 // TODO (b/119827933): Optimize memory usage here
112}
113
Nicolas Capens157ba262019-12-10 17:49:14 -0500114} // namespace vk