OSDN Git Service

Allow Command Buffers to be allocated and freed
authorAlexis Hetu <sugoi@google.com>
Mon, 19 Nov 2018 16:30:43 +0000 (11:30 -0500)
committerAlexis Hétu <sugoi@google.com>
Fri, 30 Nov 2018 19:38:13 +0000 (19:38 +0000)
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>
src/Vulkan/VkCommandPool.cpp
src/Vulkan/VkCommandPool.hpp
src/Vulkan/libVulkan.cpp

index 155dfeb..821d4fb 100644 (file)
 // 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 @@ size_t CommandPool::ComputeRequiredAllocationSize(const VkCommandPoolCreateInfo*
        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
index 46b1426..05135c1 100644 (file)
@@ -16,6 +16,7 @@
 #define VK_COMMAND_POOL_HPP_
 
 #include "VkObject.hpp"
+#include <set>
 
 namespace vk
 {
@@ -29,7 +30,11 @@ public:
 
        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)
index 0d8ca14..2b8f84c 100644 (file)
@@ -1116,9 +1116,13 @@ VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers(VkDevice device, const V
        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 @@ VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers(VkDevice device, VkCommandPool c
        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)