diff --git a/Examples/DownloadImages/main.cpp b/Examples/DownloadImages/main.cpp index 820f798..6d305c4 100644 --- a/Examples/DownloadImages/main.cpp +++ b/Examples/DownloadImages/main.cpp @@ -15,8 +15,6 @@ int main() RHI::DownloadImageArgs args{}; args.format = RHI::HostImageFormat::RGB8; args.copyRegion = {{0, 0, 0}, texture->GetDescription().extent}; - args.layerIndex = 0; - args.layersCount = 1; auto future = texture->DownloadImage(args); while (future.wait_for(std::chrono::milliseconds(100)) == std::future_status::timeout) diff --git a/Examples/test_utils/TestUtils.cpp b/Examples/test_utils/TestUtils.cpp index eaf6f67..1fd333a 100644 --- a/Examples/test_utils/TestUtils.cpp +++ b/Examples/test_utils/TestUtils.cpp @@ -41,20 +41,18 @@ RHI::ITexture * UploadTexture(const char * path, RHI::IContext * ctx, bool with_ RHI::HostTextureView hostTexture{}; { - hostTexture.extent = {static_cast(w), static_cast(h), 1}; + hostTexture.extent = {static_cast(w), static_cast(h), 1}; hostTexture.pixelData = reinterpret_cast(pixel_data); hostTexture.format = with_alpha ? RHI::HostImageFormat::RGBA8 : RHI::HostImageFormat::RGB8; - hostTexture.layersCount = 1; + hostTexture.type = RHI::ImageType::Image2D; }; RHI::TextureDescription imageArgs{}; { imageArgs.extent = hostTexture.extent; - imageArgs.layersCount = hostTexture.layersCount; imageArgs.type = RHI::ImageType::Image2D; imageArgs.format = with_alpha ? RHI::ImageFormat::RGBA8 : RHI::ImageFormat::RGB8; imageArgs.mipLevels = useMips ? RHI::CalcMaxMipLevels(imageArgs.extent) : 1; - ; } auto texture = ctx->CreateTexture(imageArgs); @@ -62,9 +60,6 @@ RHI::ITexture * UploadTexture(const char * path, RHI::IContext * ctx, bool with_ { args.srcTexture = hostTexture; args.copyRegion = {{0, 0, 0}, hostTexture.extent}; - args.dstOffset = {0, 0, 0}; - args.layerIndex = 0; - args.layersCount = 1; } texture->UploadImage(args); if (useMips) @@ -91,8 +86,8 @@ RHI::ITexture * UploadLayeredTexture(RHI::IContext * ctx, auto && hostTexture = textures.emplace_back(); hostTexture.pixelData = pixel_data; - hostTexture.extent = {static_cast(w), static_cast(h), 1}; - hostTexture.layersCount = 1; + hostTexture.extent = {static_cast(w), static_cast(h), 1}; + hostTexture.type = RHI::ImageType::Image2D; hostTexture.format = with_alpha ? RHI::HostImageFormat::RGBA8 : RHI::HostImageFormat::RGB8; } @@ -103,10 +98,10 @@ RHI::ITexture * UploadLayeredTexture(RHI::IContext * ctx, RHI::TextureDescription imageArgs{}; { imageArgs.extent = textures.front().extent; + imageArgs.extent[2] = static_cast(textures.size()); imageArgs.type = RHI::ImageType::Image2D_Array; imageArgs.format = with_alpha ? RHI::ImageFormat::RGBA8 : RHI::ImageFormat::RGB8; imageArgs.mipLevels = useMips ? RHI::CalcMaxMipLevels(imageArgs.extent) : 1; - imageArgs.layersCount = static_cast(textures.size()); } auto texture = ctx->CreateTexture(imageArgs); @@ -117,9 +112,7 @@ RHI::ITexture * UploadLayeredTexture(RHI::IContext * ctx, { args.srcTexture = hostTexture; args.copyRegion = {{0, 0, 0}, {hostTexture.extent}}; - args.dstOffset = {0, 0, 0}; - args.layerIndex = i; - args.layersCount = 1; + args.dstOffset = {0, 0, static_cast(i)}; } texture->UploadImage(args); } diff --git a/Source/Public/Images.hpp b/Source/Public/Images.hpp index 968ee51..fab55cd 100644 --- a/Source/Public/Images.hpp +++ b/Source/Public/Images.hpp @@ -3,6 +3,7 @@ #include #include +#include #include @@ -11,7 +12,7 @@ namespace RHI /// @brief Defines image's layout in memory. Also defines if image can have mipmaps or not /// For example image1d is line of pixels, image2d is a rectangle of pixels -enum class ImageType +enum class ImageType : uint8_t { Image1D, ///< image with height = 1. has only width.Can have one mipmap for a whole image Image2D, ///< generic image with width and height. Can have one mipmap for a whole image @@ -69,7 +70,7 @@ enum class ImageFormat : uint8_t }; /// @brief -enum ShaderAttachmentSlot +enum ShaderAttachmentSlot : uint8_t { Color, ///< color attachment DepthStencil, ///< depth-stencil attachment @@ -78,28 +79,30 @@ enum ShaderAttachmentSlot TOTAL }; +using texel_t = uint16_t; /// For Image1D used only 0'th index /// For Image2D used only 0 and 1 index /// For Image3D used all 3 indices like width, height and layer /// For Image1D used 0 and 1 index as width and i-th array element /// For Image2D used all 3 indices as width, height and i-th array element /// For Cubemap used all 3 indices as width, height and i-th surface of cube -using TexelIndex = std::array; +using TexelIndex = std::array; +static constexpr texel_t g_InvalidTexel = std::numeric_limits::max(); /// Gabarit of texture using TextureExtent = TexelIndex; -struct TextureRegion +struct TextureRegion final { - TexelIndex offset; - TextureExtent extent; + TexelIndex offset{0, 0, 0}; + TextureExtent extent{g_InvalidTexel, g_InvalidTexel, g_InvalidTexel}; + int reserved = 0; }; struct TextureDescription final { - TextureExtent extent; - uint32_t layersCount = 1; + TextureExtent extent; ///< gabarit of texture (width, height, depth/layer) ImageType type; ImageFormat format; uint32_t mipLevels = 1; @@ -109,10 +112,24 @@ RHI_API uint32_t CalcMaxMipLevels(TextureExtent extent, uint32_t minLength = 1); struct HostTextureView final { - TextureExtent extent; - uint8_t * pixelData = nullptr; - HostImageFormat format; - uint32_t layersCount = 1; + TextureExtent extent{g_InvalidTexel, g_InvalidTexel, + g_InvalidTexel}; ///< size of image (width, height, depth/layers) + uint8_t * pixelData = nullptr; ///< pointer on pixel data + HostImageFormat format; ///< format of pixel + ImageType type; ///< type of image (1D, 2D, 3D, Cubemap, etc) +}; + +struct UploadImageArgs final +{ + HostTextureView srcTexture; ///< host texture + TextureRegion copyRegion{}; ///< subregion of host texture to copy + TexelIndex dstOffset{0, 0, 0}; ///< offset in destination where to copy +}; + +struct DownloadImageArgs final +{ + HostImageFormat format; ///< desired format + TextureRegion copyRegion{}; }; } // namespace RHI diff --git a/Source/Public/RHI.hpp b/Source/Public/RHI.hpp index 2034ebc..7070853 100644 --- a/Source/Public/RHI.hpp +++ b/Source/Public/RHI.hpp @@ -344,23 +344,6 @@ struct IBufferGPU virtual size_t Size() const noexcept = 0; }; -struct UploadImageArgs final -{ - HostTextureView srcTexture; - TextureRegion copyRegion; - TextureExtent dstOffset; - uint32_t layerIndex = 0; - uint32_t layersCount = std::numeric_limits::max(); -}; - -struct DownloadImageArgs final -{ - HostImageFormat format; - TextureRegion copyRegion; - uint32_t layerIndex = 0; - uint32_t layersCount = std::numeric_limits::max(); -}; - /// Image with mipmaps, compression struct ITexture { diff --git a/Source/Vulkan/Attachments/GenericAttachment.cpp b/Source/Vulkan/Attachments/GenericAttachment.cpp index 69a5f54..2bc7c9a 100644 --- a/Source/Vulkan/Attachments/GenericAttachment.cpp +++ b/Source/Vulkan/Attachments/GenericAttachment.cpp @@ -127,8 +127,6 @@ std::future GenericAttachment::DownloadImage(HostImageFormat for DownloadImageArgs args{}; args.format = format; args.copyRegion = region; - args.layerIndex = 0; - args.layersCount = 1; return GetContext().GetTransferer().DownloadImage(*this, args); } @@ -191,6 +189,17 @@ uint32_t GenericAttachment::GetLayersCount() const noexcept return 1; } +VkImageType GenericAttachment::GetImageType() const noexcept +{ + assert(m_description.type == RHI::ImageType::Image2D); + return VK_IMAGE_TYPE_2D; +} + +VkImageViewType GenericAttachment::GetImageViewType() const noexcept +{ + return VK_IMAGE_VIEW_TYPE_2D; +} + //-------------------- IAttachment interface -------------------- void GenericAttachment::Invalidate() @@ -275,7 +284,8 @@ void GenericAttachment::TransferLayout(VkImageLayout layout) noexcept void GenericAttachment::Resize(const VkExtent2D & new_extent) noexcept { - m_description.extent = {new_extent.width, new_extent.height, 1}; + m_description.extent = {static_cast(new_extent.width), + static_cast(new_extent.height), 1}; m_changedSize = true; } diff --git a/Source/Vulkan/Attachments/GenericAttachment.hpp b/Source/Vulkan/Attachments/GenericAttachment.hpp index f93175f..68305d5 100644 --- a/Source/Vulkan/Attachments/GenericAttachment.hpp +++ b/Source/Vulkan/Attachments/GenericAttachment.hpp @@ -42,6 +42,8 @@ struct GenericAttachment : public IAttachment, virtual VkExtent3D GetInternalExtent() const noexcept override; virtual uint32_t GetMipLevelsCount() const noexcept override; virtual uint32_t GetLayersCount() const noexcept override; + virtual VkImageType GetImageType() const noexcept override; + virtual VkImageViewType GetImageViewType() const noexcept override; public: // IInternalAttachment interface virtual void Invalidate() override; diff --git a/Source/Vulkan/Attachments/SurfacedAttachment.cpp b/Source/Vulkan/Attachments/SurfacedAttachment.cpp index eb73901..f7a0474 100644 --- a/Source/Vulkan/Attachments/SurfacedAttachment.cpp +++ b/Source/Vulkan/Attachments/SurfacedAttachment.cpp @@ -37,8 +37,6 @@ std::future SurfacedAttachment::DownloadImage(HostImageFormat fo DownloadImageArgs args{}; args.format = format; args.copyRegion = region; - args.layerIndex = 0; - args.layersCount = 1; return GetContext().GetTransferer().DownloadImage(*this, args); } @@ -49,7 +47,8 @@ TextureDescription SurfacedAttachment::GetDescription() const noexcept description.mipLevels = 1; description.type = RHI::ImageType::Image2D; auto extent = GetInternalExtent(); - description.extent = {extent.width, extent.height, extent.depth}; + description.extent = {static_cast(extent.width), static_cast(extent.height), + static_cast(extent.depth)}; description.format = g_imagesFormat; } return description; @@ -115,6 +114,16 @@ uint32_t SurfacedAttachment::GetLayersCount() const noexcept return 1; } +VkImageType SurfacedAttachment::GetImageType() const noexcept +{ + return VK_IMAGE_TYPE_2D; +} + +VkImageViewType SurfacedAttachment::GetImageViewType() const noexcept +{ + return VK_IMAGE_VIEW_TYPE_2D; +} + void SurfacedAttachment::BlitTo(ITexture * texture) { //if (auto * ptr = dynamic_cast(texture)) diff --git a/Source/Vulkan/Attachments/SurfacedAttachment.hpp b/Source/Vulkan/Attachments/SurfacedAttachment.hpp index f44b915..819c9d9 100644 --- a/Source/Vulkan/Attachments/SurfacedAttachment.hpp +++ b/Source/Vulkan/Attachments/SurfacedAttachment.hpp @@ -40,6 +40,8 @@ struct SurfacedAttachment : public IAttachment, virtual VkExtent3D GetInternalExtent() const noexcept override; virtual uint32_t GetMipLevelsCount() const noexcept override; virtual uint32_t GetLayersCount() const noexcept override; + virtual VkImageType GetImageType() const noexcept override; + virtual VkImageViewType GetImageViewType() const noexcept override; public: // IAttachment interface virtual void BlitTo(ITexture * texture) override; diff --git a/Source/Vulkan/ImageUtils/ImageUtils.cpp b/Source/Vulkan/ImageUtils/ImageUtils.cpp index 08feb29..759bff1 100644 --- a/Source/Vulkan/ImageUtils/ImageUtils.cpp +++ b/Source/Vulkan/ImageUtils/ImageUtils.cpp @@ -22,4 +22,135 @@ VkImageView CreateImageView(VkDevice device, VkImage image, VkFormat format, VkI return view; } + +bool AreImageTypesCompatible(RHI::ImageType type, VkImageType vkType) noexcept +{ + switch (type) + { + case RHI::ImageType::Image1D: + case RHI::ImageType::Image1D_Array: + return vkType == VK_IMAGE_TYPE_1D; + case RHI::ImageType::Image2D: + case RHI::ImageType::Image2D_Array: + case RHI::ImageType::Cubemap: + return vkType == VK_IMAGE_TYPE_2D; + case RHI::ImageType::Image3D: + return vkType == VK_IMAGE_TYPE_3D; + } + return false; +} + +bool AreImageTypesCompatible(RHI::ImageType type, VkImageViewType vkType) noexcept +{ + switch (type) + { + case RHI::ImageType::Image1D: + return vkType == VK_IMAGE_VIEW_TYPE_1D; + case RHI::ImageType::Image1D_Array: + return vkType == VK_IMAGE_VIEW_TYPE_1D_ARRAY; + case RHI::ImageType::Image2D: + return vkType == VK_IMAGE_VIEW_TYPE_2D; + case RHI::ImageType::Image2D_Array: + return vkType == VK_IMAGE_VIEW_TYPE_2D_ARRAY; + case RHI::ImageType::Cubemap: + return vkType == VK_IMAGE_VIEW_TYPE_CUBE; + case RHI::ImageType::Image3D: + return vkType == VK_IMAGE_VIEW_TYPE_3D; + } + return false; +} + + +std::pair UnpackExtentAndLayers(const TextureExtent & extent, + RHI::ImageType type) noexcept +{ + VkExtent3D resultExtent{static_cast(extent[0]), static_cast(extent[1]), + static_cast(extent[2])}; + uint32_t layersCount = 1; + switch (type) + { + case RHI::ImageType::Image1D: + case RHI::ImageType::Image1D_Array: + layersCount = resultExtent.height; + resultExtent.height = 1; + resultExtent.depth = 1; + break; + case RHI::ImageType::Image2D: + case RHI::ImageType::Image2D_Array: + layersCount = resultExtent.depth; + resultExtent.depth = 1; + break; + } + + return {resultExtent, layersCount}; +} + +std::pair UnpackExtentAndLayers(const TextureExtent & extent, + VkImageType type) noexcept +{ + VkExtent3D resultExtent{static_cast(extent[0]), static_cast(extent[1]), + static_cast(extent[2])}; + uint32_t layersCount = 1; + switch (type) + { + case VK_IMAGE_TYPE_1D: + layersCount = resultExtent.height; + resultExtent.height = 1; + resultExtent.depth = 1; + break; + case VK_IMAGE_TYPE_2D: + layersCount = resultExtent.depth; + resultExtent.depth = 1; + break; + } + + return {resultExtent, layersCount}; +} + +std::pair UnpackOffsetAndBaseLayer(const TexelIndex & offset, + RHI::ImageType type) noexcept +{ + VkOffset3D resultOffset{static_cast(offset[0]), static_cast(offset[1]), + static_cast(offset[2])}; + uint32_t baseLayer = 0; + switch (type) + { + case RHI::ImageType::Image1D: + case RHI::ImageType::Image1D_Array: + baseLayer = resultOffset.y; + resultOffset.y = 0; + resultOffset.z = 0; + break; + case RHI::ImageType::Image2D: + case RHI::ImageType::Image2D_Array: + baseLayer = resultOffset.z; + resultOffset.z = 0; + break; + } + + return {resultOffset, baseLayer}; +} + +std::pair UnpackOffsetAndBaseLayer(const TexelIndex & offset, + VkImageType type) noexcept +{ + VkOffset3D resultOffset{static_cast(offset[0]), static_cast(offset[1]), + static_cast(offset[2])}; + uint32_t baseLayer = 0; + switch (type) + { + case VK_IMAGE_TYPE_1D: + baseLayer = resultOffset.y; + resultOffset.y = 0; + resultOffset.z = 0; + break; + case VK_IMAGE_TYPE_2D: + baseLayer = resultOffset.z; + resultOffset.z = 0; + break; + } + + return {resultOffset, baseLayer}; +} + } // namespace RHI::vulkan::utils diff --git a/Source/Vulkan/ImageUtils/ImageUtils.hpp b/Source/Vulkan/ImageUtils/ImageUtils.hpp index 09aec21..9571334 100644 --- a/Source/Vulkan/ImageUtils/ImageUtils.hpp +++ b/Source/Vulkan/ImageUtils/ImageUtils.hpp @@ -6,4 +6,17 @@ namespace RHI::vulkan::utils { VkImageView CreateImageView(VkDevice device, VkImage image, VkFormat format, VkImageViewType type, VkImageAspectFlags aspectFlags); -} + +bool AreImageTypesCompatible(RHI::ImageType type, VkImageType vkType) noexcept; +bool AreImageTypesCompatible(RHI::ImageType type, VkImageViewType VkType) noexcept; + +std::pair UnpackExtentAndLayers(const TextureExtent & extent, + RHI::ImageType type) noexcept; +std::pair UnpackExtentAndLayers(const TextureExtent & extent, + VkImageType type) noexcept; + +std::pair UnpackOffsetAndBaseLayer(const TexelIndex & offset, + RHI::ImageType type) noexcept; +std::pair UnpackOffsetAndBaseLayer(const TexelIndex & offset, + VkImageType type) noexcept; +} // namespace RHI::vulkan::utils diff --git a/Source/Vulkan/ImageUtils/TextureInterface.hpp b/Source/Vulkan/ImageUtils/TextureInterface.hpp index 42eba3b..da1fb79 100644 --- a/Source/Vulkan/ImageUtils/TextureInterface.hpp +++ b/Source/Vulkan/ImageUtils/TextureInterface.hpp @@ -22,6 +22,8 @@ struct IInternalTexture virtual VkExtent3D GetInternalExtent() const noexcept = 0; virtual uint32_t GetMipLevelsCount() const noexcept = 0; virtual uint32_t GetLayersCount() const noexcept = 0; + virtual VkImageType GetImageType() const noexcept = 0; + virtual VkImageViewType GetImageViewType() const noexcept = 0; }; } // namespace RHI::vulkan diff --git a/Source/Vulkan/Memory/MemoryBlock.cpp b/Source/Vulkan/Memory/MemoryBlock.cpp index eef866b..1d3df7d 100644 --- a/Source/Vulkan/Memory/MemoryBlock.cpp +++ b/Source/Vulkan/Memory/MemoryBlock.cpp @@ -1,5 +1,6 @@ #include "MemoryBlock.hpp" +#include #include #include @@ -57,15 +58,15 @@ MemoryBlock::MemoryBlock(MemoryAllocator & allocator, const TextureDescription & VkSharingMode shareMode) : OwnedBy(allocator) { + auto [extent, layersCount] = utils::UnpackExtentAndLayers(description.extent, description.type); + VkImageCreateInfo imageInfo{}; { imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageInfo.imageType = utils::CastInterfaceEnum2Vulkan(description.type); - imageInfo.extent.width = description.extent[0]; - imageInfo.extent.height = description.extent[1]; - imageInfo.extent.depth = description.extent[2]; + imageInfo.extent = extent; imageInfo.mipLevels = description.mipLevels; - imageInfo.arrayLayers = description.layersCount; + imageInfo.arrayLayers = layersCount; imageInfo.format = utils::CastInterfaceEnum2Vulkan(description.format); imageInfo.tiling = /*description.format == RHI::ImageFormat::DEPTH_STENCIL ? VK_IMAGE_TILING_LINEAR diff --git a/Source/Vulkan/RenderPass/Framebuffer.cpp b/Source/Vulkan/RenderPass/Framebuffer.cpp index 6c10e39..ab4a5b6 100644 --- a/Source/Vulkan/RenderPass/Framebuffer.cpp +++ b/Source/Vulkan/RenderPass/Framebuffer.cpp @@ -59,7 +59,8 @@ void Framebuffer::Invalidate() auto extent = m_attachments[0]->GetInternalExtent(); // all attachments must have equal count of buffers assert(std::all_of(m_attachments.begin(), m_attachments.end(), - [buffersCount, extent](IInternalAttachment * att) { + [buffersCount, extent](IInternalAttachment * att) + { return buffersCount == att->GetBuffering() && att->GetInternalExtent() == extent; })); @@ -212,7 +213,8 @@ void Framebuffer::Resize(uint32_t width, uint32_t height) RHI::TexelIndex Framebuffer::GetExtent() const { auto internalExtent = m_attachments[0]->GetInternalExtent(); - return {internalExtent.width, internalExtent.height, internalExtent.depth}; + return {static_cast(internalExtent.width), static_cast(internalExtent.height), + static_cast(internalExtent.depth)}; } } // namespace RHI::vulkan diff --git a/Source/Vulkan/RenderPass/RenderTarget.cpp b/Source/Vulkan/RenderPass/RenderTarget.cpp index 5daa5ac..04de6a0 100644 --- a/Source/Vulkan/RenderPass/RenderTarget.cpp +++ b/Source/Vulkan/RenderPass/RenderTarget.cpp @@ -61,7 +61,8 @@ void RenderTarget::SetClearValue(uint32_t attachmentIndex, float depth, uint32_t TexelIndex RenderTarget::GetExtent() const noexcept { - return {m_extent.width, m_extent.height, m_extent.depth}; + return {static_cast(m_extent.width), static_cast(m_extent.height), + static_cast(m_extent.depth) /*= 1*/}; } void RenderTarget::Invalidate() diff --git a/Source/Vulkan/Resources/Texture.cpp b/Source/Vulkan/Resources/Texture.cpp index 315c0dc..b511bcc 100644 --- a/Source/Vulkan/Resources/Texture.cpp +++ b/Source/Vulkan/Resources/Texture.cpp @@ -16,11 +16,9 @@ Texture::Texture(Context & ctx, const TextureDescription & args) VK_SAMPLE_COUNT_1_BIT)) , m_layout(m_memBlock.GetImage()) { - m_view = - utils::CreateImageView(GetContext().GetGpuConnection().GetDevice(), m_memBlock.GetImage(), - GetInternalFormat(), - utils::CastInterfaceEnum2Vulkan(m_description.type), - VK_IMAGE_ASPECT_COLOR_BIT); + m_view = utils::CreateImageView(GetContext().GetGpuConnection().GetDevice(), + m_memBlock.GetImage(), GetInternalFormat(), GetImageViewType(), + VK_IMAGE_ASPECT_COLOR_BIT); } Texture::~Texture() @@ -87,7 +85,8 @@ VkFormat Texture::GetInternalFormat() const noexcept VkExtent3D Texture::GetInternalExtent() const noexcept { - return {m_description.extent[0], m_description.extent[1], m_description.extent[2]}; + auto [extent, _] = utils::UnpackExtentAndLayers(m_description.extent, m_description.type); + return extent; } uint32_t Texture::GetMipLevelsCount() const noexcept @@ -97,7 +96,18 @@ uint32_t Texture::GetMipLevelsCount() const noexcept uint32_t Texture::GetLayersCount() const noexcept { - return m_description.layersCount; + auto [_, layersCount] = utils::UnpackExtentAndLayers(m_description.extent, m_description.type); + return layersCount; +} + +VkImageType Texture::GetImageType() const noexcept +{ + return utils::CastInterfaceEnum2Vulkan(m_description.type); +} + +VkImageViewType Texture::GetImageViewType() const noexcept +{ + return utils::CastInterfaceEnum2Vulkan(m_description.type); } } // namespace RHI::vulkan diff --git a/Source/Vulkan/Resources/Texture.hpp b/Source/Vulkan/Resources/Texture.hpp index 6f98e30..3098a06 100644 --- a/Source/Vulkan/Resources/Texture.hpp +++ b/Source/Vulkan/Resources/Texture.hpp @@ -33,13 +33,16 @@ struct Texture : public ITexture, public: // IInternalTexture interface virtual VkImageView GetImageView() const noexcept override; - virtual void TransferLayout(details::CommandBuffer & commandBuffer, VkImageLayout layout) override; + virtual void TransferLayout(details::CommandBuffer & commandBuffer, + VkImageLayout layout) override; virtual VkImageLayout GetLayout() const noexcept override; virtual VkImage GetHandle() const noexcept override; virtual VkFormat GetInternalFormat() const noexcept override; virtual VkExtent3D GetInternalExtent() const noexcept override; virtual uint32_t GetMipLevelsCount() const noexcept override; virtual uint32_t GetLayersCount() const noexcept override; + virtual VkImageType GetImageType() const noexcept override; + virtual VkImageViewType GetImageViewType() const noexcept override; private: TextureDescription m_description; diff --git a/Source/Vulkan/Resources/Transferer.cpp b/Source/Vulkan/Resources/Transferer.cpp index 5540f0a..f190ec7 100644 --- a/Source/Vulkan/Resources/Transferer.cpp +++ b/Source/Vulkan/Resources/Transferer.cpp @@ -1,6 +1,7 @@ #include "Transferer.hpp" #include +#include #include #include #include @@ -156,14 +157,24 @@ std::future Transferer::PendingTasksContainer::UploadImage( const size_t copyingRegionSize = RHI::utils::GetSizeOfImage(args.copyRegion.extent, dstImage.GetInternalFormat()); BufferGPU stagingBuffer(GetContext(), copyingRegionSize, g_stagingUsage, true); + + auto [srcExtent, layersCount] = + utils::UnpackExtentAndLayers(args.copyRegion.extent, args.srcTexture.type); + + auto [srcOffset, srcLayerBase] = + utils::UnpackOffsetAndBaseLayer(args.copyRegion.offset, args.srcTexture.type); + + auto [dstOffset, dstLayerBase] = + utils::UnpackOffsetAndBaseLayer(args.dstOffset, dstImage.GetImageType()); + if (auto && mapped_ptr = stagingBuffer.Map()) { MappedGpuTextureView gpuTexture{}; gpuTexture.pixelData = reinterpret_cast(mapped_ptr.get()); gpuTexture.extent = args.copyRegion.extent; gpuTexture.format = dstImage.GetInternalFormat(); - gpuTexture.baseLayerIndex = args.layerIndex; - gpuTexture.layersCount = args.layersCount; + gpuTexture.baseLayerIndex = srcLayerBase; + gpuTexture.layersCount = layersCount; auto dstExtent = dstImage.GetInternalExtent(); CopyImageFromHost(args.srcTexture, gpuTexture, args.copyRegion); mapped_ptr.reset(); @@ -179,15 +190,12 @@ std::future Transferer::PendingTasksContainer::UploadImage( region.bufferOffset = 0; region.bufferRowLength = 0; region.bufferImageHeight = 0; - region.imageExtent = {args.copyRegion.extent[0], args.copyRegion.extent[1], - args.copyRegion.extent[2]}; - region.imageOffset = {static_cast(args.copyRegion.offset[0]), - static_cast(args.copyRegion.offset[1]), - static_cast(args.copyRegion.offset[2])}; + region.imageExtent = srcExtent; + region.imageOffset = dstOffset; region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; region.imageSubresource.mipLevel = 0; - region.imageSubresource.baseArrayLayer = args.layerIndex; - region.imageSubresource.layerCount = args.layersCount; + region.imageSubresource.baseArrayLayer = dstLayerBase; + region.imageSubresource.layerCount = layersCount; } VkImageLayout oldLayout = dstImage.GetLayout(); @@ -208,20 +216,24 @@ std::future Transferer::PendingTasksContainer::DownloadImage( RHI::utils::GetSizeOfImage(args.copyRegion.extent, srcImage.GetInternalFormat()), g_stagingUsage, true); + + auto [srcOffset, layerBase] = + utils::UnpackOffsetAndBaseLayer(args.copyRegion.offset, srcImage.GetImageType()); + + auto [srcExtent, layersCount] = + utils::UnpackExtentAndLayers(args.copyRegion.extent, srcImage.GetImageType()); + VkBufferImageCopy region{}; { region.bufferOffset = 0; region.bufferRowLength = 0; region.bufferImageHeight = 0; - region.imageExtent = {args.copyRegion.extent[0], args.copyRegion.extent[1], - args.copyRegion.extent[2]}; - region.imageOffset = {static_cast(args.copyRegion.offset[0]), - static_cast(args.copyRegion.offset[1]), - static_cast(args.copyRegion.offset[2])}; + region.imageExtent = srcExtent; + region.imageOffset = srcOffset; region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; region.imageSubresource.mipLevel = 0; - region.imageSubresource.baseArrayLayer = args.layerIndex; - region.imageSubresource.layerCount = args.layersCount; + region.imageSubresource.baseArrayLayer = layerBase; + region.imageSubresource.layerCount = layersCount; } auto createDownloadResult =