图像视图。这也是一个比较诡异的概念,正常来讲,我们创建了图像资源,那么为什么不知使用,还要创建一个图像视图的概念呢?
这是因为在vulkan中图像资源并不能被直接使用,因为需要的信息比它包含的信息更多,所以我们不能把图像资源直接作为帧缓冲的attachment使用,也不能将其绑定到描述符集,用来给shader采样。
一般来说vulkan中,都是通过图像资源创建图像视图来解决这个问题。
图像视图的创建也很简单:1
2
3
4
5VKAPI_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
10typedef 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
7typedef 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
7void 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 | VkImageView createImageView(VkImage image, VkFormat format, VkImageAspectFlags aspectFlags, uint32_t mipLevels) { |