1// 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"
16#include "VkCommandBuffer.hpp"
17#include "VkDestroy.h"
18#include <algorithm>
19#include <new>
20
21namespace vk
22{
23
24CommandPool::CommandPool(const VkCommandPoolCreateInfo* pCreateInfo, void* mem)
25{
26 // FIXME (b/119409619): use an allocator here so we can control all memory allocations
27 void* deviceMemory = vk::allocate(sizeof(std::set<VkCommandBuffer>), REQUIRED_MEMORY_ALIGNMENT,
28 DEVICE_MEMORY, GetAllocationScope());
29 ASSERT(deviceMemory);
30 commandBuffers = new (deviceMemory) std::set<VkCommandBuffer>();
31}
32
33void CommandPool::destroy(const VkAllocationCallbacks* pAllocator)
34{
35 // Free command Buffers allocated in allocateCommandBuffers
36 for(auto commandBuffer : *commandBuffers)
37 {
38 vk::destroy(commandBuffer, DEVICE_MEMORY);
39 }
40
41 // FIXME (b/119409619): use an allocator here so we can control all memory allocations
42 vk::deallocate(commandBuffers, DEVICE_MEMORY);
43}
44
45size_t CommandPool::ComputeRequiredAllocationSize(const VkCommandPoolCreateInfo* pCreateInfo)
46{
47 return 0;
48}
49
50VkResult CommandPool::allocateCommandBuffers(VkCommandBufferLevel level, uint32_t commandBufferCount, VkCommandBuffer* pCommandBuffers)
51{
52 for(uint32_t i = 0; i < commandBufferCount; i++)
53 {
54 // FIXME (b/119409619): use an allocator here so we can control all memory allocations
55 void* deviceMemory = vk::allocate(sizeof(DispatchableCommandBuffer), REQUIRED_MEMORY_ALIGNMENT,
56 DEVICE_MEMORY, DispatchableCommandBuffer::GetAllocationScope());
57 ASSERT(deviceMemory);
58 DispatchableCommandBuffer* commandBuffer = new (deviceMemory) DispatchableCommandBuffer(level);
59 if(commandBuffer)
60 {
61 pCommandBuffers[i] = *commandBuffer;
62 }
63 else
64 {
65 for(uint32_t j = 0; j < i; j++)
66 {
67 vk::destroy(pCommandBuffers[j], DEVICE_MEMORY);
68 }
69 for(uint32_t j = 0; j < commandBufferCount; j++)
70 {
71 pCommandBuffers[j] = VK_NULL_HANDLE;
72 }
73 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
74 }
75 }
76
77 commandBuffers->insert(pCommandBuffers, pCommandBuffers + commandBufferCount);
78
79 return VK_SUCCESS;
80}
81
82void CommandPool::freeCommandBuffers(uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers)
83{
84 for(uint32_t i = 0; i < commandBufferCount; ++i)
85 {
86 commandBuffers->erase(pCommandBuffers[i]);
87 vk::destroy(pCommandBuffers[i], DEVICE_MEMORY);
88 }
89}
90
91VkResult CommandPool::reset(VkCommandPoolResetFlags flags)
92{
93 // According the Vulkan 1.1 spec:
94 // "All command buffers that have been allocated from
95 // the command pool are put in the initial state."
96 for(auto commandBuffer : *commandBuffers)
97 {
98 vk::Cast(commandBuffer)->reset(flags);
99 }
100
101 // According the Vulkan 1.1 spec:
102 // "Resetting a command pool recycles all of the
103 // resources from all of the command buffers allocated
104 // from the command pool back to the command pool."
105 commandBuffers->clear();
106
107 return VK_SUCCESS;
108}
109
110void CommandPool::trim(VkCommandPoolTrimFlags flags)
111{
112 // TODO (b/119827933): Optimize memory usage here
113}
114
115} // namespace vk
116