Vulkan编程指南翻译 第四章 队列和命令 第4节 复制图像数据
来源:互联网 发布:兰芝淘宝旗舰店 编辑:程序博客网 时间:2024/04/20 09:19
4.4 复制图像数据
在前一节,我们讨论了如何清空图像并通过一个简单的数据结构来填充数据。在很多情况下,你需要把纹理数据上传到图像或者复制图像数据到另一图像。Vulkan支持从缓冲区向图像复制数据,在图像之间复制数据,和从图像向缓冲区复制数据。
调用vkCmdCopyBufferToImage(),可从缓冲区向图像的一个或者多个区域复制数据。其原型如下:
void vkCmdCopyBufferToImage (
VkCommandBuffer commandBuffer,
VkBuffer srcBuffer,
VkImage dstImage,
VkImageLayout dstImageLayout,
uint32_t regionCount,
const VkBufferImageCopy* pRegions);
将要执行复制操作命令的命令缓冲区通过commandBuffer参数指定,源缓冲区srcBuffer参数指定,数据将要复制到的目标图像由dstImage参数指定。和需要清空的目标图像一样,目标图像的布局须为 VK_IMAGE_LAYOUT_GENERAL 或 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,通过dstImageLayout参数指定。
需要更新的区域数量由regionCount参数给定,pRegions参数是一个指针,指向一个大小为regionCount、类型为VkBufferImageCopy的数组,每一个元素定义图像中需要向其复制数据的一个区域。VkBufferImageCopy的定义如下:
typedef struct VkBufferImageCopy {
VkDeviceSize bufferOffset;
uint32_t bufferRowLength;
uint32_t bufferImageHeight;
VkImageSubresourceLayers imageSubresource;
VkOffset3D imageOffset;
VkExtent3D imageExtent;
} VkBufferImageCopy;bufferOffset域包含了缓冲区中数据的偏移量,单位是byte。缓冲区内的数据从左到右、从上到下排放,如图4.1所示。bufferRowLength域指定了源图像中纹素的个数,bufferImageHeight图像数据的行数。如果bufferRowLength为0,图像就被认为是在缓冲区中紧致压缩的,因此和imageExtent.width相等。同样,如果bufferImageHeight为0,那么源图像的行数就被认为和图像extend的高度,亦即 imageExtent.height相等。
图4.1 缓冲区中图像的数据排放
需要复制数据到的子资源,是通过一个VkImageSubresourceLayers类型的数据来指定的。其原型如下:
typedef struct VkImageSubresourceLayers {
VkImageAspectFlags aspectMask;
uint32_t mipLevel;
uint32_t baseArrayLayer;
uint32_t layerCount;
} VkImageSubresourceLayers;
VkImageSubresourceLayers的aspectMask域包含复制数据操作目标图像的aspect或多个aspect。通常,这将会是VkImageAspectFlagBits枚举中的某一个。如果目标图像是颜色图像,那么将是VK_IMAGE_ASPECT_DEPTH_BIT,如果图像是stencil-only图像,它将是VK_IMAGE_ASPECT_STENCIL_BIT。如果图像是复合的depth-stencil图像,那么你需要指定VK_IMAGE_ASPECT_DEPTH_BIT 和 VK_IMAGE_ASPECT_STENCIL_BIT这两个标志位,以同时复制数据到深度和stencil aspect。
目标mipmap层数通过mipLevel参数指定。你可以用pRegions数组中每一元素复制到mipmap的某一层,即使你可以指定多个元素,每个对应不同的层。
如果目标图像是array 图像,那么你就可以通过baseArrayLayer 和layerCount指定图像的起始层和层数。如果图像不是array图像,那么这两个域就应该分别置为0和1.
每个区域可以对应一整个mipmap层或者一层中更小的一块窗口。窗口的偏移量通过imageOffset指定,窗口的大小通过imageExtent指定。可以通过设置 imageOffset.x 和
imageOffset.y 为0,imageExtent.width 和imageExtent.height分别为mipmap level的大小,来覆盖掉整个mipmap层。需要你自己来做计算,Vulkan不会替你做这个工作的。
也可以反方向的做复制操作--从一个图像对象复制数据到缓冲区。需要调用vkCmdCopyImageToBuffer()命令,其原型如下:
void vkCmdCopyImageToBuffer (
VkCommandBuffer commandBuffer,
VkImage srcImage,
VkImageLayout srcImageLayout,
VkBuffer dstBuffer,
uint32_t regionCount,
const VkBufferImageCopy* pRegions);
做这个操作的命令缓冲区通过commandBuffer指定,含有源数据的图像通过srcImage参数传递,复制操作的目标图像通过dstImage参数传递。再有,两个图像的布局也需要传递到复制命令。srcImageLayout是复制操作中期望的源图像布局,值为VK_IMAGE_LAYOUT_GENERAL或VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL(当它是转移操作的源)。同样的,dstImageLayout是期望的目标图像布局,值为VK_IMAGE_LAYOUT_GENERAL或VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL。
和“缓冲区至图像”,“图像至缓冲区”命令一样,vkCmdCopyImage()可同时复制多个区域。regionCount指定了复制区域的个数,每一个都通过VkImageCopy类型数组内的一个实例表示,数组的地址通过pRegions传递。VkImageCopy定义如下:
typedef struct VkImageCopy {
VkImageSubresourceLayers srcSubresource;
VkOffset3D srcOffset;
VkImageSubresourceLayers dstSubresource;
VkOffset3D dstOffset;
VkExtent3D extent;
} VkImageCopy;
每一个VkImageCopy实例包含子资源信息和源、目标的窗口起始位置。vkCmdCopyImage()不能改变数据的尺寸,所以源和目标图像的extent是相同的,且包含在extent域。
srcSubresource包含子对源数据子资源的定义,和传递给vkCmdCopyImageToBuffer()命令的VkBufferImageCopy的imageSubresource域是相同的意思。同样,dstSubresource包含了对目标区域的子资源的定义,和传递给vkCmdCopyImageToBuffer()命令的VkBufferImageCopy的imageSubresource域意思相同。
- Vulkan编程指南翻译 第四章 队列和命令 第4节 复制图像数据
- Vulkan编程指南翻译 第四章 队列和命令 第5节 复制压缩图像数据
- Vulkan编程指南翻译 第四章 队列和命令 第6节 展开图像
- Vulkan编程指南翻译 第四章 队列和命令 第3节 清空和填充图像
- Vulkan编程指南翻译 第四章 队列和命令 第1节 管理资源的状态
- Vulkan编程指南翻译 第四章 队列和命令 第2节 清空和填充缓冲区
- Vulkan编程指南翻译 第三章 队列和命令 第1节 设备队列
- Vulkan编程指南翻译 第三章 队列和命令 第2节 创建命令缓冲区
- Vulkan编程指南翻译 第三章 队列和命令 第3节 记录命令
- Vulkan编程指南翻译 第六章 着色器和管线 第5节 第6段 图像采样
- Vulkan编程指南翻译 第六章 着色器和管线 第4节 执行工作
- Vulkan编程指南翻译 第八章 图形管线 第2节 顶点数据
- Vulkan编程指南翻译 第六章 着色器和管线 第1节 GLSL简介
- Vulkan编程指南翻译 第六章 着色器和管线 第2节 SPIR-V 概述
- Vulkan编程指南翻译 第六章 着色器和管线 第3节 管线
- Vulkan编程指南翻译 第七章 图形管线 第4节 创建简单的图形管线
- Vulkan编程指南翻译 第六章 着色器和管线 第5节 在着色器中访问资源
- Vulkan编程指南翻译 第七章 图形管线 第4节 创建简单的图形管线(下)
- Android ADB 命令总结
- 【算法】打乱有序的算法——洗牌算法
- 并查集 模板
- Python命名空间详解ANDpython中的作用域
- 解决yum不能使用方法
- Vulkan编程指南翻译 第四章 队列和命令 第4节 复制图像数据
- 四边形不等式优化
- class属性中间存在空格,到底是什么意思呢?!
- centos64 上安装mysql
- js常见兼容性问题举例包含完整代码
- OpenJudge1.4编程基础之逻辑表达式与条件分支之 03:奇偶数判断
- Codeforces 362B. Petya and Staircases
- jdk1.8中的filter应用
- ubuntu 14.04 LTS软件中心闪退