Vulkan 学习(8)---- vkImageView 创建

embedded/2024/9/23 7:22:07/

目录

        • OverView
        • 创建方法
        • 关键结构
        • 参考代码

OverView

Vulkan Components

Vulkan 的图像视图(VkImageView) 用于描述如何访问 VkImage 对象以及访问图像的哪一部分,

图像视图定义了图像格式和访问方式,允许渲染管线和图像进行交互,无论是作为纹理,颜色附件或者深度/模板附件

在交换链中,我们需要为每个图像(VkImage)创建一个基本的图像视图(VkImageView),以便将它们作为颜色附件

创建方法

通过 vkCreateImageView 函数创建 vkImageView,函数原型如下:

VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(VkDevice                                    device,const VkImageViewCreateInfo*                pCreateInfo,const VkAllocationCallbacks*                pAllocator,VkImageView*                                pView);

其中的VkImageViewCreateInfo是包含了主要创建信息的结构体:

typedef struct VkImageViewCreateInfo {// 结构体类型,必须是 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFOVkStructureType            sType;// 指向扩展特定数据的指针,对于 核心 vulkan 功能,通常为 nullconst void*                pNext;// 创建图像视图使用的标志位VkImageViewCreateFlags     flags;// 对应的 VkImage 对象VkImage                    image;// 图像视图的类型,决定了视图是如何解释图像的VkImageViewType            viewType;// 图像视图的格式,决定了图像数据的解释方式VkFormat                   format;// 用于在创建视图时重新映射图像的颜色分量VkComponentMapping         components;// 定义了图像视图的子资源范围,包括 mipmap 级别,数组层以及深度层的范围VkImageSubresourceRange    subresourceRange;
} VkImageViewCreateInfo;

其中关键的 VkImageViewTypeVkComponentMappingVkImageSubresourceRange 需要重点关注:

关键结构

VkImageViewType 定义了图像视图的类型:

typedef enum VkImageViewType {VK_IMAGE_VIEW_TYPE_1D = 0,VK_IMAGE_VIEW_TYPE_2D = 1,VK_IMAGE_VIEW_TYPE_3D = 2,VK_IMAGE_VIEW_TYPE_CUBE = 3,VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4,VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5,VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6,VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF
} VkImageViewType;

VkComponentMapping 用于指定如何从源图像中的颜色分量映射到目标图像视图中的颜色分量
通过 VkComponentMapping 类型的属性(components),可以灵活控制图像视图中每个颜色分量的来源,这对于图像处理非常有用,比如转换颜色格式,调整颜色通道等。

默认情况下,我们将每个分量设置为VK_COMPONENT_SWIZZLE_IDENTITY,这意味着它们将直接从源图像中取值:

typedef enum VkComponentSwizzle {VK_COMPONENT_SWIZZLE_IDENTITY = 0, // 使用原始值VK_COMPONENT_SWIZZLE_ZERO = 1, // 使用零值VK_COMPONENT_SWIZZLE_ONE = 2, // 使用一值VK_COMPONENT_SWIZZLE_R = 3, // 使用 R 分量VK_COMPONENT_SWIZZLE_G = 4, // 使用 G 分量VK_COMPONENT_SWIZZLE_B = 5, // 使用 B 分量VK_COMPONENT_SWIZZLE_A = 6, // 使用 A 分量VK_COMPONENT_SWIZZLE_MAX_ENUM = 0x7FFFFFFF
} VkComponentSwizzle;typedef struct VkComponentMapping {VkComponentSwizzle    r; // r 分量 来源VkComponentSwizzle    g; // g 分量 来源VkComponentSwizzle    b; // b 分量 来源VkComponentSwizzle    a; // a 分量 来源
} VkComponentMapping;

VkImageSubresourceRange 允许你选择图像的哪些层面和 mip 级别应该被应用在图像视图中:

typedef struct VkImageSubresourceRange {// 需要包含的图像 aspect(图像特性的层面)VkImageAspectFlags    aspectMask;// mip 级别的起始级别uint32_t              baseMipLevel;// mip 级别的数量uint32_t              levelCount;// 数组层的起始索引uint32_t              baseArrayLayer;// 数组层数量uint32_t              layerCount;
} VkImageSubresourceRange;

aspectMask 用于指定需要包含在图像视图中图像aspect(图像的特性的层面),
比如图像有深度和/或模板信息,你可以选择只包括颜色方面
(VK_IMAGE_ASPECT_COLOR_BIT),或者包括深度方面 (VK_IMAGE_ASPECT_DEPTH_BIT) 和/或模板方面 (VK_IMAGE_ASPECT_STENCIL_BIT)

参考代码

这里一般和VkImage一起创建例子,因为VkImageView 的创建需要包含 VkImage 对象 作为参数:

void vulkanBasicDemo::vulkanCreateVulkanImage() {VkImageCreateInfo imageInfo = {};imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;  // 结构体类型imageInfo.pNext = nullptr;                              // 指向扩展信息的指针imageInfo.flags = 0;                                    // 图像创建标志imageInfo.imageType = VK_IMAGE_TYPE_2D;                 // 图像类型为 2DimageInfo.format = VK_FORMAT_R8G8B8A8_UNORM;            // 图像格式imageInfo.extent.width = test_width;                      // 图像宽度imageInfo.extent.height = test_height;                    // 图像高度imageInfo.extent.depth = 1;                             // 图像深度(对于 2D 图像为 1)imageInfo.mipLevels = 1;                                // MIP 级别数imageInfo.arrayLayers = 1;                              // 图像数组层数imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;              // 多重采样数量(1 表示不使用多重采样)imageInfo.tiling = VK_IMAGE_TILING_LINEAR;             // 图像数据的存储方式(优化存储)imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; // 图像用途(作为传输目标和采样器)imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;      // 共享模式(独占模式)imageInfo.queueFamilyIndexCount = 0;                    // 使用队列族索引的数量imageInfo.pQueueFamilyIndices = &graphicsQueueFamilyIndex;      // 队列族索引的指针imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;    // 图像的初始布局(未定义)VkImage textureImage; // 定义 VkImage 变量// 创建图像if (vkCreateImage(device, &imageInfo, nullptr, &textureImage) != VK_SUCCESS) {throw std::runtime_error("failed to create texture image!"); // 如果创建图像失败,抛出异常}std::cout << __FUNCTION__ <<" vkCreateImage create image successs!" << std::endl;// 获取图像的内存需求VkMemoryRequirements memRequirements;vkGetImageMemoryRequirements(device, textureImage, &memRequirements);// 创建 VkMemoryAllocateInfo 结构体并初始化VkMemoryAllocateInfo allocInfo = {};allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; // 结构体类型allocInfo.allocationSize = memRequirements.size;          // 所需内存大小allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits,VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);                 // 内存类型索引VkDeviceMemory textureImageMemory; // 定义 VkDeviceMemory 变量// 分配内存if (vkAllocateMemory(device, &allocInfo, nullptr, &textureImageMemory) != VK_SUCCESS) {throw std::runtime_error("failed to allocate texture image memory!"); // 如果分配内存失败,抛出异常}// 将内存绑定到图像vkBindImageMemory(device, textureImage, textureImageMemory, 0);std::cout << "vkBindImageMemory Successs!" << std::endl;// 定义 VkImageViewCreateInfo 结构体并初始化VkImageViewCreateInfo viewInfo = {};viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;  // 结构体类型viewInfo.pNext = nullptr;                                   // 指向扩展信息的指针viewInfo.flags = 0;                                         // 图像视图创建标志viewInfo.image = textureImage;                              // 要创建视图的图像句柄viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;                  // 图像视图类型为 2DviewInfo.format = VK_FORMAT_R8G8B8A8_UNORM;                  // 图像视图的格式viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;      // R 分量映射viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;      // G 分量映射viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;      // B 分量映射viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;      // A 分量映射viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; // 视图的子资源范围(颜色部分)viewInfo.subresourceRange.baseMipLevel = 0;                 // 基础 MIP 级别viewInfo.subresourceRange.levelCount = 1;                   // MIP 级别数量viewInfo.subresourceRange.baseArrayLayer = 0;               // 基础数组层viewInfo.subresourceRange.layerCount = 1;                   // 数组层数量VkImageView textureImageView; // 定义 VkImageView 变量// 创建图像视图if (vkCreateImageView(device, &viewInfo, nullptr, &textureImageView) != VK_SUCCESS) {throw std::runtime_error("failed to create texture image view!"); // 如果创建视图失败,抛出异常}std::cout << __FUNCTION__ << " vkCreateImageView create imageView successs!" << std::endl;// 使用完成后销毁资源vkDestroyImageView(device, textureImageView, nullptr);  // 销毁图像试图vkDestroyImage(device, textureImage, nullptr);         // 销毁图像vkFreeMemory(device, textureImageMemory, nullptr);     // 释放图像内存std::cout << "vkDestroyImage Successs!" << std::endl;
}

http://www.ppmy.cn/embedded/115473.html

相关文章

Elastic 的 OpenTelemetry PHP 发行版简介

作者&#xff1a;Pawel Filipczak 宣布 OpenTelemetry PHP 的 Elastic 发行版的第一个 alpha 版本。在本篇博文中了解使用 OpenTelemetry 来检测 PHP 应用程序是多么简单。 我们很高兴推出 OpenTelemetry PHP 的 Elastic Distribution 的第一个 alpha 版本。在这篇文章中&…

洪涝洪水滑坡灾害数据集 灾害 2300张 带标注 voc yolo

洪涝洪水滑坡灾害数据集 灾害 2300张 带标注 voc yolo 洪涝洪水滑坡灾害数据集 数据集描述 该数据集是一个专门用于检测和识别洪涝、洪水和滑坡等自然灾害的数据集&#xff0c;旨在帮助研究人员和开发者训练和评估基于深度学习的目标检测模型。数据集涵盖了两种常见的自然灾害…

【AI创作组】Matlab绘图基础之plot函数

1. plot函数语法 1.1 基本语法 Matlab中的plot函数是最常用的绘图函数之一,其基本语法如下: plot(X,Y)X和Y可以是向量或矩阵,也可以是两个向量的元素个数相同的数组。当X和Y都是向量时,plot函数将在当前坐标轴上绘制Y对X的图。1.2 线型、颜色和标记 plot函数还允许用户…

c++----io流

提示&#xff1a;以下 是本篇文章正文内容&#xff0c;下面案例可供参考 1.标准io流 (1)数据的循环输入 对于内置类型&#xff1a;cin和cout直接使用&#xff0c;c已经重载了 (2)对于自定义类型&#xff1a; 需要我们自己对类型进行重载 2.文件io流 ifstream ifile(只输入…

【devops】devops-ansible之介绍和基础使用

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…

云盘视频保护神器,支持云盘视频加密与在线播放,配合alist使用,超完美!

平时我们保护视频&#xff0c;一般都是采用压缩工具&#xff0c;进行加密打包&#xff0c;然后在上传到网盘存储。这虽然能起到很好的保护&#xff0c;但是有很多问题&#xff1f;比如&#xff1a;无法直接在线播放&#xff0c;还得从网盘中下载后解压&#xff0c;才能进行观看…

docker 升级步骤

Docker 升级的步骤通常取决于你所使用的操作系统。以下是针对常见操作系统&#xff08;如 Ubuntu 和 CentOS&#xff09;的 Docker 升级步骤&#xff1a; Ubuntu 更新现有的包索引&#xff1a; sudo apt-get update 升级 Docker&#xff1a; 您可以运行以下命令来升级 Docker…

CentOS Stream 9部署Redis

1、安装Redis sudo dnf install redis 2、启动Redis服务 sudo systemctl start redis 3、设置Redis开机自启 sudo systemctl enable redis 4、打开Redis配置文件&#xff1a; sudo vi /etc/redis/redis.conf 在配置文件中找到并修改以下两行&#xff0c;确保密码验证功能已启…