【Vulkan入门】09-CreateFrameBuffer

目录

  • 先叨叨
  • git信息
  • 关键代码
    • VulkanEnv::FindHostVisitbaleMemoryTypeIndex()
    • TestPipeLine::CreateFramebuffers()

与网上大多数文章不同,其他文章基本上都使用窗口框架(X11、GLFW、WSL等)提供的surface来显示Vulkan渲染出的图像。我认为那样会屏蔽很多细节,因此我选择使用更原生的方式,即让Vulkan渲染到一块内存中,然后将内存读出再渲染到屏幕上。其实surface只不过是封装好的Image而以。

先叨叨

上一篇创建的RenderPass,但还没有给RenderPass分配内存空间。本篇来介绍如何给RenderPass创建内存空间。RenderPass与内存的对应关系如下图:
在这里插入图片描述
Vulkan的架构设计将RenderPass到Memeory的对应关系拉了一条很长的线路,至于为什么和这么设计的好处,我还理解不到。所以先死记硬背下来。

  1. RenderPass中有很多个Attachment每个,Attachment对应一块内存空间。Attachment用于指明该空间在渲染时具体起到的作用。如:颜色缓存、深度缓存、模板缓存等。
  2. 多个Attachment由一个Subpass进行关联,指明一次渲染会用到Subpass中的所有的Attachment。比如将第一个Attachment当作颜色缓存,将第二Attachment当作深度缓存。
  3. 一个RenderPass对应一个FrameBuffer。而FrameBuffer中有多个ImageView,每个ImageView对应一个RenderPass中的Attachment。。ImageView还不是真正的内存空间。
  4. ImageView会关联到一个Image。Image是对内存空间的描述,但Image并不是真正的内存空间。
  5. 真正的内存空间是Memory,Memory需要从Device上申请,申请完后需要绑定到Image上。

git信息

  • repository: https://gitee.com/J8_series/easy-car-ui
  • tag: 09-CreateFrameBuffer
  • url: https://gitee.com/J8_series/easy-car-ui/tree/09-CreateFrameBuffer

关键代码

VulkanEnv::FindHostVisitbaleMemoryTypeIndex()

上面介绍了Memory需要从Device上申请,而Device可能有多个内存空间(堆)。我希望找到一个GPU和CPU都能访问的堆,因为我想把渲染完的图片拷贝出来。渲染需要GPU访问,而拷贝需要CPU访问。

void VulkanEnv::FindHostVisitbaleMemoryTypeIndex()
{VkPhysicalDeviceMemoryProperties pMemoryProperties;vkGetPhysicalDeviceMemoryProperties(m_selectedPhysicalDevice, &pMemoryProperties);bool found = false;for (uint32_t i = 0; i < pMemoryProperties.memoryTypeCount; ++i){if (pMemoryProperties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT){m_hostVisitbaleMemoryTypeIndex = i;found = true;break;}}if (false == found){throw std::runtime_error("To find host visiable memory is failed");}
}

TestPipeLine::CreateFramebuffers()

本方法流程如下:

  1. 创建Image
  2. 申请Memory
  3. 将Image和Memory 绑定到一起
  4. 创建ImageView并关联到Image上
  5. 创建FrameBuffer。framebufferInfo.pAttachments的值是一个ImageView数组,数组里的元素顺序要与RenderPass中的Attachment顺序一致。Vulkan用这种方式实现了Attachment和ImageView的对应。
    void TestPipeline::CreateFramebuffers(){//https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#VkImageCreateInfoVkImageCreateInfo imageCreateInfo{};imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;imageCreateInfo.pNext = nullptr;imageCreateInfo.flags;imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;imageCreateInfo.format = VK_FORMAT_R8G8B8A8_UINT;imageCreateInfo.extent = VkExtent3D{m_width, m_height, 1};imageCreateInfo.mipLevels = 1;imageCreateInfo.arrayLayers = 1;imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;imageCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;imageCreateInfo.usage = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;imageCreateInfo.queueFamilyIndexCount = 0;imageCreateInfo.pQueueFamilyIndices = nullptr;imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;if (VK_SUCCESS != vkCreateImage(m_device, &imageCreateInfo, nullptr, &m_image)){throw std::runtime_error("To create image is failed!");}// https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#VkMemoryAllocateInfoVkMemoryAllocateInfo memoryAllocationInfo;memoryAllocationInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;memoryAllocationInfo.pNext = nullptr;memoryAllocationInfo.memoryTypeIndex = m_memroyTypeIndex;memoryAllocationInfo.allocationSize = m_width * m_height * 4;// https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#vkAllocateMemoryif (VK_SUCCESS != vkAllocateMemory(m_device, &memoryAllocationInfo, nullptr, &m_imageMemory)){throw std::runtime_error("To allocate memory is failed!");}// https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#vkBindImageMemoryif (VK_SUCCESS != vkBindImageMemory(m_device, m_image, m_imageMemory, 0)){throw std::runtime_error("To bind memory is failed!");}//https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#VkImageViewCreateInfoVkImageViewCreateInfo imageViewCreateInfo{};imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;imageViewCreateInfo.pNext = nullptr;imageViewCreateInfo.flags = 0;imageViewCreateInfo.image = m_image;imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;imageViewCreateInfo.format = VK_FORMAT_R8G8B8A8_UINT;imageViewCreateInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;imageViewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;imageViewCreateInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;imageViewCreateInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;imageViewCreateInfo.subresourceRange.baseMipLevel = 0;imageViewCreateInfo.subresourceRange.levelCount = 1;imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;imageViewCreateInfo.subresourceRange.layerCount = 1;if (VK_SUCCESS != vkCreateImageView(m_device, &imageViewCreateInfo, nullptr, &m_imageView)){throw std::runtime_error("To create image view is failed!");}VkFramebufferCreateInfo framebufferInfo{};framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;framebufferInfo.renderPass = m_renderPass;framebufferInfo.attachmentCount = 1;framebufferInfo.pAttachments = &m_imageView;framebufferInfo.width = m_width;framebufferInfo.height = m_height;framebufferInfo.layers = 1;//https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#vkCreateFramebufferif (VK_SUCCESS != vkCreateFramebuffer(m_device, &framebufferInfo, nullptr, &m_framebuffer)) {throw std::runtime_error("To create framebuffer is failed!");}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/489181.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

题目 1688: 数据结构-字符串插入

第一种方式字符串 #include<iostream> #include<cstring> #include<algorithm> using namespace std; int main(){string s1,s2;int n;cin>>s1>>s2>>n;s1.insert(n-1,s2);cout<<s1<<endl;return 0; } 第二种方式字符数组 …

【KodExplorer】可道云KodExplorer-个人网盘安装使用

说明&#xff1a;安装kodExplorer &#xff08;不是Kodbox&#xff09;&#xff1b;Kodbox需求服务器至少2核4G内存&#xff0c;要求环境具备php/redis/mysql/。安装kodExplorer 就是比较方便简单部署&#xff0c;个人版免费。 一、安装环境需求 服务器: Windows&#xff0c;…

在服务器(linux系统)安装anaconda

按照官方教程操作即可 1.下载anaconda3&#xff0c;选择对应版本 curl -O https://repo.anaconda.com/archive/Anaconda3-2024.06-1-Linux-x86_64.sh2.安装anaconda bash ~/Anaconda3-2024.06-1-Linux-x86_64.sh一直按“enter”键查看协议&#xff0c;然后选择“yes”即可。…

使用 WebRtcStreamer 实现实时视频流播放

WebRtcStreamer 是一个基于 WebRTC 协议的轻量级开源工具&#xff0c;可以在浏览器中直接播放 RTSP 视频流。它利用 WebRTC 的强大功能&#xff0c;提供低延迟的视频流播放体验&#xff0c;非常适合实时监控和其他视频流应用场景。 本文将介绍如何在Vue.js项目中使用 WebRtcSt…

建立基于TCP的客户端和服务端

函数介绍&#xff1a; 1.socket() 作用&#xff1a;创建套接字 domain: AF_INET&#xff1a;IPv4 Internet 协议族。AF_INET6&#xff1a;IPv6 Internet 协议族。AF_UNIX&#xff1a;Unix 域协议族&#xff0c;用于在同一台主机上的进程间通信。 type: SOCK_STREAM&#xff1a…

SQL语句在MySQL中如何执行

MySQL的基础架构 首先就是客户端&#xff0c;其次Server服务层&#xff0c;大多数MySQL的核心服务都在这一层&#xff0c;包括连接、分析、优化、缓存以及所有的内置函数&#xff08;时间、日期、加密函数&#xff09;&#xff0c;所有跨存储引擎功能都在这一层实现&#xff1…

轻量化特征融合 | 一种基于增强层间特征相关性的轻量级特征融合网络 | 北理工新作

论文题目&#xff1a;A Lightweight Fusion Strategy With Enhanced Interlayer Feature Correlation for Small Object Detection 论文链接&#xff1a;https://ieeexplore.ieee.org/abstract/document/10671587 giuhub&#xff1a;https://github.com/nuliweixiao/EFC 关键词…

vue2+element-ui实现多行行内表格编辑

效果图展示 当在表格中点击编辑按钮时:点击的行变成文本框且数据回显可以点击确定按钮修改数据或者取消修改回退数据: 具体实现步骤 1. 行数据定义编辑标记 行数据定义编辑标记 当在组件中获取到用于表格展示数据的方法中,针对每一行数据添加一个编辑标记 this.list.f…

docker简单私有仓库的创建

1&#xff1a;下载Registry镜像 导入镜像到本地中 [rootlocalhost ~]# docker load -i registry.tag.gz 进行检查 2&#xff1a;开启Registry registry开启的端口号为5000 [rootlocalhost ~]# docker run -d -p 5000:5000 --restartalways registry [rootlocalhost ~]# dock…

使用 GD32F470ZGT6,手写 I2C 的实现

我的代码&#xff1a;https://gitee.com/a1422749310/gd32_-official_-code I2C 具体代码位置&#xff1a;https://gitee.com/a1422749310/gd32_-official_-code/blob/master/Hardware/i2c/i2c.c 黑马 - I2C原理 官方 - IIC 协议介绍 个人学习过程中的理解&#xff0c;有错误&…

VSCode,Anaconda,JupyterNotebook

文章目录 一. 下载VSCode并安装二. 下载Anaconda并安装1. anaconda介绍2. Anaconda的包管理功能3. Anaconda的虚拟环境管理4.Jupyter Notebook5. Jupyter Notebook使用简介6. Jupyter Notebook快捷键7.Jupyter notebook的功能扩展8. Jupyter notebook和Jupyter lab的区别 三. V…

【安全研究】某黑产网站后台滲透与逆向分析

文章目录 x01. 前言x02. 分析 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python与爬虫领域研究与…

力扣 343. 整数拆分 (JAVA 记忆化搜索->动态规划)

给定一个正整数 n &#xff0c;将其拆分为 k 个 正整数 的和&#xff08; k > 2 &#xff09;&#xff0c;并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 示例 1: 输入: n 2 输出: 1 解释: 2 1 1, 1 1 1。 示例 2: 输入: n 10 输出: 36 解释: 10 3 …

一次tomcat实战jvm线上问题定位排查和解决

问题分析&#xff1a; 问题来源是客户通过闲鱼找到了我这边进行问题的排查&#xff0c;给我发了一个报错日志&#xff0c;让我帮忙分析。 首先他的项目比较老&#xff0c;很多年以前开发的软件&#xff0c;但是具体做什么业务我不知道。下面来看日志的报错分析。 问题&#…

【Linux】软硬链接

文章目录 软链接硬链接软硬链接的使用场景&#xff1a;软链接的使用场景硬链接的应用场景 总结 软链接 软链接是一种指向文件或目录的快捷方式&#xff0c;是文件系统中非常重要的功能。它类似于Windows中的快捷方式&#xff0c;但更灵活&#xff0c;可以跨文件系统创建。 ln…

操作系统(5)进程

一、定义与特点 定义&#xff1a;进程是计算机中的程序关于某数据集合上的一次运行活动&#xff0c;是系统进行资源分配和调度的基本单位&#xff0c;是操作系统结构的基础。 特点&#xff1a; 动态性&#xff1a;进程是动态创建的&#xff0c;有它自身的生命周期&#xff0c;…

安宝特分享 | AR技术助力医院总院与分院间的远程面诊

随着科技的迅猛发展&#xff0c;增强现实&#xff08;AR&#xff09;技术在各行各业的应用愈发广泛&#xff0c;特别是在医疗领域&#xff0c;其潜力和价值正在被不断挖掘。在现代医疗环境中&#xff0c;患者常常面临“看病难、看病远、看病急”等诸多挑战&#xff0c;而安宝特…

CNCF云原生生态版图-分类指南(三)- 运行时

CNCF云原生生态版图-分类指南&#xff08;三&#xff09;- 运行时 CNCF云原生生态版图-分类指南三、运行时&#xff08;Runtime&#xff09;&#xff08;一&#xff09;云原生存储&#xff08;Cloud Native Storage&#xff09;1. 是什么&#xff1f;2. 解决什么问题&#xff1…

通俗易懂的 Nginx 反向代理 配置

通俗易懂的 Nginx 反向代理 配置 首先 root 与 alias 的区别 root 是直接拼接 root location location /i/ {root /data/w3; }当请求 /i/top.gif &#xff0c;/data/w3/i/top.gif 会被返回。 alias 是用 alias 替换 location location /i/ {alias /data/w3/images/; }当请…

HiveQL命令(一)- 数据库操作

文章目录 前言一、数据库操作1. 创建数据库1.1 语法及解释1.2 创建数据库示例 2. 查看数据库2.1 查看所有数据库2.2 查看数据库信息2.2.1 语法及解释2.2.2 查看数据库信息示例 3. 切换数据库3.1 语法3.2 示例 4. 修改数据库4.1 语法4.2 示例 5. 删除数据库5.1 语法及解释5.2 示…