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_swrast

PUBLIC 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_Clear
    clear(...)
        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_开头的状态对象,是对现代显卡的底层抽象层,是架构无关层




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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【CSDN独家公开】Python解析.SchDoc格式文件转换为json文件

前情提要 因工作需求&#xff0c;需要解析.SchDoc格式文件&#xff0c;提取文本和位置关系&#xff0c;通常方式是转换为图片或PDF&#xff0c;再进行OCR&#xff0c;但是这样识别精度太低了 Github找了好些项目&#xff0c;都不支持 PyAltium不支持 https://github.com/plu…

每日一题 <leetcode--2326.螺旋矩阵>

https://leetcode.cn/problems/spiral-matrix-iv/ 函数中给出的int* returnSize和int** returnColumnSizes是需要我们返回数值的&#xff0c;这点需要注意。其中int** returnColumnSizes 是需要额外开辟一块空间。 这道题我们首先需要malloc出一快空间来把链表存放在数组中&…

元宇宙vr美术虚拟展馆激发更多文化认同和互鉴

科技引领创新潮流&#xff0c;借助前沿的Web3D技术&#xff0c;我们为用户打造了一个沉浸式的纯3D虚拟空间体验平台&#xff1a;元宇宙线上互动展厅。您只需通过网页即可轻松访问这个充满未来感的互动平台。 在这个独特的虚拟环境中&#xff0c;用户可以轻松创建个性化角色&…

Android 13 sysprop_library新增属性

前提 我们在androidP及之前的版本&#xff0c;平台侧及应用层开发习惯于通过调用&#xff08;或者反射&#xff09;SystemProperties系统API的方式进行系统属性的读写。Android R以后&#xff0c;平台侧代码采用了一种将系统属性封装成类方法的形式供开发者调用。 Android R以…

I.MX6ULL模仿 STM32 驱动开发格式实验

系列文章目录 I.MX6ULL模仿 STM32 驱动开发格式实验 I.MX6ULL模仿 STM32 驱动开发格式实验 系列文章目录一、前言二、模仿 STM32 寄存器定义2.1 STM32 寄存器定义简介2.2 I.MX6Ul 寄存器定义2.3硬件原理图2.4实验程序编写 三、编译下载验证 一、前言 使用 C 语言编写 LED 灯驱…

深度学习——自己的训练集——图像分类(CNN)

图像分类 1.导入必要的库2.指定图像和标签文件夹路径3.获取文件夹内的所有图像文件名4.获取classes.txt文件中的所有标签5.初始化一个字典来存储图片名和对应的标签6.遍历每个图片名的.txt文件7.随机选择一张图片进行展示8.构建图像的完整路径9.加载图像10.检查图像是否为空 随…

消息队列实战应用

适用场景 耗时长&#xff0c;非核心业务&#xff0c;生产者不会用到消息处理结果的情况下&#xff0c;可以将消息交给异步服务去缓存与消费 部署MQ服务 version: "3.0" services:rabbitmq:container_name: rabbitmq-15672-1image: rabbitmq:3-managementports:- &…

短视频再度重逢:四川京之华锦信息技术公司

短视频再度重逢 在数字化时代的浪潮中&#xff0c;短视频以其独特的魅力迅速崛起&#xff0c;成为现代人生活中不可或缺的一部分。而当我们谈论起短视频&#xff0c;我们不仅仅是在谈论一种娱乐方式&#xff0c;更是在谈论一种情感的载体&#xff0c;一种回忆的媒介。今天&…

【ai】LiveKit Agent 的example及python本地开发模式工程实例

title: ‘LiveKit Agent Playground’ playgroundLiveKit Community playground的环境变量&#xff1a;LiveKit API # LiveKit API Configuration LIVEKIT_API_KEYYOUR_API_KEY LIVEKIT_API_SECRETYOUR_API_SECRET# Public configuration NEXT_PUBLIC_LIVEKIT_URLwss://YOUR_…

pytorch比较操作

文章目录 常用的比较操作1.torch.allclose()2.torch.argsort()3.torch.eq()4.torch.equal()5.torch.greater_equal()6.torch.gt()7.torch.isclose()8.torch.isfinite()9.torch.isif()10.torch.isposinf()11.torch.isneginf()12.torch.isnan()13.torch.kthvalue()14.torch.less_…

【从零开始学习RabbitMQ | 第二篇】如何确保MQ的可靠性和消费者可靠性

目录 前言&#xff1a; MQ可靠性&#xff1a; 数据持久化&#xff1a; Lazy Queue&#xff1a; 消费者可靠性&#xff1a; 消费者确认机制&#xff1a; 消费失败处理&#xff1a; MQ保证幂等性&#xff1a; 方法一&#xff1a; 总结&#xff1a; 前言&#xff1a; …

以梦为马,不负韶华(3)-AGI在企业服务的应用

AGI在企业服务中&#xff0c;各应⽤已覆盖企业全流程&#xff0c;包含⼈⼒、法务、财税、流程⾃动化、知识管理和软件开发各领域。 由于⼤语⾔模型对⽂本处理类场景有着天然且直接的适配性&#xff0c;⽂本总结、⽂本内容⽣成、服务指引等发展起步早且应⽤成熟度更⾼。 在数据…

Captura完全免费的电脑录屏软件

一、简介 1、Captura 是一款免费开源的电脑录屏软件&#xff0c;允许用户捕捉电脑屏幕上的任意区域、窗口、甚至是全屏画面&#xff0c;并将这些画面录制为视频文件。这款软件具有多种功能&#xff0c;例如可以设置是否显示鼠标、记录鼠标点击、键盘按键、计时器以及声音等。此…

LeetCode题练习与总结:有序链表转换二叉搜索树--109

一、题目描述 给定一个单链表的头节点 head &#xff0c;其中的元素 按升序排序 &#xff0c;将其转换为平衡二叉搜索树。 示例 1: 输入: head [-10,-3,0,5,9] 输出: [0,-3,9,-10,null,5] 解释: 一个可能的答案是[0&#xff0c;-3,9&#xff0c;-10,null,5]&#xff0c;它表…

医疗图像处理2023:Transformers in medical imaging: A survey

医学成像中的transformer:综述 目录 一、介绍 贡献与安排 二、CNN和Transformer 1.CNN 2.ViT 三、Transformer应用于各个领域 1.图像分割 1&#xff09;器官特异性 ①2D ②3D 2&#xff09;多器官类别 ①纯transformer ②混合架构 单尺度 多尺度 3&#xff09;…

Kubernetes——监听机制与调度约束

目录 前言 一、监听机制 1.Pod启动创建过程 2.调度过程 1.指定调度节点 1.1强制匹配 1.2强制约束 二、硬策略和软策略 1.键值运算关系 1.硬策略——requiredDuringSchedulingIgnoredDuringExecution 2.软策略——preferredDuringSchedulingIgnoredDuringExecution …

Varjo XR-4功能详解:由凝视驱动的XR自动对焦相机系统

Varjo是XR市场中拥有领先技术的虚拟现实设备供应商&#xff0c;其将可变焦距摄像机直通系统带入到虚拟和混合现实场景中。在本篇文章中&#xff0c;Varjo的技术工程师维尔蒂莫宁详细介绍了这项在Varjo XR-4焦点版中投入应用的技术。 对可变焦距光学系统的需求 目前所有其他XR头…

基于STM32实现智能饮水机控制系统

目录 引言环境准备智能饮水机控制系统基础代码示例&#xff1a;实现智能饮水机控制系统 温度传感器数据读取水泵和加热器控制水位传感器数据读取用户界面与显示应用场景&#xff1a;家庭和办公室的智能饮水管理问题解决方案与优化收尾与总结 1. 引言 本教程将详细介绍如何在S…

自适应感兴趣区域的级联多尺度残差注意力CNN用于自动脑肿瘤分割| 文献速递-深度学习肿瘤自动分割

Title 题目 Cascade multiscale residual attention CNNs with adaptive ROI for automatic brain tumor segmentation 自适应感兴趣区域的级联多尺度残差注意力CNN用于自动脑肿瘤分割 01 文献速递介绍 脑肿瘤是大脑细胞异常和不受控制的增长&#xff0c;被认为是神经系统…

第二证券炒股知识:股票破发后怎么办?

当一只新股的价格跌破其发行价时&#xff0c;往往会受到商场出资者的关注。关于股票破发后怎么办&#xff0c;第二证券下面就为我们具体介绍一下。 股票破发是指股票的商场价格低于其发行价格或最近一次增发价格&#xff0c;股票破发往往是由于多种要素共同作用的结果&#xf…