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;⽂件系统是⽤来存储⽂件的。 硬盘是不能直接存放⽂件或数据。 我们通过将硬…

Xed编辑器开发第三期:使用Rust从0到1写一个文本编辑器

继续Xed编辑器开发第二期:使用Rust从0到1写一个文本编辑器的开发进度&#xff0c;这是第三期的内容&#xff1a; 4.1 逐行清除 在每次刷新之前清除整个屏幕似乎不太理想&#xff0c;最好在重新绘制每行时清除每行。让我们删除 Clear(ClearType::All)&#xff0c;而是在我们绘…

Double 4 VR混合现实情景实训教学系统在戏剧英语课堂上的应用

随着科技的不断发展&#xff0c;Double 4 VR混合现实情景实训教学系统在教育领域的应用越来越广泛。在戏剧英语课堂上&#xff0c;这种教学系统可以为学生提供更加生动、逼真的学习环境&#xff0c;增强学生的学习体验和效果。 一、模拟真实场景&#xff0c;增强学习体验 Doubl…

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

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

cesuim

new Cesium.Color(255,255,0,1), //颜色 Math.PI/2color: Cesium.Color.fromCssColorString("#f40"), //16进制颜色初始化地球 import * as Cesium from "cesium";import { onMounted } from "vue"; onMounted(() > {Cesium.Ion.defaultAcc…

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

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

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

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

重学java 50 集合 上

路随远&#xff0c;行则将至&#xff1b;路虽难&#xff0c;做则必成 —— 24.5.26 一、Collection接口 1.概述: 单列集合的顶级接口 2.使用 Collection<泛型>对象名new 实现类集合对象<>() <E>:泛型,决定集合中的元素都是啥类型的,必须指定的是引用…

网络渗透day2

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

Android性能优化方案

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

在 Vue 中实现表单校验失败后页面滚动到错误处

在 Web 应用程序中&#xff0c;表单验证是保证用户输入的正确性和完整性的关键部分。当用户提交表单时&#xff0c;我们经常需要验证表单数据&#xff0c;并在发现错误时向用户提示。在 Vue.js 中&#xff0c;实现表单验证通常是使用一些流行的库&#xff0c;比如 VeeValidate …

Linux安装Nginx脚本

Hello &#xff0c; 我是恒。 由于有一个脚本网页的仓库&#xff0c;开发必不可少的是自动化安装脚本 该shell脚本是根据某篇文章的脚本改进优化后写出来的&#xff0c;增加了软链接创建和系统服务注册的功能。 同时我也书写了PostgreSQL和Nvm的脚本&#xff0c;请在脚本专栏阅…

Github2024-05-21 Python开源项目日报 Top10

根据Github Trendings的统计,今日(2024-05-21统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目10C项目1TypeScript项目1youtube-dl - 从YouTube和其他网站下载视频的命令行程序 创建周期:4951 天开发语言:Python协议类型:The …

同时安装python2 和python3

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

LabVIEW通过OPC与PLC通讯

使用LabVIEW通过OPC与PLC&#xff08;可编程逻辑控制器&#xff09;通讯是一种常见的工业自动化解决方案。以下是详细的过程介绍&#xff0c;帮助理解并实现该通讯。 1. 理解OPC与PLC OPC&#xff1a;OPC是一种工业通讯协议&#xff0c;旨在实现不同硬件和软件之间的互操作性…

【SpringBoot笔记44】SpringBoot多数据源配置(方式一:配置多个mapper扫描不同的包路径实现多数据源配置)

这篇文章,主要介绍SpringBoot多数据源配置(方式一:配置多个mapper扫描不同的包路径实现多数据源配置)。 目录 一、多数据源配置 1.1、多数据源介绍 1.2、搭建基础工程

AIGC(人工智能生成内容)行业现在适合进入吗

AIGC&#xff08;人工智能生成内容&#xff09;行业现在适合进入吗 发展前景 随着深度学习、自然语言处理&#xff08;NLP&#xff09;、计算机视觉等人工智能技术的飞速发展&#xff0c;AIGC在文本、图像、音频、视频等多个领域都取得了显著的成果&#xff0c;为行业发展提供…

AWS存储之Amazon Aurora

Amazon Aurora是亚马逊自研提供的一种高性能、高可用性的关系型数据库引擎&#xff0c;兼容MySQL和PostgreSQL&#xff0c;提供了与这两种数据库引擎兼容的功能&#xff0c;同时具有更高的性能和可靠性。 Amazon Aurora在全球范围内提供无与伦比的高性能和可用性&#xff0c;完…

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

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

云原生架构内涵_2.云原生架构原则

云原生架构本身作为一种架构&#xff0c;也有若干架构原则作为应用架构的核心架构控制面&#xff0c;通过遵从这些架构原则可以让技术主管和架构师在做技术选择时不会出现大的偏差。 1.服务化原则 当代码规模超出小团队的合作范围时&#xff0c;就有必要进行服务化拆分了&…