创建图像
图像是含有一、二或三个维度的数据,这些数据还含有额外的mipmap纹理映射等级和层级。图像数据(纹素)的每个元素含有一个或多个样本。
图像含有很多用途,可以将图像作为复制操作的数据源;也可以通过描述符集合将图像与管线绑定,将它们作为纹理(与OpenGL类似);还可以渲染图像,在这类情况中将图像作为色彩或深度附着材料(渲染目标)。
在图像的创建过程中,可以设置图像的参数,如尺寸、格式和使用方式。
具体处理过程
(1)获取用于创建图像的逻辑设备的句柄,将该句柄存储到一个VkDevice类型的变量中,将该变量命名为logical_device。
(2)选择图像类型(决定图像含有一、二或三个维度),使用相应的值初始化类型为VkImageType、名为type的变量。
(3)选择图像的格式:组件的数量和每个图像元素含有的位数。将图像格式存储在一个VkFormat类型的变量中,将该变量命名为format。
(4)选择图像的尺寸(面积),使用该值初始化一个VkExtent3D类型的变量,将该变量命名为size。
(5)选择为图像定义的mipmap纹理映射等级的编号,将该编号存储到一个uint32_t类型的变量中,将该变量命名为num_mipmaps。
(6)选择为图像定义的图层数量,将该数量存储在一个uint32_t类型的变量中,将该变量命名为num_layers。如果要将图像作为立方体贴图,那么图层的数量必须是6的倍数。
(7)创建一个VkSampleCountFlagBits类型的变量,将其命名为samples,将样本的数量赋予该变量。
(8)选择使用图像的方式,将这些方式存储到一个VkImageUsageFlags类型的变量中,将该变量命名为usage_scenarios。
(9)创建一个VkImageCreateInfo类型的变量,将其命名为image_create_info。将下列值赋予该变量中的各个成员。
● 将VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO赋予sType成员。
● 将nullptr赋予pNext成员。
● 如果要将图像作为立方体贴图,就将VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT赋予flags成员,否则,就将0赋予flags成员。
● 将type变量的值赋予imageType成员。
● 将format变量的值赋予format成员。
● 将size变量的值赋予extent成员。
● 将num_mipmaps变量的值赋予mipLevels成员。
● 将num_layers变量的值赋予arrayLayers成员。
● 将samples变量的值赋予samples成员。
● 将VK_IMAGE_TILING_OPTIMAL赋予tiling成员。
● 将usage_scenarios变量的值赋予usage成员。
● 将VK_SHARING_MODE_EXCLUSIVE赋予sharingMode成员。
● 将0赋予queueFamilyIndexCount成员。
● 将nullptr赋予pQueueFamilyIndices成员。
● 将VK_IMAGE_LAYOUT_UNDEFINED赋予initialLayout成员。
(10)创建一个VkImage类型的变量,将其命名为image,该变量用于仓库图像的句柄。
(11)调用vkCreateImage(logical_device,&image_create_info,nullptr,&image)
函数,将第一个参数设置为逻辑设备的句柄;将第二个参数设置为指向image_create_info变量的指针;将第三个参数设置为nullptr;将第四个参数设置为指向image变量的指针。
(12)通过查明该函数调用操作的返回值等于VK_SUCCESS,确认该函数调用操作成功完成。
具体运行情况
在创建图像前需要准备多个参数:图像的类型、面积(尺寸)、组件的数量和每个组件(格式)的位数。了解图像是否会含有mipmap纹理映射,图像是否会拥有多个图层(常规图像必须含有至少一个图层,立方体贴图必须含有至少6个图层)。我们还需要考虑使用图像的方式,其中参数是在创建图像的过程中被定义的。如果在创建图像的过程中没有定义使用图像的方式,我们就不能通过这种方式使用图像。
TIP 只能通过在创建图像时定义的方式使用图像。
下面列出了得到支持的图像使用方式:
● 使用VK_IMAGE_USAGE_TRANSFER_SRC_BIT标志值可以指明能够将图像作为复制操作的数据源。
● 使用VK_IMAGE_USAGE_TRANSFER_DST_BIT标志值可以指明能够将数据复制到图像中。
● 使用VK_IMAGE_USAGE_SAMPLED_BIT标志值可以设定能够从着色器中的图像采样。
● 使用VK_IMAGE_USAGE_STORAGE_BIT标志值可以设定能够将图像作为着色器中的仓库图像。
● 使用VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT标志值可以设定能够渲染图像(将图像作为帧缓冲区中的色彩渲染目标/附着材料)。
● 使用VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT标志值可以设定能够将图像作为深度和/或刻板缓冲区(将图像作为帧缓冲区中的深度渲染目标/附着材料)。
● 使用VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT标志值可以设定能够通过惰性方式(根据需要)分配与图像绑定的内存。
● 使用VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT标志值可以设定能够将图像作为着色器中的输入附着材料。
不同的使用场景需要使用不同的图像布局,使用图像内存屏障可以更改(切换)这些布局。但在创建图像的过程中,只能设置VK_IMAGE_LAYOUT_UNDEFINED布局(用于不考虑图像初始内容的情况)和VK_IMAGE_LAYOUT_PREINITIALIZED布局(用于通过映射主机可见内存上传数据的情况),而且在使用图像时总是需要切换到另一种布局。
所有图像参数都是通过VkImageCreateInfo类型的变量设置的。

在创建图像时,需要设置平铺(tiling)类型。平铺类型定义了图像的内存结构,其类型有两种:线性和最优。
在使用线性平铺时,图像的数据会以线性方式存储在内存中(与缓冲区和C/C++数组相似)。这使我们能够映射图像的内存,并通过我们编写的应用程序直接初始化图像的内存和从图像的内存读取数据,这是因为我们知道该图像内存的组织方式。但是,这限制了许多图像的其他用途,如无法将图像作为深度纹理或立方体贴图(某些驱动程序可能支持该用法,但它不属于技术规范,通常情况下,我们不应该依赖它)。线性平铺还会降低应用程序的性能。
TIP为了获得最佳性能,我们推荐使用最优平铺方式创建图像。
通过最优平铺方式创建的图像可以用于所有用途,而且含有更好的性能,但这使我们无法知道图像内存的组织形式。下图展示了图像的数据和内部结构。

在使用最优平铺方式时,每种图形硬件都可能使用不同的方式仓库图像数据。因此,我们无法映射图像的内存,也无法通过我们编写的应用程序直接初始化图像的内存和从图像的内存读取数据。在这种情况下,就需要使用暂存资源(staging resources)。做好准备工作后,可以使用下列代码创建图像。

酷客网相关文章:
评论前必须登录!
注册