DRM系列七:Drm之CREATE_DUMB

本系列文章基于linux 5.15

DRM驱动的显存由GEM(Graphics execution management)管理。

一、创建流程

创建buf时,user层提供需要buf的width,height以及bpp(bite per pixel),然后调用drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create)接口进入kernel层,kernel层根据这些信息分配出handle和pitch提供给user层使用。
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/0e278bc5737d4e9fb7774dd7163f4646.png

二、kernel层调用流程

kernel层会调用drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create),然后通过DRM_IOCTL_DEF 宏进行映射到drm_mode_create_dumb_ioctl中。

/*DRM_IOCTL_DEF 宏用于简化 DRM 子系统中 IOCTL 命令的定义和映射。
它通过将 IOCTL 命令、处理函数和标志打包到一个 drm_ioctl_desc 结构体中,
方便内核开发者管理和扩展 DRM 的 IOCTL 接口。*/
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, 0),
int drm_mode_create_dumb_ioctl(struct drm_device *dev,void *data, struct drm_file *file_priv)
{return drm_mode_create_dumb(dev, data, file_priv);
}

2.drm_mode_create_dumb

drm_mode_create_dumb首先user层传来的参数width/height/bpp是否符合条件,然后调用dev->driver->dumb_create这一回调获取handle和pitch。

int drm_mode_create_dumb(struct drm_device *dev,struct drm_mode_create_dumb *args,struct drm_file *file_priv)
{u32 cpp, stride, size;
/*判别user层提供的width/height/bpp是否符合条件*/if (!dev->driver->dumb_create)return -ENOSYS;if (!args->width || !args->height || !args->bpp)return -EINVAL;/* overflow checks for 32bit size calculations */if (args->bpp > U32_MAX - 8)return -EINVAL;cpp = DIV_ROUND_UP(args->bpp, 8);if (cpp > U32_MAX / args->width)return -EINVAL;stride = cpp * args->width;if (args->height > U32_MAX / stride)return -EINVAL;/* test for wrap-around */size = args->height * stride;if (PAGE_ALIGN(size) == 0)return -EINVAL;args->handle = 0;args->pitch = 0;args->size = 0;return dev->driver->dumb_create(file_priv, dev, args);
}

dumb_create这一回调是各大厂商自己实现的,以msm厂商为例,会调用msm_gem_dumb_create这一函数.

static const struct drm_driver msm_driver = {.driver_features    = DRIVER_GEM |DRIVER_RENDER |DRIVER_ATOMIC |DRIVER_MODESET |DRIVER_SYNCOBJ,.open               = msm_open,.postclose           = msm_postclose,.lastclose          = drm_fb_helper_lastclose,.dumb_create        = msm_gem_dumb_create,.dumb_map_offset    = msm_gem_dumb_map_offset,.prime_handle_to_fd = drm_gem_prime_handle_to_fd,.prime_fd_to_handle = drm_gem_prime_fd_to_handle,.gem_prime_import_sg_table = msm_gem_prime_import_sg_table,.gem_prime_mmap     = drm_gem_prime_mmap,
#ifdef CONFIG_DEBUG_FS.debugfs_init       = msm_debugfs_init,
#endif.ioctls             = msm_ioctls,.num_ioctls         = ARRAY_SIZE(msm_ioctls),.fops               = &fops,.name               = "msm",.desc               = "MSM Snapdragon DRM",.date               = "20130625",.major              = MSM_VERSION_MAJOR,.minor              = MSM_VERSION_MINOR,.patchlevel         = MSM_VERSION_PATCHLEVEL,
};
int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev,struct drm_mode_create_dumb *args)
{args->pitch = align_pitch(args->width, args->bpp);args->size  = PAGE_ALIGN(args->pitch * args->height);return msm_gem_new_handle(dev, file, args->size,MSM_BO_SCANOUT | MSM_BO_WC, &args->handle, "dumb");
}int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,uint32_t size, uint32_t flags, uint32_t *handle,char *name)
{struct drm_gem_object *obj;int ret;/*创建一个新的 GEM 对象*/obj = msm_gem_new(dev, size, flags);if (IS_ERR(obj))return PTR_ERR(obj);if (name)msm_gem_object_set_name(obj, "%s", name);/*为 GEM 对象创建句柄*/ret = drm_gem_handle_create(file, obj, handle);/* 减少对象的引用计数(句柄已经持有引用) */drm_gem_object_put(obj);return ret;
}

2.1drm_gem_handle_create

drm_gem_handle_create主要使用idr_alloc将drm_gem_object对象添加到file_priv->object_idr,并返回handle。

idr_alloc:是为了使用一个id与一个obj绑定。这样就可以通过id找到对应obj。这里将handle与分配的gem_object进行绑定,后面通过handle可以找到gem_object。

int drm_gem_handle_create(struct drm_file *file_priv,struct drm_gem_object *obj,u32 *handlep)
{mutex_lock(&obj->dev->object_name_lock);return drm_gem_handle_create_tail(file_priv, obj, handlep);
}int drm_gem_handle_create_tail(struct drm_file *file_priv,struct drm_gem_object *obj,u32 *handlep)
{struct drm_device *dev = obj->dev;u32 handle;int ret;WARN_ON(!mutex_is_locked(&dev->object_name_lock));if (obj->handle_count++ == 0)drm_gem_object_get(obj);/** Get the user-visible handle using idr.  Preload and perform* allocation under our spinlock.*/idr_preload(GFP_KERNEL);spin_lock(&file_priv->table_lock);ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);spin_unlock(&file_priv->table_lock);idr_preload_end();mutex_unlock(&dev->object_name_lock);if (ret < 0)goto err_unref;handle = ret;ret = drm_vma_node_allow(&obj->vma_node, file_priv);if (ret)goto err_remove;if (obj->funcs->open) {ret = obj->funcs->open(obj, file_priv);if (ret)goto err_revoke;}*handlep = handle;return 0;err_revoke:drm_vma_node_revoke(&obj->vma_node, file_priv);
err_remove:spin_lock(&file_priv->table_lock);idr_remove(&file_priv->object_idr, handle);spin_unlock(&file_priv->table_lock);
err_unref:drm_gem_object_handle_put_unlocked(obj);return ret;
}

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

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

相关文章

我们信仰AI?从神明到人工智能——信任的进化

信任的进化&#xff1a; 信任是我们最宝贵的资产。而现在&#xff0c;它正像黑色星期五促销的廉价平板电视一样&#xff0c;被一点点拆解。在过去&#xff0c;世界很简单&#xff1a;人们相信晚间新闻、那些满是灰尘书籍的教授&#xff0c;或者手持病历、眉头紧锁的医生。而如…

数据分析系列--[11] RapidMiner,K-Means聚类分析(含数据集)

一、数据集 二、导入数据 三、K-Means聚类 数据说明:提供一组数据,含体重、胆固醇、性别。 分析目标:找到这组数据中需要治疗的群体供后续使用。 一、数据集 点击下载数据集 二、导入数据 三、K-Means聚类 Ending, congratulations, youre done.

1-刷力扣问题记录

25.1.19 1.size()和.length()有什么区别 2.result.push_back({nums[i], nums[left], nums[right]});为什么用大括号&#xff1f; 使用大括号 {} 是 C11 引入的 初始化列表 语法&#xff0c;它允许我们在构造或初始化对象时直接传入一组值。大括号的使用在许多情况下都能让代码…

神经网络参数量和运算量的计算- 基于deepspeed库和thop库函数

引言 最近需要对神经网络的参数量和运算量进行统计。找到一个基于deepspeed库函数计算参数量和运算量的例子。而我之前一直用thop库函数来计算。 看到有一篇勘误博文写道使用thops库得到的运算量是MACs (Multiply ACcumulate operations&#xff0c;乘加累积操作次数&#xf…

读书笔记--分布式架构的异步化和缓存技术原理及应用场景

本篇是在上一篇的基础上&#xff0c;主要对分布式应用架构下的异步化机制和缓存技术进行学习&#xff0c;主要记录和思考如下&#xff0c;供大家学习参考。大家知道原来传统的单一WAR应用中&#xff0c;由于所有数据都在同一个数据库中&#xff0c;因此事务问题一般借助数据库事…

无用知识研究:std::initializer_list的秘密

先说结论&#xff0c;用std::initializer_list初始化vector&#xff0c;内部逻辑是先生成了一个临时数组&#xff0c;进行了拷贝构造&#xff0c;然后用这个数组的起终指针初始化initializer_list。然后再用initializer_list对vector进行初始化&#xff0c;这个动作又触发了拷贝…

Jupyterlab和notebook修改文件的默认存放路径的方法

文章目录 1.缘由2.操作流程2.1找到默认的路径2.2创建配置文件2.3修改配置文件内容2.4注意事项 1.缘由 我自己使用jupyterlab的时候&#xff0c;打开是在这个浏览器上面打开的&#xff0c;但是这个打开的文件路径显示的是C盘上面路径&#xff0c;所以这个就很麻烦&#xff0c;因…

HarmonyOS:ArkWeb进程

ArkWeb是多进程模型,分为应用进程、Web渲染进程、Web GPU进程、Web孵化进程和Foundation进程。 说明 Web内核没有明确的内存大小申请约束,理论上可以无限大,直到被资源管理释放。 ArkWeb进程模型图 应用进程中Web相关线程(应用唯一) 应用进程为主进程。包含网络线程、Vi…

基于Spring Security 6的OAuth2 系列之九 - 授权服务器--token的获取

之所以想写这一系列&#xff0c;是因为之前工作过程中使用Spring Security OAuth2搭建了网关和授权服务器&#xff0c;但当时基于spring-boot 2.3.x&#xff0c;其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0&#xff0c;结果一看Spring Security也升级…

音标-- 02-- 重音 音节 变音

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 国际音标1.重音2.音节3.变音 国际音标 1.重音 2.音节 3.变音

Adaptive LLM Transformer²

看到了一个不错的论文https://arxiv.org/pdf/2501.06252 TRANSFORMER-SQUARED: SELF-ADAPTIVE LLMS 挺有意思的&#xff0c;是一家日本AI公司SakanaAI的论文&#xff08;我以前写过他们的不训练提升模型的能力的文章&#xff0c;感兴趣可以去翻&#xff09;它家有Lion Jones坐镇…

优化代码性能:利用CPU缓存原理

在计算机的世界里&#xff0c;有一场如同龟兔赛跑般的速度较量&#xff0c;主角便是 CPU 和内存 。龟兔赛跑的故事大家都耳熟能详&#xff0c;兔子速度飞快&#xff0c;乌龟则慢吞吞的。在计算机中&#xff0c;CPU 就如同那敏捷的兔子&#xff0c;拥有超高的运算速度&#xff0…

linux 函数 sem_init () 信号量、sem_destroy()

&#xff08;1&#xff09; &#xff08;2&#xff09; 代码举例&#xff1a; #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #include <unistd.h>sem_t semaphore;void* thread_function(void* arg) …

分库分表技术方案选型

一、MyCat 官方网站&#xff0c;技术文档 MyCat是一款由阿里Cobar演变而来的用于支持数据库读写分离、分片的数据库中间件。它基于MySQL协议&#xff0c;实现了MySQL的协议和能力&#xff0c;并作为代理层位于应用和数据库之间&#xff0c;可以隐藏底层数据库的复杂性。 原理…

【智力测试——二分、前缀和、乘法逆元、组合计数】

题目 代码 #include <bits/stdc.h> using namespace std; using ll long long; const int mod 1e9 7; const int N 1e5 10; int r[N], c[N], f[2 * N]; int nr[N], nc[N], nn, nm; int cntr[N], cntc[N]; int n, m, t;void init(int n) {f[0] f[1] 1;for (int i …

IBM DB2常用命令(windows版),包含建库、建表、增删改查等命令

安装IBM DB2可以参考我上篇博客&#xff1a;IBM Db2 & IBM Db2 Data Management Console(可视化管理工具)的下载与安装&#xff08;简洁版&#xff09;-CSDN博客 使用管理员权限打开cmd窗口 G: cd G:\IBM\SQLLIB\BIN db2cmd首先&#xff0c;在服务端需要配置好服务名、监…

Flutter Scaffold 页面结构

Material是一套设计风格&#xff0c;提供了大量的小部件&#xff0c;这里用Material风格搭建一个常见的应用页面结构。 创建Material应用 import package:flutter/material.dart;class App extends StatelessWidget {overrideWidget build(BuildContext context) {return Mat…

【C++】string类(上):string类的常用接口介绍

文章目录 前言一、C中设计string类的意义二、string类的常用接口说明1. string类对象的常见构造2. string类对象的容量操作2.1 size、capacity 和 empty的使用2.2 clear的使用2.3 reserve的使用2.4 resize的使用 3. string类对象的访问及遍历操作3.1 下标[ ] 和 at3.2 迭代器it…

一文讲解Java中的ArrayList和LinkedList

ArrayList和LinkedList有什么区别&#xff1f; ArrayList 是基于数组实现的&#xff0c;LinkedList 是基于链表实现的。 二者用途有什么不同&#xff1f; 多数情况下&#xff0c;ArrayList更利于查找&#xff0c;LinkedList更利于增删 由于 ArrayList 是基于数组实现的&#…

STM32 DMA+AD多通道

接线图 代码配置 ADC单次扫描DMA单次转运模式 uint16_t AD_Value[4]; //DMAAD多通道 void DMA_Config(void) {//定义结构体变量 GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO结构体变量 ADC_InitTypeDef ADC_InitStructure; //定义ADC结构体变量 DMA_InitTypeDef DMA_In…