当源图像使用 VK_IMAGE_TILING_OPTIMAL 时,vkCmdCopyImageToBuffer 是否有效?
Does vkCmdCopyImageToBuffer work when source image uses VK_IMAGE_TILING_OPTIMAL?
我读过(在 运行 自己进入限制之后)从主机复制数据到 VK_IMAGE_TILING_OPTIMAL
VkImage,你最好关闭使用 VkBuffer 而不是 VkImage 作为暂存图像,以避免对 mipmap 和层数的限制。 (Here and Here)
因此,在实现 glReadPixels
式的功能以将渲染到纹理的结果读回主机时,我认为使用 vkCmdCopyImageToBuffer
而不是使用暂存 VkImage 是个好主意。
但是,我还没有能够让它工作,我看到了大部分预期的图像,但是图像的矩形块位于不正确的位置,甚至有些位重复。
很有可能我在某处搞砸了我的同步或布局转换,我将继续调查这种可能性。
但是,我无法从规范中弄清楚将 vkCmdCopyImageToBuffer
与使用 VK_IMAGE_TILING_OPTIMAL
的图像源一起使用是否实际上应该 'un-tile' 图像,或者我是否真的应该如果我尝试这样做,预计会收到乱码的实现定义的图像布局。
所以我的问题是:使用 VK_IMAGE_TILING_OPTIMAL
源图像的 vkCmdCopyImageToBuffer
是否使用线性平铺数据或最佳(实现定义的)平铺数据填充缓冲区?
Section 18.4 描述了 source/destination 缓冲区中数据的布局,相对于正在复制的图像 from/to。 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
部分是图像中相关像素的位置。由于此位置不依赖于图像的平铺(没有任何说明会如此),buffer/image 份副本将同样适用于两种平铺。
此外,请注意此规范在 vkCmdCopyImageToBuffer
和 vkCmdCopyBufferToImage
之间 共享 。因此,如果一个副本以一种方式工作,它必然必须以另一种方式工作。
我读过(在 运行 自己进入限制之后)从主机复制数据到 VK_IMAGE_TILING_OPTIMAL
VkImage,你最好关闭使用 VkBuffer 而不是 VkImage 作为暂存图像,以避免对 mipmap 和层数的限制。 (Here and Here)
因此,在实现 glReadPixels
式的功能以将渲染到纹理的结果读回主机时,我认为使用 vkCmdCopyImageToBuffer
而不是使用暂存 VkImage 是个好主意。
但是,我还没有能够让它工作,我看到了大部分预期的图像,但是图像的矩形块位于不正确的位置,甚至有些位重复。
很有可能我在某处搞砸了我的同步或布局转换,我将继续调查这种可能性。
但是,我无法从规范中弄清楚将 vkCmdCopyImageToBuffer
与使用 VK_IMAGE_TILING_OPTIMAL
的图像源一起使用是否实际上应该 'un-tile' 图像,或者我是否真的应该如果我尝试这样做,预计会收到乱码的实现定义的图像布局。
所以我的问题是:使用 VK_IMAGE_TILING_OPTIMAL
源图像的 vkCmdCopyImageToBuffer
是否使用线性平铺数据或最佳(实现定义的)平铺数据填充缓冲区?
Section 18.4 描述了 source/destination 缓冲区中数据的布局,相对于正在复制的图像 from/to。 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
部分是图像中相关像素的位置。由于此位置不依赖于图像的平铺(没有任何说明会如此),buffer/image 份副本将同样适用于两种平铺。
此外,请注意此规范在 vkCmdCopyImageToBuffer
和 vkCmdCopyBufferToImage
之间 共享 。因此,如果一个副本以一种方式工作,它必然必须以另一种方式工作。