*/
// 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-pipeline.h>
-#include <dali/graphics/vulkan/vulkan-descriptor-set.h>
#include <dali/graphics/vulkan/vulkan-surface.h>
+#include <dali/graphics/vulkan/vulkan-types.h>
namespace Dali
{
{
namespace Vulkan
{
-
struct CommandBuffer::Impl
{
Impl( CommandPool& commandPool, const vk::CommandBufferAllocateInfo& allocateInfo, vk::CommandBuffer commandBuffer )
mAllocateInfo( allocateInfo ),
mCommandBuffer( commandBuffer )
{
-
}
~Impl()
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 );
{
// 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() );
+ inheritance.setRenderPass( mGraphics.GetSurface( 0 ).GetRenderPass() );
info.setPInheritanceInfo( &inheritance );
}
- VkAssert(mCommandBuffer.begin(info));
+ VkAssert( mCommandBuffer.begin( info ) );
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);
+ assert( mCommandBuffer && "Invalid command buffer!" );
+ mGraphics.GetDevice().freeCommandBuffers( mOwnerCommandPool.GetPool(), mCommandBuffer );
}
- void ImageLayoutTransition(vk::Image image,
- vk::ImageLayout oldLayout,
- vk::ImageLayout newLayout,
- vk::ImageAspectFlags aspectMask)
+ void ImageLayoutTransition( vk::Image image,
+ vk::ImageLayout oldLayout,
+ vk::ImageLayout newLayout,
+ vk::ImageAspectFlags aspectMask )
{
// 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
vk::PipelineStageFlags srcStageMask, dstStageMask;
// TODO: add other transitions
- switch(oldLayout)
+ switch( oldLayout )
{
case vk::ImageLayout::eUndefined:
{
break;
case vk::ImageLayout::ePresentSrcKHR:
{
- srcStageMask = vk::PipelineStageFlagBits::eBottomOfPipe;
+ srcStageMask = vk::PipelineStageFlagBits::eBottomOfPipe;
srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead;
}
break;
case vk::ImageLayout::eColorAttachmentOptimal:
{
- srcStageMask = vk::PipelineStageFlagBits::eFragmentShader | vk::PipelineStageFlagBits::eColorAttachmentOutput;
+ srcStageMask = vk::PipelineStageFlagBits::eFragmentShader | vk::PipelineStageFlagBits::eColorAttachmentOutput;
srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead;
}
break;
case vk::ImageLayout::eSharedPresentKHR:
{
}
- }
+ }
- switch(newLayout)
- {
+ switch( newLayout )
+ {
case vk::ImageLayout::eColorAttachmentOptimal:
{
- dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eFragmentShader;
+ 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;
+ dstAccessMask =
+ vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
break;
}
case vk::ImageLayout::ePresentSrcKHR:
{
break;
}
-
}
- RecordImageLayoutTransition(image, srcAccessMask, dstAccessMask, srcStageMask, dstStageMask,
- oldLayout, newLayout, aspectMask);
+ RecordImageLayoutTransition(
+ image, srcAccessMask, dstAccessMask, srcStageMask, dstStageMask, oldLayout, newLayout, aspectMask );
}
#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)
+ 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);
-
+ 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);
+ 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);
+ 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& surface = mGraphics.GetSurface( framebufferId );
+ auto renderPass = surface.GetRenderPass();
+ auto frameBuffer = surface.GetFramebuffer( bufferIndex );
+ auto clearValues = surface.GetClearValues();
auto info = vk::RenderPassBeginInfo{};
info.setFramebuffer( frameBuffer );
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 {};
+ Graphics& mGraphics;
+ CommandPool& mOwnerCommandPool;
+ vk::CommandBufferAllocateInfo mAllocateInfo{};
- vk::CommandBuffer mCommandBuffer {};
+ 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 };
+ bool mRecording{false};
};
/**
*
*/
-CommandBuffer::CommandBuffer( CommandPool& commandPool, const vk::CommandBufferAllocateInfo& allocateInfo, vk::CommandBuffer vkCommandBuffer )
+CommandBuffer::CommandBuffer( CommandPool& commandPool,
+ const vk::CommandBufferAllocateInfo& allocateInfo,
+ vk::CommandBuffer vkCommandBuffer )
{
mImpl = MakeUnique<Impl>( commandPool, allocateInfo, vkCommandBuffer );
}
}
/** Begin recording */
-void CommandBuffer::Begin(vk::CommandBufferUsageFlags usageFlags, vk::CommandBufferInheritanceInfo* inheritanceInfo)
+void CommandBuffer::Begin( vk::CommandBufferUsageFlags usageFlags, vk::CommandBufferInheritanceInfo* inheritanceInfo )
{
mImpl->Begin( usageFlags, inheritanceInfo );
}
}
/** Records image layout transition barrier for one image */
-void CommandBuffer::ImageLayoutTransition(vk::Image image,
- vk::ImageLayout oldLayout,
- vk::ImageLayout newLayout,
- vk::ImageAspectFlags aspectMask)
+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)
+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 );
+ 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,
+ 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 );
}
{
namespace Vulkan
{
-
struct Framebuffer::Impl
{
- Impl( Framebuffer& owner, Graphics& graphics, uint32_t width, uint32_t height ) :
- mInterface( owner ),
- mGraphics( graphics )
+ Impl( Framebuffer& owner, Graphics& graphics, uint32_t width, uint32_t height )
+ : mInterface( owner ), mGraphics( graphics )
{
-
}
// Framebuffer creation may be deferred
bool Initialise()
{
- if(mInitialised)
+ if( mInitialised )
{
return true;
}
- if(!Validate())
+ if( !Validate() )
{
return false;
}
mInitialised = true;
}
+ // creating render pass may happen either as deferred or
+ // when framebuffer is initialised into immutable state
+ void CreateRenderPass()
+ {
+ // for each attachment...
+#if 0
+ auto attRef = vk::AttachmentReference{};
+
+ // 1. Need to know layout during render pass ( Image::GetLayout() )
+ // 2. Usually it's going to be:
+ // - color_attachment_optimal
+ // - depth_stencil_attachment_optimal
+ //attRef.setLayout();
+ //attRef.setAttachment();
+
+ // Single subpass support, all attachments used
+ // TODO: input, preserve, resolve
+ // TODO: create subpasses
+
+ // creating single subpass per framebuffer
+ auto subpassDesc = vk::SubpassDescription{};
+ subpassDesc.setPipelineBindPoint( vk::PipelineBindPoint::eGraphics );
+ subpassDesc.setColorAttachmentCount( 0 );
+ subpassDesc.setInputAttachmentCount( 0 );
+ subpassDesc.setPDepthStencilAttachment( nullptr );
+ subpassDesc.setPColorAttachments( nullptr );
+ subpassDesc.setPInputAttachments( nullptr );
+ subpassDesc.setPPreserveAttachments( nullptr );
+ subpassDesc.setPResolveAttachments( nullptr );
+
+ // create compatible render pass
+ auto rpInfo = vk::RenderPassCreateInfo{};
+ //rpInfo.setAttachmentCount( mAttachments.size() );
+ //rpInfo.setPAttachments( )
+ rpInfo.setDependencyCount( 0 );
+ rpInfo.setPDependencies( nullptr );
+ rpInfo.setPSubpasses( &subpassDesc );
+ rpInfo.setSubpassCount( 1 );
+#endif
+ }
+
+ void InitialiseAttachments()
+ {
+ ImageRef attachment;
+ vk::ImageViewCreateInfo info;
+ info.setViewType( vk::ImageViewType::e2D );
+ info.setSubresourceRange( //get layercount, get level count
+ vk::ImageSubresourceRange{}.setLevelCount( 1 ).setLayerCount( 1 ).setBaseMipLevel( 0 ).setBaseArrayLayer( 0 ) );
+ info.setImage( attachment->GetVkImage() ); //
+ info.setComponents( vk::ComponentMapping(
+ vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eG, vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eA ) );
+ info.setFormat( vk::Format::eD16Unorm ); // get format
+
+ //ImageViewRef ref = ImageView::New( attachment );
+ }
+
+ void CreateFramebuffer()
+ {
+ // assert if framebuffer is already created
+ InitialiseAttachments();
+
+ vk::FramebufferCreateInfo info;
+ info.setRenderPass( mVkRenderPass )
+ .setPAttachments( nullptr ) // attach imageviews, imageviews are created from supplied images
+ .setLayers( 1 )
+ .setWidth( mWidth )
+ .setHeight( mHeight )
+ .setAttachmentCount( 1 );
+
+ mVkFramebuffer = VkAssert( mGraphics.GetDevice().createFramebuffer( info, mGraphics.GetAllocator() ) );
+ }
void SetAttachment( Handle<Image> image, Framebuffer::AttachmentType type, uint32_t index )
{
if( attachments.size() <= index )
{
- attachments.resize( index+1 );
+ attachments.resize( index + 1 );
}
attachments[index] = image;
}
bool Validate()
{
- if( mWidth == 0u || mHeight == 0 )
+ if( mWidth == 0u || mHeight == 0 )
{
return false;
}
~Impl()
{
-
}
vk::RenderPass GetVkRenderPass() const
return mVkFramebuffer;
}
- Framebuffer& mInterface;
- Graphics& mGraphics;
+ Framebuffer& mInterface;
+ Graphics& mGraphics;
- uint32_t mWidth;
- uint32_t mHeight;
- std::vector<Handle<Image>> mColorAttachments;
- std::vector<Handle<Image>> mDepthStencilAttachments;
+ uint32_t mWidth;
+ uint32_t mHeight;
+ std::vector<Handle<Image>> mColorAttachments;
+ std::vector<Handle<Image>> mDepthStencilAttachments;
- std::vector<ImageView> mImageViewAttachments;
- vk::Framebuffer mVkFramebuffer;
- vk::RenderPass mVkRenderPass;
+ std::vector<ImageView> mImageViewAttachments;
+ vk::Framebuffer mVkFramebuffer;
+ vk::RenderPass mVkRenderPass;
- bool mInitialised { false };
+ bool mInitialised{false};
};
-
Handle<Framebuffer> Framebuffer::New( Graphics& graphics, uint32_t width, uint32_t height )
{
return FramebufferRef();
{
namespace Vulkan
{
+struct Image::Impl
+{
+ Impl( Image& owner, Graphics& graphics, vk::ImageCreateInfo createInfo, vk::Image externalImage = nullptr )
+ : mOwner( owner ),
+ mGraphics( graphics ),
+ mVkImage( externalImage ),
+ mCreateInfo( std::move( createInfo ) ),
+ mIsExternal( static_cast<bool>( externalImage ) )
+ {
+ }
+
+ ~Impl()
+ {
+ if( !mIsExternal )
+ {
+ // destroy
+ }
+ }
+
+ bool Initialise()
+ {
+ if( !mIsExternal )
+ {
+ mVkImage = VkAssert( mGraphics.GetDevice().createImage( mCreateInfo, mGraphics.GetAllocator() ) );
+ if( !mVkImage )
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ Image& mOwner;
+ Graphics& mGraphics;
+ vk::Image mVkImage;
+ vk::ImageLayout mVkImageLayout;
+ vk::ImageCreateInfo mCreateInfo;
+
+ bool mIsExternal;
+};
+
+Image::~Image() = default;
+
+ImageRef Image::New( Graphics& graphics, vk::ImageCreateInfo createInfo )
+{
+ ImageRef retval( new Image( graphics, createInfo, nullptr ) );
+ if( !retval->mImpl->Initialise() )
+ {
+ retval.Reset();
+ }
+ else
+ {
+ graphics.AddImage( retval );
+ }
+ return retval;
+}
+
+ImageRef Image::New( Graphics& graphics, vk::ImageCreateInfo createInfo, vk::Image externalImage )
+{
+ ImageRef retval( new Image( graphics, createInfo, externalImage ) );
+ if( !retval->mImpl->Initialise() )
+ {
+ retval.Reset();
+ }
+ else
+ {
+ graphics.AddImage( retval );
+ }
+ return retval;
+}
-Image::Image(Graphics& graphics, const vk::ImageCreateInfo& createInfo) : mGraphics(graphics)
+Image::Image( Graphics& graphics, const vk::ImageCreateInfo& createInfo, vk::Image externalImage )
{
+ mImpl = MakeUnique<Impl>( *this, graphics, createInfo, externalImage );
}
-Image::Image(Graphics& graphics, vk::Image externalImage)
-: mGraphics(graphics), mImage(externalImage)
+vk::Image Image::GetVkImage() const
{
+ return mImpl->mVkImage;
}
-vk::ImageView Image::CreateUnmanagedView(const vk::ImageViewCreateInfo& info)
+vk::ImageLayout Image::GetVkImageLayout() const
{
- NotImplemented();
- return nullptr;
+ return mImpl->mVkImageLayout;
}
-ImageViewRef Image::CreateView(const vk::ImageViewCreateInfo& info)
+uint32_t Image::GetWidth() const
{
- return MakeRef< ImageView >(mGraphics, *this, info);
+ return mImpl->mCreateInfo.extent.width;
}
-ImageView::ImageView(Graphics& graphics, Image& image) : mGraphics(graphics), mImageRef(&image)
+uint32_t Image::GetHeight() const
{
+ return mImpl->mCreateInfo.extent.height;
}
-ImageView::ImageView(Graphics& graphics, Image& image, const VkImageViewCreateInfo& createInfo)
-: mGraphics(graphics), mImageRef(&image)
+uint32_t Image::GetLayerCount() const
{
- mImageView =
- VkAssert(mGraphics.GetDevice().createImageView(createInfo, mGraphics.GetAllocator()));
+ return mImpl->mCreateInfo.arrayLayers;
}
-ImageView::~ImageView()
+uint32_t Image::GetLevelCount() const
{
- if(mImageView)
+ return mImpl->mCreateInfo.mipLevels;
+}
+
+vk::Format Image::GetVkFormat() const
+{
+ return mImpl->mCreateInfo.format;
+}
+
+vk::ImageType Image::GetVkImageType() const
+{
+ return mImpl->mCreateInfo.imageType;
+}
+
+vk::ImageTiling Image::GetVkImageTiling() const
+{
+ return mImpl->mCreateInfo.tiling;
+}
+
+void Image::BindMemory( GpuMemoryBlockRef& handle )
+{
+}
+
+/***************************************************************************
+ *
+ * ImageView
+ *
+ */
+
+struct ImageView::Impl
+{
+ Impl( ImageView& owner, Graphics& graphics, ImageRef image, vk::ImageViewCreateInfo createInfo )
+ : mOwner( owner ), mGraphics( graphics ), mImage( image ), mCreateInfo( createInfo )
+ {
+ }
+
+ ~Impl()
+ {
+ }
+
+ bool Initialise()
{
- mGraphics.GetDevice().destroyImageView( mImageView, mGraphics.GetAllocator());
+ mVkImageView = VkAssert( mGraphics.GetDevice().createImageView( mCreateInfo, mGraphics.GetAllocator() ) );
+ if( !mVkImageView )
+ {
+ return false;
+ }
+ return true;
}
+
+ ImageView& mOwner;
+ Graphics& mGraphics;
+ ImageRef mImage;
+ vk::ImageViewCreateInfo mCreateInfo;
+
+ vk::ImageView mVkImageView;
+};
+
+ImageViewRef ImageView::New( Graphics& graphics, ImageRef image, vk::ImageViewCreateInfo info )
+{
+ auto retval = ImageViewRef( new ImageView( graphics, image, info ) );
+ if(!retval->mImpl->Initialise())
+ {
+ return ImageViewRef();
+ }
+ return retval;
+}
+
+ImageView::ImageView( Graphics& graphics, ImageRef image, const VkImageViewCreateInfo& createInfo )
+{
+ mImpl = MakeUnique<Impl>( *this, graphics, image, createInfo );
+}
+
+ImageView::~ImageView() = default;
+
+const vk::ImageView& ImageView::GetVkImageView() const
+{
+ return mImpl->mVkImageView;
+}
+
+ImageRef ImageView::GetImage() const
+{
+ return mImpl->mImage;
}
} // namespace Vulkan