Vulkan Cookbook 第五章 2 创建采样图像

创建采样图像

译者注:示例代码点击此处

采样图像用于从着色器内的图像(纹理)读取数据。通常它们与采样器一起使用。并且为了能够将图像用作采样图像,必须使用VK_IMAGE_USAGE_SAMPLED_BIT用法创建图像。

怎么做...

1.获取物理设备句柄将其存储在名为physical_device的VkPhysicalDevice变量中。
2.选择将用于图像的格式初始化名为format的VkFormat类型变量。
3.创建名为format_properties的VkFormatProperties类型变量。
4.调用vkGetPhysicalDeviceFormatProperties( physical_device, format, &format_properties ),为其提供physical_device变量、format变量和指向format_properties变量的指针。
5.通过检查是否设置了format_properties变量的optimalTilingFeatures成员的VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT位确保所选图像格式适合采样图像。
6.如果样本图像将被线性滤波或者其mipmap将被线性滤波,通过检查检查是否设置了format_properties变量的optimalTilingFeatures成员的VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT确保所选格式适合于线性滤波的采样图像。
7.获取使用physical_device变量创建的逻辑设备的句柄,并存储在名为logical_device的VkDevice类型变量中。
8.使用logical_device和format变量创建图像,然后选择其余的图像参数。不要忘记在图像创建期间提供VK_IMAGE_USAGE_SAMPLED_BIT用法。将图像的句柄存储在名为sampled_image的VkImage类型变量中(请参阅第四章资源和内存的创建图像内容)。
9.使用VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT属性分配内存对象(或使用现有的内存对象)并将其绑定到创建的图像(参见第四章资源和内存的分配内存对象和将其绑定到图像内容)。
10.使用logical_device、sampled_image和format变量创建图像视图,然后选择其余的视图参数。将图像视图的句柄存储在名为sampled_image_view的VkImageView类型变量中(参见第四章资源和内存的创建图像视图内容)。

这个怎么运作...

采样图像用作着色器内的图像数据(纹理)的来源。要从图像中获取数据,通常我们需要一个采样器对象,它定义了如何读取数据(情参阅创建采样器内容)。

提示:采样图像使用VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE描述符类型。

在着色器中,我们可以使用多个采样器以不同的方式从同一图像中读取数据。也可以用相同的采样器对多个图像进行采样。但是在某些平台上,使用组合图像采样器对象可能更合适。该组合图像采样器将采样器和采样图像聚集在一个对象中。

 并非所有图像格式都支持采样图像,这取决于执行应用程序的平台。但是有一组强制格式可以始终用于采样图像和线性滤波的采样图像。这种格式的示例包括(但不限于)下列:
·VK_FORMAT_B4G4R4A4_UNORM_PACK16
·VK_FORMAT_R5G6B5_UNORM_PACK16
·VK_FORMAT_A1R5G5B5_UNORM_PACK16
·VK_FORMAT_R8_UNORM and VK_FORMAT_R8_SNORM
·VK_FORMAT_R8G8_UNORM and VK_FORMAT_R8G8_SNORM
·VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_SNORM, and VK_FORMAT_R8G8B8A8_SRGB ·VK_FORMAT_B8G8R8A8_UNORM and VK_FORMAT_B8G8R8A8_SRGB
·VK_FORMAT_A8B8G8R8_UNORM_PACK32, VK_FORMAT_A8B8G8R8_SNORM_PACK32, and ·VK_FORMAT_A8B8G8R8_SRGB_PACK32
·VK_FORMAT_A2B10G10R10_UNORM_PACK32
·VK_FORMAT_R16_SFLOAT
·VK_FORMAT_R16G16_SFLOAT
·VK_FORMAT_R16G16B16A16_SFLOAT
·VK_FORMAT_B10G11R11_UFLOAT_PACK32
·VK_FORMAT_E5B9G9R9_UFLOAT_PACK32

如果我们想使用一些不太典型的格式,需要检查他是否可用于采样图像。可以这样完成:

VkFormatProperties format_properties;
vkGetPhysicalDeviceFormatProperties( physical_device, format, &format_properties );
if( !(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ) {
  std::cout << "Provided format is not supported for a sampled image." << std::endl;
  return false; 
}
if( linear_filtering &&
!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) ) {
  std::cout << "Provided format is not supported for a linear image filtering." << std::endl;
  return false; 
}
                

如果我们确定所选的格式可用,可以创建图像、用于它的内存对象和图像视图(在Vulkan中,大多数情况下图像是用图像视图表示的)。我们需要在图像创建期间指定VK_IMAGE_USAGE_SAMPLED_BIT的使用方式:

if( !CreateImage( logical_device, type, format, size, num_mipmaps, num_layers, VK_SAMPLE_COUNT_1_BIT, usage | VK_IMAGE_USAGE_SAMPLED_BIT, cubemap, sampled_image ) ) {
  return false;
}

if( !AllocateAndBindMemoryObjectToImage( physical_device, logical_device, sampled_image, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, memory_object ) ) {
  return false;
}

if( !CreateImageView( logical_device, sampled_image, view_type, format, aspect, sampled_image_view ) ) {
  return false;
}
return true;

当我们想要将图像用作采样图像时,在从其加载数据到着色器内之前,需要将图像的格式转换为VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL。

提示:为了创建表示着色器中的采样图像的uniform变量。我们需要使用适当的关键字(可能具有前缀)与适当的纹理维度。

可以生成SPIR-V程序集的GLSL代码示例(使用采样图像)可能如下所示:

layout (set=m, binding=n) uniform texture2D <variable name>;

猜你喜欢

转载自blog.csdn.net/qq_19473837/article/details/85087868