Vulkan LoaderLayer

news2024/11/26 19:56:20

目录

一、Loader

The Loader

二、Layer

调度链Dispatch Chains

 JSON


一、Loader

Vulkan是一个层架构,由Vulkan Application+Loader+Layer+ICDs(Installable Client Drivers)组成。

High Level View of Loader

Vulkan 是一个显式 API,可以直接控制 GPU 的实际工作方式。因此,Vulkan 支持具有多个 GPU 的系统,每个 GPU 运行不同的驱动程序或 ICD(可安装客户端驱动程序)。 Vulkan 还支持多个全局上下文(Vulkan 术语中的实例)。 ICD 加载器是一个放置在 Vulkan 应用程序和任意数量的 Vulkan 驱动程序之间的库,以支持多个驱动程序以及跨这些驱动程序工作的实例级功能。此外,加载程序还管理在应用程序和驱动程序之间插入 Vulkan 层库,例如验证层。

The Loader

application在一端,直接和loader打交道。loader另一端是ICDs,在application和ICDs之间,loader可以插入一系列可选的layers。loader负责和各个layer交互并且支持多GPUs和其驱动。任何一个vulkan api函数可以经过loader,layers和ICDs,loader负责将api传递dispatch给合适的layers和ICDs,vulkan对象模型允许loader插入layers层,并且组成调用链上一环,并最终传递给vulkan api给ICD。

loader的职责简单总结如下:

  1. 支持1个ICD或者多个ICDs,且保证ICD间不相互干扰,ICD是就是不同厂商对图形API所做的驱动文件。
  2. 支持Vulkan Layer,Layer是可选的
  3. 已最可能低的方式影响vulkan应用性能

High Level View of Loader

恰巧vulkan的一个思想就是,去除掉验证层,那么验证层能放在何处?也就是放在这个SDK里,类似各种Graphic Debugger的实现,Vulkan有很多Validation Layer,可以根据需求载入,在真正的函数调用之前,截取一些信息,获得一些信息,最后再调用真正的接口。也就是说整个SDK不仅仅是一个函数指针获取器,还是一个Graphic Debugger。

二、Layer

layers是可选组件,可以增强vulkan系统,可以拦截,修改vulkan api,layers是作为lib库实现,可以通过不同方式使能并且在CreateInstance中被加载。每个layer可以选择任何vulkan api进行拦截,一个layer不需要拦截所有vulkan api function,layer可以选择取拦截所有已知vulkan api,也可以拦截一条vulkan api。

layer的一些示例如下:

  1. 校验api使用
  2. 增加debug和trace等调试信息
  3. 覆盖额外内容

因为layer是可选的,我们可以在调试阶段使能,在release时关闭。

vulkan中很多扩展和函数(api)被分成两个主要组,一个是实例instance相关对象,另一个是device相关对象。

vulkan instance是一个high-level系统级信息或者函数,vulkan对象如VkInstance和VkPhysicalDevice,vulkan函数如vkEnumerateInstanceExtensionProperties、vkEnumeratePhysicalDevices、vkCreateInstance、vkDestroyInstance等。可以使用vkGetInstanceProcAddr查询vulkan instance function,vkGetXXXProcAddr可以查询device或者instance入口点,返回的函数指针对实例或者基于实例创建的对象有效,包括vkDevice对象,同理,instance扩展是一系列vulkan实例函数。

vulkan device是一个逻辑标识,别用于在特定physical device关联的api,device object有vkDevice,vkQueue,vkCommandBuffer,任何是前面三个object孩子的dispatchable object。device function一般是将device object作为第一个参数的api,比如vkQueueSubmit、vkBeginComandBuffer、vkCreateEvent等。

可以使用vkGetInstanceProcAddr和vkGetDeviceProcAddr获取device function。

调度链Dispatch Chains

此时,我们需要讨论单个函数调用(如vkCreateInstance)如何传播到加载器、ICD 或 ICD 以及许多不同的层。

当应用程序调用加载器静态导出的任何函数时,它会调用trampoline function。然后,这个trampoline function调用调度链Dispatch Chains。调度链的思想来自函数指针链。它从加载器的trampoline function入口点开始,然后trampoline function调用第一层,然后第一层调用第二层。该链一直持续到最终到达 ICD 中的端点以真正完成工作。

更明确地说,vkCreateInstance就是这些特殊功能之一。在调度链开头的trampoline function中,它首先验证请求的层和扩展是否有效。一旦满足,它就会分配 Vulkan 实例和调度链,然后调用vkCreateInstance第一层的函数。第一层将初始化自身和任何内部结构,然后将执行传递到vkCreateInstance下一层,依此类推。

现在,从应用程序的角度来看,Vulkan 实例主要是一个加载器概念。它们代表了 Vulkan 使用的所有内容,但它们也将所有可用的 ICD 整合到一起。这意味着当我们到达vkCreateInstance 的调度链末端时,我们不会以 ICD 结束。可能有多个同时使用,并且 ICD 不知道彼此是否链接在一起。

加载器通过将自己的终止符函数放在调度链的末尾terminator function on the end of the dispatch chain,供最后一层调用来解决这个问题。然后,该terminator function 依次调用vkCreateInstance每个可用的 ICD 并存储所有这些 ICD 以供以后使用:

当我们进行时,各层正在初始化自己并为它们在调度链中的位置做好准备。特别是,每一层都用vkGetInstanceProcAddr查找它希望能够在下一层中调用的所有入口点。每层调用下一层的vkGetInstanceProcAddr并将它们存储在调度表中。这只是一个充满函数指针的结构。当加载程序调用链中第一层的入口点时,它已经知道要传递到下一层的位置。这还实现了一个有用的功能 - 层不必挂钩每个Vulkan 函数,只需挂钩它们感兴趣的函数即可。

当加载器和每一层调用vkGetInstanceProcAddr以查找调度链中的下一个函数时,就会发生这种情况。如果某个层不想拦截函数调用,则它不必返回自己的little stub function。相反,t can just forward the call to the next layer and return the result.。只要每个点的调度表都知道下一个要调用的函数,它们是否跳过一两层并不重要。

跳过某些层的函数的调度链

 JSON

加载器将使用它来寻找入口点vkGetInstanceProcAddr/vkGetDeviceProcAddr,用于构建调度链。这些是模块需要导出的唯一入口点。由于必须导出与 API 函数名称完全相同的函数可能会很尴尬或不方便,因此您可以改为导出

  • SampleLayer_GetInstanceProcAddr
  • SampleLayer_GetDeviceProcAddr
{
  "file_format_version" : "1.0.0",
  "layer" : {
    "name": "VK_LAYER_SAMPLE_SampleLayer",
    "type": "GLOBAL",
    "library_path": ".\\sample_layer.dll",
    "api_version": "1.0.0",
    "implementation_version": "1",
    "description": "Sample layer - https://renderdoc.org/vulkan-layer-guide.html",
    "functions": {
      "vkGetInstanceProcAddr": "SampleLayer_GetInstanceProcAddr",
      "vkGetDeviceProcAddr": "SampleLayer_GetDeviceProcAddr"
    },
  }
}

针对导出的每个函数按顺序strcmp参数pName,然后返回入口点的地址。

应用程序调用其中之一时,它们会调用loader而不是直接调用 Vulkan 驱动程序。

vkGet**ProcAddr:该命令可获取所有Vulkan命令的函数指针
Hook这一层的函数:在vkGet**ProcAddr中返回本地函数指针
调用下一层实体:每层调用下一层的vkGet**ProcAddr,并将其存储在调度表中

loader_platform_open_library(const char * libPath)
loader_scanned_icd_add(...)
loader_icd_scan(...)
vkCreateInstance(...)
main()

由于应用程序与任一调度链都无关,因此真正的区别在于,在可能的情况下,vkGetDeviceProcAddr直接返回指向调度链中第一个条目的函数指针 - 如果不存在任何层,则通常将函数指针直接指向 ICD。vkGetInstanceProcAddr可能会返回与加载程序导出的相同的函数,该函数从可分派句柄中获取分派表并跳转到它。

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

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

相关文章

get请求报错400 非法参数

get请求报错400 非法参数 背景&#xff1a;get请求数据&#xff0c;SpringBoot提供接口&#xff0c;返回400&#xff0c;报错非法参数此种情况排除接口本身错误之外&#xff0c;检查参数中有没有特殊字符 " < > [ \ ] ^ { | } 我这边就是因为其中一个参数中有中括…

数字货运保持深层角力,满帮业绩与投资价值双丰收

上半年&#xff0c;经济持续活跃&#xff0c;货运物流行业承担着帮助经济要素流通的职责&#xff0c;也成为最直接的受益者。 数字货运平台满帮8月23日发布的财报显示&#xff0c;2023年第二季度&#xff0c;其平台单量、用户量均取得显著增长&#xff0c;并带动平台业绩创下新…

【网络设备】交换机的概念、工作原理、功能以及以太网帧格式

个人主页&#xff1a;insist--个人主页​​​​​​ 本文专栏&#xff1a;网络基础——带你走进网络世界 本专栏会持续更新网络基础知识&#xff0c;希望大家多多支持&#xff0c;让我们一起探索这个神奇而广阔的网络世界。 目录 一、认识交换机 二、交换机的主要功能 1、数…

Android——基本控件(下)(十九)

1. 菜单&#xff1a;Menu 1.1 知识点 &#xff08;1&#xff09;掌握Android中菜单的使用&#xff1b; &#xff08;2&#xff09;掌握选项菜单&#xff08;OptionsMenu&#xff09;的使用&#xff1b; &#xff08;3&#xff09;掌握上下文菜单&#xff08;ContextMenu&am…

STM32F4_SD卡

目录 前言 1. SDIO协议简介 2. SDIO命令及响应 3. SD卡的操作模式及切换 4. STM32的SDIO接口 5. SDIO结构体 6. SDIO相关寄存器 7. 实验程序 7.1 main.c 7.2 SDIO_Card.c 7.3 SDIO_Card.h 前言 在之前的单片机学习过程中&#xff0c;我们已经了解到了单片机系统都需…

SQL server开启变更数据捕获(CDC)

一、CDC简介 变更数据捕获&#xff08;Change Data Capture &#xff0c;简称 CDC&#xff09;&#xff1a;记录 SQL Server 表的插入、更新和删除操作。开启cdc的源表在插入、更新和删除操作时会插入数据到日志表中。cdc通过捕获进程将变更数据捕获到变更表中&#xff0c;通过…

java子类继承父类方法、或者接口中方法的javadoc注释

说明 详情可以阅读&#xff1a; https://docs.oracle.com/en/java/javase/19/docs/specs/javadoc/doc-comment-spec.html#method-comment-inheritance 子类继承父类、或者子类实现接口&#xff0c;在子类中为了避免重复写注释&#xff0c;可以在子类方法注释的主要描述部分、或…

基于GitHooks实现项目自动实时部署

目录 基于GitHooks实现项目自动部署 基于SVNJenkins发布项目 基于GitHooks实现项目自动部署 以上创建的所有任务&#xff0c;构建工作是基于在开发人员提交完代码到远程仓库完成&#xff0c;通知运维后&#xff0c;需要手动执行构建任务&#xff0c;这样就有些不太方便。我们…

智能优化算法一元函数优化

目录 一、问题描述 二、解决方法 1.模拟退火 1.1 算法思路 1.2 求解代码 1.3 计算结果 2.粒子群算法 2.1 算法思路 2.2 求解代码 2.3 计算结果 3.遗传算法 3.1 算法思路 3.2 求解代码 3.3 计算结果 一、问题描述 本篇文章所做的是分别用模拟退火、粒子群算法…

MySQL 8.1安装

1. 下载地址 https://dev.mysql.com/downloads/mysql/8.0.html 我这里没有采用installer安装&#xff0c;因为installer安装依赖visual studio&#xff0c;所以&#xff0c;我下载的是zip文件。 最终下载的版本如下&#xff1a; 2. 添加环境变量 解压&#xff0c;添加环境…

图的存储:邻接表法

1.邻接表的定义 不同于邻接矩阵&#xff08;二维数组存储&#xff09;&#xff0c;邻接表采用的顺序链式存储实现的。 1.存储方式 顶点&#xff1a;使用结构体存储顶点&#xff0c;一个顶点包括顶点信息和指向第一条边或者弧的指针。用邻接表存储图&#xff1a;使用结构体存…

Spring Boot存在路径遍历漏洞CVE-2021-22118

文章目录 0.前言1.参考文档2.基础介绍1. 影响的版本2. **漏洞利用原理&#xff1a;** 3.解决方案3.1. 方案13.2. 方案23. 方案3 0.前言 背景&#xff1a;Spring Boot存在路径遍历漏洞。CVE-2021-22118: 官方 issue也有对此的记录&#xff0c;感兴趣可以看下 https://github.com…

Spring Boot集成MyBatis Plus

文章目录 一、前言二、步骤2.1、步骤 1&#xff1a;创建 Spring Boot 项目2.2、添加依赖2.2.1、基本的Spring和Spring MVC功能2.2.2、MySQL驱动依赖2.2.3、 MyBatis Plus 的依赖 2.3、配置数据库连接2.4、创建实体类2.5、创建 Mapper 接口2.6、编写 Service 层2.7、编写 Contro…

自动化运维工具——ansible安装及模块介绍

目录 一、ansible——自动化运维工具 1.1 Ansible 自动运维工具特点 1.2 Ansible 运维工具原理 二、安装ansible 三、ansible命令模块 3.1 command模块 3.2 shell模块 3.3 cron模块 3.4 user模块 3.5 group 模块 3.6 copy模块 3.7 file模块 3.8 ping模…

Mat类数据的读取

目录 1.Mat类矩阵的常用属性 2.Mat元素的读取 1.at方法读取Mat矩阵元素 at (int row,int col) 2.矩阵元素地址定位方式访问元素 3.Android jni demo 1.Mat类矩阵的常用属性 下面是一些Mat类的常用属性&#xff1a; rows: 返回Mat对象的行数。 cols: 返回Mat对象的列数。 …

linux top命令的参数解释

参考&#xff1a; https://blog.csdn.net/weixin_45465395/article/details/115728520?ydrefereraHR0cHM6Ly9jbi5iaW5nLmNvbS8%3D 上面的一列是总的CPU使用情况&#xff0c;id是指的总的空闲的 内容 含义 0.0%us 用户空间占用CPU百分比 0.0%sy 内核空间占用CPU百分比 0.0%ni…

gpt-3.5-turbo微调图形界面;Hugging Face完成2.35亿美元融资

&#x1f989; AI新闻 &#x1f680; 人工智能初创公司Hugging Face完成2.35亿美元融资&#xff0c;估值达到45亿美元 摘要&#xff1a;总部位于纽约的人工智能初创公司Hugging Face完成了一轮2.35亿美元的融资&#xff0c;估值达到45亿美元。本轮融资的投资者包括谷歌、亚马…

网络编程 day 2

1、TCP的服务器 客户端的代码 #include <myhead.h>#define ERR_MSG(msg) do{\fprintf(stderr, "__%d__:", __LINE__); \perror(msg);\ }while(0)#define PORT 8888 //端口号&#xff0c;范围1024~49151 #define IP "192.168.114.64"…

匿名对象和一般对象的区别

1.格式的不同 一般对象的格式&#xff1a; ​ Object obj new Object(); ​ 匿名对象的格式&#xff1a; ​ new Object(); 2.作为参数传递机制的不同 2.1先看看一般对象的使用机制 执行步骤&#xff1a; 1.首先程序进入main()函数&#xff0c;执行Object obj&#xff0c;…

vscode打开项目太大,文件太多,无法找到自己的目录

我的技巧是直接在vscode的terminal里面 用find ./ -name *file_name*寻找我想要找的文件。 这样子出来的文件还带有路径&#xff0c;可以直接点过去。