Vulkan之ImageView

图像视图。这也是一个比较诡异的概念,正常来讲,我们创建了图像资源,那么为什么不知使用,还要创建一个图像视图的概念呢?

这是因为在vulkan中图像资源并不能被直接使用,因为需要的信息比它包含的信息更多,所以我们不能把图像资源直接作为帧缓冲的attachment使用,也不能将其绑定到描述符集,用来给shader采样。

一般来说vulkan中,都是通过图像资源创建图像视图来解决这个问题。

图像视图的创建也很简单:

1
2
3
4
5
VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(
VkDevice device,
const VkImageViewCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkImageView* pView);

其中比较复杂的是createInfo结构

1
2
3
4
5
6
7
8
9
10
typedef struct VkImageViewCreateInfo {
VkStructureType sType; // 类型信息VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
const void* pNext; // 扩展
VkImageViewCreateFlags flags; //
VkImage image; // 图像资源
VkImageViewType viewType; //指定图像被看作是一维纹理、二维纹理、三维纹理还是立方体贴图
VkFormat format; // 图像的格式
VkComponentMapping components; //图像颜色通道的映射
VkImageSubresourceRange subresourceRange;
} VkImageViewCreateInfo;

subresourceRange成员变量用于指定图像的用途和图像的哪一部分可以被访问

1
2
3
4
5
6
7
typedef struct VkImageSubresourceRange {
VkImageAspectFlags aspectMask; // 需要用到的图像资源的的层的位表示
uint32_t baseMipLevel; // 从mipMap的那个层开始
uint32_t levelCount; // 包含多少个mipMap层
uint32_t baseArrayLayer; // 起始层
uint32_t layerCount; //层数
} VkImageSubresourceRange;

实际的应用如下所示:

1
2
3
4
5
6
7
void createImageViews() {
swapChainImageViews.resize(swapChainImages.size());

for (uint32_t i = 0; i < swapChainImages.size(); i++) {
swapChainImageViews[i] = createImageView(swapChainImages[i], swapChainImageFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
VkImageView createImageView(VkImage image, VkFormat format, VkImageAspectFlags aspectFlags, uint32_t mipLevels) {
VkImageViewCreateInfo viewInfo{};
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = image;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = format;
viewInfo.subresourceRange.aspectMask = aspectFlags;
viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = mipLevels;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = 1;

VkImageView imageView;
if (vkCreateImageView(device, &viewInfo, nullptr, &imageView) != VK_SUCCESS) {
throw std::runtime_error("failed to create texture image view!");
}

return imageView;
}
显示 Gitment 评论