Changed the command pool management
authorAngelos Gkountis <a.gkountis@samsung.com>
Wed, 6 Jun 2018 16:53:56 +0000 (17:53 +0100)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Mon, 11 Jun 2018 17:05:46 +0000 (17:05 +0000)
> The Vulkan::Graphics class manages all command pools.
> Creation of command pools is no longer exposed.
> Command pools are lazily created when command buffer creation is required and are stored in a map using the calling thread's ID as the key.
> All the command pools allocated by the Vulkan::Graphics class are using the eResetCommanBuffer flag to allow for explicit command buffer resetting.

Change-Id: I92a275cf591b3a85c98d596f977b9ec4ef4211c6

dali/graphics/vulkan/api/vulkan-api-controller.cpp
dali/graphics/vulkan/vulkan-command-pool.h
dali/graphics/vulkan/vulkan-framebuffer.cpp
dali/graphics/vulkan/vulkan-graphics-texture.cpp
dali/graphics/vulkan/vulkan-graphics.cpp
dali/graphics/vulkan/vulkan-graphics.h
dali/graphics/vulkan/vulkan-resource-cache.cpp
dali/graphics/vulkan/vulkan-resource-cache.h
dali/graphics/vulkan/vulkan-swapchain.cpp

index c07249d..c01db12 100644 (file)
@@ -178,12 +178,8 @@ struct Controller::Impl
 
       //apiCommand->PreparePipeline();
 
-      if( !mCommandPool )
-      {
-        mCommandPool = Vulkan::CommandPool::New( mGraphics );
-      }
       // start new command buffer
-      auto cmdbuf = mCommandPool->NewCommandBuffer( false );
+      auto cmdbuf = mGraphics.CreateCommandBuffer( false );//mCommandPool->NewCommandBuffer( false );
       cmdbuf->Reset();
       cmdbuf->Begin( vk::CommandBufferUsageFlagBits::eRenderPassContinue );
       cmdbuf->BindGraphicsPipeline( apiCommand->GetPipeline() );
index 7ac2f3d..464d163 100644 (file)
@@ -35,22 +35,9 @@ class CommandBuffer;
 class CommandPool : public VkManaged
 {
 
-public:
-
-  /**
-   *
-   * @param graphics
-   * @param createInfo
-   * @return
-   */
-  static RefCountedCommandPool New( Graphics& graphics, const vk::CommandPoolCreateInfo& createInfo );
+  friend class Graphics;
 
-  /**
-   *
-   * @param graphics
-   * @return
-   */
-  static RefCountedCommandPool New( Graphics& graphics );
+public:
 
   ~CommandPool() override;
 
@@ -121,6 +108,21 @@ private:
 
   CommandPool( Graphics& graphics, const vk::CommandPoolCreateInfo& createInfo );
 
+  /**
+ *
+ * @param graphics
+ * @param createInfo
+ * @return
+ */
+  static RefCountedCommandPool New( Graphics& graphics, const vk::CommandPoolCreateInfo& createInfo );
+
+  /**
+   *
+   * @param graphics
+   * @return
+   */
+  static RefCountedCommandPool New( Graphics& graphics );
+
   struct Impl;
   std::unique_ptr<Impl> mImpl;
 
index 652ea84..c70748e 100644 (file)
@@ -223,7 +223,6 @@ struct Framebuffer::Impl
 
   uint32_t GetAttachmentCount( AttachmentType type ) const
   {
-    std::vector<RefCountedImageView> retval{};
     switch( type )
     {
       case AttachmentType::COLOR:
index 196885c..765d73e 100644 (file)
@@ -113,44 +113,36 @@ struct Texture::Impl
                               .setLayerCount( 1 )
                               .setBaseArrayLayer( 0 ) );
 
-    if(!mCommandPool)
-    {
-      mCommandPool   = CommandPool::New(mGraphics);
-      mCommandBuffer = mCommandPool->NewCommandBuffer(true);
-    }
-    else
-    {
-      mCommandBuffer->Reset();
-    }
-
-    mCommandBuffer->Begin(vk::CommandBufferUsageFlagBits::eOneTimeSubmit);
+    auto commandBuffer = mGraphics.CreateCommandBuffer( true );
+
+    commandBuffer->Begin(vk::CommandBufferUsageFlagBits::eOneTimeSubmit);
 
     // change layout
-    auto barrier = std::vector<vk::ImageMemoryBarrier>{mCommandBuffer->ImageLayoutTransitionBarrier(
+    auto barrier = std::vector<vk::ImageMemoryBarrier>{commandBuffer->ImageLayoutTransitionBarrier(
       mImage, vk::ImageLayout::ePreinitialized, vk::ImageLayout::eTransferDstOptimal, vk::ImageAspectFlagBits::eColor )};
 
     // change layout to prepare image to transfer data
-    mCommandBuffer->PipelineBarrier(
+    commandBuffer->PipelineBarrier(
       vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, {barrier} );
 
     // copy image
-    mCommandBuffer->CopyBufferToImage( buffer, mImage, vk::ImageLayout::eTransferDstOptimal, {copy} );
+    commandBuffer->CopyBufferToImage( buffer, mImage, vk::ImageLayout::eTransferDstOptimal, {copy} );
 
     // change layout to shader read-only optimal
-    mCommandBuffer->PipelineBarrier(
+    commandBuffer->PipelineBarrier(
       vk::PipelineStageFlagBits::eVertexShader,
       vk::PipelineStageFlagBits::eVertexShader,
       {},
       {},
       {},
-      {mCommandBuffer->ImageLayoutTransitionBarrier(
+      {commandBuffer->ImageLayoutTransitionBarrier(
         mImage, vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, vk::ImageAspectFlagBits::eColor )} );
 
-    mCommandBuffer->End();
+    commandBuffer->End();
 
     // submit and wait till image is uploaded so temporary buffer can be destroyed safely
     auto fence = mGraphics.CreateFence({});
-    VkAssert(mGraphics.Submit( mGraphics.GetGraphicsQueue( 0u ), { SubmissionData{}.SetCommandBuffers( { mCommandBuffer } ) }, fence ));
+    VkAssert(mGraphics.Submit( mGraphics.GetGraphicsQueue( 0u ), { SubmissionData{}.SetCommandBuffers( { commandBuffer } ) }, fence ));
     VkAssert(mGraphics.WaitForFence(fence, std::numeric_limits<uint32_t>::max()));
     return true;
   }
@@ -217,11 +209,6 @@ struct Texture::Impl
   RefCountedImageView mImageView;
   RefCountedSampler   mSampler;
 
-  // command pools should be 'per-thread' so they can be safely
-  // used withing one single thread before submitting them
-  RefCountedCommandPool   mCommandPool;
-  RefCountedCommandBuffer mCommandBuffer; // primary buffer, executed independent
-
   // layouts
   vk::ImageLayout mOldLayout;
   vk::ImageLayout mNewLayout;
index bd2d16c..66808fa 100644 (file)
@@ -73,7 +73,7 @@ const auto VALIDATION_LAYERS = std::vector< const char* >{
   //"VK_LAYER_LUNARG_monitor",             // monitor
   "VK_LAYER_LUNARG_swapchain",           // swapchain
   "VK_LAYER_GOOGLE_threading",           // threading
-  "VK_LAYER_LUNARG_api_dump",            // api
+  //"VK_LAYER_LUNARG_api_dump",            // api
   "VK_LAYER_LUNARG_object_tracker",      // objects
   "VK_LAYER_LUNARG_core_validation",     // core
   "VK_LAYER_GOOGLE_unique_objects",      // unique objects
@@ -365,25 +365,6 @@ RefCountedDescriptorPool Graphics::CreateDescriptorPool()
   NotImplemented()
 }
 
-RefCountedCommandPool Graphics::CreateCommandPool( const vk::CommandPoolCreateInfo& info )
-{
-  //TODO: move the logic of creation here
-  //TODO: add the object to the cache
-  return CommandPool::New( *this,
-                           vk::CommandPoolCreateInfo{}.setQueueFamilyIndex( 0u )
-                                                      .setFlags( vk::CommandPoolCreateFlagBits::eResetCommandBuffer ));
-}
-
-RefCountedCommandBuffer Graphics::CreateCommandBuffer()
-{
-  NotImplemented()
-}
-
-std::vector< RefCountedCommandBuffer > Graphics::CreateCommandBuffers()
-{
-  NotImplemented()
-}
-
 RefCountedGpuMemoryBlock Graphics::CreateGpuMemoryBlock()
 {
   NotImplemented()
@@ -405,6 +386,13 @@ RefCountedSampler Graphics::CreateSampler( const vk::SamplerCreateInfo& samplerC
   return refCountedSampler;
 
 }
+
+RefCountedCommandBuffer Graphics::CreateCommandBuffer( bool primary )
+{
+  auto commandPool = FindCommandPool( std::this_thread::get_id() );
+
+  return commandPool->NewCommandBuffer( primary );
+}
 // --------------------------------------------------------------------------------------------------------------
 
 // Actions ------------------------------------------------------------------------------------------------------
@@ -657,7 +645,7 @@ void Graphics::AddShader( Handle< Shader > shader )
 void Graphics::AddCommandPool( Handle< CommandPool > pool )
 {
   std::lock_guard< std::mutex > lock{ mMutex };
-  mResourceCache->AddCommandPool( std::move( pool ));
+  mResourceCache->AddCommandPool( std::this_thread::get_id(), std::move( pool ));
 }
 
 void Graphics::AddDescriptorPool( Handle< DescriptorPool > pool )
@@ -776,10 +764,10 @@ Graphics::CreateInstance( const std::vector< const char* >& extensions,
       .setPpEnabledLayerNames(validationLayers.data());
 
 #if defined(DEBUG_ENABLED)
-  if( ! getenv("LOG_VULKAN") )
-  {
-    info.setEnabledLayerCount(0);
-  }
+//  if( ! getenv("LOG_VULKAN") )
+//  {
+//    info.setEnabledLayerCount(0);
+//  }
 #endif
 
   mInstance = VkAssert(vk::createInstance(info, *mAllocator));
@@ -1001,6 +989,23 @@ std::vector< const char* > Graphics::PrepareDefaultInstanceExtensions()
   return retval;
 }
 
+RefCountedCommandPool Graphics::FindCommandPool( std::thread::id )
+{
+  RefCountedCommandPool commandPool;
+  {
+    std::lock_guard< std::mutex > lock{ mMutex };
+    commandPool = mResourceCache->FindCommandPool( std::this_thread::get_id() );
+  }
+
+  if( !commandPool )
+  {
+    auto&& createInfo = vk::CommandPoolCreateInfo{}.setFlags( vk::CommandPoolCreateFlagBits::eResetCommandBuffer );
+    commandPool = CommandPool::New( *this,  createInfo);
+  }
+
+  return commandPool;
+}
+
 } // namespace Vulkan
 } // namespace Graphics
 } // namespace Dali
index 5268cdd..1f6d161 100644 (file)
@@ -126,18 +126,14 @@ public: // Create methods
 
   RefCountedDescriptorPool CreateDescriptorPool();
 
-  RefCountedCommandPool CreateCommandPool( const vk::CommandPoolCreateInfo& info );
-
-  RefCountedCommandBuffer CreateCommandBuffer();
-
-  std::vector< RefCountedCommandBuffer > CreateCommandBuffers();
-
   RefCountedGpuMemoryBlock CreateGpuMemoryBlock();
 
   RefCountedDescriptorSet CreateDescriptorSet();
 
   RefCountedSampler CreateSampler( const vk::SamplerCreateInfo& samplerCreateInfo );
 
+  RefCountedCommandBuffer CreateCommandBuffer( bool primary );
+
 public: // Actions
   vk::Result WaitForFence( RefCountedFence fence, uint32_t timeout = std::numeric_limits< uint32_t >::max() );
 
@@ -255,6 +251,8 @@ private: // Methods
 
   std::vector< const char* > PrepareDefaultInstanceExtensions();
 
+  RefCountedCommandPool FindCommandPool( std::thread::id );
+
 private: // Members
 
   std::unique_ptr< GpuMemoryManager > mDeviceMemoryManager;
index 199fee7..05b33d3 100644 (file)
@@ -61,9 +61,9 @@ ResourceCache& ResourceCache::AddShader( RefCountedShader shader )
   return *this;
 }
 
-ResourceCache& ResourceCache::AddCommandPool( RefCountedCommandPool pool )
+ResourceCache& ResourceCache::AddCommandPool( std::thread::id currentThreadId, RefCountedCommandPool pool )
 {
-  mCommandPools.push_back( pool );
+  mCommandPools[currentThreadId] = pool;
   return *this;
 }
 
@@ -100,13 +100,9 @@ RefCountedShader ResourceCache::FindShader( vk::ShaderModule shaderModule )
   return iterator == mShaders.end() ? RefCountedShader() : RefCountedShader(&**iterator);
 }
 
-RefCountedCommandPool ResourceCache::FindCommandPool( vk::CommandPool commandPool )
+RefCountedCommandPool ResourceCache::FindCommandPool( std::thread::id currentThreadId )
 {
-  auto iterator = std::find_if(mCommandPools.begin(),
-                               mCommandPools.end(),
-                               [&](const RefCountedCommandPool entry) { return entry->GetVkHandle() == commandPool; });
-
-  return iterator == mCommandPools.end() ? RefCountedCommandPool() : RefCountedCommandPool(&**iterator);
+  return mCommandPools.find( currentThreadId ) == mCommandPools.end() ? RefCountedCommandPool() : mCommandPools[ currentThreadId ];
 }
 
 RefCountedDescriptorPool ResourceCache::FindDescriptorPool( vk::DescriptorPool descriptorPool )
@@ -236,13 +232,12 @@ ResourceCache& ResourceCache::RemoveCommandPool( CommandPool& commandPool )
 {
   if( !mCommandPools.empty() )
   {
+    using EntryPair = std::pair< std::thread::id, RefCountedCommandPool >;
     auto iterator = std::find_if(mCommandPools.begin(),
                                  mCommandPools.end(),
-                                 [&](const RefCountedCommandPool entry) { return &*entry == &commandPool; });
+                                 [&](const EntryPair& entry) { return &*(entry.second) == &commandPool; });
 
-    std::iter_swap(iterator, std::prev(mCommandPools.end()));
-    mCommandPools.back().Reset();
-    mCommandPools.pop_back();
+    mCommandPools.erase( iterator );
   }
   return *this;
 }
index d99dc10..d4811ec 100644 (file)
@@ -25,6 +25,7 @@
 // INTERNAL INCLUDES
 #include <dali/graphics/vulkan/vulkan-types.h>
 #include <functional>
+#include <thread>
 
 namespace Dali
 {
@@ -33,6 +34,9 @@ namespace Graphics
 namespace Vulkan
 {
 
+using CommandPoolMap = std::unordered_map< std::thread::id, RefCountedCommandPool >;
+using DiscardQueue = std::vector< std::function< void() > >;
+
 /**
  * Stores and manages Vulkan resources
  */
@@ -72,7 +76,7 @@ public:
    * @param pool The command pool object to be added to the cache
    * @return A reference to the ResourceCache
    */
-  ResourceCache& AddCommandPool( RefCountedCommandPool pool );
+  ResourceCache& AddCommandPool( std::thread::id currentThreadId, RefCountedCommandPool pool );
 
   /**
    * Adds the provided descriptor pool object to the descriptor pool cache
@@ -132,10 +136,10 @@ public:
 
   /**
    * Finds the CommandPool object using the specified Vulkan handle
-   * @param commandPool The Vulkan handle of the CommandPool object to be found
+   * @param currentThreadId The Vulkan handle of the CommandPool object to be found
    * @return A Handle to the CommandPool object if found. An empty Handle otherwise
    */
-  RefCountedCommandPool FindCommandPool( vk::CommandPool commandPool );
+  RefCountedCommandPool FindCommandPool( std::thread::id currentThreadId );
 
   /**
    * Finds the DescriptorPool object using the specified Vulkan handle
@@ -249,13 +253,16 @@ private:
   std::vector< RefCountedImage >          mImages;
   std::vector< RefCountedImageView >      mImageViews;
   std::vector< RefCountedShader >         mShaders;
-  std::vector< RefCountedCommandPool >    mCommandPools;
   std::vector< RefCountedDescriptorPool > mDescriptorPools;
   std::vector< RefCountedFramebuffer >    mFramebuffers;
   std::vector< RefCountedSampler >        mSamplers;
   std::vector< RefCountedFence >          mFences;
 
-  std::vector< std::function< void() > >    mDiscardQueue;
+
+  // Command pool map using thread IDs as keys
+  CommandPoolMap                          mCommandPools;
+
+  DiscardQueue                            mDiscardQueue;
 };
 
 } //namespace Vulkan
index bde0881..484155c 100644 (file)
@@ -48,11 +48,6 @@ struct SwapchainBuffer
   RefCountedCommandBuffer masterCmdBuffer;
 
   /*
-   * Each buffer has a command pool to allocate from
-   */
-  RefCountedCommandPool masterCommandPool;
-
-  /*
    * Framebuffer object associated with the buffer
    */
   RefCountedFramebuffer framebuffer;
@@ -137,14 +132,12 @@ struct Swapchain::Impl
     mSwapchainBuffer.clear();
     for( auto&& fb : mFramebuffers )
     {
-      auto cmdPool   = CommandPool::New( mGraphics, vk::CommandPoolCreateInfo{}.setFlags( vk::CommandPoolCreateFlagBits::eResetCommandBuffer ) );
-      auto masterCmd = cmdPool->NewCommandBuffer( true );
+      auto masterCmd = mGraphics.CreateCommandBuffer( true );
 
       auto swapBuffer              = SwapchainBuffer{};
       swapBuffer.framebuffer       = fb;
       swapBuffer.index             = 0;
       swapBuffer.masterCmdBuffer   = masterCmd;
-      swapBuffer.masterCommandPool = cmdPool;
       swapBuffer.endOfFrameFence   = mGraphics.CreateFence({});
       swapBuffer.firstUse          = true;
       mSwapchainBuffer.emplace_back( swapBuffer );
@@ -173,8 +166,7 @@ struct Swapchain::Impl
     /*
      * Create temporary command pool
      */
-    auto commandPool = CommandPool::New( mGraphics );
-    auto cmdBuffer   = commandPool->NewCommandBuffer();
+    auto cmdBuffer   = mGraphics.CreateCommandBuffer( true );
 
     std::vector<vk::ImageMemoryBarrier> barriers;
     RefCountedImageView                        depthStencilImage{};