Files
FGL-Engine/src/engine/assets/image/Image.cpp

243 lines
6.9 KiB
C++

//
// Created by kj16609 on 12/4/23.
//
#include "Image.hpp"
#include "ImageView.hpp"
namespace fgl::engine
{
std::shared_ptr< ImageView > Image::getView()
{
if ( !m_view.expired() )
return m_view.lock();
else
{
assert( m_handle );
auto ptr { std::make_shared< ImageView >( m_handle ) };
m_view = ptr;
return ptr;
}
}
constexpr vk::AccessFlags getAccessFlags( const vk::ImageLayout layout )
{
switch ( layout )
{
case vk::ImageLayout::eUndefined:
return vk::AccessFlags( 0 );
case vk::ImageLayout::eGeneral:
break;
case vk::ImageLayout::eColorAttachmentOptimal:
return vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite;
break;
case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
break;
case vk::ImageLayout::eShaderReadOnlyOptimal:
return vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eInputAttachmentRead;
case vk::ImageLayout::eTransferSrcOptimal:
return vk::AccessFlagBits::eTransferRead;
case vk::ImageLayout::eTransferDstOptimal:
return vk::AccessFlagBits::eTransferWrite;
case vk::ImageLayout::ePreinitialized:
return vk::AccessFlagBits::eHostWrite;
case vk::ImageLayout::eDepthReadOnlyStencilAttachmentOptimal:
break;
case vk::ImageLayout::eDepthAttachmentStencilReadOnlyOptimal:
break;
case vk::ImageLayout::eStencilAttachmentOptimal:
break;
case vk::ImageLayout::eDepthStencilAttachmentOptimal:
[[fallthrough]];
case vk::ImageLayout::eDepthReadOnlyOptimal:
[[fallthrough]];
case vk::ImageLayout::eDepthAttachmentOptimal:
return vk::AccessFlagBits::eDepthStencilAttachmentRead
| vk::AccessFlagBits::eDepthStencilAttachmentWrite;
case vk::ImageLayout::eStencilReadOnlyOptimal:
break;
case vk::ImageLayout::eReadOnlyOptimal:
break;
case vk::ImageLayout::eAttachmentOptimal:
break;
case vk::ImageLayout::ePresentSrcKHR:
return vk::AccessFlags( 0 );
case vk::ImageLayout::eVideoDecodeDstKHR:
break;
case vk::ImageLayout::eVideoDecodeSrcKHR:
break;
case vk::ImageLayout::eVideoDecodeDpbKHR:
break;
case vk::ImageLayout::eSharedPresentKHR:
break;
case vk::ImageLayout::eFragmentDensityMapOptimalEXT:
break;
case vk::ImageLayout::eFragmentShadingRateAttachmentOptimalKHR:
return vk::AccessFlagBits::eFragmentShadingRateAttachmentReadKHR;
case vk::ImageLayout::eRenderingLocalReadKHR:
return vk::AccessFlagBits::eColorAttachmentWrite;
case vk::ImageLayout::eVideoEncodeDstKHR:
break;
case vk::ImageLayout::eVideoEncodeSrcKHR:
break;
case vk::ImageLayout::eVideoEncodeDpbKHR:
break;
case vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT:
break;
default:
FGL_UNREACHABLE();
}
FGL_UNREACHABLE();
}
constexpr vk::PipelineStageFlags getPipelineStageFlags( const vk::ImageLayout layout )
{
switch ( layout )
{
default:
FGL_UNREACHABLE();
case vk::ImageLayout::eUndefined:
return vk::PipelineStageFlagBits::eTopOfPipe;
case vk::ImageLayout::eGeneral:
break;
case vk::ImageLayout::eColorAttachmentOptimal:
return vk::PipelineStageFlagBits::eColorAttachmentOutput;
case vk::ImageLayout::eDepthStencilAttachmentOptimal:
break;
case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
break;
case vk::ImageLayout::eShaderReadOnlyOptimal:
return vk::PipelineStageFlagBits::eVertexShader | vk::PipelineStageFlagBits::eFragmentShader;
case vk::ImageLayout::eTransferSrcOptimal:
[[fallthrough]];
case vk::ImageLayout::eTransferDstOptimal:
return vk::PipelineStageFlagBits::eTransfer;
case vk::ImageLayout::ePreinitialized:
break;
case vk::ImageLayout::eDepthReadOnlyStencilAttachmentOptimal:
break;
case vk::ImageLayout::eDepthAttachmentStencilReadOnlyOptimal:
break;
case vk::ImageLayout::eDepthAttachmentOptimal:
break;
case vk::ImageLayout::eDepthReadOnlyOptimal:
break;
case vk::ImageLayout::eStencilAttachmentOptimal:
break;
case vk::ImageLayout::eStencilReadOnlyOptimal:
break;
case vk::ImageLayout::eReadOnlyOptimal:
break;
case vk::ImageLayout::eAttachmentOptimal:
break;
case vk::ImageLayout::ePresentSrcKHR:
return vk::PipelineStageFlagBits::eBottomOfPipe;
case vk::ImageLayout::eVideoDecodeDstKHR:
break;
case vk::ImageLayout::eVideoDecodeSrcKHR:
break;
case vk::ImageLayout::eVideoDecodeDpbKHR:
break;
case vk::ImageLayout::eSharedPresentKHR:
break;
case vk::ImageLayout::eFragmentDensityMapOptimalEXT:
break;
case vk::ImageLayout::eFragmentShadingRateAttachmentOptimalKHR:
break;
case vk::ImageLayout::eRenderingLocalReadKHR:
break;
case vk::ImageLayout::eVideoEncodeDstKHR:
break;
case vk::ImageLayout::eVideoEncodeSrcKHR:
break;
case vk::ImageLayout::eVideoEncodeDpbKHR:
break;
case vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT:
break;
}
FGL_UNREACHABLE();
}
vk::ImageMemoryBarrier Image::transitionTo(
const vk::ImageLayout old_layout,
const vk::ImageLayout new_layout,
const vk::ImageSubresourceRange& range ) const
{
vk::ImageMemoryBarrier barrier {};
barrier.srcAccessMask = getAccessFlags( old_layout );
barrier.dstAccessMask = getAccessFlags( new_layout );
barrier.oldLayout = old_layout;
barrier.newLayout = new_layout;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.subresourceRange = range;
barrier.setImage( this->getVkImage() );
return barrier;
}
vk::ImageMemoryBarrier Image::transitionTo(
const vk::ImageLayout old_layout, const vk::ImageLayout new_layout, const vk::ImageAspectFlags aspect )
{
assert( m_handle->m_name.empty() == false && "Image name not assigned" );
const vk::ImageSubresourceRange subresource { aspect, 0, 1, 0, 1 };
const vk::ImageMemoryBarrier barrier { transitionTo( old_layout, new_layout, subresource ) };
return barrier;
}
Image::Image(
const vk::Extent2D extent,
const vk::Format format,
const vk::Image image,
const vk::ImageUsageFlags usage ) noexcept :
m_handle( std::make_shared< ImageHandle >( extent, format, image, usage ) ),
m_extent( extent )
{}
Image::Image(
const vk::Extent2D extent,
const vk::Format format,
const vk::ImageUsageFlags usage,
const vk::ImageLayout inital_layout,
const vk::ImageLayout final_layout ) :
m_handle( std::make_shared< ImageHandle >( extent, format, usage, inital_layout, final_layout ) ),
m_extent( extent )
{}
Image& Image::operator=( const Image& other )
{
m_handle = other.m_handle;
m_view = {};
return *this;
}
VkImage Image::getVkImage() const
{
return m_handle->getVkImage();
}
Image& Image::operator=( Image&& other ) noexcept
{
m_handle = std::move( other.m_handle );
m_view = std::move( other.m_view );
m_extent = other.m_extent;
return *this;
}
Image& Image::setName( const std::string& str )
{
m_handle->setName( str );
return *this;
}
} // namespace fgl::engine