// Copyright 2018 The SwiftShader Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "VkCommandPool.hpp" #include "VkCommandBuffer.hpp" #include "VkDestroy.h" #include <algorithm> namespace vk { CommandPool::CommandPool(const VkCommandPoolCreateInfo* pCreateInfo, void* mem) { // FIXME (b/119409619): use an allocator here so we can control all memory allocations commandBuffers = new std::set<VkCommandBuffer>(); } void CommandPool::destroy(const VkAllocationCallbacks* pAllocator) { // Free command Buffers allocated in allocateCommandBuffers for(auto commandBuffer : *commandBuffers) { vk::destroy(commandBuffer, DEVICE_MEMORY); } // FIXME (b/119409619): use an allocator here so we can control all memory allocations delete commandBuffers; } size_t CommandPool::ComputeRequiredAllocationSize(const VkCommandPoolCreateInfo* pCreateInfo) { return 0; } VkResult CommandPool::allocateCommandBuffers(VkCommandBufferLevel level, uint32_t commandBufferCount, VkCommandBuffer* pCommandBuffers) { for(uint32_t i = 0; i < commandBufferCount; i++) { DispatchableCommandBuffer* commandBuffer = new (DEVICE_MEMORY) DispatchableCommandBuffer(level); if(commandBuffer) { pCommandBuffers[i] = *commandBuffer; } else { for(uint32_t j = 0; j < i; j++) { vk::destroy(pCommandBuffers[j], DEVICE_MEMORY); } for(uint32_t j = 0; j < commandBufferCount; j++) { pCommandBuffers[j] = VK_NULL_HANDLE; } return VK_ERROR_OUT_OF_DEVICE_MEMORY; } } commandBuffers->insert(pCommandBuffers, pCommandBuffers + commandBufferCount); return VK_SUCCESS; } void CommandPool::freeCommandBuffers(uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers) { for(uint32_t i = 0; i < commandBufferCount; ++i) { commandBuffers->erase(pCommandBuffers[i]); vk::destroy(pCommandBuffers[i], DEVICE_MEMORY); } } VkResult CommandPool::reset(VkCommandPoolResetFlags flags) { // According the Vulkan 1.1 spec: // "All command buffers that have been allocated from // the command pool are put in the initial state." for(auto commandBuffer : *commandBuffers) { Cast(commandBuffer)->reset(flags); } // According the Vulkan 1.1 spec: // "Resetting a command pool recycles all of the // resources from all of the command buffers allocated // from the command pool back to the command pool." commandBuffers->clear(); return VK_SUCCESS; } void CommandPool::trim(VkCommandPoolTrimFlags flags) { // TODO (b/119827933): Optimize memory usage here } } // namespace vk