Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add texture array support to vulkan readback #3235

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 18 additions & 9 deletions src/renderer_vk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2305,6 +2305,7 @@ VK_IMPORT_DEVICE
uint32_t height = bx::uint32_max(1, texture.m_height >> _mip);
uint32_t pitch = texture.m_readback.pitch(_mip);
uint32_t size = height * pitch;
size *= bx::uint32_max(1, texture.m_numLayers);

VkDeviceMemory stagingMemory;
VkBuffer stagingBuffer;
Expand All @@ -2320,7 +2321,8 @@ VK_IMPORT_DEVICE

kick(true);

texture.m_readback.readback(stagingMemory, 0, _data, _mip);
uint32_t memRead = texture.m_readback.readback(stagingMemory, 0, _data, _mip);
BX_ASSERT(memRead == size, "Readback did not copy the same amount of memory as allocated in stagingBuffer");

vkDestroy(stagingBuffer);
vkDestroy(stagingMemory);
Expand Down Expand Up @@ -4031,7 +4033,7 @@ VK_IMPORT_DEVICE
const uint32_t height = _swapChain.m_sci.imageExtent.height;

ReadbackVK readback;
readback.create(image, width, height, _swapChain.m_colorFormat);
readback.create(image, width, height, 1 /*numLayer*/, _swapChain.m_colorFormat);
const uint32_t pitch = readback.pitch();

readback.copyImageToBuffer(m_commandBuffer, _buffer, layout, VK_IMAGE_ASPECT_COLOR_BIT);
Expand Down Expand Up @@ -5594,12 +5596,13 @@ VK_DESTROY
}
}

void ReadbackVK::create(VkImage _image, uint32_t _width, uint32_t _height, TextureFormat::Enum _format)
void ReadbackVK::create(VkImage _image, uint32_t _width, uint32_t _height, uint32_t _numLayers, TextureFormat::Enum _format)
{
m_image = _image;
m_width = _width;
m_height = _height;
m_format = _format;
m_numLayers = _numLayers;
}

void ReadbackVK::destroy()
Expand Down Expand Up @@ -5628,7 +5631,7 @@ VK_DESTROY
, _mip
, 1
, 0
, 1
, VK_REMAINING_ARRAY_LAYERS
);

VkBufferImageCopy bic;
Expand All @@ -5638,7 +5641,7 @@ VK_DESTROY
bic.imageSubresource.aspectMask = _aspect;
bic.imageSubresource.mipLevel = _mip;
bic.imageSubresource.baseArrayLayer = 0;
bic.imageSubresource.layerCount = 1;
bic.imageSubresource.layerCount = m_numLayers;
bic.imageOffset = { 0, 0, 0 };
bic.imageExtent = { mipWidth, mipHeight, 1 };

Expand Down Expand Up @@ -5667,33 +5670,39 @@ VK_DESTROY
, _mip
, 1
, 0
, 1
, VK_REMAINING_ARRAY_LAYERS
);
}

void ReadbackVK::readback(VkDeviceMemory _memory, VkDeviceSize _offset, void* _data, uint8_t _mip) const
uint32_t ReadbackVK::readback(VkDeviceMemory _memory, VkDeviceSize _offset, void* _data, uint8_t _mip) const
{
if (m_image == VK_NULL_HANDLE)
{
return;
return 0;
}

uint32_t mipHeight = bx::uint32_max(1, m_height >> _mip);
// for texture arrays we iterate over each layer as well.
mipHeight *= bx::uint32_max(1, m_numLayers);

uint32_t rowPitch = pitch(_mip);

uint8_t* src;
VK_CHECK(vkMapMemory(s_renderVK->m_device, _memory, 0, VK_WHOLE_SIZE, 0, (void**)&src) );
src += _offset;
uint8_t* dst = (uint8_t*)_data;

uint32_t memRead = 0;
for (uint32_t yy = 0; yy < mipHeight; ++yy)
{
bx::memCopy(dst, src, rowPitch);
src += rowPitch;
dst += rowPitch;
memRead += rowPitch;
}

vkUnmapMemory(s_renderVK->m_device, _memory);
return memRead;
}

VkResult TextureVK::create(VkCommandBuffer _commandBuffer, uint32_t _width, uint32_t _height, uint64_t _flags, VkFormat _format)
Expand Down Expand Up @@ -6130,7 +6139,7 @@ VK_DESTROY

bx::free(g_allocator, imageInfos);

m_readback.create(m_textureImage, m_width, m_height, TextureFormat::Enum(m_textureFormat) );
m_readback.create(m_textureImage, m_width, m_height, m_numLayers, TextureFormat::Enum(m_textureFormat) );
}

return m_directAccessPtr;
Expand Down
5 changes: 3 additions & 2 deletions src/renderer_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -623,15 +623,16 @@ VK_DESTROY_FUNC(DescriptorSet);

struct ReadbackVK
{
void create(VkImage _image, uint32_t _width, uint32_t _height, TextureFormat::Enum _format);
void create(VkImage _image, uint32_t _width, uint32_t _height, uint32_t _numLayers, TextureFormat::Enum _format);
void destroy();
uint32_t pitch(uint8_t _mip = 0) const;
void copyImageToBuffer(VkCommandBuffer _commandBuffer, VkBuffer _buffer, VkImageLayout _layout, VkImageAspectFlags _aspect, uint8_t _mip = 0) const;
void readback(VkDeviceMemory _memory, VkDeviceSize _offset, void* _data, uint8_t _mip = 0) const;
uint32_t readback(VkDeviceMemory _memory, VkDeviceSize _offset, void* _data, uint8_t _mip = 0) const;

VkImage m_image;
uint32_t m_width;
uint32_t m_height;
uint32_t m_numLayers;
TextureFormat::Enum m_format;
};

Expand Down