DRM的GEM_drm gem-程序员宅基地

技术标签: linux显示相关  DRM  GEM  

GEM(Graphics Execution Manager)主要完成:内存申请释放、指令执行、执行命令时的光圈管理(what?!)。缓存对象的申请主要与linux提供的shmem层相关。设备相关操作如指令执行、pinning、buffer读写、映射、域所有权的转移等,还是归设备驱动的ioctl。

初始化

使用GEM的驱动必须在struct drm_driver->driver_features置DRIVER_GEM位,DRM core将会在执行load操作前自动初始化GEM core,这就意味着会构建一个DRM内存管理器,这个DRM内存管理器为对象的申请提供地址空间池。

在KMS设置上,如果硬件需要的话,驱动在核心GEM初始化后,需要申请并初始化环形缓冲区,这部分一般不由GEM管理,而是需要独立的初始化到自己的DRM MM对象。

创建GEM对象

GEM将创建GEM对象和其后的申请内存操作分成了两个不同的操作。GEM对象由struct drm_gem_object表示。驱动一般需要用私有信息来扩展GEM对象,因此struct drm_gem_object都是嵌入在驱动私有GEM结构体内的。创建一个GEM对象,驱动为自有GEM对象申请内存,并通过drm_gem_object_init(struct drm_device* ,struct drm_gem_object *,size_t )来初始化嵌入在其中的struct drm_gem_object。

GEM使用shmem来申请匿名页内存,drm_gem_object_init将会根据传入的size_t创建一个shmfs,并将这个shmfs file放到struct drm_gem_object的filp区。当图形硬件使用系统内存,这些内存就会作为对象的主存储直接使用,否则就会作为后备内存。驱动负责调用shmem_read_mapping_page_gfp()做实际物理页面的申请,初始化GEM对象时驱动可以决定申请页面,或者延迟到需要内存时再申请(需要内存时是指:用户态访问内存发生缺页中断,或是驱动需要启动DMA用到这段内存)。

匿名页面内存并不是一定需要的,嵌入式设备一般需要物理连续系统内存,驱动可以创建GEM对象儿没有shmfs,并调用drm_gem_private_object_init()初始化此私有GEM对象,不过这样的话,私有GEM对象的存储管理就需要驱动自行完成。

GEM对象的生命周期

所有GEM对象都有GEM core做引用计数,drm_gem_object_get()加数,drm_gem_object_put()减数,执行drm_gem_object_get()调用者必须持有struct drm_device的struct_mutex锁,而为了方便也提供了drm_gem_object_put_unlocked()也可以不持锁操作。当最后一个对GEM对象的引用释放时,GEM core调用struct drm_driver gem_free_object_unlocked,这一操作对于使能了GEM的驱动来说是必须,并且必须释放所有相关资源。driver实现接口void (*gem_free_object)(struct drm_gem_object *obj),负责释放所有GEM对象资源,这其中包括要调用drm_gem_object_release()来释放GEM core创建的资源。

GEM对象命名

GEM对象有本地handle、全局名称和文件描述符,都是32bit数。

对于本地handle:drm_gem_handle_create()创建GEM对象handle,这个函数拿着DRM file的指针和GEM对象,算得一个局部唯一handle,这个handle可以通过drm_gem_handle_delete()来删除,drm_gem_object_lookup()可以由handle找出对应的GEM对象。handle仅是一个对GEM对象的引用,在handle销毁时减去这一引用。

对于全局名称:可以在进程之间传递,不过在DRM API中,全局名称不能直接指到GEM对象,通过ioctl的DRM_IOCTL_GEM_FLINK (转成对象)和DRM_IOCTL_GEM_OPEN(转回全局名称),DRM core做此转换。GEM也支持通过PRIME dma-buf文件描述符的缓存共享,基于GEM的驱动必须使用提供的辅助函数来实现exoprting和importing。共享文件描述符比可以被猜测的全局名称更安全,因此是首选的缓存共享机制。通过GEM全局名称进行缓存共享仅在传统用户态支持。更进一步的说,PRIME由于其基于dma-buf,还允许跨设备缓存共享。

GEM对象映射

因为映射操作费时,GEM更多使用ioctl将内存映射到用户态,通过读写访问缓存;但是当随机访问缓存多的时候,如使用了软渲染,直接访问GEM对象高效。mmap系统调用不能直接映射GEM对象,因为GEM对象没有自己的文件描述符。目前同时存在两种map GEM对象到用户态的办法,一是用驱动自己的ioctl做映射操作,钩子后面挂上do_mmap(),不鼓励,比描述了;另一种方法是对DRM文件描述符使用mmap直接映射GEM对象,虽然GEM对象没有文件描述符,但是通过mmap(void*addr,size_t length,int port,int flags,int fd, off_t offset)中的offset参数,DRM可以找出这个GEM对象,为了能识别这个offset,驱动必须先对这个GEM对象执行了drm_gem_create_mmap_offset(),这样得到的offset值需要先通过驱动指定的方式传给用户态程序,然后就可以通过mmap传下来,找到这个GEM对象。GEM core提供有一个辅助方法drm_gem_mmap()来处理对象映射,这个方法可以直接设置为mmap文件操作的处理函数,它将会由offset查出GEM对象,然后设置VMA操作到struct drm_driver的gem_vm_ops;注意drm_gem_mmap()不映射内存到用户态,需要依赖于驱动提供的缺页处理函数做页面的映射,因此要用drm_gem_mmap(),驱动必须将struct drm_driver的gem_vm_ops填入,也就是填好

struct vm_operations_struct{

    void (*open)(struct vm_area_struct* area);

    void (*close)(struct vm_area_struct* area);

    vm_fault_t (*fault)(struct vm_fault* vamp);

}

其中,open/close需要更新GEM对象的引用计数,驱动可以用drm_gem_vm_open()和drm_gem_vm_close()辅助函数直接作为open/close的处理函数;fault操作的处理函数负责在缺页发生时映射独立页面到用户态,驱动可以根据内存申请方案在缺页发生时申请页面,也可以在GEM对象建立时申请。对于没有MMU的平台,还有其他考虑,但是不予介绍。

内存对齐

当一个对象的后备页面映射到设备或用于指令缓存,这个页面就会被刷到内存并标记为CPU与GPU都会写入,比如:GPU渲染到一个对象,渲染完后CPU访问这个对象,那么这个对象就必须与CPU的内存视图保持一致,这就需要通过调用GPU缓存外刷等操作。这种CPU-GPU内存对齐的管理就由驱动指定的ioctl提供:看看对象当前域,必要的话要做刷新或同步使对象转到想要的域,不过对象可能会忙(比如正在被渲染),这时候就会发生阻塞,等待渲染完成,再做刷新或同步。

指令执行

提供指令执行接口给client可能是GEM最重要的功能,client程序构建指令缓存并提交到GEM,而这个指令缓存会引用到很多已经申请过的内存对象;这时候,GEM小心翼翼的绑定所有的对象到GTT,执行这个指令缓存,然后在client们之间提供必要的同步。这个过程中一般还会有扔掉一些对象,以及再绑进一些对象(开销很大),然后还要提供重映射将GTT的偏移量对client们隐藏起来。client们也要注意提交的指令缓存所引用的内存对象不要超过GTT的要求,如果超过则会被GEM拒绝,然后就不会有渲染操作执行了。一般来说,如果指令缓存中的这段渲染操作中的很多对象都需要申请fence寄存器,那么就要注意不要超过可以提供给client使用的fence寄存器的总数。这些资源的管理都要从libdrm重的客户端中抽象出来。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ytfy339784578/article/details/104557569

智能推荐

oracle 12c 集群安装后的检查_12c查看crs状态-程序员宅基地

文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态

解决jupyter notebook无法找到虚拟环境的问题_jupyter没有pytorch环境-程序员宅基地

文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境

国内安装scoop的保姆教程_scoop-cn-程序员宅基地

文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn

Element ui colorpicker在Vue中的使用_vue el-color-picker-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker

迅为iTOP-4412精英版之烧写内核移植后的镜像_exynos 4412 刷机-程序员宅基地

文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机

Linux系统配置jdk_linux配置jdk-程序员宅基地

文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk

随便推点

matlab(4):特殊符号的输入_matlab微米怎么输入-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入

C语言程序设计-文件(打开与关闭、顺序、二进制读写)-程序员宅基地

文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。‍ Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。

Touchdesigner自学笔记之三_touchdesigner怎么让一个模型跟着鼠标移动-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动

【附源码】基于java的校园停车场管理系统的设计与实现61m0e9计算机毕设SSM_基于java技术的停车场管理系统实现与设计-程序员宅基地

文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计

Android系统播放器MediaPlayer源码分析_android多媒体播放源码分析 时序图-程序员宅基地

文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;amp;gt;Jni-&amp;amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图

java 数据结构与算法 ——快速排序法-程序员宅基地

文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法