From 4686de8ebdd99832c85a1dbb9646149b9b530291 Mon Sep 17 00:00:00 2001 From: niki Date: Sat, 30 Jul 2022 02:17:58 +0200 Subject: [PATCH] vulkan: implement copy Texture <-> buffer methods --- src/modules/graphics/vulkan/Texture.cpp | 41 +++++++++++++++++++++++++ src/modules/graphics/vulkan/Texture.h | 4 +-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/modules/graphics/vulkan/Texture.cpp b/src/modules/graphics/vulkan/Texture.cpp index 75cd58b9c..172f6e664 100644 --- a/src/modules/graphics/vulkan/Texture.cpp +++ b/src/modules/graphics/vulkan/Texture.cpp @@ -274,6 +274,47 @@ void Texture::uploadByteData(PixelFormat pixelformat, const void* data, size_t s vgfx->queueDatatransfer(command, cleanUp); } + +void Texture::copyFromBuffer(graphics::Buffer* source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect& rect) { + vgfx->queueDatatransfer([source, textureImage = textureImage, rect=rect, sourceoffset, sourcewidth, size, slice, mipmap](VkCommandBuffer commandBuffer){ + VkImageSubresourceLayers layers{}; + layers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + layers.mipLevel = mipmap; + layers.baseArrayLayer = slice; + layers.layerCount = 1; + + VkBufferImageCopy region{}; + region.bufferOffset = sourceoffset; + region.bufferRowLength = sourcewidth; + region.bufferImageHeight = 1; + region.imageSubresource = layers; + region.imageExtent.width = static_cast(rect.w); + region.imageExtent.height = static_cast(rect.h); + + vkCmdCopyBufferToImage(commandBuffer, (VkBuffer)source->getHandle(), textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + }, nullptr); +} + +void Texture::copyToBuffer(graphics::Buffer* dest, int slice, int mipmap, const Rect& rect, size_t destoffset, int destwidth, size_t size) { + vgfx->queueDatatransfer([dest, textureImage = textureImage, rect=rect, destoffset, destwidth, size, slice, mipmap](VkCommandBuffer commandBuffer){ + VkImageSubresourceLayers layers{}; + layers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + layers.mipLevel = mipmap; + layers.baseArrayLayer = slice; + layers.layerCount = 1; + + VkBufferImageCopy region{}; + region.bufferOffset = destoffset; + region.bufferRowLength = destwidth; + region.bufferImageHeight = 1; + region.imageSubresource = layers; + region.imageExtent.width = static_cast(rect.w); + region.imageExtent.height = static_cast(rect.h); + + vkCmdCopyImageToBuffer(commandBuffer, textureImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, (VkBuffer) dest->getHandle(), 1, ®ion); + }, nullptr); +} + } // vulkan } // graphics } // love diff --git a/src/modules/graphics/vulkan/Texture.h b/src/modules/graphics/vulkan/Texture.h index 27353dd64..5de550df6 100644 --- a/src/modules/graphics/vulkan/Texture.h +++ b/src/modules/graphics/vulkan/Texture.h @@ -20,8 +20,8 @@ public: virtual bool loadVolatile() override; virtual void unloadVolatile() override; - void copyFromBuffer(graphics::Buffer* source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect& rect) override { }; - void copyToBuffer(graphics::Buffer* dest, int slice, int mipmap, const Rect& rect, size_t destoffset, int destwidth, size_t size) override { }; + void copyFromBuffer(graphics::Buffer* source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect& rect) override; + void copyToBuffer(graphics::Buffer* dest, int slice, int mipmap, const Rect& rect, size_t destoffset, int destwidth, size_t size) override; ptrdiff_t getRenderTargetHandle() const override { return (ptrdiff_t)textureImage; }; ptrdiff_t getSamplerHandle() const override { return (ptrdiff_t)textureSampler; };