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.pswp.cn/web/75674.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75674.shtml
英文地址,請注明出處:http://en.pswp.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中已有…