/*
- * 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
{
{
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()
return true;
}
- template <class T>
+ template<class T>
bool IsResourceAdded( Handle<T> resourceHandle )
{
for( auto&& res : mResources )
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;
/**
*
*/
- 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;
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 );
}
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 );
}
// 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 )
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;
}
// 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 );
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};
};
/**
*
*/
-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()
}
/** Begin recording */
-void CommandBuffer::Begin(vk::CommandBufferUsageFlags usageFlags, vk::CommandBufferInheritanceInfo* inheritanceInfo)
+void CommandBuffer::Begin( vk::CommandBufferUsageFlags usageFlags, vk::CommandBufferInheritanceInfo* inheritanceInfo )
{
mImpl->Begin( usageFlags, inheritanceInfo );
}
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;
}
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 )
}
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 )
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 );
}
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