2

我已经读过(在自己遇到限制之后),为了将数据从主机复制到VK_IMAGE_TILING_OPTIMAL VkImage,最好使用VkBuffer而不是 VkImage 作为暂存图像,以避免对 mipmap 和层数的限制。(这里这里

因此,当涉及到实现一个glReadPixels类似功能以将渲染到纹理的结果读取回主机时,我认为使用暂存 VkImagevkCmdCopyImageToBuffer而不是使用暂存 VkImage 读取暂存 VkBuffer 是一个好主意。

但是,我还不能让它工作,我看到了大部分预期的图像,但是图像的矩形块位置不正确,甚至有些位重复。

我很有可能在某个地方搞砸了我的同步或布局转换,我将继续调查这种可能性。

但是,我无法从规范中弄清楚使用vkCmdCopyImageToBuffer图像源 usingVK_IMAGE_TILING_OPTIMAL是否实际上应该“取消平铺”图像,或者如果我尝试这样一个事物。

所以我的问题是:源图像是vkCmdCopyImageToBufferVK_IMAGE_TILING_OPTIMAL线性平铺数据还是最佳(实现定义)平铺数据填充缓冲区?

4

1 回答 1

2

第 18.4 节描述了源/目标缓冲区中数据的布局,相对于从/到复制的图像。这在VkBufferImageCopy结构的描述中有所概述。本节中没有任何语言允许与平铺图像不同的行为。

该规范甚至有关于副本如何工作的伪代码(这是针对非块压缩图像):

rowLength = region->bufferRowLength;
if (rowLength == 0)
    rowLength = region->imageExtent.width;

imageHeight = region->bufferImageHeight;
if (imageHeight == 0)
    imageHeight = region->imageExtent.height;

texelSize = <texel size taken from the src/dstImage>;

address of (x,y,z) = region->bufferOffset + (((z * imageHeight) + y) * rowLength + x) * texelSize;

where x,y,z range from (0,0,0) to region->imageExtent.width,height,depth}.

x,y,z部分是图像中相关像素的位置。由于这个位置不依赖于图像的平铺(正如没有任何说明它会证明的那样),缓冲区/图像副本将在两种平铺上同样有效。

另外,请注意,此规范在和之间共享。因此,如果副本以一种方式工作,它必然必须以另一种方式工作。vkCmdCopyImageToBuffervkCmdCopyBufferToImage

于 2016-05-13T16:18:34.297 回答