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;它允许我们在构造或初始化对象时直接传入一组值。大括号的使用在许多情况下都能让代码…

信息学奥赛一本通 2113:【24CSPJ普及组】小木棍(sticks) | 洛谷 P11229 [CSP-J 2024] 小木棍

【题目链接】 ybt 2113&#xff1a;【24CSPJ普及组】小木棍&#xff08;sticks&#xff09; 洛谷 P11229 [CSP-J 2024] 小木棍 【题目考点】 1. 思维题&#xff0c;找规律 【解题思路】 解法1&#xff1a;找规律 该题为&#xff1a;求n根木棍组成的无前导0的所有可能的数…

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

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

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

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

postgresql的用户、数据库和表

在 PostgreSQL 中&#xff0c;用户、数据库和表是关系型数据库系统的基本组成部分。理解这些概念对数据库管理和操作至关重要。下面是对这些概念的详细解释&#xff1a; 1. 用户&#xff08;User&#xff09; 在 PostgreSQL 中&#xff0c;用户&#xff08;也称为 角色&#…

360大数据面试题及参考答案

数据清理有哪些方法? 数据清理是指发现并纠正数据文件中可识别的错误,包括检查数据一致性,处理无效值和缺失值等。常见的数据清理方法有以下几种: 去重处理:数据中可能存在重复的记录,这不仅会占用存储空间,还可能影响分析结果。通过对比每条记录的关键属性,若所有关键…

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

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

代码随想录day27

669. /** lc appleetcode.cn id669 langcpp** [669] 修剪二叉搜索树*/// lc codestart /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}…

基于JMX实现消息队列监控

引言 实时监控中间件保障集群的可用性是极其重要的&#xff0c;本篇文章以JAVA语音基于JMX来实现对Kafka消息队列的监控 实现 添加依赖 在 pom.xml 中添加以下依赖&#xff1a; <dependencies><!-- Kafka 客户端依赖 --><dependency><groupId>org…

.Net Core笔记知识点(跨域、缓存)

设置前端跨域配置示例&#xff1a; builder.Services.AddCors(option > {option.AddDefaultPolicy(policy > {policy.WithOrigins(originUrls).AllowAnyMethod().AllowAnyHeader().AllowCredentials();});});var app builder.Build();app.UseCors(); 【客户端缓存】接…

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.变音

验证回文串 II - 题解与分析

680. 验证回文串 II - 题解与分析 题目描述 给定一个字符串 s&#xff0c;最多可以从中删除一个字符。请判断 s 是否能通过删除一个字符后变成回文字符串。如果能&#xff0c;则返回 true&#xff1b;否则&#xff0c;返回 false。 示例 1: 输入&#xff1a;s "aba&q…

连续预测、

一、连续预测 调用模型遍历需要预测文件夹中的图片&#xff1a; image_ids open(‘VOCdevkit/VOC2007/ImageSets/Main/test.txt’).read().strip().split() for image_id in tqdm(image_ids): # 遍历测试图像 image_path “./VOCdevkit/VOC2007/JPEGImages/” image_id …

蓝桥备赛指南(6)

这篇文章非常简单&#xff01;重点只有两个&#xff0c;而且都和set非常相似。 se集合 set简介 首先&#xff0c;set集合是一种容器&#xff0c;用于存储一组唯一的元素&#xff0c;并按照一定的排序规则进行排序&#xff0c;set中的元素是按照升序排序的&#xff0c;默认情…

搜索插入位置(35)

35. 搜索插入位置 - 力扣&#xff08;LeetCode&#xff09; 相关算法&#xff1a;二分查找最左侧和最右侧target的index-CSDN博客 class Solution { public:int searchInsert(vector<int>& nums, int target) {int left 0;int right nums.size() - 1;int ans nu…