Mesa GL Dispatch分发分析与理解

Mesa GL Dispatch分发分析与理解



引言

这篇博客的核心是从OpenGL应用程序的典型api入手,分析gl api 调用到用户态驱动后端的过程,进而总结出一个典型的调用栈。理解了这个典型调用栈,对后续任何一个API的调用过程分析,都是a piece of cake。

在正式分析相关分发流程之前,我们必须明确的一点就是现在的Mesa采用的是最新的gallium架构,下图的左侧调用栈是在gallium 架构之前采用的模式,右侧是gallium架构下的模式。可以看出gallium架构有比较明显的三个分层(夹心饼干):

  • state_tracker层:负责收集OpenGL状态

  • GPU-specific层:厂商的用户态驱动核心部分

  • OS WinSys层:操作系统对接层

下面章节出现的build-android-aarch64目录是通过meson编译的out目录!



二. glClear和glFlush的调用栈分析

接下来以glClear的函数实现,来分析从应用程序到GPU-specific的调用栈。先把关键调用栈组织如下(省略了不相关的调用)。

glClear(GL_COLOR_BUFFER_BIT);_mesa_Clear(GL_COLOR_BUFFER_BIT);st_Clear(ctx, GL_COLOR_BUFFER_BIT);st->pipe->Clear(...);gpu_specific_Clear(...);

我们详细分析下glFlush的流程实现:

GL_API void GL_APIENTRY glFlush (void)//gl.h
//build-android-aarch64/src/mapi/es2api/glapi_mapi_tmp.h
GLAPI void APIENTRY glFlush(void)
{const struct _glapi_table *_tbl = entry_current_get();//核心点,找到tablemapi_func _func = ((const mapi_func *) _tbl)[217];((void (APIENTRY *)(void)) _func)();
}    // src/mapi/entry.c   
static inline const struct _glapi_table *
entry_current_get(void)
{return GET_DISPATCH();
}    //build-android-aarch64/src/mapi/glapi/glapi.h 
_GLAPI_EXPORT extern __THREAD_INITIAL_EXEC struct _glapi_table * _glapi_tls_Dispatch;
_GLAPI_EXPORT extern __THREAD_INITIAL_EXEC void * _glapi_tls_Context;    
# define GET_DISPATCH() _glapi_tls_Dispatch
# define GET_CURRENT_CONTEXT(C)  struct gl_context *C = (struct gl_context *) _glapi_tls_Context

这个_glapi_tls_Dispatch是在那里被实现的呢,我们继续往下看:

//build-android-aarch64/src/mapi/u_current.c
__THREAD_INITIAL_EXEC struct _glapi_table *_glapi_tls_Dispatch= (struct _glapi_table *) table_noop_array;

这个table_noop_array是不是似曾相见,有点眼熟,是的在前面eglCreateContext里面见过:

//build-android-aarch64/src/mapi/shared-glapi/glapi_mapi_tmp.h
static void APIENTRY noopFlush(void)
{noop_warn("glFlush");
}
const mapi_func table_noop_array[] = {...(mapi_func) noopFlush,...
}

通过我们前面的st_create_context_priv分析可知,获取到table表以后,然后通过id会找到对应的函数,即指向了_mesa_Flush。

//build-android-aarch64/src/mesa/main/context.c
/*** Execute glFlush().*/
void GLAPIENTRY
_mesa_Flush(void)
{GET_CURRENT_CONTEXT(ctx);//转换成gl_contextASSERT_OUTSIDE_BEGIN_END(ctx);_mesa_flush(ctx);
}
_mesa_flush(...)struct st_context *st = st_context(ctx);st_glFlush(st, ...)//src/mesa/state_tracker/st_cb_flush.cst->pipe->flush(st->pipe, fence, flags);//st->pipe指向pipe_context,最终会调用到gpu_specific代码,这里通过前面的eglCreateContext分析可以知道会调用到xxx_gpu_flushxxx_gpu_flush(...)//src/gallium/drivers/xxx_gpuxxx_gpu_context.c   


三.对于GL Dispatch分发的理解

3.1 gl开头的函数

gl_开头的函数是gl的api入口函数,其是通过libglapi.so作为入口切入的。


3.2 _mesa_开头的函数

gl_打头的函数是OpenGL API,首先这些函数都是函数指针,这些函数挂载的函数就是mesa里以_mesa_打头的对应函数。这里有个调试技巧,把函数名gl_前缀换成_mesa_前缀即可。例如glGenBuffers的mesa入口函数是_mesa_GenBuffers。 _mesa_打头函数在前文的libmesa.a静态库中,而libmesa.a又被libgallium_dri.so包含,因此这些代码都是后端驱动的一部分,可以随意修改。


3.3 st_开头的函数

_mesa_打头的函数会调用st_开头的函数。这些st函数就是上图中的state tracker层。


3.4 pipe层字样的函数

pipe层,是接近于硬件的模块,GPU-specific层是从pipe层继承的。可以把pipe层看成接口层,各家驱动实现该接口。


3.5 GPU-specific层的函数

把pipe层的OpenGL状态转换为厂商支持的状态字段。该层一般会封装和处理硬件相关的状态,即硬件命令字。这些封装数据一般要由kmd交给硬件配置相关寄存器。



四、gl api 典型调用栈

通过以上分析,这里给出一个典型的gl函数的调用栈。即:mesa层、st层、pipe层、gpu-spec层。

image

mesa典型调用栈

这里并没有给出winsys层,因为不同的OS有不同实现,这里关注Android。就是上图中的与libdrm交互的那一层,这层会使用ioctl将gpu-spec层组织的数据交给kms,再由kms把数据下发到gpu硬件。



总结

本文从glClear和glFlush的函数的调用栈分析了mesa实现OpenGL的一个典型流程。对于任何一个gl api可以套用该流程,熟悉mesa代码的调用脉络。

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

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

相关文章

Java项目在linux上部署步骤

1、根据linux系统在网上下载对应的jdk1.8安装包,有32位和64位区别。 2、解压并配置jdk的环境 (1)解压安装包: tar xzvf jdk安装包 (2)修改环境变量: vim /etc/profile 最后加上: export JAVA_H…

文本匹配.grep与Select-String用法对比

Linux Shell与PowerShell上匹配字符串 grep与Select-String用法对比 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article…

家居厨房安全无小事:可燃气体报警器探头校准检测重要性解析

家居厨房作为日常生活中烹饪美食的重要场所,其安全问题不容忽视。 近年来,随着家庭用气设备的普及,煤气泄露事件时有发生,给人们的生命财产安全带来了严重威胁。 因此,安装可燃气体报警器探头,及时检测并…

Python Orange3库:数据挖掘与机器学习的终极利器

更多Python学习内容:ipengtao.com Orange3是一个开源的数据挖掘和机器学习库,提供了丰富的工具和算法来处理和分析数据。Orange3的图形用户界面使得非编程用户也能轻松进行数据分析,而其Python API则为编程用户提供了强大的灵活性。本文将详细…

TypeScript类型体操练习

历史小剧场 这个世界上,有两种人最痛苦,第一种是身居高位者,第二种是身居底层者,第一种人很少,第二种人很多。第一种人叫崇祯,第二种人叫百姓。 而最幸福的,就是中间那拨人,主要工作…

【NOIP2013普及组复赛】题2:表达式求值

题2:表达式求值 【题目描述】 给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值。 【输入文件】 输入仅有一行,为需要你计算的表达式,表达式中只包含数字、加法运算符 “ ” “” “”和乘法运算符 “ ∗ ” “…

根据标签名递归读取xml字符串中element

工具类&#xff1a; /*** 根据标签名递归读取xml字符串中element* 例&#xff1a;* String xml * "<req>\n" * "<tag1></tag1>\n" * "<tag2>\n" * " <tag4></tag4>\n" * "</tag2>\n&…

go panic和recover

panic 能够改变程序的控制流&#xff0c;调用 panic 后会立刻停止执行当前函数的剩余代码&#xff0c;并在当前 goroutine 中递归执行调用方的 defer。recover 可以中止 panic 造成的程序崩溃。它是一个只能在 defer 中发挥作用的函数&#xff0c;在其他作用域中调用不会发挥作…

如何在线转换图片的格式?一键修改图片格式的方法

图片是日常生活和工作中的一种常用的内容展示类型&#xff0c;在使用图片的时候不同用途需要使用的图片格式也是不同的&#xff0c;比如我们手中有一张jpg格式图片&#xff0c;但是平台上传要求格式是png&#xff0c;那么怎样才能将jpg转png格式呢&#xff1f;下面将教大家图片…

模拟量4~20mA电流传感器接线方式

一、模拟量4~20mA电流传感器接线方式 无源双线制是常见的电流型传感器接线方式&#xff0c;它具有简单、经济的特点。其接线方式如下&#xff1a; 传感器的“”接到数据采集器的电源“”上&#xff0c; 传感器的“-”端子连接到数据采集器的“AI”端子上&#xff0c; 数据采集器…

无人机+EasyDSS互联网视频平台:构建秸秆焚烧监控的“天眼”系统

一、方案背景 在每年的夏收时节&#xff0c;秸秆禁烧成为各地政府面临的一项重要任务。随着夏收季节的结束&#xff0c;大量农作物秸秆的处理问题逐渐凸显。一方面农作物种植面积辽阔&#xff0c;禁烧区域面积较大&#xff0c;监管巡逻人员的数量有限&#xff0c;无法全面顾及…

使用 ASM 修改字段类型,解决闪退问题

问题 我的问题是什么&#xff1f; 在桥接类 UnityBridgeActivity 中处理不同 unity 版本调用 mUnityPlayer.destroy(); 闪退问题。 闪退日志如&#xff1a; 闪退日志说在 UnityBridgeActivity中找不到类型为 UnityPlayer 的属性 mUnityPlayer。 我们知道&#xff0c;Android…

【鸟叔的Linux私房菜】2-主机规划与磁盘分区

文章目录 2.1 Linux与硬件的搭配各硬件设备在Linux的文件名使用虚拟机学习 2.2 磁盘分区磁盘连接方式和设备文件名的关系MBR(MS-DOS)与GPT磁盘分区表MBR(MS-DOS)GPT磁盘分区表 启动流程的BIOS与UEFI启动检测程序BIOS搭配MBR/GPT的启动流程UEFI BIOS搭配 GPT启动的流程 Linux安装…

RGB 平均值统计

任务&#xff1a;有一一对应的图片多组如下&#xff0c;希望统计灰色部分原有grb平均值&#xff0c;彩色部分rgb平均值。 方法&#xff1a;由下图对各个像素分析&#xff0c;分为3类&#xff0c;并记录坐标&#xff0c;根据坐标统计上图的rgb平均值&#xff0c;结果放在一张Exc…

Linux完整版命令大全(十八)

quotacheck 功能说明&#xff1a;检查磁盘的使用空间与限制。语  法&#xff1a;quotacheck [-adgRuv][文件系统...]补充说明&#xff1a;执行quotacheck指令&#xff0c;扫描挂入系统的分区&#xff0c;并在各分区的文件系统根目录下产生quota.user和quota.group文件&#…

linux开发之设备树基本语法二

设备树特殊节点,对节点定义别名,chosen节点用来uboot给内核传参 上面的mmc0就是sdmmc0节点的别名 device_type属性 只对cpu节点和memory节点进行描述 自定义属性 这部分自定义,比如定义管脚标号,初始数值等 为什么我们可以在设备树上自己定义属性呢?设备树文件描述的是硬…

JD3-40/23漏电继电器 AC220V 50-500mA 0.1s 导轨安装

系列型号&#xff1a; JD3-40/13漏电继电器JD3-40/23漏电继电器JD3-40/33漏电继电器JD3-40/43漏电继电器 JD3-70/13漏电继电器JD3-70/23漏电继电器JD3-70/33漏电继电器JD3-70/43漏电继电器 JD3-100/23漏电继电器JD3-100/43漏电继电器JD3-100/33漏电继电器JD3-100/13漏电继电…

轻松入门Linux命令行(一)

1. 打开终端 在Linux系统中&#xff0c;我们可以通过终端&#xff08;Terminal&#xff09;来执行各种命令。不同的Linux发行版可能有不同的终端程序&#xff0c;但通常都可以在应用程序菜单中找到。打开终端后&#xff0c;我们就可以看到一个命令行提示符&#xff0c;等待我们…

260 基于matlab的工业乙醇发酵GUI仿真

基于matlab的工业乙醇发酵GUI仿真。首先对经典的流加半经验半理论模型进行动态和稳态仿真&#xff0c;考虑实际情况密&#xff0c;逐步将温度&#xff0c;气体排放等因素考虑到模型中去&#xff0c;进行综合性仿真。结合GUI技术&#xff0c;以动力学模型为核心&#xff0c;制作…

国产高边驱动对标英飞凌BTS7020-2

车规级高边驱动系列产品可P2P替换BTS7020-2的高边驱动芯片。类比半导体高边驱动产品可用于驱动车身控制域中的各种阻性、感性及容性负载的驱动&#xff0c;其在车内外的应用非常广泛&#xff0c;包括车内饰灯、头尾灯、座椅和方向盘及后视镜加热、电磁阀、门锁、电机等场景。 …