[Vulkan] graphics controller, multiple pipelines
[platform/core/uifw/dali-core.git] / dali / graphics / vulkan / vulkan-command-buffer.cpp
index f67dba9..ff64a71 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 // INTERNAL INCLUDES
 #include <dali/graphics/vulkan/vulkan-types.h>
+#include <dali/graphics/vulkan/vulkan-buffer.h>
 #include <dali/graphics/vulkan/vulkan-command-buffer.h>
 #include <dali/graphics/vulkan/vulkan-command-pool.h>
+#include <dali/graphics/vulkan/vulkan-descriptor-set.h>
 #include <dali/graphics/vulkan/vulkan-graphics.h>
-#include <dali/graphics/vulkan/vulkan-buffer.h>
 #include <dali/graphics/vulkan/vulkan-image.h>
+#include <dali/graphics/vulkan/vulkan-fence.h>
 #include <dali/graphics/vulkan/vulkan-pipeline.h>
-#include <dali/graphics/vulkan/vulkan-descriptor-set.h>
 #include <dali/graphics/vulkan/vulkan-surface.h>
+#include <dali/graphics/vulkan/vulkan-framebuffer.h>
 
 namespace Dali
 {
@@ -32,20 +34,30 @@ namespace Graphics
 {
 namespace Vulkan
 {
-
 struct CommandBuffer::Impl
 {
-  Impl( CommandPool& commandPool, const vk::CommandBufferAllocateInfo& allocateInfo, vk::CommandBuffer commandBuffer )
-  : mGraphics( commandPool.GetGraphics() ),
+  Impl( CommandBuffer& owner, CommandPool& commandPool, uint32_t poolIndex, const vk::CommandBufferAllocateInfo& allocateInfo, vk::CommandBuffer commandBuffer )
+  : mOwner( owner ),
+    mGraphics( commandPool.GetGraphics() ),
     mOwnerCommandPool( commandPool ),
+    mPoolAllocationIndex( poolIndex ),
     mAllocateInfo( allocateInfo ),
     mCommandBuffer( commandBuffer )
   {
-
   }
 
   ~Impl()
   {
+    mGraphics.GetDevice().freeCommandBuffers( mOwnerCommandPool.GetPool(),
+                                              1, &mCommandBuffer );
+  }
+
+  void ReleaseCommandBuffer()
+  {
+    mResources.clear();
+
+    // tell pool the buffer is not in use anymore
+    mOwnerCommandPool.ReleaseCommandBuffer(mOwner, false);
   }
 
   bool Initialise()
@@ -53,7 +65,7 @@ struct CommandBuffer::Impl
     return true;
   }
 
-  template <class T>
+  template<class T>
   bool IsResourceAdded( Handle<T> resourceHandle )
   {
     for( auto&& res : mResources )
@@ -66,12 +78,12 @@ struct CommandBuffer::Impl
     return false;
   }
 
-  template <class T>
+  template<class T>
   bool PushResource( Handle<T> resourceHandle )
   {
-    if(!IsResourceAdded( resourceHandle ))
+    if( !IsResourceAdded( resourceHandle ) )
     {
-      mResources.push_back(VkTypeCast<VkManaged>( resourceHandle ));
+      mResources.push_back( VkTypeCast<VkManaged>( resourceHandle ) );
       return true;
     }
     return false;
@@ -80,170 +92,74 @@ struct CommandBuffer::Impl
   /**
    *
    */
-  void Begin(vk::CommandBufferUsageFlags usageFlags, vk::CommandBufferInheritanceInfo* inheritanceInfo)
+  void Begin( vk::CommandBufferUsageFlags usageFlags, vk::CommandBufferInheritanceInfo* inheritanceInfo )
   {
-    assert(!mRecording && "CommandBuffer already is in the recording state");
+    assert( !mRecording && "CommandBuffer already is in the recording state" );
     auto info = vk::CommandBufferBeginInfo{};
-    info.setPInheritanceInfo(inheritanceInfo);
-    info.setFlags(usageFlags);
+    info.setPInheritanceInfo( inheritanceInfo );
+    info.setFlags( usageFlags );
 
     // set the inheritance option
     auto inheritance = vk::CommandBufferInheritanceInfo{}.setSubpass( 0 );
 
     if( mAllocateInfo.level == vk::CommandBufferLevel::eSecondary )
     {
-      // todo: sets render pass from 'default' surface, should be supplied from primary command buffer
-      // which has render pass associated within execution context
-      inheritance.setRenderPass( mGraphics.GetSurface(0).GetRenderPass() );
+      // Render pass is obtained from the default framebuffer
+      // it's a legacy but little nicer
+      auto swapchain = mGraphics.GetSwapchainForFBID( 0u );
+      inheritance.setRenderPass( swapchain->GetCurrentFramebuffer()->GetVkRenderPass() );
       info.setPInheritanceInfo( &inheritance );
     }
 
-    VkAssert(mCommandBuffer.begin(info));
+    VkAssert( mCommandBuffer.begin( info ) );
+
+    mResources.clear();
+
     mRecording = true;
   }
 
   void End()
   {
-    assert(mRecording && "CommandBuffer is not in the recording state!");
-    VkAssert(mCommandBuffer.end());
+    assert( mRecording && "CommandBuffer is not in the recording state!" );
+    VkAssert( mCommandBuffer.end() );
     mRecording = false;
   }
 
   void Reset()
   {
-    assert(!mRecording && "Can't reset command buffer during recording!");
-    assert(mCommandBuffer && "Invalid command buffer!");
-    mCommandBuffer.reset(vk::CommandBufferResetFlagBits::eReleaseResources);
-  }
+    assert( !mRecording && "Can't reset command buffer during recording!" );
+    assert( mCommandBuffer && "Invalid command buffer!" );
+    mCommandBuffer.reset( vk::CommandBufferResetFlagBits::eReleaseResources );
 
-  void Free()
-  {
-    assert(mCommandBuffer && "Invalid command buffer!");
-    mGraphics.GetDevice().freeCommandBuffers(mOwnerCommandPool.GetPool(), mCommandBuffer);
+    mResources.clear();
   }
 
-  void ImageLayoutTransition(vk::Image            image,
-                             vk::ImageLayout      oldLayout,
-                             vk::ImageLayout      newLayout,
-                             vk::ImageAspectFlags aspectMask)
+  void Free()
   {
-    // just push new image barrier until any command is being called or buffer recording ends.
-    // it will make sure we batch barriers together rather than calling cmdPipelineBarrier
-    // for each separately
-    vk::AccessFlags        srcAccessMask, dstAccessMask;
-    vk::PipelineStageFlags srcStageMask, dstStageMask;
-
-    // TODO: add other transitions
-    switch(oldLayout)
-    {
-      case vk::ImageLayout::eUndefined:
-      {
-        srcStageMask = vk::PipelineStageFlagBits::eTopOfPipe;
-      }
-      break;
-      case vk::ImageLayout::ePresentSrcKHR:
-      {
-        srcStageMask = vk::PipelineStageFlagBits::eBottomOfPipe;
-        srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead;
-      }
-      break;
-      case vk::ImageLayout::eColorAttachmentOptimal:
-      {
-        srcStageMask = vk::PipelineStageFlagBits::eFragmentShader | vk::PipelineStageFlagBits::eColorAttachmentOutput;
-        srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead;
-      }
-      break;
-      case vk::ImageLayout::eGeneral:
-      case vk::ImageLayout::eDepthStencilAttachmentOptimal:
-      case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
-      case vk::ImageLayout::eShaderReadOnlyOptimal:
-      case vk::ImageLayout::eTransferSrcOptimal:
-      case vk::ImageLayout::eTransferDstOptimal:
-      case vk::ImageLayout::ePreinitialized:
-      case vk::ImageLayout::eSharedPresentKHR:
-      {
-      }
-      }
-
-      switch(newLayout)
-      {
-      case vk::ImageLayout::eColorAttachmentOptimal:
-      {
-        dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eFragmentShader;
-        dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eHostWrite;
-        break;
-      }
-      case vk::ImageLayout::eDepthStencilAttachmentOptimal:
-      {
-        dstStageMask = vk::PipelineStageFlagBits::eFragmentShader | vk::PipelineStageFlagBits::eEarlyFragmentTests;
-        dstAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
-        break;
-      }
-      case vk::ImageLayout::ePresentSrcKHR:
-      {
-        dstStageMask  = vk::PipelineStageFlagBits::eBottomOfPipe;
-        dstAccessMask = vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eMemoryRead;
-      }
-      case vk::ImageLayout::eGeneral:
-      case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
-      case vk::ImageLayout::eShaderReadOnlyOptimal:
-      case vk::ImageLayout::eTransferSrcOptimal:
-      case vk::ImageLayout::eTransferDstOptimal:
-      case vk::ImageLayout::ePreinitialized:
-      case vk::ImageLayout::eUndefined:
-      case vk::ImageLayout::eSharedPresentKHR:
-      {
-        break;
-      }
-
-    }
-
-    RecordImageLayoutTransition(image, srcAccessMask, dstAccessMask, srcStageMask, dstStageMask,
-                                oldLayout, newLayout, aspectMask);
+    assert( mCommandBuffer && "Invalid command buffer!" );
+    mGraphics.GetDevice().freeCommandBuffers( mOwnerCommandPool.GetPool(), mCommandBuffer );
   }
 
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wframe-larger-than="
-  void RecordImageLayoutTransition(vk::Image image, vk::AccessFlags srcAccessMask,
-                                   vk::AccessFlags dstAccessMask, vk::PipelineStageFlags srcStageMask,
-                                   vk::PipelineStageFlags dstStageMask, vk::ImageLayout oldLayout,
-                                   vk::ImageLayout newLayout, vk::ImageAspectFlags aspectMask)
-  {
-    vk::ImageSubresourceRange subres;
-    subres.setLayerCount(1).setBaseMipLevel(0).setBaseArrayLayer(0).setLevelCount(1).setAspectMask(aspectMask);
-
-
-    auto barrier = vk::ImageMemoryBarrier{};
-    barrier
-      .setImage(image)
-      .setSubresourceRange(subres)
-      .setSrcAccessMask(srcAccessMask)
-      .setDstAccessMask(dstAccessMask)
-      .setOldLayout(oldLayout)
-      .setNewLayout(newLayout);
-    ;
-    // todo: implement barriers batching
-    mCommandBuffer.pipelineBarrier(srcStageMask, dstStageMask, vk::DependencyFlags{}, nullptr, nullptr, barrier);
-  }
-#pragma GCC diagnostic pop
 
   /** Push wait semaphores */
-  void PushWaitSemaphores(const std::vector< vk::Semaphore >&          semaphores,
-                          const std::vector< vk::PipelineStageFlags >& stages)
+  void PushWaitSemaphores( const std::vector<vk::Semaphore>&          semaphores,
+                           const std::vector<vk::PipelineStageFlags>& stages )
   {
     mWaitSemaphores = semaphores;
     mWaitStages     = stages;
   }
 
   /** Push signal semaphores */
-  void PushSignalSemaphores(const std::vector< vk::Semaphore >& semaphores)
+  void PushSignalSemaphores( const std::vector<vk::Semaphore>& semaphores )
   {
     mSignalSemaphores = semaphores;
   }
 
   // TODO: handles should be synchronized
-  void BindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount, std::vector<Handle<Buffer>> buffers,
-                                        const vk::DeviceSize *pOffsets)
+  void BindVertexBuffers( uint32_t                    firstBinding,
+                          uint32_t                    bindingCount,
+                          std::vector<Handle<Buffer>> buffers,
+                          const vk::DeviceSize*       pOffsets )
   {
     // update list of used resources and create an array of VkBuffers
     std::vector<vk::Buffer> vkBuffers;
@@ -251,16 +167,17 @@ struct CommandBuffer::Impl
     for( auto&& buffer : buffers )
     {
       vkBuffers.emplace_back( buffer->GetVkBuffer() );
-      PushResource(buffer);
+      PushResource( buffer );
     }
 
-    mCommandBuffer.bindVertexBuffers( firstBinding, bindingCount, vkBuffers.data(), pOffsets);
+    mCommandBuffer.bindVertexBuffers( firstBinding, bindingCount, vkBuffers.data(), pOffsets );
   }
 
-  void BindIndexBuffer( BufferRef buffer, uint32_t offset, vk::IndexType indexType)
+  void BindIndexBuffer( BufferRef buffer, uint32_t offset, vk::IndexType indexType )
   {
     // validate
-    assert ( (buffer->GetUsage() & vk::BufferUsageFlagBits::eIndexBuffer) && "The buffer used as index buffer has wrong usage flags!" );
+    assert( ( buffer->GetUsage() & vk::BufferUsageFlagBits::eIndexBuffer ) &&
+            "The buffer used as index buffer has wrong usage flags!" );
 
     PushResource( buffer );
     mCommandBuffer.bindIndexBuffer( buffer->GetVkBuffer(), offset, indexType );
@@ -274,7 +191,9 @@ struct CommandBuffer::Impl
   }
 
   void BindDescriptorSets( std::vector<Dali::Graphics::Vulkan::Handle<DescriptorSet>> descriptorSets,
-                                          Handle<Pipeline> pipeline, uint32_t firstSet, uint32_t descriptorSetCount )
+                           Handle<Pipeline>                                           pipeline,
+                           uint32_t                                                   firstSet,
+                           uint32_t                                                   descriptorSetCount )
   {
     // update resources
     PushResource( pipeline );
@@ -287,8 +206,13 @@ struct CommandBuffer::Impl
     }
 
     // TODO: support dynamic offsets
-    mCommandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, pipeline->GetVkPipelineLayout(),
-    firstSet, descriptorSetCount, vkSets.data(), 0, nullptr );
+    mCommandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics,
+                                       pipeline->GetVkPipelineLayout(),
+                                       firstSet,
+                                       descriptorSetCount,
+                                       vkSets.data(),
+                                       0,
+                                       nullptr );
   }
 
   void Draw( uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance )
@@ -296,12 +220,14 @@ struct CommandBuffer::Impl
     mCommandBuffer.draw( vertexCount, instanceCount, firstVertex, firstInstance );
   }
 
-  void DrawIndexed( uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, uint32_t vertexOffset, uint32_t firstInstance )
+  void DrawIndexed(
+    uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, uint32_t vertexOffset, uint32_t firstInstance )
   {
-    mCommandBuffer.drawIndexed( indexCount, instanceCount, firstIndex, vertexOffset, firstInstance );
+    mCommandBuffer.drawIndexed(
+      indexCount, instanceCount, firstIndex, static_cast<int32_t>( vertexOffset ), firstInstance );
   }
 
-  const std::vector< Handle<VkManaged>> GetResources() const
+  const std::vector<Handle<VkManaged>> GetResources() const
   {
     return mResources;
   }
@@ -309,17 +235,18 @@ struct CommandBuffer::Impl
   // RENDER PASS
   void BeginRenderPass( FBID framebufferId, uint32_t bufferIndex )
   {
-    auto& surface = mGraphics.GetSurface( framebufferId );
-    auto renderPass = surface.GetRenderPass();
-    auto frameBuffer = surface.GetFramebuffer( bufferIndex );
-    auto clearValues = surface.GetClearValues();
+    auto swapchain = mGraphics.GetSwapchainForFBID( 0u );
+    auto surface = mGraphics.GetSurface( 0u );
+    auto frameBuffer = swapchain->GetCurrentFramebuffer();
+    auto renderPass = frameBuffer->GetVkRenderPass();
+    auto clearValues = frameBuffer->GetDefaultClearValues();
 
     auto info = vk::RenderPassBeginInfo{};
-    info.setFramebuffer( frameBuffer );
+    info.setFramebuffer( frameBuffer->GetVkFramebuffer() );
     info.setRenderPass( renderPass );
-    info.setClearValueCount( U32(clearValues.size()) );
+    info.setClearValueCount( U32( clearValues.size() ) );
     info.setPClearValues( clearValues.data() );
-    info.setRenderArea( vk::Rect2D( { 0,0 }, surface.GetSize() ) );
+    info.setRenderArea( vk::Rect2D( {0, 0}, surface->GetSize() ) );
 
     mCurrentRenderPass = renderPass;
     mCommandBuffer.beginRenderPass( info, vk::SubpassContents::eInline );
@@ -350,24 +277,79 @@ struct CommandBuffer::Impl
     mCommandBuffer.executeCommands( vkBuffers );
   }
 
-  Graphics&                       mGraphics;
-  CommandPool&                    mOwnerCommandPool;
-  vk::CommandBufferAllocateInfo   mAllocateInfo {};
+  void PipelineBarrier( vk::PipelineStageFlags srcStageMask,
+                        vk::PipelineStageFlags dstStageMask,
+                        vk::DependencyFlags dependencyFlags,
+                        std::vector<vk::MemoryBarrier> memoryBarriers,
+                        std::vector<vk::BufferMemoryBarrier> bufferBarriers,
+                        std::vector<vk::ImageMemoryBarrier> imageBarriers )
+  {
+    /*
+     * Track resources
+     */
+    if( !imageBarriers.empty() )
+    {
+      for( auto&& imageBarrier : imageBarriers )
+      {
+        ImageRef imageResource{};
+        if( (imageResource = mGraphics.FindImage( imageBarrier.image )) )
+        {
+          PushResource( imageResource );
+        }
+      }
+    }
+    //@ todo other resource tracking
+
+    mCommandBuffer.pipelineBarrier( srcStageMask, dstStageMask, dependencyFlags, memoryBarriers, bufferBarriers, imageBarriers );
+  }
 
-  vk::CommandBuffer     mCommandBuffer {};
+  void CopyBufferToImage( BufferRef srcBuffer, ImageRef dstImage, vk::ImageLayout dstLayout, std::vector<vk::BufferImageCopy> regions )
+  {
+    PushResource( srcBuffer );
+    PushResource( dstImage );
+
+    mCommandBuffer.copyBufferToImage( srcBuffer->GetVkBuffer(), dstImage->GetVkImage(), dstLayout, regions );
+  }
+
+  vk::ImageMemoryBarrier ImageLayoutTransitionBarrier( ImageRef image,
+                                                      const vk::AccessFlags&        srcAccessMask,
+                                                      const vk::AccessFlags&        dstAccessMask,
+                                                      vk::ImageLayout        oldLayout,
+                                                      vk::ImageLayout        newLayout,
+                                                      const vk::ImageAspectFlags&   aspectMask
+  ) const
+  {
+    return vk::ImageMemoryBarrier{}
+         .setNewLayout( newLayout )
+         .setImage( image->GetVkImage() )
+         .setOldLayout( oldLayout )
+         .setSrcAccessMask( srcAccessMask )
+         .setDstAccessMask( dstAccessMask )
+         .setSubresourceRange( vk::ImageSubresourceRange{ aspectMask, 0, image->GetLevelCount(), 0, image->GetLayerCount() } );
+  }
+
+  CommandBuffer&                mOwner;
+  Graphics&                     mGraphics;
+  CommandPool&                  mOwnerCommandPool;
+  uint32_t                      mPoolAllocationIndex;
+  vk::CommandBufferAllocateInfo mAllocateInfo{};
+
+  vk::CommandBuffer mCommandBuffer{};
 
   // semaphores per command buffer
-  std::vector< vk::Semaphore >          mSignalSemaphores {};
-  std::vector< vk::Semaphore >          mWaitSemaphores {};
-  std::vector< vk::PipelineStageFlags > mWaitStages {};
+  std::vector<vk::Semaphore>          mSignalSemaphores{};
+  std::vector<vk::Semaphore>          mWaitSemaphores{};
+  std::vector<vk::PipelineStageFlags> mWaitStages{};
 
-  std::vector< Handle<VkManaged>> mResources; // used resources
+  std::vector<Handle<VkManaged>> mResources; // used resources
 
   PipelineRef mCurrentPipeline;
 
   vk::RenderPass mCurrentRenderPass;
 
-  bool mRecording { false };
+  FenceRef       mFinishedFence;
+
+  bool mRecording{false};
 };
 
 /**
@@ -376,9 +358,12 @@ struct CommandBuffer::Impl
  *
  */
 
-CommandBuffer::CommandBuffer( CommandPool& commandPool, const vk::CommandBufferAllocateInfo& allocateInfo, vk::CommandBuffer vkCommandBuffer )
+CommandBuffer::CommandBuffer( CommandPool&                         commandPool,
+                              uint32_t                             poolIndex,
+                              const vk::CommandBufferAllocateInfo& allocateInfo,
+                              vk::CommandBuffer                    vkCommandBuffer )
 {
-  mImpl = MakeUnique<Impl>( commandPool, allocateInfo, vkCommandBuffer );
+  mImpl = MakeUnique<Impl>( *this, commandPool, poolIndex, allocateInfo, vkCommandBuffer );
 }
 
 CommandBuffer::~CommandBuffer()
@@ -386,7 +371,7 @@ CommandBuffer::~CommandBuffer()
 }
 
 /** Begin recording */
-void CommandBuffer::Begin(vk::CommandBufferUsageFlags usageFlags, vk::CommandBufferInheritanceInfo* inheritanceInfo)
+void CommandBuffer::Begin( vk::CommandBufferUsageFlags usageFlags, vk::CommandBufferInheritanceInfo* inheritanceInfo )
 {
   mImpl->Begin( usageFlags, inheritanceInfo );
 }
@@ -409,47 +394,30 @@ void CommandBuffer::Free()
   mImpl->Free();
 }
 
-/** Records image layout transition barrier for one image */
-void CommandBuffer::ImageLayoutTransition(vk::Image            image,
-                                          vk::ImageLayout      oldLayout,
-                                          vk::ImageLayout      newLayout,
-                                          vk::ImageAspectFlags aspectMask)
-{
-  mImpl->ImageLayoutTransition( image, oldLayout, newLayout, aspectMask );
-}
-
-void CommandBuffer::RecordImageLayoutTransition(vk::Image image, vk::AccessFlags srcAccessMask,
-                                                vk::AccessFlags dstAccessMask, vk::PipelineStageFlags srcStageMask,
-                                                vk::PipelineStageFlags dstStageMask, vk::ImageLayout oldLayout,
-                                                vk::ImageLayout newLayout, vk::ImageAspectFlags aspectMask)
-{
-  mImpl->RecordImageLayoutTransition( image, srcAccessMask, dstAccessMask,srcStageMask, dstStageMask, oldLayout, newLayout, aspectMask );
-}
-
 /** Push wait semaphores */
-void CommandBuffer::PushWaitSemaphores(const std::vector< vk::Semaphore >&          semaphores,
-                                       const std::vector< vk::PipelineStageFlags >& stages)
+void CommandBuffer::PushWaitSemaphores( const std::vector<vk::Semaphore>&          semaphores,
+                                        const std::vector<vk::PipelineStageFlags>& stages )
 {
   mImpl->PushWaitSemaphores( semaphores, stages );
 }
 
 /** Push signal semaphores */
-void CommandBuffer::PushSignalSemaphores(const std::vector< vk::Semaphore >& semaphores)
+void CommandBuffer::PushSignalSemaphores( const std::vector<vk::Semaphore>& semaphores )
 {
   mImpl->PushSignalSemaphores( semaphores );
 }
 
-const std::vector< vk::Semaphore >& CommandBuffer::GetSignalSemaphores() const
+const std::vector<vk::Semaphore>& CommandBuffer::GetSignalSemaphores() const
 {
   return mImpl->mSignalSemaphores;
 }
 
-const std::vector< vk::Semaphore >& CommandBuffer::GetSWaitSemaphores() const
+const std::vector<vk::Semaphore>& CommandBuffer::GetSWaitSemaphores() const
 {
   return mImpl->mWaitSemaphores;
 }
 
-const std::vector< vk::PipelineStageFlags >& CommandBuffer::GetWaitSemaphoreStages() const
+const std::vector<vk::PipelineStageFlags>& CommandBuffer::GetWaitSemaphoreStages() const
 {
   return mImpl->mWaitStages;
 }
@@ -464,20 +432,24 @@ bool CommandBuffer::IsPrimary() const
   return mImpl->mAllocateInfo.level == vk::CommandBufferLevel::ePrimary;
 }
 
-void CommandBuffer::BindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount, std::vector<Handle<Buffer>> buffers,
-                       const vk::DeviceSize *pOffsets)
+void CommandBuffer::BindVertexBuffers( uint32_t                    firstBinding,
+                                       uint32_t                    bindingCount,
+                                       std::vector<Handle<Buffer>> buffers,
+                                       const vk::DeviceSize*       pOffsets )
 {
   mImpl->BindVertexBuffers( firstBinding, bindingCount, buffers, pOffsets );
 }
 
-void CommandBuffer::BindIndexBuffer( BufferRef buffer, uint32_t offset, vk::IndexType indexType)
+void CommandBuffer::BindIndexBuffer( BufferRef buffer, uint32_t offset, vk::IndexType indexType )
 {
   mImpl->BindIndexBuffer( buffer, offset, indexType );
 }
 
-void CommandBuffer::BindVertexBuffer(uint32_t binding, Dali::Graphics::Vulkan::Handle<Buffer> buffer, vk::DeviceSize offset )
+void CommandBuffer::BindVertexBuffer( uint32_t                               binding,
+                                      const Dali::Graphics::Vulkan::Handle<Buffer>& buffer,
+                                      vk::DeviceSize                         offset )
 {
-  mImpl->BindVertexBuffers( binding, 1, std::vector<Handle<Buffer>>({ buffer }), &offset );
+  mImpl->BindVertexBuffers( binding, 1, std::vector<Handle<Buffer>>( {buffer} ), &offset );
 }
 
 void CommandBuffer::BindGraphicsPipeline( Handle<Pipeline> pipeline )
@@ -486,14 +458,18 @@ void CommandBuffer::BindGraphicsPipeline( Handle<Pipeline> pipeline )
 }
 
 void CommandBuffer::BindDescriptorSets( std::vector<Dali::Graphics::Vulkan::Handle<DescriptorSet>> descriptorSets,
-                         Handle<Pipeline> pipeline, uint32_t firstSet, uint32_t descriptorSetCount )
+                                        Handle<Pipeline>                                           pipeline,
+                                        uint32_t                                                   firstSet,
+                                        uint32_t                                                   descriptorSetCount )
 {
   mImpl->BindDescriptorSets( descriptorSets, pipeline, firstSet, descriptorSetCount );
 }
 
-void CommandBuffer::BindDescriptorSets( std::vector<Dali::Graphics::Vulkan::Handle<DescriptorSet>> descriptorSets, uint32_t firstSet )
+void CommandBuffer::BindDescriptorSets( std::vector<Dali::Graphics::Vulkan::Handle<DescriptorSet>> descriptorSets,
+                                        uint32_t                                                   firstSet )
 {
-  mImpl->BindDescriptorSets( descriptorSets, mImpl->mCurrentPipeline, 0, static_cast<uint32_t>(descriptorSets.size()) );
+  mImpl->BindDescriptorSets(
+    descriptorSets, mImpl->mCurrentPipeline, 0, static_cast<uint32_t>( descriptorSets.size() ) );
 }
 
 void CommandBuffer::Draw( uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance )
@@ -501,7 +477,8 @@ void CommandBuffer::Draw( uint32_t vertexCount, uint32_t instanceCount, uint32_t
   mImpl->Draw( vertexCount, instanceCount, firstVertex, firstInstance );
 }
 
-void CommandBuffer::DrawIndexed( uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, uint32_t vertexOffset, uint32_t firstInstance )
+void CommandBuffer::DrawIndexed(
+  uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, uint32_t vertexOffset, uint32_t firstInstance )
 {
   mImpl->DrawIndexed( indexCount, instanceCount, firstIndex, vertexOffset, firstInstance );
 }
@@ -526,6 +503,139 @@ void CommandBuffer::ExecuteCommands( std::vector<Dali::Graphics::Vulkan::Handle<
   mImpl->ExecuteCommands( commandBuffers );
 }
 
+void CommandBuffer::PipelineBarrier( vk::PipelineStageFlags srcStageMask,
+                      vk::PipelineStageFlags dstStageMask,
+                      vk::DependencyFlags dependencyFlags,
+                      std::vector<vk::MemoryBarrier> memoryBarriers,
+                      std::vector<vk::BufferMemoryBarrier> bufferBarriers,
+                      std::vector<vk::ImageMemoryBarrier> imageBarriers )
+{
+  mImpl->PipelineBarrier( srcStageMask, dstStageMask, dependencyFlags, memoryBarriers, bufferBarriers, imageBarriers );
+}
+
+void CommandBuffer::CopyBufferToImage( BufferRef srcBuffer, ImageRef dstImage,
+                                       vk::ImageLayout dstLayout, std::vector<vk::BufferImageCopy> regions )
+{
+  mImpl->CopyBufferToImage( srcBuffer, dstImage, dstLayout, regions );
+}
+
+vk::ImageMemoryBarrier CommandBuffer::ImageLayoutTransitionBarrier( ImageRef image,
+                                                     vk::AccessFlags        srcAccessMask,
+                                                     vk::AccessFlags        dstAccessMask,
+                                                     vk::ImageLayout        oldLayout,
+                                                     vk::ImageLayout        newLayout,
+                                                     vk::ImageAspectFlags   aspectMask
+) const
+{
+  return mImpl->ImageLayoutTransitionBarrier( image,
+                                              srcAccessMask, dstAccessMask,
+                                              oldLayout, newLayout,
+                                              aspectMask  );
+}
+
+vk::ImageMemoryBarrier CommandBuffer::ImageLayoutTransitionBarrier( ImageRef image,
+                                                     vk::ImageLayout        oldLayout,
+                                                     vk::ImageLayout        newLayout,
+                                                     vk::ImageAspectFlags   aspectMask
+) const
+{
+
+  vk::AccessFlags  srcAccessMask, dstAccessMask;
+  vk::PipelineStageFlags srcStageMask, dstStageMask;
+
+  switch( oldLayout )
+  {
+    case vk::ImageLayout::ePreinitialized:
+    case vk::ImageLayout::eUndefined:
+    {
+      srcAccessMask = {};
+      srcStageMask  = vk::PipelineStageFlagBits::eTopOfPipe;
+      break;
+    }
+    case vk::ImageLayout::ePresentSrcKHR:
+    {
+      srcAccessMask = vk::AccessFlagBits::eColorAttachmentRead;
+      srcStageMask  = vk::PipelineStageFlagBits::eColorAttachmentOutput;
+      break;
+    }
+    case vk::ImageLayout::eTransferSrcOptimal:
+    {
+      srcAccessMask = vk::AccessFlagBits::eMemoryRead;
+      srcStageMask  = vk::PipelineStageFlagBits::eTransfer;
+      break;
+    }
+    case vk::ImageLayout::eTransferDstOptimal:
+    {
+      srcAccessMask = vk::AccessFlagBits::eMemoryWrite;
+      srcStageMask  = vk::PipelineStageFlagBits::eTransfer;
+      break;
+    }
+    case vk::ImageLayout::eGeneral:
+    case vk::ImageLayout::eColorAttachmentOptimal:
+    case vk::ImageLayout::eDepthStencilAttachmentOptimal:
+    case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
+    case vk::ImageLayout::eShaderReadOnlyOptimal:
+    case vk::ImageLayout::eSharedPresentKHR:
+    {
+      break;
+    }
+  }
+
+  switch( newLayout )
+  {
+    case vk::ImageLayout::ePresentSrcKHR:
+    {
+      dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
+      dstStageMask  = vk::PipelineStageFlagBits::eBottomOfPipe;
+      break;
+    }
+    case vk::ImageLayout::eTransferSrcOptimal:
+    {
+      dstAccessMask = vk::AccessFlagBits::eMemoryRead;
+      dstStageMask  = vk::PipelineStageFlagBits::eTransfer;
+      break;
+    }
+    case vk::ImageLayout::eTransferDstOptimal:
+    {
+      dstAccessMask = vk::AccessFlagBits::eMemoryWrite;
+      dstStageMask  = vk::PipelineStageFlagBits::eTransfer;
+      break;
+    }
+    case vk::ImageLayout::eShaderReadOnlyOptimal:
+    {
+      dstAccessMask = vk::AccessFlagBits::eMemoryRead;
+      dstStageMask = vk::PipelineStageFlagBits::eVertexShader;
+      break;
+    }
+    case vk::ImageLayout::eUndefined:
+    case vk::ImageLayout::eGeneral:
+    case vk::ImageLayout::eColorAttachmentOptimal:
+    case vk::ImageLayout::eDepthStencilAttachmentOptimal:
+    case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
+    case vk::ImageLayout::ePreinitialized:
+    case vk::ImageLayout::eSharedPresentKHR:
+    {
+      break;
+    }
+  }
+
+  return mImpl->ImageLayoutTransitionBarrier( image,
+                                              srcAccessMask, dstAccessMask,
+                                              oldLayout, newLayout,
+                                              aspectMask  );
+}
+
+uint32_t CommandBuffer::GetPoolAllocationIndex() const
+{
+  return mImpl->mPoolAllocationIndex;
+}
+
+bool CommandBuffer::OnDestroy()
+{
+  mImpl->ReleaseCommandBuffer();
+  return true;
+}
+
 } // namespace Vulkan
 } // namespace Graphics
 } // namespace Dali