243 lines
6.9 KiB
C++
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
|