> 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(<image>, <memory>, <offset>) method.
> Altered already existing image creation code to use the new paradigm.
Change-Id: I32bd621dcd59eac7c24a0759798bde15a7870083
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]);
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 )
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 )
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);
#include <dali/graphics/vulkan/vulkan-resource-cache.h>
#include <dali/graphics/vulkan/vulkan-debug.h>
#include <dali/graphics/vulkan/vulkan-fence.h>
+#include <dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-handle.h>
#include <dali/graphics-api/graphics-api-controller.h>
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,
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 };
return CreateImageView( {},
image,
vk::ImageViewType::e2D,
- image->GetVkFormat(),
+ image->GetFormat(),
componentsMapping,
subresourceRange );
}
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 ------------------------------------------------------------------------------------------------------
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 };
{
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;
}
{
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;
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 );
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;
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<void()> deleter);
+ void DiscardResource( std::function< void() > deleter );
private: // Methods
- 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();
+ 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<GpuMemoryManager> mDeviceMemoryManager;
+ std::unique_ptr< GpuMemoryManager > mDeviceMemoryManager;
- vk::Instance mInstance;
- std::unique_ptr<vk::AllocationCallbacks> 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<Queue> > mGraphicsQueues;
- std::vector< std::unique_ptr<Queue> > mTransferQueues;
- std::vector< std::unique_ptr<Queue> > 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<Dali::Graphics::VulkanAPI::Controller> mGfxController;
+ std::unique_ptr< Dali::Graphics::VulkanAPI::Controller > mGfxController;
// TODO: rename
- std::unique_ptr<PipelineCache> mPipelineDatabase;
+ std::unique_ptr< PipelineCache > mPipelineDatabase;
- std::mutex mMutex;
- std::unique_ptr< ResourceCache > mResourceCache;
+ std::mutex mMutex;
+ std::unique_ptr< ResourceCache > mResourceCache;
};
operator vk::ImageView*();
+ //TODO: Use the graphics class to manage lifetime.
+
private:
ImageView( Graphics& graphics,
RefCountedImage image,
{
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 ) )
- {
- 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<bool>(externalImage))
{
- mImpl = MakeUnique<Impl>( *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
{
namespace Vulkan
{
-class ImageView;
-using InternalVkImage = vk::Image;
+
class Image : public VkManaged
{
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
* Returns VkImageLayout associated with the image
* @return
*/
- vk::ImageLayout GetVkImageLayout() const;
+ vk::ImageLayout GetImageLayout() const;
/**
* Returns width in pixels
* 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
* @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<Impl> mImpl;
+ Graphics* mGraphics;
+ vk::ImageCreateInfo mCreateInfo;
+ vk::Image mImage;
+ vk::ImageLayout mImageLayout;
+
+ RefCountedGpuMemoryBlock mDeviceMemory;
+ bool mIsExternal;
};
} // namespace Vulkan
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<void()> > mDiscardQueue;
+ std::vector< std::function< void() > > mDiscardQueue;
};
} //namespace Vulkan
.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);
// 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;
}
for( auto&& imageView : attachments )
{
- barriers.emplace_back( barrier.setImage( *imageView->GetImage() ) );
+ barriers.emplace_back( barrier.setImage( imageView->GetImage()->GetVkHandle() ) );
}
cmdBuf->PipelineBarrier( vk::PipelineStageFlagBits::eBottomOfPipe,