Allow Command Buffers to be allocated and freed Added functionality so that the CommandPool can allocate and free command buffer objects. Bug b/119827933 Change-Id: I190ba3cd7738f2b5e37b196a0abba6d07cfae173 Reviewed-on: https://swiftshader-review.googlesource.com/c/22748 Tested-by: Alexis Hétu <sugoi@google.com> Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Vulkan/VkCommandPool.cpp b/src/Vulkan/VkCommandPool.cpp index 155dfeb..821d4fb 100644 --- a/src/Vulkan/VkCommandPool.cpp +++ b/src/Vulkan/VkCommandPool.cpp
@@ -13,16 +13,28 @@ // limitations under the License. #include "VkCommandPool.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) @@ -30,4 +42,41 @@ 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); + } +} + } // namespace vk
diff --git a/src/Vulkan/VkCommandPool.hpp b/src/Vulkan/VkCommandPool.hpp index 46b1426..05135c1 100644 --- a/src/Vulkan/VkCommandPool.hpp +++ b/src/Vulkan/VkCommandPool.hpp
@@ -16,6 +16,7 @@ #define VK_COMMAND_POOL_HPP_ #include "VkObject.hpp" +#include <set> namespace vk { @@ -29,7 +30,11 @@ static size_t ComputeRequiredAllocationSize(const VkCommandPoolCreateInfo* pCreateInfo); + VkResult allocateCommandBuffers(VkCommandBufferLevel level, uint32_t commandBufferCount, VkCommandBuffer* pCommandBuffers); + void freeCommandBuffers(uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers); + private: + std::set<VkCommandBuffer>* commandBuffers; }; static inline CommandPool* Cast(VkCommandPool object)
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp index 0d8ca14..2b8f84c 100644 --- a/src/Vulkan/libVulkan.cpp +++ b/src/Vulkan/libVulkan.cpp
@@ -1116,9 +1116,13 @@ TRACE("(VkDevice device = 0x%X, const VkCommandBufferAllocateInfo* pAllocateInfo = 0x%X, VkCommandBuffer* pCommandBuffers = 0x%X)", device, pAllocateInfo, pCommandBuffers); - UNIMPLEMENTED(); + if(pAllocateInfo->pNext) + { + UNIMPLEMENTED(); + } - return VK_SUCCESS; + return vk::Cast(pAllocateInfo->commandPool)->allocateCommandBuffers( + pAllocateInfo->level, pAllocateInfo->commandBufferCount, pCommandBuffers); } VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers) @@ -1126,7 +1130,7 @@ TRACE("(VkDevice device = 0x%X, VkCommandPool commandPool = 0x%X, uint32_t commandBufferCount = %d, const VkCommandBuffer* pCommandBuffers = 0x%X)", device, commandPool, commandBufferCount, pCommandBuffers); - UNIMPLEMENTED(); + vk::Cast(commandPool)->freeCommandBuffers(commandBufferCount, pCommandBuffers); } VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo* pBeginInfo)