vulkanscenegraph显示倾斜模型(5.9)-vsg中vulkan资源的编译
前言
上一章深入剖析了GPU资源内存及其管理,vsg中为了提高设备内存的利用率,同时减少内存(GPU)碎片,采用GPU资源内存池机制(vsg::MemoryBufferPools)管理逻辑缓存(VkBuffer)与物理内存(VkDeviceMemory)。本章将深入vsg中vulkan资源的编译(包含视景器编译),着重于当vsg::TransferTask不为空时,vulkan资源的创建与收集过程。
目录
- 1 视景器编译
- 2 VertexIndexDraw的编译
1 视景器编译
如下为Viewer.cpp中387-393行代码,对视景器中的所有vsg::RecordAndSubmitTask对象执行编译任务,其中RecordAndSubmitTask 用于录制其 CommandGraph 列表到 CommandBuffer,并最终将这些命令缓冲区提交到对应的 Vulkan 队列,vsg::Viewer依赖于一个vsg::RecordAndSubmitTask数组,其创建的详细过程在vsg::Viewer::assignRecordAndSubmitTaskAndPresentation函数中体现。
for (auto& task : recordAndSubmitTasks){auto& deviceResource = deviceResourceMap[task->device];auto& resourceRequirements = deviceResource.collectResources.requirements;compileManager->compileTask(task, resourceRequirements);task->transferTask->assign(resourceRequirements.dynamicData);}
如下为数据编译过程中的类图关系:

vsg::RecordAndSubmitTask与vsg::DatabasePager依赖于vsg::CompileManager进行数据编译,分别对应视景器的编译、节点动态加载后的编译。vsg::CompileManager是一个辅助类,用于编译与vsg::CompileManager相关联的窗口(vsg::Windows)/帧缓冲区(vsg::Framebuffer)的子图。vsg::CompileManager依赖于vsg::CompileTraversal对子图进行遍历,其继承自vsg::Visitor。CompileTraversal 会遍历场景图(scene graph),并调用所有 StateCommand/Command::compile(..) 方法,以创建 Vulkan 对象、分配 GPU 内存,当vsg::TransferTask对象为空时,将数据传输到 GPU。以BufferInfo.cpp中vsg::createBufferAndTransferData函数为例(280-294行),当vsg::TransferTask对象非空时,将待传输的数据信息记录到vsg::TransferTask对象中:
if (transferTask){vsg::debug("vsg::createBufferAndTransferData(..)");for (auto& bufferInfo : bufferInfoList){vsg::debug(" ", bufferInfo, ", ", bufferInfo->data, ", ", bufferInfo->buffer, ", ", bufferInfo->offset);bufferInfo->data->dirty();bufferInfo->parent = deviceBufferInfo;}transferTask->assign(bufferInfoList);return true;}
vsg::CompileTraversal中存在多个vsg::Context,而vsg::Compileable节点的编译依赖vsg::Context,即同一个vsg::Compileable节点可以依赖多个vsg::Context对象编译多次,以void CompileTraversal::apply(Commands& commands)函数为例:
void CompileTraversal::apply(Commands& commands)
{CPU_INSTRUMENTATION_L3_NC(instrumentation, "CompileTraversal Commands", COLOR_COMPILE);for (auto& context : contexts){commands.compile(*context);}
}
vsg::Context的创建赖于vsg::View,如下为函数void CompileTraversal::add(const Viewer& viewer, const ResourceRequirements& resourceRequirements)215-225行:
void apply(View& view) override
{if (!objectStack.empty()){auto obj = objectStack.top();if (auto window = obj.cast<Window>())ct->add(*window, transferTask, ref_ptr<View>(&view), resourceRequirements);else if (auto framebuffer = obj.cast<Framebuffer>())ct->add(*framebuffer, transferTask, ref_ptr<View>(&view), resourceRequirements);}
}
上方代码ct->add(...)的调用具体实现如下:
void CompileTraversal::add(Window& window, ref_ptr<TransferTask> transferTask, ref_ptr<ViewportState> viewport, const ResourceRequirements& resourceRequirements)
{auto device = window.getOrCreateDevice();auto renderPass = window.getOrCreateRenderPass();auto queueFamily = device->getPhysicalDevice()->getQueueFamily(queueFlags);auto context = Context::create(device, resourceRequirements);context->instrumentation = instrumentation;context->renderPass = renderPass;context->commandPool = CommandPool::create(device, queueFamily, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);context->graphicsQueue = device->getQueue(queueFamily, queueFamilyIndex);context->transferTask = transferTask;if (viewport)context->defaultPipelineStates.emplace_back(viewport);elsecontext->defaultPipelineStates.emplace_back(vsg::ViewportState::create(window.extent2D()));if (renderPass->maxSamples != VK_SAMPLE_COUNT_1_BIT) context->overridePipelineStates.emplace_back(MultisampleState::create(renderPass->maxSamples));contexts.push_back(context);
}
总结来说,在CompileTraversal创建过程中,通过遍历场景树,遍历所有vsg::View,逐一添加vsg::Context对象,接着利用CompileTraversal遍历场景树,遍历所有vsg::Context对象,逐一编译vsg::Compilable节点。
2 VertexIndexDraw的编译
回到第4章(vulkanscenegraph显示倾斜模型(4)-数据读取-CSDN博客)悬疑列表之一的osg::Geometry转vsg::Command的具体细节,其最终将osg::Geometry转化为了vsg:VertexIndexDraw对象,本节将以vsg::VertexIndexDraw为例,深入节点(继承自vsg::Compilable)的编译过程。
void VertexIndexDraw::compile(Context& context)
{if (arrays.empty() || !indices){// VertexIndexDraw does not contain required arrays and indicesreturn;}auto deviceID = context.deviceID;bool requiresCreateAndCopy = false;if (indices->requiresCopy(deviceID))requiresCreateAndCopy = true;else{for (auto& array : arrays){if (array->requiresCopy(deviceID)){requiresCreateAndCopy = true;break;}}}if (requiresCreateAndCopy){BufferInfoList combinedBufferInfos(arrays);combinedBufferInfos.push_back(indices);createBufferAndTransferData(context, combinedBufferInfos, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE);// info("VertexIndexDraw::compile() create and copy ", this);}else{// info("VertexIndexDraw::compile() no need to create and copy ", this);}assignVulkanArrayData(deviceID, arrays, _vulkanData[deviceID]);
}
其中arrays变量记录顶点以及顶点属性,indices变量记录三角网索引。主要过程为创建 Vulkan 对象、分配 GPU 内存(createBufferAndTransferData),而assignVulkanArrayData函数仅将arrays中的Vulkan对象和偏移以数组连续的方式存储在_vulkanData[deviceId]对象中,方便后续vsg:VertexIndexDraw::record函数的调用。创建 Vulkan 对象、分配 GPU 内存过程中的依赖关系如下:

文末:本章在上一章的基础上,深入分析VSG中Vulkan资源的编译过程,并以vsg::VertexIndexDraw为例进行详解。在VSG中,资源编译主要包括创建Vulkan对象和分配GPU内存两个核心步骤。当vsg::TransferTask非空时,程序会将待传输的数据信息记录至该对象,以便后续处理。下一章将重点剖析VSG中的数据传输(Transfer)机制。
相关文章:
vulkanscenegraph显示倾斜模型(5.9)-vsg中vulkan资源的编译
前言 上一章深入剖析了GPU资源内存及其管理,vsg中为了提高设备内存的利用率,同时减少内存(GPU)碎片,采用GPU资源内存池机制(vsg::MemoryBufferPools)管理逻辑缓存(VkBuffer)与物理内存(VkDeviceMemory)。本章将深入vsg中vulkan资源的编译(包含…...
今日行情明日机会——20250409
今日行情还需要考虑关税对抗~ 2025年4月8日涨停的主要行业方向分析 1. 军工(19家涨停) 细分领域:国防装备、航空航天、军民融合。催化因素:国家安全战略升级、国防预算增加、重大军工项目落地预期。 2. 免税(15家涨…...
XHR、FetchAxios详解网络相关大片文件上传下载
以下是 XHR(XMLHttpRequest) 与 Fetch API 的全面对比分析,涵盖语法、功能、兼容性等核心差异: 一、语法与代码风格 XHR(基于事件驱动) 需要手动管理请求状态(如 onreadystatechange 事件)和错误处理,代码冗长且易出现回调地狱。 const xhr = new XMLHttpRequest(); x…...
Python基础总结(四)之元组
文章目录 一、元组格式二、元组操作2.1 转换元组 与 列表一样,元组也是序列,唯一的区别在于元组是不能修改的,与字符串一样。 一、元组格式 元组的创建方式很简单,秩序用逗号将元素隔开就能自动创建一个元组 示例: …...
系统分析师(六)-- 计算机网络
概述 TCP/IP 协议族 DNS DHCP 网络规划与设计 逻辑网络设计 物理网络设计 题目 层次化网络设计 网络冗余设计 综合布线系统 IP地址 网络接入技术 其他网络技术应用 物联网...
【前端】【React】useCallback的作用与使用场景总结
一、useCallback 的作用与使用场景总结 useCallback 是 React 提供的一个 Hook,用于缓存函数的引用,避免因为组件重新渲染而导致函数地址发生变化。它返回一个记忆(memoized)后的回调函数,只有当依赖项发生变化时才会…...
Qwen2.5-VL Technical Report 论文翻译和理解
一、TL;DR Qwen2.5-VL是QwenVL的最新模型,在视觉识别、精准目标定位、稳健文档解析以及长视频理解等方面实现了重大突破引入了动态分辨率处理和绝对时间编码,使其能够处理不同尺寸的图像以及长达数小时的视频,并实现秒级事件定位…...
Foxmail邮件客户端跨站脚本攻击漏洞(CNVD-2025-06036)技术分析
Foxmail邮件客户端跨站脚本攻击漏洞(CNVD-2025-06036)技术分析 漏洞背景 漏洞编号:CNVD-2025-06036 CVE编号:待分配 厂商:腾讯Foxmail 影响版本:Foxmail < 7.2.25 漏洞类型&#x…...
C语言打印的坑
使用下面的代码buf dprt("data: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); 明明是一个字节一个字节的打,打出来的数据有些却是4个字节 0xffffffff 0xffffffff 0xffffffff 0x7f 0xffffffff 0x7f0…...
高并发内存池(三):PageCache(页缓存)的实现
前言: 在前两期内容中,我们深入探讨了内存管理机制中在 ThreadCache 和 CentralCache两个层级进行内存申请的具体实现。这两层缓存作为高效的内存分配策略,能够快速响应线程的内存需求,减少锁竞争,提升程序性能。 本期…...
pycharm已有python3.7,如何新增Run Configurations中的Python interpreter为python 3.9
在 PyCharm 中,如果你已经安装了 Python 3.9,并且希望在 Run Configurations 中新增一个 Python 3.9 的解释器,可以按照以下步骤操作: 步骤 1:打开 PyCharm 设置 点击 PyCharm 左上角的 File 菜单。选择 Settings&am…...
Linux驱动开发-网络设备驱动
Linux驱动开发-网络设备驱动 一,网络设备总体结构1.1 总体架构1.2 NAPI数据处理机制 二,RMII和MDIO2.1 RMII接口2.2 MDIO接口 三,MAC和PHY模块3.1 MAC模块3.2 PHY模块 四,网络模型4.1 网络的OSI和TCP/IP分层模型4.1.1 传输层&…...
学习笔记083——Java Stream API
文章目录 1、过滤数据 filter()2、转换元素 map()3、排序 sorted()3.1、自定义排序规则 4、去重 distinct()5、限制元素数量 limit()6、收集结果 collect()6.1、收集为List6.2、收集为Set6.3、转为Map6.4、基本用法(注意键冲突会抛异常)6.5、处理键冲突&…...
DataEase同比环比
DataEase同比环比 前言术语实现表结构设计DataEase设计创建数据集创建仪表盘最后前言 某大数据项目,需要比较展示今年跟去年的数据,如下图: 说明:比较24,25的产品销量,相同月份做一组,并排放一块 还有更进一步: 说明:比较24,25相同月份,相同产品的销量 直接用DataE…...
RAG 工程基础
RAG 概念 RAG(Retrieval - Augmented Generation)技术是一种将检索与生成相结合的人工智能技术,旨在利用外部知识源来增强语言模型的生成能力,提高生成内容的质量、准确性和相关性。 具体来说,RAG 技术在处理用户输入的…...
基础算法:滑动窗口_python版本
能使用滑动窗口的题,基本都需要数字为正整数,这样才能保证滑入一个数字总和是增加的(单调性) 一、209. 长度最小的子数组 思路: 已每个位置为右端点,依次加大左端点,最短不满足 sum(num[left,right]) < target的。…...
Qt 之opengl shader language
着色器示例代码 实际运行效果...
PyRoboPlan 库,给 panda 机械臂微分 IK 上大分,关节限位、碰撞全不怕
视频讲解: PyRoboPlan 库,给 panda 机械臂微分 IK 上大分,关节限位、碰撞全不怕 代码仓库:https://github.com/LitchiCheng/mujoco-learning 今天分享PyRoboPlan库,比之前的方式优点在于,这个库考虑了机械…...
GPT - TransformerDecoderBlock
本节代码定义了一个 TransformerDecoderBlock 类,它是 Transformer 架构中解码器的一个基本模块。这个模块包含了多头自注意力(Multi-Head Attention)、前馈网络(Feed-Forward Network, FFN)和层归一化(Lay…...
LabVIEW 控制电机需注意的关键问题
在自动化控制系统中,LabVIEW 作为图形化编程平台,因其高度可视化、易于集成硬件等优势,被广泛应用于电机控制场景。然而,要实现稳定、精确、高效的电机控制,仅有软件并不足够,还需结合硬件选型、控制逻辑设…...
CSS 定位属性的生动比喻:以排队为例理解 relative 与 absolute
目录 一、理解标准流与队伍的类比 二、relative 定位:队伍中 “小范围活动” 的人 三、absolute 定位:队伍中 “彻底离队” 的人 在学习 CSS 的过程中,定位属性relative和absolute常常让初学者感到困惑。它们的行为方式和对页面布局的影响较为抽象,不过,我们可以通过一个…...
Jenkins 发送钉钉消息
这里不介绍 Jenkins 的安装,可以网上找到很多安装教程,重点介绍如何集成钉钉消息。 需要提前准备钉钉机器人的 webhook 地址。(网上找下,很多教程) 下面开始配置钉钉机器人,登录 Jenkins,下载 …...
nt!KeRemoveQueue 函数分析之加入队列后进入等待状态
第一部分: 参考例子:应用程序调用kernel32!GetQueuedCompletionStatus后会调用nt!KeRemoveQueue函数进入进入等待状态 0: kd> g Breakpoint 8 hit nt!KiDeliverApc: 80a3c776 55 push ebp 0: kd> kc # 00 nt!KiDeliverApc 01 nt…...
OpenCV 风格迁移
一、引言 在计算机视觉和图像处理领域,风格迁移是一项令人着迷的技术。它能够将一幅图像(风格图像)的艺术风格,如梵高画作的笔触风格、莫奈的色彩风格等,迁移到另一幅图像(内容图像)上&#x…...
35.Java线程池(线程池概述、线程池的架构、线程池的种类与创建、线程池的底层原理、线程池的工作流程、线程池的拒绝策略、自定义线程池)
一、线程池概述 1、线程池的优势 线程池是一种线程使用模式,线程过多会带来调度开销,进而影响缓存局部性和整体性能,而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务,这避免了在处理短时间任务时创建与…...
Kubernetes nodeName Manual Scheduling practice (K8S节点名称绑定以及手工调度)
Manual Scheduling 在 Kubernetes 中,手动调度框架允许您将 Pod 分配到特定节点,而无需依赖默认调度器。这对于测试、调试或处理特定工作负载非常有用。您可以通过在 Pod 的规范中设置 nodeName 字段来实现手动调度。以下是一个示例: apiVe…...
QML中访问c++数据,并实现类似C#中mvvm模式详细方法
1. 背景需求2. 实现步骤 2.1. 定义 Model(数据模型) 2.1.1. DataModel.h2.1.2. DataModel.cpp 2.2. 定义 ViewModel(视图模型) 2.2.1. PersonViewModel.h2.2.2. PersonViewModel.cpp 2.3. 在 QML 中使用 ViewModel 2.3.1. main.cp…...
React 获得dom节点和组件通信
通过REF 实例对象的.current属性获得绑定的DOM节点 组件通信 组件通信 1 父传子 父组件传递数据 子组件接受数据 通过pros对象接受 子组件的形参列表props只读 props中数据不可修改 特殊情况 在子传父的过程中没有直接给子组件添加属性,而是向父组件中添加其他…...
代码,Java Maven项目打包遇到的环境问题
这几天在写一些Java版本的Langchain4J的 AI 测试case,有一段时间不运行的Java环境,反复出现环境问题,记录下 1、Java编译版本的问题 修改编译版本: 2、在IDE中运行遇到Maven中JDK版本问题 在ide中执行maven命令,遇到下…...
fisco-bcos 关于服务bash status.sh启动runing 中但是5002端口监听不到,出错的问题
bash status.sh Server com.webank.webase.front.Application Port 5002 is running PID(4587) yjmyjm-VMware-Virtual-Platform:~/webase-front$ sudo netstat -anlp | grep 5002 没有端口信息输出 此时可以查看log文件夹下的WeBASE-front.log,找到报错信息如下…...
