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)机制。

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

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

相关文章

探秘 Python 网络编程:构建简单聊天服务器

在计算机网络的世界里&#xff0c;网络编程是实现不同设备之间通信的关键技术。Python 凭借其简洁的语法和强大的库支持&#xff0c;在网络编程领域有着广泛的应用。无论是构建简单的聊天服务器&#xff0c;还是开发复杂的网络应用&#xff0c;Python 都能轻松胜任。 1 理论基础…

Go语言Slice切片底层

Go语言&#xff08;Golang&#xff09;中切片&#xff08;slice&#xff09;的相关知识、包括切片与数组的关系、底层结构、扩容机制、以及切片在函数传递、截取、增删元素、拷贝等操作中的特性。并给出了相关代码示例和一道面试题。关键要点包括&#xff1a; 数组特性&#xf…

vue3 ts 自定义指令 app.directive

在 Vue 3 中&#xff0c;app.directive 是一个全局 API&#xff0c;用于注册或获取全局自定义指令。以下是关于 app.directive 的详细说明和使用方法 app.directive 用于定义全局指令&#xff0c;这些指令可以用于直接操作 DOM 元素。自定义指令在 Vue 3 中非常强大&#xff0…

基于python的机器学习(五)—— 聚类(二)

一、k-medoids聚类算法 k-medoids是一种聚类算法&#xff0c;它是基于k-means聚类算法的一种改进。k-medoids算法也是一种迭代算法&#xff0c;但是它将中心点限定为数据集中的实际样本点&#xff0c;而不是任意的点。 具体来说&#xff0c;k-medoids算法从数据集中选择k个初…

解释:指数加权移动平均(EWMA)

指数加权移动平均&#xff08;EWMA, Exponential Weighted Moving Average&#xff09; 是一种常用于时间序列平滑、异常检测、过程控制等领域的统计方法。相比普通移动平均&#xff0c;它对最近的数据赋予更高权重&#xff0c;对旧数据逐渐“淡化”。 ✅ 一、通俗理解 想象你…

Spring Boot 项目基于责任链模式实现复杂接口的解耦和动态编排!

全文目录&#xff1a; 开篇语前言一、责任链模式概述责任链模式的组成部分&#xff1a; 二、责任链模式的核心优势三、使用责任链模式解耦复杂接口1. 定义 Handler 接口2. 实现具体的 Handler3. 创建订单对象4. 在 Spring Boot 中使用责任链模式5. 配置责任链6. 客户端调用 四、…

COMSOL仿真遇到的两个小问题

最近跑热仿真的时候跑出了两个问题&#xff0c;上网查发现也没什么解决方式&#xff0c;最后自己误打误撞的摸索着解决了&#xff0c;在这里分享一下。 问题一 我当时一准备跑仿真就弹出了这个东西&#xff0c;但在此之前从未遇到 然后我试着在它说的路径中建立recoveries文件…

如何在英文学术写作中正确使用标点符号?

标点符号看似微不足道&#xff0c;但它们是书面语言的无名英雄。就像熟练的指挥家指挥管弦乐队一样&#xff0c;标点符号可以确保您的写作流畅、传达正确的含义并引起读者的共鸣。正如放错位置的音符会在音乐中造成不和谐一样&#xff0c;放错位置的逗号或缺少分号也会使您的写…

【深度学习与大模型基础】第10章-期望、方差和协方差

一、期望 ——————————————————————————————————————————— 1. 期望是什么&#xff1f; 期望&#xff08;Expectation&#xff09;可以理解为“长期的平均值”。比如&#xff1a; 掷骰子&#xff1a;一个6面骰子的点数是1~6&#x…

JAVA虚拟机(JVM)学习

入门 什么是JVM JVM&#xff1a;Java Virtual Machine&#xff0c;Java虚拟机。 JVM是JRE(Java Runtime Environment)的一部分&#xff0c;安装了JRE就相当于安装了JVM&#xff0c;就可以运行Java程序了。JVM的作用&#xff1a;加载并执行Java字节码&#xff08;.class&#…

【数据结构与算法】——堆(补充)

前言 上一篇文章讲解了堆的概念和堆排序&#xff0c;本文是对堆的内容补充 主要包括&#xff1a;堆排序的时间复杂度、TOP 这里写目录标题 前言正文堆排序的时间复杂度TOP-K 正文 堆排序的时间复杂度 前文提到&#xff0c;利用堆的思想完成的堆排序的代码如下&#xff08;包…

什么是柜台债

柜台债&#xff08;柜台债券业务&#xff09;是指通过银行等金融机构的营业网点或电子渠道&#xff0c;为投资者提供债券买卖、托管、结算等服务的业务模式。它允许个人、企业及机构投资者直接参与银行间债券市场的交易&#xff0c;打破了以往仅限机构参与的壁垒。以下是综合多…

【Android读书笔记】读书笔记记录

文章目录 一. Android开发艺术探索1. Activity的生命周期和启动模式1.1 生命周期全面分析 一. Android开发艺术探索 1. Activity的生命周期和启动模式 1.1 生命周期全面分析 onPause和onStop onPause后会快速调用onStop&#xff0c;极端条件下直接调用onResume 当用户打开新…

Java对象内存结构详解

Java对象内存结构详解 Java对象在JVM内存中的存储结构可以分为三个部分&#xff1a;对象头&#xff08;Header&#xff09;、实例数据&#xff08;Instance Data&#xff09;和对齐填充&#xff08;Padding&#xff09;。以下是64位JVM&#xff08;开启压缩指针&#xff09;下…

【TI MSPM0】Printf重定向学习

一、新建工程 通过XDS110与电脑进行通信。 选择这两个引脚 需要添加这两个头文件 在程序中添加这三个函数即可对printf进行重定向 二、封装函数 另一种方法 封装一个函数&#xff0c;定义一个数组

深度强化学习基础 0:通用学习方法

过去自己学习深度强化学习的痛点&#xff1a; 只能看到各种术语、数学公式勉强看懂&#xff0c;没有建立清晰且准确关联 多变量交互关系浮于表面&#xff0c;有时候连环境、代理控制的变量都混淆 模型种类繁多&#xff0c;概念繁杂难整合、对比或复用&#xff0c;无框架分析所…

asm汇编源代码之-字库转换程序

将标准的16x16点阵汉字库(下载16x16汉字库)转换成适合VGA文本模式下显示的点阵汉字库 本程序需要调用file.asm中的子程序,所以连接时需要把file连接进来,如下 C:\> tlink chghzk file 调用参数描述如下 C:\> chghzk ; 无调用参数,转换标准库文件(SRC16.FNT)为适合VGA…

uniapp转换markdown

效果 AI智能体 微信小程序 流式 1.安装Node.js 参考:2024最新版Node.js下载安装及环境配置教程&#xff08;非常详细&#xff09;_node.js 安装-CSDN博客 2.需要克隆项目到本地或直接到项目地址下载压缩包。 参考&#xff1a;uniapp中解析markdown支持网页和小程序_uniapp ma…

用java代码如何存取数据库的blob字段

一.业务 在业务中我们被要求将文件或图片等转成 byte[] 或 InputStream存到数据库的Blob类型的字段中. 二.Blob类型介绍 在 MySQL 中&#xff0c;Blob 数据类型用于存储二进制数据。MySQL 提供了四种不同的 Blob 类型&#xff1a; TINYBLOB: 最大存储长度为 255 个字节。BL…

qemu(2) -- 定制开发板

1. 前言 qemu支持自定义开发板&#xff0c;本文就记录一下折腾的过程。基于qemu-10.0.0-rc3添加x210vb3s开发板。 2. 添加板卡文件 网上参考了一些文章&#xff0c;有些文章使用的版本和我的不一样&#xff0c;折腾起来费了点时间&#xff0c;最后发现还是直接参考qemu中已有…