Mesa软件框架以及重要数据结构分析

Mesa软件框架以及重要数据结构分析



引言

Mesa的实现比较复杂,其中还有许多的数据结构之间的关系逻辑还不是很清楚。感觉分析了又没有分析一样,这里我们再理一理!


1.1 Mesa下EGL/GL核心数据结构和层级关系

在这里插入图片描述

MESA的核心数据结构很多很复杂,上图列举了一些核心数据结构主要强调了它们的层次关系,即上层使用下层的抽象结构(比如 函数指针调用),下层为上次做具体的实现(比如具体的函数实现),虽然是C代码但设计理念基本上与C++的继承类似(这个也是C语言实现大型代码框架的核心)。

这里的核心主要是Mesa软件EGL/GL层级的递进调用。


1.2 Mesa下核心文件和核心结构体


在这里插入图片描述


先从核心的几个文件入手:

  • dri2.c:该文件主要定义了dri库函数的扩展的入口,和各种extensions的对接,通常会通过dlsym加载__driDriverGetExtensions_##drivername对应函数,然后通过函数指针匹配到对应的extensions进行赋值
//mesa/src/gallium/frontends/dri/dri2.c/* The extension is modified during runtime if DRI_PRIME is detected */
static const __DRIimageExtension dri2ImageExtensionTempl = {.base = { __DRI_IMAGE, 18 },.createImageFromName          = dri2_create_image_from_name,.createImageFromRenderbuffer  = dri2_create_image_from_renderbuffer,.destroyImage                 = dri2_destroy_image,.createImage                  = dri2_create_image,.queryImage                   = dri2_query_image,.dupImage                     = dri2_dup_image,.validateUsage                = dri2_validate_usage,.createImageFromNames         = dri2_from_names,.fromPlanar                   = dri2_from_planar,.createImageFromTexture       = dri2_create_from_texture,.createImageFromFds           = NULL,.createImageFromDmaBufs       = NULL,.blitImage                    = dri2_blit_image,.getCapabilities              = dri2_get_capabilities,.mapImage                     = dri2_map_image,.unmapImage                   = dri2_unmap_image,.createImageWithModifiers     = NULL,.createImageFromDmaBufs2      = NULL,.createImageFromDmaBufs3      = NULL,.queryDmaBufFormats           = NULL,.queryDmaBufModifiers         = NULL,.queryDmaBufFormatModifierAttribs = NULL,.createImageFromRenderbuffer2 = dri2_create_image_from_renderbuffer2,
};/** Backend function init_screen.*/static const __DRIextension *dri_screen_extensions_base[] = {&driTexBufferExtension.base,&dri2FlushExtension.base,&dri2RendererQueryExtension.base,&dri2GalliumConfigQueryExtension.base,&dri2ThrottleExtension.base,&dri2FenceExtension.base,&dri2InteropExtension.base,&dri2NoErrorExtension.base,&driBlobExtension.base,
};/*** DRI driver virtual function table.** DRI versions differ in their implementation of init_screen and swap_buffers.*/
const struct __DriverAPIRec galliumdrm_driver_api = {.InitScreen = dri2_init_screen,.DestroyScreen = dri_destroy_screen,.CreateContext = dri_create_context,.DestroyContext = dri_destroy_context,.CreateBuffer = dri2_create_buffer,.DestroyBuffer = dri_destroy_buffer,.MakeCurrent = dri_make_current,.UnbindContext = dri_unbind_context,.AllocateBuffer = dri2_allocate_buffer,.ReleaseBuffer  = dri2_release_buffer,
};/*** DRI driver virtual function table.** KMS/DRM version of the DriverAPI above sporting a different InitScreen* hook. The latter is used to explicitly initialise the kms_swrast driver* rather than selecting the approapriate driver as suggested by the loader.*/
const struct __DriverAPIRec dri_kms_driver_api = {.InitScreen = dri_kms_init_screen,.DestroyScreen = dri_destroy_screen,.CreateContext = dri_create_context,.DestroyContext = dri_destroy_context,.CreateBuffer = dri2_create_buffer,.DestroyBuffer = dri_destroy_buffer,.MakeCurrent = dri_make_current,.UnbindContext = dri_unbind_context,.AllocateBuffer = dri2_allocate_buffer,.ReleaseBuffer  = dri2_release_buffer,
};/* This is the table of extensions that the loader will dlsym() for. */
const __DRIextension *galliumdrm_driver_extensions[] = {&driCoreExtension.base,// 它的实现在dri_util.c,并且它会被target.c调用到 &driImageDriverExtension.base,&driDRI2Extension.base,&gallium_config_options.base,NULL
};

  • target.c:这个文件我们要怎么描述它的相关功能呢,我们可以理解它为dri库函数库入口,我们会在dri_load_driver函数中通过dri_open_driver打开对应的so库,然后通过dlsym加载__driDriverGetExtensions_##drivername函数,然后通过dri_bind_extensions获取对应的扩展!
//mesa/src/gallium/targets/dri/target.c//非常重要的一个宏定义
#define DEFINE_LOADER_DRM_ENTRYPOINT(drivername)                          \
const __DRIextension **__driDriverGetExtensions_##drivername(void);       \
PUBLIC const __DRIextension **__driDriverGetExtensions_##drivername(void) \
{                                                                         \globalDriverAPI = &galliumdrm_driver_api;                              \return galliumdrm_driver_extensions;                                   \
}#if defined(HAVE_LIBDRM)const __DRIextension **__driDriverGetExtensions_kms_swrast(void);//kms_swrastPUBLIC const __DRIextension **__driDriverGetExtensions_kms_swrast(void)
{LOGE("__driDriverGetExtensions_kms_swrast");globalDriverAPI = &dri_kms_driver_api;//它的实现被定义在dri2.c中return galliumdrm_driver_extensions;//它的实现被定义在Dri2.cz中
}#endif//intel I915定义
#if defined(GALLIUM_I915)
DEFINE_LOADER_DRM_ENTRYPOINT(i915)
#endif//AMD显卡dri函数入口定义
#if defined(GALLIUM_R300)
DEFINE_LOADER_DRM_ENTRYPOINT(r300)
#endif#if defined(GALLIUM_R600)
DEFINE_LOADER_DRM_ENTRYPOINT(r600)
#endif

  • dri_util.c:它是dri2框架中的一个工具类,它内部实现的函数基本是前面dri2.c中扩展extensions的实现
//mesa/src/mesa/drivers/dri/common/dri_util.c/*** \file dri_util.c* DRI utility functions.** This module acts as glue between GLX and the actual hardware driver.  A DRI* driver doesn't really \e have to use any of this - it's optional.  But, some* useful stuff is done here that otherwise would have to be duplicated in most* drivers.* * Basically, these utility functions take care of some of the dirty details of* screen initialization, context creation, context binding, DRM setup, etc.** These functions are compiled into each DRI driver so libGL.so knows nothing* about them.* DRI实用功能* 此模块充当GLX和实际硬件驱动程序之间的粘合剂。DRI驱动程序实际上并不需要使用这些——它是可选的。* 但是,这里完成了一些有用的东西,否则将不得不在大多数驱动程序中重复。*基本上,这些实用程序函数负责屏幕初始化,上下文创建,上下文绑定,DRM设置等一些肮脏的细节。* 这些函数被编译到每个DRI驱动程序中,所以libGL。所以对他们一无所知。*//** Core interface */
const __DRIcoreExtension driCoreExtension = {.base = { __DRI_CORE, 2 },.createNewScreen            = NULL,.destroyScreen              = driDestroyScreen,.getExtensions              = driGetExtensions,.getConfigAttrib            = driGetConfigAttrib,.indexConfigAttrib          = driIndexConfigAttrib,.createNewDrawable          = NULL,.destroyDrawable            = driDestroyDrawable,.swapBuffers                = driSwapBuffers, /* swrast */.createNewContext           = driCreateNewContext, /* swrast */.copyContext                = driCopyContext,.destroyContext             = driDestroyContext,.bindContext                = driBindContext,.unbindContext              = driUnbindContext
};/** DRI2 interface */
const __DRIdri2Extension driDRI2Extension = {.base = { __DRI_DRI2, 4 },.createNewScreen            = dri2CreateNewScreen,.createNewDrawable          = driCreateNewDrawable,.createNewContext           = driCreateNewContext,.getAPIMask                 = driGetAPIMask,.createNewContextForAPI     = driCreateNewContextForAPI,.allocateBuffer             = dri2AllocateBuffer,.releaseBuffer              = dri2ReleaseBuffer,.createContextAttribs       = driCreateContextAttribs,.createNewScreen2           = driCreateNewScreen2,
};const __DRIswrastExtension driSWRastExtension = {.base = { __DRI_SWRAST, 4 },.createNewScreen            = driSWRastCreateNewScreen,.createNewDrawable          = driCreateNewDrawable,.createNewContextForAPI     = driCreateNewContextForAPI,.createContextAttribs       = driCreateContextAttribs,.createNewScreen2           = driSWRastCreateNewScreen2,
};/** Image driver interface */
const __DRIimageDriverExtension driImageDriverExtension = {.base = { __DRI_IMAGE_DRIVER, 1 },.createNewScreen2           = driCreateNewScreen2,.createNewDrawable          = driCreateNewDrawable,.getAPIMask                 = driGetAPIMask,.createContextAttribs       = driCreateContextAttribs,
};

通过我们前面的总结,我们可以看到dri的extensions的结构galliumdrm_driver_extensions定义在dri2.c中,它其中的实现在dri_util.c


  • gl_context:gl绘制上下文核心结构体
//mesa/src/mesa/main/mtypes.h
/*** Mesa rendering context.** This is the central context data structure for Mesa.  Almost all* OpenGL state is contained in this structure.* Think of this as a base class from which device drivers will derive* sub classes.*/
struct gl_context
{.../*** The current dispatch table for non-displaylist-saving execution, either* BeginEnd or OutsideBeginEnd*/struct _glapi_table *Exec;...   /*** Device driver function pointer table*/struct dd_function_table Driver;  ...
}

  • st_context:官方没有介绍,我们可以把他理解为状态上下文(state tracker context)
//src/mesa/state_tracker/st_context.h
struct st_context
{...struct gl_context *ctx;struct pipe_screen *screen;struct pipe_context *pipe;...
}//src/mesa/state_tracker/st_context.c
static void
st_init_driver_functions(struct pipe_screen *screen,struct dd_function_table *functions)
{_mesa_init_sampler_object_functions(functions);st_init_draw_functions(functions);st_init_blit_functions(functions);st_init_bufferobject_functions(screen, functions);st_init_clear_functions(functions);functions->Clear = st_Clear;st->pipe->clear(...)、、这里的pipi是pipe_context,且在lp_context中,llvmpipe->pipe.clear = llvmpipe_clear;st_init_bitmap_functions(functions);st_init_copy_image_functions(functions);st_init_drawpixels_functions(functions);st_init_rasterpos_functions(functions);st_init_drawtex_functions(functions);st_init_eglimage_functions(functions);st_init_fbo_functions(functions);
// 省略
}_mesa_Clearclear(...)ctx->Driver.Clear(...)//此处的ctx为gl_context,Driver为dd_function_table,在前面被赋值//这块怎么被调用到的详见章节3
struct st_context *
st_create_context(gl_api api, struct pipe_context *pipe,const struct gl_config *visual,struct st_context *share,const struct st_config_options *options,bool no_error)
{struct gl_context *ctx;struct gl_context *shareCtx = share ? share->ctx : NULL;struct dd_function_table funcs;struct st_context *st;util_cpu_detect();memset(&funcs, 0, sizeof(funcs));st_init_driver_functions(pipe->screen, &funcs);...
}

  • pipe_context:Gallium渲染上下文
//src/gallium/include/pipe/p_context.h
/*** Gallium rendering context.  Basically:*  - state setting functions*  - VBO drawing functions*  - surface functions*/
struct pipe_context {struct pipe_screen *screen;void (*draw_vbo)(...);...

看注释,这个结构体蛮厉害的!


  • dd_function_table:这个结构体,起到了承接gl_xxx—>mesa_xxx到st_xxx的作用
//src/mesa/main/dd.h
/*** Device driver function table.* Core Mesa uses these function pointers to call into device drivers.* Most of these functions directly correspond to OpenGL state commands.* Core Mesa will call these functions after error checking has been done* so that the drivers don't have to worry about error testing.** Vertex transformation/clipping/lighting is patched into the T&L module.* Rasterization functions are patched into the swrast module.** Note: when new functions are added here, the drivers/common/driverfuncs.c* file should be updated too!!!*/
struct dd_function_table {.../*** Clear the color/depth/stencil/accum buffer(s).* \param buffers  a bitmask of BUFFER_BIT_* flags indicating which*                 renderbuffers need to be cleared.*/void (*Clear)( struct gl_context *ctx, GLbitfield buffers );    ...
}

  • kms_sw_winsys:功能,通过libdrm,和内核drm交互:申请显存(也可能是内存)bo,显存map到内存,查询bo是否忙(正在被显卡使用)

  • llvmpipe_screen:使用kms_swrast并且是llvmpipe做后端,接口类,功能:查询显卡特性参数。另外,注册了资源构造函数。资源指显存资源,如bo,texture,并且现了pipe_screen定义的接口其中注册了一个sw_winsys,以辅助实现pipe_screen定义的接口.screen主要体现硬件的能力,创建和管理资源
struct llvmpipe_screen
{struct pipe_screen base;struct sw_winsys *winsys;...
}

  • llvmpipe_context继承自pipe_context其中定义了和context相关的函数集context可以认为是硬件的一个pipe line的实例,涉及到state的设置,fence等
struct llvmpipe_context {struct pipe_context pipe;  /**< base class */...
}
Setting rendering state (texture sampler state, blending state, rasterization state, vertex array info, drawing surfaces, etc.)
Setting shader state, using the TGSI binary shader representation.
Vertex array and indexed vertex array drawing.

  • pipe_开头函数: pipe_开头的状态对象,是对现代显卡的底层抽象层,是架构无关层




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

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

相关文章

10.RedHat认证-Linux文件系统(上)

10.RedHat认证-Linux文件系统(上) ⽂件系统&#xff0c;顾名思义&#xff0c;是⼀个组织⽂件的“系统(system)”。file system ⽂件系统是⽤来组织⽂件的&#xff0c;通俗⼀点理解的话&#xff0c;⽂件系统是⽤来存储⽂件的。 硬盘是不能直接存放⽂件或数据。 我们通过将硬…

mybatis关联查询使用resultMap查询到了多条,结果返回一条。

今天在写代码时候&#xff0c;遇到了一个很让我费解的问题&#xff0c;在使用关联查询的时候&#xff0c;在明明数据库里面&#xff0c;已经查到了两条数据&#xff0c;结果resultMap这个集合里面&#xff0c;就只返回一条数据。 数据库的SQL&#xff1a; mybatis的xml里面的r…

【Python编程实战】基于Python语言实现学生信息管理系统

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

C++的第一道门坎:类与对象(二)

一.类中生成的默认成员函数详解 0.类的6个默认成员函数 编译器会给类生成六个默认成员函数&#xff0c;在类中即使我们什么都不做&#xff0c;也会自动生成。 默认成员函数&#xff1a;用户没有显式实现&#xff0c;编译器会自动生成的成员函数称为默认成员函数。 下面我们逐…

网络渗透day2

Windows登录的明文密码存储过程和密文存储位置 明文密码存储过程&#xff1a; Windows操作系统不会以明文形式存储用户密码。相反&#xff0c;当用户设置或更改密码时&#xff0c;系统会对密码进行哈希处理&#xff0c;然后存储其哈希值。哈希处理的目的是为了提高密码的安全性…

Android性能优化方案

1.启动优化&#xff1a; application中不要做大量耗时操作,如果必须的话&#xff0c;建议异步做耗时操作2.布局优化&#xff1a;使用合理的控件选择&#xff0c;少嵌套。&#xff08;合理使用include,merge,viewStub等使用&#xff09;3.apk优化&#xff08;资源文件优化&#…

同时安装python2 和python3

最近的项目因为工具的原因 需要同时安装python2 和python3 我又想学着使用python 写东西 导致遇到了很多问题 记录下来 1 同时安装 python2 和python 1.1 安装完把/确认 Path 环境变量里 同时有python2,python2\Scripts和python3 ,python3\Scripts四个环境变量 修改python3…

3步骤找回丢失文件!EasyRecovery让你轻松应对数据灾难!

EasyRecovery&#xff1a;数据丢失的终结者&#xff0c;您的数字世界守护神 在数字化时代&#xff0c;数据已经成为我们生活的一部分。无论是个人照片、重要文件还是企业资料&#xff0c;数据都扮演着重要的角色。然而&#xff0c;意外删除、格式化、系统崩溃或病毒攻击等原因导…

云易办springboot+vue后端

springbootvue云易办后端项目完成 一.创建项目 创建父项目&#xff1a;yeb&#xff0c; 使用spring Initializr&#xff0c;完成创建之后删除无用文件夹&#xff0c;作为父项目 添加packaging <packaging>pom</packaging>二.创建子模块&#xff1a;yeb-server …

Day 56 647. 回文子串 516.最长回文子序列

回文子串 给定一个字符串&#xff0c;你的任务是计算这个字符串中有多少个回文子串。 具有不同开始位置或结束位置的子串&#xff0c;即使是由相同的字符组成&#xff0c;也会被视作不同的子串。 示例 1&#xff1a; 输入&#xff1a;“abc”输出&#xff1a;3解释&#xf…

蓝桥杯—SysTick中断精准定时实现闪烁灯

在嵌入式系统中&#xff0c;SysTick_Handler 是一个中断服务例程&#xff08;Interrupt Service Routine, ISR&#xff09;&#xff0c;用于处理 SysTick 定时器的中断。SysTick 定时器通常用于提供一个周期性的定时中断&#xff0c;可以用来实现延时或者周期性任务。 SysTick…

SQL 语言:数据控制

文章目录 概述授权&#xff08;GRANT)销权&#xff08;REVOKE&#xff09;总结 概述 SQL语言中的数据控制权限分配是数据库管理的重要组成部分&#xff0c;它涉及到如何合理地为用户分配对数据库资源的访问和使用权限。 权限类型&#xff1a;在SQL中&#xff0c;权限主要分为…

【Python-OS】os.path.splitext()

作用&#xff1a;将文件路径分割成文件名和扩展名两部分。 slide_id, _ os.path.splitext(slide) print("slide:") print(slide) print("slide_id:") print(slide_id)注&#xff1a; slide是文件名&#xff0c;可以自行赋值

【IT小知识】堡垒机支持哪些私有云平台?

随着企业对网络安全的重视&#xff0c;以及等保政策的要求&#xff0c;越来越多的企业打算采购堡垒机。但不少企业对于堡垒机了解不多&#xff0c;一些小伙伴在问&#xff0c;堡垒机支持哪些私有云平台&#xff1f; 堡垒机支持哪些私有云平台&#xff1f; 【回答】&#xff1a…

数据分析必备:一步步教你如何用Pandas做数据分析(10)

1、Pandas 文本处理 Pandas 文本处理操作实例 在本章中&#xff0c;我们将使用基本的Series / Index讨论字符串操作。在随后的章节中&#xff0c;我们将学习如何在DataFrame上应用这些字符串函数。 Pandas提供了一组字符串函数&#xff0c;可以轻松地对字符串数据进行操作。最…

Talken - 语音命令系统

Talken - 语音命令系统 通过集成最先进的语音命令系统 Talken,释放游戏的全部潜力。 借助 Talken,您可以让玩家通过语音命令控制动作,从而重新定义游戏体验。 观看角色移动并对语音指令做出实时反应,模糊游戏与现实之间的界限。 主要特征: 🗣️ 语音驱动的游戏玩法:…

几个原则

&#xff08;1&#xff09; 成功是成功之母&#xff0c;失败不是成功之母。100分的试卷一模一样&#xff0c;不及格的试卷千奇百怪。向成功者学习。 不要研究失败&#xff0c;因为研究了一万个失败的原因&#xff0c;也不能找到一把成功的钥匙。 &#xff08;2&#xff09; 要定…

自由应用大本营?开源免费的Android应用商店:F-Droid Client

F-Droid Client&#xff1a;拥抱开源&#xff0c;守护隐私&#xff0c;让自由软件成为您生活的一部分- 精选真开源&#xff0c;释放新价值。 概览 F-Droid Client是一个开源的Android应用商店&#xff0c;它在GitHub上免费提供。这个项目致力于收集和展示各类自由及开源软件&a…

“星战之父”乔治・卢卡斯吐槽好莱坞“几乎没有原创思维”,AI 将“不可避免”用于电影制作

《星球大战》系列的创作者乔治・卢卡斯&#xff08;George Lucas&#xff09;在 1977 年奠定了电影制作传奇人物的地位&#xff0c;他对当今电影的状况及其发展方向有一些自己的看法。 他在 2024 年戛纳电影节上谈到了当前的电影行业。现年 80 岁的卢卡斯在接受法国媒体 Brut …

C# 读取 CSV 文件的方法汇总

文章目录 1. 使用System.IO命名空间中的类2. 处理标题行和指定列3. 使用CsvHelper库4. 高级功能和异常处理5. 使用 LINQ6. 总结 CSV&#xff08;Comma-Separated Values&#xff0c;逗号分隔值&#xff09;文件是一种简单的文本文件格式&#xff0c;用于存储表格数据。在C#中&a…