【Vulkan入门】09-CreateFrameBuffer
目录
- 先叨叨
- git信息
- 关键代码
- VulkanEnv::FindHostVisitbaleMemoryTypeIndex()
- TestPipeLine::CreateFramebuffers()
与网上大多数文章不同,其他文章基本上都使用窗口框架(X11、GLFW、WSL等)提供的surface来显示Vulkan渲染出的图像。我认为那样会屏蔽很多细节,因此我选择使用更原生的方式,即让Vulkan渲染到一块内存中,然后将内存读出再渲染到屏幕上。其实surface只不过是封装好的Image而以。
先叨叨
上一篇创建的RenderPass,但还没有给RenderPass分配内存空间。本篇来介绍如何给RenderPass创建内存空间。RenderPass与内存的对应关系如下图:

Vulkan的架构设计将RenderPass到Memeory的对应关系拉了一条很长的线路,至于为什么和这么设计的好处,我还理解不到。所以先死记硬背下来。
- RenderPass中有很多个Attachment每个,Attachment对应一块内存空间。Attachment用于指明该空间在渲染时具体起到的作用。如:颜色缓存、深度缓存、模板缓存等。
- 多个Attachment由一个Subpass进行关联,指明一次渲染会用到Subpass中的所有的Attachment。比如将第一个Attachment当作颜色缓存,将第二Attachment当作深度缓存。
- 一个RenderPass对应一个FrameBuffer。而FrameBuffer中有多个ImageView,每个ImageView对应一个RenderPass中的Attachment。。ImageView还不是真正的内存空间。
- ImageView会关联到一个Image。Image是对内存空间的描述,但Image并不是真正的内存空间。
- 真正的内存空间是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()
本方法流程如下:
- 创建Image
- 申请Memory
- 将Image和Memory 绑定到一起
- 创建ImageView并关联到Image上
- 创建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!");}}
相关文章:
【Vulkan入门】09-CreateFrameBuffer
目录 先叨叨git信息关键代码VulkanEnv::FindHostVisitbaleMemoryTypeIndex()TestPipeLine::CreateFramebuffers() 与网上大多数文章不同,其他文章基本上都使用窗口框架(X11、GLFW、WSL等)提供的surface来显示Vulkan渲染出的图像。我认为那样会…...
FPGA设计-Vivado的Off-Chip Termination设置问题
目录 简介: 设置规则: output strength(输出驱动器的电流驱动能力) slew rate(输出电压压摆率) Pull type(上下拉类型) On-chip termination(输入端/输出端的内置片上端接电阻) 输出端接电阻配置 简介: 经常遇到在FPGA设计时,很多人很迷惑这些关于硬件的终…...
GC常见垃圾回收算法,JVM分代模型
如何判断是垃圾?引用计数器和Root可达性算法 如何进行清除?标记清除、复制、标记整理 堆分代模型?Eden,Surevivor,Tenuring 一个对象从创建到消亡的过程? 对象什么时候进入老年代? 一、GC&a…...
面试题整理(三)
芯冰乐知识星球入口:...
可视化建模以及UML期末复习----做题篇
一、单项选择题。(20小题,每小题2分,共40分) 1、UML图不包括( ) A、用例图 B、状态机图 C、流程图 D、类图 E、通信图 答案:C、流程图 UML中不包括传统意义上的流程图,流程图通常是指B…...
PostGIS分区表学习相关
在Postgresql中对空间数据进行表分区的实践_postgresql空间数据-CSDN博客文章浏览阅读1.4k次,点赞26次,收藏21次。Postgresql的分区功能允许将一个大表按照特定的规则拆分成多个小的分区表。这样做的好处在于,在查询数据时,可以只…...
JavaEE 【知识改变命运】03 多线程(3)
文章目录 多线程带来的风险-线程安全线程不安全的举例分析产出线程安全的原因:1.线程是抢占式的2. 多线程修改同一个变量(程序的要求)3. 原子性4. 内存可见性5. 指令重排序 总结线程安全问题产生的原因解决线程安全问题1. synchronized关键字…...
Flash操作 原子写 非原子写
原子和非原子操作 读、修改、写操作 对一个变量 A 1或上0x01,C语言写法: A 1| 0x01; 通过编译转成汇编后: LOAD R1,[#A 1] ; Read a value from A 1 into R1 MOVE R2,#0x01 ; Move the absolute constant 1 into R2 OR R1,R2 ; Bitwise O…...
厦门凯酷全科技有限公司怎么样?
随着短视频和直播带货的兴起,抖音电商平台迅速崛起,成为众多品牌和商家争夺的新战场。在这个竞争激烈的市场中,如何抓住机遇、实现销售增长,成为了每个企业面临的挑战。厦门凯酷全科技有限公司(以下简称“凯酷全”&…...
ubuntu 18.04设置命令行历史记录并同时显示执行命令的时间
以下相关详细信息请参考ubuntu官网。 在Ubuntu 18.04中,查看特定用户(例如用户broko)的命令行历史记录,并同时显示执行命令的时间,可以通过修改用户的shell配置文件来实现: • 设置HISTTIMEFORMAT环境变量…...
推荐系统里面的多任务学习概述
1. 概述 多任务学习(multi-task learning),本质上是希望使用一个模型完成多个任务的建模,在推荐系统中,多任务学习一般即指多目标学习(multi-label learning),不同目标输入相同的fe…...
解决uview ui赋值后表单无法通过验证
微信小程序中 主要还是文档有这样一段话://如果需要兼容微信小程序,并且校验规则中含有方法等,只能通过setRules方法设置规则。 添加即可通过 onReady() {//如果需要兼容微信小程序,并且校验规则中含有方法等,只能通过…...
【GL010】C/C++总结(二)
C部分 1. C中类成员的访问权限 无论成员被声明为 public、protected 还是 private,都是可以互相访问的,没有访问权限的限制。在类的外部 (定义类的代码之外),只能通过对象访问成员,并且通过对象只能访问 p…...
【合作原创】使用Termux搭建可以使用的生产力环境(五)
前言 在上一篇【合作原创】使用Termux搭建可以使用的生产力环境(四)-CSDN博客我们讲到了如何让proot-distro中的Debian声音驱动正常,将我们的系统备份后,通过VNC客户端连接到VNC服务器,这一篇我们来讲一下xfce桌面的美…...
初始数据结构
程序数据结构算法 数据结构研究计算机数据(元素)间关系 包括数据的逻辑结构和存储结构及其(数据间)操作 一、基本概念 1.1数据 数据即信息的载体,能被输入到计算机中并且能被它识别、存储和处理的符号总称 1.2数据…...
给我的小程序加了个丝滑的搜索功能,踩坑表情包长度问题
前言 最近在用自己的卡盒小程序的时候,发现卡片越来越多,有时候要找到某一张来看看笔记要找半天,于是自己做了一个搜索功能,先看效果: 怎么样,是不是还挺不错的,那么这篇文章就讲讲这样一个搜索…...
MATLAB中的合并分类数组
目录 创建分类数组 串联分类数组 创建具有不同类别的分类数组 串联具有不同类别的数组 分类数组的并集 此示例演示了如何合并两个分类数组。 创建分类数组 创建分类数组 A,其中包含教室 A 中的 25 个学生的首选午餐饮料。 rng(default) A randi(3,[25,1]); …...
ShardingSphere-JDBC
1. 什么是分库分表? 分库分表是一种数据库扩展技术,通过将数据拆分到多个数据库(分库)或多个表(分表)中来解决单一数据库或表带来的性能瓶颈。分库分表可以有效提升系统的可扩展性、性能和高并发处理能力&…...
企业如何选择远程控制软件来远程IT运维?
在当今企业的日常运作中,IT运维无疑是核心环节之一,它对于保持企业信息系统的稳定运行和数据安全至关重要。随着科技的快速进步,远程控制软件在IT运维中的应用变得越来越重要。今天,我们就来探讨一下远程控制软件如何助力企业IT运…...
Meta Llama 3.3 70B:性能卓越且成本效益的新选择
Meta Llama 3.3 70B:性能卓越且成本效益的新选择 引言 在人工智能领域,大型语言模型一直是研究和应用的热点。Meta公司最近发布了其最新的Llama系列模型——Llama 3.3 70B,这是一个具有70亿参数的生成式AI模型,它在性能上与4050…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
