From: Angelos Gkountis Date: Wed, 30 May 2018 14:32:52 +0000 (+0100) Subject: Refactored the Vulkan::Image class X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fbcc01aa9caf4a2fb627a19010628b5f58408e00;p=platform%2Fcore%2Fuifw%2Fdali-core.git Refactored the Vulkan::Image class > Removed the PIMPL pattern. > Renamed the static method New that created a RefCountedImage from an external Vulkan image handle to NewFromExternal. > Removed the Vk prefix from certain getter methods in the Vulkan::Image class. > Moved the image creation login to the Vulkan::Graphics class. > Moved the image memory binding logic to the Vulkan::Graphics class. > Renamed the BindMemory method of the Vulkan::Image class to AssingMemory. > AssignMemory now only assigns the RefCountedGpuMemoryBlock to the image to increase the ref count. To bind memory to an image, users should use the Graphics::BindImageMemory(, , ) method. > Altered already existing image creation code to use the new paradigm. Change-Id: I32bd621dcd59eac7c24a0759798bde15a7870083 --- diff --git a/dali/graphics/vulkan/tests/texture-test.cpp b/dali/graphics/vulkan/tests/texture-test.cpp index 71198ba..23dbfce 100644 --- a/dali/graphics/vulkan/tests/texture-test.cpp +++ b/dali/graphics/vulkan/tests/texture-test.cpp @@ -68,22 +68,25 @@ struct Texture bool Initialise() { // create image - mImage = Image::New( mGraphics, - vk::ImageCreateInfo{} - .setFormat( mPixmap.pixelFormat ) - .setInitialLayout( vk::ImageLayout::ePreinitialized ) - .setSamples( vk::SampleCountFlagBits::e1 ) - .setSharingMode( vk::SharingMode::eExclusive ) - .setUsage( vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst ) - .setExtent( {mPixmap.width, mPixmap.height, 1} ) - .setArrayLayers( 1 ) - .setImageType( vk::ImageType::e2D ) - .setTiling( vk::ImageTiling::eOptimal ) - .setMipLevels( 1 ) ); - - // allocate memory and bind to the image - auto& allocator = mGraphics.GetDeviceMemoryManager().GetDefaultAllocator(); - mImage->BindMemory( allocator.Allocate( mImage, vk::MemoryPropertyFlagBits::eDeviceLocal ) ); + auto imageCreateInfo = vk::ImageCreateInfo{} + .setFormat( mPixmap.pixelFormat ) + .setInitialLayout( vk::ImageLayout::ePreinitialized ) + .setSamples( vk::SampleCountFlagBits::e1 ) + .setSharingMode( vk::SharingMode::eExclusive ) + .setUsage( vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst ) + .setExtent( {mPixmap.width, mPixmap.height, 1} ) + .setArrayLayers( 1 ) + .setImageType( vk::ImageType::e2D ) + .setTiling( vk::ImageTiling::eOptimal ) + .setMipLevels( 1 ); + + mImage = mGraphics.CreateImage( imageCreateInfo ); + + auto& allocator = mGraphics + .GetDeviceMemoryManager() + .GetDefaultAllocator(); + + mGraphics.BindImageMemory( mImage, allocator.Allocate( mImage, vk::MemoryPropertyFlagBits::eDeviceLocal ), 0 ); // create transient buffer to copy data auto size = mPixmap.data.size()*sizeof(mPixmap.data[0]); diff --git a/dali/graphics/vulkan/vulkan-framebuffer.cpp b/dali/graphics/vulkan/vulkan-framebuffer.cpp index 7ae876b..652ea84 100644 --- a/dali/graphics/vulkan/vulkan-framebuffer.cpp +++ b/dali/graphics/vulkan/vulkan-framebuffer.cpp @@ -58,7 +58,7 @@ struct Framebuffer::Impl vk::AttachmentDescription attDesc{}; attDesc.setSamples( vk::SampleCountFlagBits::e1 ) .setInitialLayout( vk::ImageLayout::eUndefined ) - .setFormat( colorAttachment->GetImage()->GetVkFormat() ) + .setFormat( colorAttachment->GetImage()->GetFormat() ) .setStencilStoreOp( vk::AttachmentStoreOp::eDontCare ) .setStencilLoadOp( vk::AttachmentLoadOp::eDontCare ) .setLoadOp( vk::AttachmentLoadOp::eClear ) @@ -87,7 +87,7 @@ struct Framebuffer::Impl vk::AttachmentDescription attDesc{}; attDesc.setSamples( vk::SampleCountFlagBits::e1 ) .setInitialLayout( vk::ImageLayout::eUndefined ) - .setFormat( mDepthStencilImageViewAttachment->GetImage()->GetVkFormat() ) + .setFormat( mDepthStencilImageViewAttachment->GetImage()->GetFormat() ) .setStencilStoreOp( vk::AttachmentStoreOp::eDontCare ) .setStencilLoadOp( vk::AttachmentLoadOp::eDontCare ) .setLoadOp( vk::AttachmentLoadOp::eClear ) diff --git a/dali/graphics/vulkan/vulkan-graphics-texture.cpp b/dali/graphics/vulkan/vulkan-graphics-texture.cpp index 63afce1..800eb01 100644 --- a/dali/graphics/vulkan/vulkan-graphics-texture.cpp +++ b/dali/graphics/vulkan/vulkan-graphics-texture.cpp @@ -154,27 +154,33 @@ struct Texture::Impl return true; } - // creates image with preallocated memory and default sampler, no data + // creates image with pre-allocated memory and default sampler, no data // uploaded at this point bool Initialise() { - //TODO: Create image using the Graphics class // create image - mImage = Image::New( mGraphics, - vk::ImageCreateInfo{} - .setFormat( mPixmap.pixelFormat ) - .setInitialLayout( vk::ImageLayout::ePreinitialized ) - .setSamples( vk::SampleCountFlagBits::e1 ) - .setSharingMode( vk::SharingMode::eExclusive ) - .setUsage( vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst ) - .setExtent( {mPixmap.width, mPixmap.height, 1} ) - .setArrayLayers( 1 ) - .setImageType( vk::ImageType::e2D ) - .setTiling( vk::ImageTiling::eOptimal ) - .setMipLevels( 1 ) ); - // allocate memory and bind to the image - auto& allocator = mGraphics.GetDeviceMemoryManager().GetDefaultAllocator(); - mImage->BindMemory( allocator.Allocate( mImage, vk::MemoryPropertyFlagBits::eDeviceLocal ) ); + auto imageCreateInfo = vk::ImageCreateInfo{} + .setFormat( mPixmap.pixelFormat ) + .setInitialLayout( vk::ImageLayout::ePreinitialized ) + .setSamples( vk::SampleCountFlagBits::e1 ) + .setSharingMode( vk::SharingMode::eExclusive ) + .setUsage( vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst ) + .setExtent( {mPixmap.width, mPixmap.height, 1} ) + .setArrayLayers( 1 ) + .setImageType( vk::ImageType::e2D ) + .setTiling( vk::ImageTiling::eOptimal ) + .setMipLevels( 1 ); + + // Create the image handle + mImage = mGraphics.CreateImage( imageCreateInfo ); + + // allocate memory for the image + auto memory = mGraphics.GetDeviceMemoryManager() + .GetDefaultAllocator() + .Allocate(mImage, vk::MemoryPropertyFlagBits::eDeviceLocal ); + + // bind the allocated memory to the image + mGraphics.BindImageMemory( mImage, memory, 0 ); // create default image view mImageView = mGraphics.CreateImageView(mImage); diff --git a/dali/graphics/vulkan/vulkan-graphics.cpp b/dali/graphics/vulkan/vulkan-graphics.cpp index 15ca0c9..8bb95ff 100644 --- a/dali/graphics/vulkan/vulkan-graphics.cpp +++ b/dali/graphics/vulkan/vulkan-graphics.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -289,9 +290,13 @@ RefCountedFramebuffer Graphics::CreateFramebuffer() NotImplemented() } -RefCountedImage Graphics::CreateImage() +RefCountedImage Graphics::CreateImage( const vk::ImageCreateInfo& imageCreateInfo ) { - NotImplemented() + auto refCountedImage = Image::New(*this, imageCreateInfo); + + VkAssert( mDevice.createImage( &imageCreateInfo, mAllocator.get(), refCountedImage->Ref() ) ); + + return refCountedImage; } RefCountedImageView Graphics::CreateImageView( const vk::ImageViewCreateFlags& flags, @@ -321,16 +326,16 @@ RefCountedImageView Graphics::CreateImageView( RefCountedImage image ) vk::ComponentMapping componentsMapping = { vk::ComponentSwizzle::eR, vk::ComponentSwizzle::eG, vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eA }; vk::ImageAspectFlags aspectFlags{}; - if( image->GetVkImageUsageFlags() & vk::ImageUsageFlagBits::eColorAttachment ) + if( image->GetUsageFlags() & vk::ImageUsageFlagBits::eColorAttachment ) { aspectFlags |= vk::ImageAspectFlagBits::eColor; //componentsMapping = { vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eB,vk::ComponentSwizzle::eA }; } - if( image->GetVkImageUsageFlags() & vk::ImageUsageFlagBits::eDepthStencilAttachment ) + if( image->GetUsageFlags() & vk::ImageUsageFlagBits::eDepthStencilAttachment ) { aspectFlags |= ( vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil ); } - if( image->GetVkImageUsageFlags() & vk::ImageUsageFlagBits::eSampled ) + if( image->GetUsageFlags() & vk::ImageUsageFlagBits::eSampled ) { aspectFlags |= ( vk::ImageAspectFlagBits::eColor ); //componentsMapping = { vk::ComponentSwizzle::eB, vk::ComponentSwizzle::eG, vk::ComponentSwizzle::eR,vk::ComponentSwizzle::eA }; @@ -346,7 +351,7 @@ RefCountedImageView Graphics::CreateImageView( RefCountedImage image ) return CreateImageView( {}, image, vk::ImageViewType::e2D, - image->GetVkFormat(), + image->GetFormat(), componentsMapping, subresourceRange ); } @@ -424,6 +429,13 @@ vk::Result Graphics::ResetFences( const std::vector< RefCountedFence >& fences ) return mDevice.resetFences( vkFenceHandles ); } + +vk::Result Graphics::BindImageMemory( RefCountedImage image, RefCountedGpuMemoryBlock memory, uint32_t offset ) +{ + auto result = VkAssert( mDevice.bindImageMemory( image->GetVkHandle(), *memory, offset ) ); + image->AssignMemory(memory); + return result; +} // -------------------------------------------------------------------------------------------------------------- // Getters ------------------------------------------------------------------------------------------------------ @@ -612,6 +624,12 @@ void Graphics::RemoveBuffer( Buffer& buffer ) mResourceCache->RemoveBuffer( buffer ); } +void Graphics::RemoveImage( Image& image ) +{ + std::lock_guard< std::mutex > lock{ mMutex }; + mResourceCache->RemoveImage( image ); +} + void Graphics::RemoveShader( Shader& shader ) { std::lock_guard< std::mutex > lock{ mMutex }; @@ -770,12 +788,8 @@ std::vector< vk::DeviceQueueCreateInfo > Graphics::GetQueueCreateInfos() { transferFamily = queueFamilyIndex; } - if( mPhysicalDevice.getSurfaceSupportKHR( queueFamilyIndex, mSurfaceFBIDMap.begin() - ->second - .surface - ->GetSurfaceKHR()) - .value && - presentFamily == -1u ) + if( mPhysicalDevice.getSurfaceSupportKHR( queueFamilyIndex, mSurfaceFBIDMap.begin()->second. + surface->GetSurfaceKHR()).value && presentFamily == -1u ) { presentFamily = queueFamilyIndex; } diff --git a/dali/graphics/vulkan/vulkan-graphics.h b/dali/graphics/vulkan/vulkan-graphics.h index 4cb64d8..af31ca3 100644 --- a/dali/graphics/vulkan/vulkan-graphics.h +++ b/dali/graphics/vulkan/vulkan-graphics.h @@ -49,15 +49,25 @@ namespace Vulkan { class Buffer; + class Image; + class Pipeline; + class Shader; + class Framebuffer; + class Surface; + class CommandPool; + class DescriptorPool; + class GpuMemoryManager; + class PipelineCache; + class ResourceCache; using SurfaceFactory = Dali::Integration::Graphics::SurfaceFactory; @@ -73,46 +83,72 @@ class Graphics public: Graphics(); - Graphics(const Graphics&) = delete; - Graphics& operator=(const Graphics&) = delete; + + Graphics( const Graphics& ) = delete; + + Graphics& operator=( const Graphics& ) = delete; + ~Graphics(); public: // Create methods - void Create(); - void CreateDevice(); - FBID CreateSurface(std::unique_ptr< SurfaceFactory > surfaceFactory); - RefCountedSwapchain CreateSwapchainForSurface( RefCountedSurface surface ); - RefCountedShader CreateShader(); //will see if this will work - RefCountedPipeline CreatePipeline(); - RefCountedFence CreateFence( const vk::FenceCreateInfo& fenceCreateInfo ); - RefCountedBuffer CreateBuffer( size_t size, BufferType type ); - RefCountedBuffer CreateBuffer( const vk::BufferCreateInfo& bufferCreateInfo ); - RefCountedFramebuffer CreateFramebuffer(); - RefCountedImage CreateImage(); - RefCountedImageView CreateImageView(const vk::ImageViewCreateFlags& flags, - const RefCountedImage& image, - vk::ImageViewType viewType, - vk::Format format, - vk::ComponentMapping components, - vk::ImageSubresourceRange subresourceRange); - RefCountedImageView CreateImageView(RefCountedImage image); - RefCountedDescriptorPool CreateDescriptorPool(); - RefCountedCommandPool CreateCommandPool(const vk::CommandPoolCreateInfo& info); - RefCountedCommandBuffer CreateCommandBuffer(); - std::vector< RefCountedCommandBuffer > CreateCommandBuffers(); - RefCountedGpuMemoryBlock CreateGpuMemoryBlock(); - RefCountedDescriptorSet CreateDescriptorSet(); - RefCountedSampler CreateSampler(); + void Create(); + + void CreateDevice(); + + FBID CreateSurface( std::unique_ptr< SurfaceFactory > surfaceFactory ); + + RefCountedSwapchain CreateSwapchainForSurface( RefCountedSurface surface ); + + RefCountedShader CreateShader(); //will see if this will work + RefCountedPipeline CreatePipeline(); + + RefCountedFence CreateFence( const vk::FenceCreateInfo& fenceCreateInfo ); + + RefCountedBuffer CreateBuffer( size_t size, BufferType type ); + + RefCountedBuffer CreateBuffer( const vk::BufferCreateInfo& bufferCreateInfo ); + + RefCountedFramebuffer CreateFramebuffer(); + + RefCountedImage CreateImage( const vk::ImageCreateInfo& imageCreateInfo ); + + RefCountedImageView CreateImageView( const vk::ImageViewCreateFlags& flags, + const RefCountedImage& image, + vk::ImageViewType viewType, + vk::Format format, + vk::ComponentMapping components, + vk::ImageSubresourceRange subresourceRange ); + + RefCountedImageView CreateImageView( RefCountedImage image ); + + RefCountedDescriptorPool CreateDescriptorPool(); + + RefCountedCommandPool CreateCommandPool( const vk::CommandPoolCreateInfo& info ); + + RefCountedCommandBuffer CreateCommandBuffer(); + + std::vector< RefCountedCommandBuffer > CreateCommandBuffers(); + + RefCountedGpuMemoryBlock CreateGpuMemoryBlock(); + + RefCountedDescriptorSet CreateDescriptorSet(); + + RefCountedSampler CreateSampler(); public: // Actions vk::Result WaitForFence( RefCountedFence fence, uint32_t timeout = 0 ); + vk::Result WaitForFences( const std::vector< RefCountedFence >& fences, bool waitAll = true, - uint32_t timeout = std::numeric_limits< uint32_t >::max() ); + uint32_t timeout = std::numeric_limits< uint32_t >::max()); + vk::Result ResetFence( RefCountedFence fence ); + vk::Result ResetFences( const std::vector< RefCountedFence >& fences ); + vk::Result BindImageMemory( RefCountedImage image, RefCountedGpuMemoryBlock memory, uint32_t offset); + public: // Getters RefCountedSurface GetSurface( FBID surfaceId ); @@ -132,9 +168,12 @@ public: // Getters const vk::PhysicalDeviceMemoryProperties& GetMemoryProperties() const; - Queue& GetGraphicsQueue(uint32_t index = 0u) const; - Queue& GetTransferQueue(uint32_t index = 0u) const; - Queue& GetComputeQueue(uint32_t index = 0u) const; + Queue& GetGraphicsQueue( uint32_t index = 0u ) const; + + Queue& GetTransferQueue( uint32_t index = 0u ) const; + + Queue& GetComputeQueue( uint32_t index = 0u ) const; + Queue& GetPresentQueue() const; Platform GetDefaultPlatform() const; @@ -146,76 +185,95 @@ public: // Getters public: //Cache management methods void AddBuffer( RefCountedBuffer buffer ); + void AddImage( RefCountedImage image ); + void AddShader( RefCountedShader shader ); + void AddCommandPool( RefCountedCommandPool pool ); + void AddDescriptorPool( RefCountedDescriptorPool pool ); + void AddFramebuffer( RefCountedFramebuffer framebuffer ); RefCountedShader FindShader( vk::ShaderModule shaderModule ); + RefCountedImage FindImage( vk::Image image ); void RemoveBuffer( Buffer& buffer ); + + void RemoveImage( Image& image ); + void RemoveShader( Shader& shader ); + void RemoveCommandPool( CommandPool& commandPool ); + void RemoveDescriptorPool( DescriptorPool& pool ); + void RemoveFramebuffer( Framebuffer& framebuffer ); + void RemoveSampler( Sampler& sampler ); void CollectGarbage(); - void DiscardResource(std::function deleter); + void DiscardResource( std::function< void() > deleter ); private: // Methods - void CreateInstance( const std::vector& extensions, - const std::vector& validationLayers ); - void DestroyInstance(); - void PreparePhysicalDevice(); - void GetPhysicalDeviceProperties(); - void GetQueueFamilyProperties(); - std::vector< vk::DeviceQueueCreateInfo > GetQueueCreateInfos(); - std::vector PrepareDefaultInstanceExtensions(); + void CreateInstance( const std::vector< const char* >& extensions, + const std::vector< const char* >& validationLayers ); + + void DestroyInstance(); + + void PreparePhysicalDevice(); + + void GetPhysicalDeviceProperties(); + + void GetQueueFamilyProperties(); + + std::vector< vk::DeviceQueueCreateInfo > GetQueueCreateInfos(); + + std::vector< const char* > PrepareDefaultInstanceExtensions(); private: // Members - std::unique_ptr mDeviceMemoryManager; + std::unique_ptr< GpuMemoryManager > mDeviceMemoryManager; - vk::Instance mInstance; - std::unique_ptr mAllocator{nullptr}; + vk::Instance mInstance; + std::unique_ptr< vk::AllocationCallbacks > mAllocator{ nullptr }; // physical device vk::PhysicalDevice mPhysicalDevice; // logical device - vk::Device mDevice; + vk::Device mDevice; // physical device properties - std::unique_ptr< vk::PhysicalDeviceProperties > mPhysicalDeviceProperties; - std::unique_ptr< vk::PhysicalDeviceMemoryProperties > mPhysicalDeviceMemoryProperties; - std::unique_ptr< vk::PhysicalDeviceFeatures > mPhysicalDeviceFeatures; + std::unique_ptr< vk::PhysicalDeviceProperties > mPhysicalDeviceProperties; + std::unique_ptr< vk::PhysicalDeviceMemoryProperties > mPhysicalDeviceMemoryProperties; + std::unique_ptr< vk::PhysicalDeviceFeatures > mPhysicalDeviceFeatures; // queue family properties - std::vector< vk::QueueFamilyProperties > mQueueFamilyProperties; + std::vector< vk::QueueFamilyProperties > mQueueFamilyProperties; - std::unordered_map< FBID, SwapchainSurfacePair > mSurfaceFBIDMap; - FBID mBaseFBID{0u}; + std::unordered_map< FBID, SwapchainSurfacePair > mSurfaceFBIDMap; + FBID mBaseFBID{ 0u }; // Sets of queues - std::vector< std::unique_ptr > mGraphicsQueues; - std::vector< std::unique_ptr > mTransferQueues; - std::vector< std::unique_ptr > mComputeQueues; + std::vector< std::unique_ptr< Queue > > mGraphicsQueues; + std::vector< std::unique_ptr< Queue > > mTransferQueues; + std::vector< std::unique_ptr< Queue > > mComputeQueues; //std::unique_ptr< Queue > mPresentQueue; - Platform mPlatform { Platform::UNDEFINED }; + Platform mPlatform{ Platform::UNDEFINED }; - std::unique_ptr mGfxController; + std::unique_ptr< Dali::Graphics::VulkanAPI::Controller > mGfxController; // TODO: rename - std::unique_ptr mPipelineDatabase; + std::unique_ptr< PipelineCache > mPipelineDatabase; - std::mutex mMutex; - std::unique_ptr< ResourceCache > mResourceCache; + std::mutex mMutex; + std::unique_ptr< ResourceCache > mResourceCache; }; diff --git a/dali/graphics/vulkan/vulkan-image-view.h b/dali/graphics/vulkan/vulkan-image-view.h index f322ca7..fe2aa28 100644 --- a/dali/graphics/vulkan/vulkan-image-view.h +++ b/dali/graphics/vulkan/vulkan-image-view.h @@ -82,6 +82,8 @@ public: operator vk::ImageView*(); + //TODO: Use the graphics class to manage lifetime. + private: ImageView( Graphics& graphics, RefCountedImage image, diff --git a/dali/graphics/vulkan/vulkan-image.cpp b/dali/graphics/vulkan/vulkan-image.cpp index 16603b1..ac1b9f6 100644 --- a/dali/graphics/vulkan/vulkan-image.cpp +++ b/dali/graphics/vulkan/vulkan-image.cpp @@ -25,143 +25,110 @@ namespace Graphics { 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( externalImage ) ) - { - mVkImageLayout = mCreateInfo.initialLayout; - } - - ~Impl() - { - if( !mIsExternal ) - { - // destroy - } - } - - bool Initialise() - { - if( !mIsExternal ) - { - mVkImage = VkAssert( mGraphics.GetDevice().createImage( mCreateInfo, mGraphics.GetAllocator() ) ); - if( !mVkImage ) - { - return false; - } - } - return true; - } - - void BindMemory( const RefCountedGpuMemoryBlock& handle ) - { - mGraphics.GetDevice().bindImageMemory( mVkImage, *handle, 0 ); - mDeviceMemory = handle; - } - - Image& mOwner; - Graphics& mGraphics; - vk::Image mVkImage; - vk::ImageLayout mVkImageLayout; - vk::ImageCreateInfo mCreateInfo; - - RefCountedGpuMemoryBlock mDeviceMemory; - bool mIsExternal; -}; Image::~Image() = default; RefCountedImage Image::New( Graphics& graphics, vk::ImageCreateInfo createInfo ) { - RefCountedImage retval( new Image( graphics, createInfo, nullptr ) ); - if( !retval->mImpl->Initialise() ) - { - retval.Reset(); - } - else - { - graphics.AddImage( retval ); - } - return retval; + return RefCountedImage( new Image( graphics, createInfo, nullptr ) ); } -RefCountedImage Image::New( Graphics& graphics, vk::ImageCreateInfo createInfo, vk::Image externalImage ) +RefCountedImage Image::NewFromExternal( Graphics& graphics, vk::ImageCreateInfo createInfo, vk::Image externalImage ) { - RefCountedImage retval( new Image( graphics, createInfo, externalImage ) ); - if( !retval->mImpl->Initialise() ) - { - retval.Reset(); - } - else - { - graphics.AddImage( retval ); - } - return retval; + return RefCountedImage( new Image( graphics, createInfo, externalImage ) ); } Image::Image( Graphics& graphics, const vk::ImageCreateInfo& createInfo, vk::Image externalImage ) + : mGraphics(&graphics), + mCreateInfo(createInfo), + mImage(externalImage), + mImageLayout(mCreateInfo.initialLayout), + mIsExternal( static_cast(externalImage)) { - mImpl = MakeUnique( *this, graphics, createInfo, externalImage ); } vk::Image Image::GetVkHandle() const { - return mImpl->mVkImage; + return mImage; } -vk::ImageLayout Image::GetVkImageLayout() const +vk::ImageLayout Image::GetImageLayout() const { - return mImpl->mVkImageLayout; + return mImageLayout; } uint32_t Image::GetWidth() const { - return mImpl->mCreateInfo.extent.width; + return mCreateInfo.extent.width; } uint32_t Image::GetHeight() const { - return mImpl->mCreateInfo.extent.height; + return mCreateInfo.extent.height; } uint32_t Image::GetLayerCount() const { - return mImpl->mCreateInfo.arrayLayers; + return mCreateInfo.arrayLayers; } uint32_t Image::GetMipLevelCount() const { - return mImpl->mCreateInfo.mipLevels; + return mCreateInfo.mipLevels; +} + +vk::Format Image::GetFormat() const +{ + return mCreateInfo.format; +} + +vk::ImageType Image::GetImageType() const +{ + return mCreateInfo.imageType; +} + +vk::ImageTiling Image::GetImageTiling() const +{ + return mCreateInfo.tiling; +} + +void Image::AssignMemory( RefCountedGpuMemoryBlock memory ) +{ + mDeviceMemory = memory; } -vk::Format Image::GetVkFormat() const +const Image& Image::ConstRef() { - return mImpl->mCreateInfo.format; + return *this; } -vk::ImageType Image::GetVkImageType() const +Image& Image::Ref() { - return mImpl->mCreateInfo.imageType; + return *this; } -vk::ImageTiling Image::GetVkImageTiling() const +Image::operator vk::Image*() { - return mImpl->mCreateInfo.tiling; + return &mImage; } -void Image::BindMemory( const RefCountedGpuMemoryBlock& handle ) +vk::ImageUsageFlags Image::GetUsageFlags() const { - mImpl->BindMemory( handle ); + return mCreateInfo.usage; } -vk::ImageUsageFlags Image::GetVkImageUsageFlags() const +bool Image::OnDestroy() { - return mImpl->mCreateInfo.usage; + if( !mIsExternal ) + { + mGraphics->RemoveImage(*this); + + mGraphics->DiscardResource([this]() { + mGraphics->GetDevice().destroyImage(mImage, mGraphics->GetAllocator()); + }); + } + + return false; } } // namespace Vulkan diff --git a/dali/graphics/vulkan/vulkan-image.h b/dali/graphics/vulkan/vulkan-image.h index 1da112b..90e5647 100644 --- a/dali/graphics/vulkan/vulkan-image.h +++ b/dali/graphics/vulkan/vulkan-image.h @@ -26,8 +26,7 @@ namespace Graphics { namespace Vulkan { -class ImageView; -using InternalVkImage = vk::Image; + class Image : public VkManaged { public: @@ -47,7 +46,7 @@ public: * @param image * @return */ - static RefCountedImage New( Graphics& graphics, vk::ImageCreateInfo createInfo, vk::Image externalImage ); + static RefCountedImage NewFromExternal( Graphics& graphics, vk::ImageCreateInfo createInfo, vk::Image externalImage ); /** * Destructor @@ -64,7 +63,7 @@ public: * Returns VkImageLayout associated with the image * @return */ - vk::ImageLayout GetVkImageLayout() const; + vk::ImageLayout GetImageLayout() const; /** * Returns width in pixels @@ -94,31 +93,42 @@ public: * Returns pixel format * @return */ - vk::Format GetVkFormat() const; + vk::Format GetFormat() const; /** * returns image type ( VkImageType) * @return */ - vk::ImageType GetVkImageType() const; + vk::ImageType GetImageType() const; /** * Returns used image tiling mode * @return */ - vk::ImageTiling GetVkImageTiling() const; + vk::ImageTiling GetImageTiling() const; /** * * @return */ - vk::ImageUsageFlags GetVkImageUsageFlags() const; + vk::ImageUsageFlags GetUsageFlags() const; /** - * Binds image memory - * @param handle + * Assigns the specified image memory to the image + * @warning This method does NOT bind the memory. Use Graphics::BindImageMemory instead + * @param memory The device memory to be assigned to the image */ - void BindMemory( const RefCountedGpuMemoryBlock& handle ); + void AssignMemory( RefCountedGpuMemoryBlock memory ); + + const Image& ConstRef(); + + Image& Ref(); + + operator vk::Image*(); + + bool OnDestroy() override; + +private: /** * Creates new VkImage with given specification, it doesn't @@ -126,16 +136,16 @@ public: * @param graphics * @param createInfo */ - Image( Graphics& graphics, const vk::ImageCreateInfo& createInfo, vk::Image externalImage ); - - operator InternalVkImage() const - { - return GetVkHandle(); - } + Image( Graphics& graphics, const vk::ImageCreateInfo& createInfo, vk::Image externalImage = nullptr ); private: - struct Impl; - std::unique_ptr mImpl; + Graphics* mGraphics; + vk::ImageCreateInfo mCreateInfo; + vk::Image mImage; + vk::ImageLayout mImageLayout; + + RefCountedGpuMemoryBlock mDeviceMemory; + bool mIsExternal; }; } // namespace Vulkan diff --git a/dali/graphics/vulkan/vulkan-resource-cache.h b/dali/graphics/vulkan/vulkan-resource-cache.h index 9251922..8623896 100644 --- a/dali/graphics/vulkan/vulkan-resource-cache.h +++ b/dali/graphics/vulkan/vulkan-resource-cache.h @@ -206,13 +206,14 @@ public: private: std::vector< RefCountedBuffer > mBuffers; std::vector< RefCountedImage > mImages; + //TODO: add storage for ImageViews std::vector< RefCountedShader > mShaders; std::vector< RefCountedCommandPool > mCommandPools; std::vector< RefCountedDescriptorPool > mDescriptorPools; std::vector< RefCountedFramebuffer > mFramebuffers; std::vector< RefCountedSampler > mSamplers; - std::vector< std::function > mDiscardQueue; + std::vector< std::function< void() > > mDiscardQueue; }; } //namespace Vulkan diff --git a/dali/graphics/vulkan/vulkan-swapchain.cpp b/dali/graphics/vulkan/vulkan-swapchain.cpp index 9c4a43f..578b3ab 100644 --- a/dali/graphics/vulkan/vulkan-swapchain.cpp +++ b/dali/graphics/vulkan/vulkan-swapchain.cpp @@ -345,14 +345,14 @@ struct Swapchain::Impl .setInitialLayout( vk::ImageLayout::eUndefined ) .setSamples( vk::SampleCountFlagBits::e1 ); - // create depth stencil image - auto dsRefCountedImage = Image::New( mGraphics, imageCreateInfo); + auto dsRefCountedImage = mGraphics.CreateImage( imageCreateInfo ); - auto memory = mGraphics.GetDeviceMemoryManager().GetDefaultAllocator().Allocate( - dsRefCountedImage, vk::MemoryPropertyFlagBits::eDeviceLocal ); + auto memory = mGraphics + .GetDeviceMemoryManager() + .GetDefaultAllocator() + .Allocate( dsRefCountedImage, vk::MemoryPropertyFlagBits::eDeviceLocal ); - //TODO: use the graphics class to bind memory. Maybe... - dsRefCountedImage->BindMemory( memory ); + mGraphics.BindImageMemory( dsRefCountedImage, memory, 0 ); // create imageview to be used within framebuffer auto dsImageViewRef = mGraphics.CreateImageView(dsRefCountedImage); @@ -383,12 +383,12 @@ struct Swapchain::Impl // Create external Image reference // Note that despite we don't create VkImage, we still fill the createinfo structure // as this data will be used later - auto refCountedImage = Image::New( mGraphics, imageCreateInfo, image ); + auto refCountedImage = Image::NewFromExternal( mGraphics, imageCreateInfo, image ); // Create basic imageview ( all mipmaps, all layers ) - RefCountedImageView iv = mGraphics.CreateImageView(refCountedImage); + auto refCountedImageView = mGraphics.CreateImageView(refCountedImage); - fbRef->SetAttachment( iv, Framebuffer::AttachmentType::COLOR, 0u ); + fbRef->SetAttachment( refCountedImageView, Framebuffer::AttachmentType::COLOR, 0u ); return fbRef; } @@ -502,7 +502,7 @@ struct Swapchain::Impl for( auto&& imageView : attachments ) { - barriers.emplace_back( barrier.setImage( *imageView->GetImage() ) ); + barriers.emplace_back( barrier.setImage( imageView->GetImage()->GetVkHandle() ) ); } cmdBuf->PipelineBarrier( vk::PipelineStageFlagBits::eBottomOfPipe,