如何实现一个OpenGL库?

一直很好奇OpenGL是如何实现,如何与显卡硬件交互的,下边这个知乎上的问答基本上回答了这个疑问,总结起来如下:

(1)OpenGL是一个规范,规定了一系列特定接口

(2)接口实现,可以通过操作cpu实现(软实现),也可以通过操作GPU实现

(3)操作GPU的实现方式一般都是各GPU厂商实现,且非公开的

(4)Opengl的开源实现mesa

下边是知乎上讨论:

我是说,在硬件基础上(比如NV的某款显卡)实现某个版本的OpenGL?大致流程是什么?需要身条件?

关注者

136

被浏览

34,716

关注问题​写回答

​邀请回答

​好问题 8

​1 条评论

​分享

11 个回答

默认排序

知乎用户

游戏开发等 2 个话题下的优秀答主

120 人赞同了该回答

这个事情其实并没有那么酷,也没有那么难,主要都是脏活累活。

OpenGL本身其实只是一套接口标准,定义了一个暴露给上层应用的接口而已。这种定义并非是唯一的,OpenGL本身的设计也谈不上什么十分优雅,现在竞品也一大堆,如DX、Metal、还有亲戚Vulkan。

实现一个OpenGL库的关键其实并不是在OpenGL,无非是将某个GPU的硬件接口包装成OpenGL接口,这个过程当然需要有OpenGL相关知识(但是基本上就是查相关标准),更多是需要关于某款型号GPU硬件相关的知识(也基本就是查芯片的参考手册、datasheet),都是一些脏活累活而已。

这个过程一般来说,芯片设计公司在实际流片之前,就会用软件模拟的方法搭建一个虚拟的GPU。这个GPU很可能是一个庞大的机房,然后画个三角形要好几小时甚至几十个小时这种。跑的是类似VHDL等这种硬件设计语言。

开发者就首先在这个上面进行原理验证。后面实际的片子出来了,再在实际的片子上验证,修bug,不断迭代这样。有的时候甚至要看示波器验证代码,这可能是这个工作比较有意思的地方。当然对于不喜欢的那就是恶梦。

现代的GPU驱动其实也分好几层。首先是最为底层的驱动完成一些GPU自身的启动啊、模块自检啊、初始设置啊、固件更新啊、安全相关检测啊什么的。也可以看作是GPU当中的一个迷你版操作系统,用来管理GPU当中各个子模块的。

然后才是面向应用的驱动,提供一些关于管线配置、数据传输、调试等等的功能。

再上面才是诸如OpenGL、DX、CUDA等等的驱动。

越高层,越抽象,对于特定硬件依赖少。所以大部分时候也就是拿着之前的改一改而已。(当然别以为谁都知道应该改哪里,怎么改)

通常这些模块都是由不同的人负责的。但是一般情况下都是GPU厂家里面的人,属于GPU产品开发的一部分。

少部分产品,如定制化GPU产品,高层驱动可能会开放给客户自己去写。但是底层依然是GPU厂家的秘密。

总之个人是觉得这个东西其实对于大多数人来说没啥好研究的。除非是想要自己研发GPU的,或者是想要和两家进行深度定制化开发的,这些极少数的情形。

当然真正做这个事情的全球可能加起来也不超过一百人,你说是不是稀有人才倒是也是稀有人才。但是并不是什么关键岗位,毕竟其实就那么点儿东西,况且说到底硬件本身的设计才是核心。

当然无论从事何种领域,能够打通上下游,有比较广泛的知识和认识,这是很有价值的。

编辑于 2021-09-29 12:20

​赞同 120​​6 条评论

​分享

​收藏​喜欢收起​

龙泉寺扫地僧

首席浏览器架构吹牛师,全球最小chromium内核--miniblink作者

74 人赞同了该回答

chromium里有个库swiftshader,就是完全用纯软件算法绘制并实现了opengl。谷歌是从一个个人开发者手里买的代码并开源出去好像。目前chrome在一些不适合gpu加速的机器上(比如有的机器显卡太垃圾,甚至被谷歌列为黑名单显卡)就是用这个库实现的webgl。这个库挺牛逼的,可以学习学习

发布于 2021-09-29 12:06

​赞同 74​​4 条评论

​分享

​收藏​喜欢

XZiar

中央处理器 (CPU)话题下的优秀答主

33 人赞同了该回答

主要是个体力活,毕竟这么多年下来的API外加一堆扩展相互影响,但前提要求是对OpenGL API有较深的了解,还得知道和底层硬件的沟通方式(大多数厂商都是不公开驱动细节的)。

最完善的参考资料就是mesa了吧,linux下统一的开源图形库。提供比较通用的各类API的实现, 背后则靠DRI驱动(正在弃用)或Gallium3D驱动来与硬件做衔接。(OGL实现主要在src/mesa/main下)

Mesa / mesa​gitlab.freedesktop.org/mesa/mesa正在上传…重新上传取消

硬件驱动部分可以是AMD/Intel这样主动做的开源驱动,对于不公开驱动的厂商,也有panfrost/freedreno/nouveau这样的逆向实现。此外驱动也可以是LLVMPipe这样的纯CPU实现,或者Zink/glon12这样基于其他API的分层实现,这种情况下倒是不用担心第三点没有硬件驱动资料的问题了。

Mesamatrix: The OpenGL vs Mesa matrix​mesamatrix.net/正在上传…重新上传取消

不过上面的mesa库,活跃贡献人数也就20来位甚至不到,其中一部分大概还是专注于Gallium3D驱动的。要维护这么完整的OpenGL实现本身就是极大的工作量了,这种吃力不讨好的工作自然也没多少人在全职做……


其实OpenGL库就是从标准API接受命令,根据需求撰写出GPU能接受的指令,然后发给GPU驱动,当成一个虚拟机也可以。正因为是“虚拟机”,所以可以嵌套。

前面的mesa就假象了一个Gallium3D作为虚拟的硬件规范,使得OpenGL的实现部分只用做一次,然后再交由Gallium3D驱动去把各类操作、NIR shader转译到实际的GPU或者虚拟实现上。

甚至于,既然前端有了mesa这样完善的实现,大家也没意愿从头做一个,只要去实现后端就行了,比如Zink还有微软的glon12就是如此。

https://www.collabora.com/news-and-blog/blog/2020/07/09/deep-dive-into-opengl-over-directx-layering/​www.collabora.com/news-and-blog/blog/2020/07/09/deep-dive-into-opengl-over-directx-layering/

Introducing Zink, an OpenGL implementation on top of Vulkan​www.collabora.com/news-and-blog/blog/2018/10/31/introducing-zink-opengl-implementation-vulkan/正在上传…重新上传取消

编辑于 2021-09-29 15:18

​赞同 33​​添加评论

​分享

​收藏​喜欢收起​

正在上传…重新上传取消腾讯云

广告​

不感兴趣知乎广告介绍

腾讯云服务器今日秒杀首年211元,点击了解参与!

"原价:3060元 型号:4核8G 宽带:10M 系统盘:100G SSD盘 现价:211元/年 100%CPU性能,灵活安全"查看详情

知乎用户

13 人赞同了该回答

先答如何实现:

在Windows上你可以考虑实现一个OpenGL ICD:

OpenGL FAQ / 5 Microsoft Windows SpecificsLoading an OpenGL Installable Client Driver (Windows Drivers)

在Linux上,你需要做一个Linux驱动,注册你的设备(虚拟设备,指的是你这个驱动本身),然后暴露一个设备给应用程序。在Linux中设备是通过文件访问的,也就是实际上你暴露的是一个文件路径。然后你需要做一个包装库,这个库导出OpenGL的API,并通过设备(也就是通过open函数访问文件设备)访问你的驱动程序来实现功能。

在其他操作系统中的情况没有调查过。

流程:

用熟OpenGL的功能,比如固定管线,顶点渲染引擎,片段渲染引擎。

在CPU上实现这些功能,这可以保证你对概念理解无误,想法也正确。

把计算中GPU可以加速的部分转移到GPU中进行。

条件:

计算机图形学知识,硬件知识,软件开发、项目管理经验,底层编程能力和经验。如果硬件是自家公司生产的那还好办,如果要做nVidia之类的大厂的驱动而且你还不是它的雇员的话你还需要很强大的逆向工程能力。

编辑于 2013-09-22 13:03

​赞同 13​​12 条评论

​分享

​收藏​喜欢

加百列

I love cunnilingus.

20 人赞同了该回答

基于显卡驱动实现OpenGL这样的api是比较复杂的。尤其是NVIDIA这种驱动不开源,文档也不公布的,想要实现OpenGL需要做大量的逆向工作找到硬件工作细节。

相比较而言,使用内存作为显存,配合CPU的simd指令实现OpenGL倒是一件很容易的事情。渲染好之后将结果输出至帧缓冲区就可以了。相当于软件光栅化。

成熟的项目比如mesa的llvmpipe就是纯软件实现的OpenGL,会根据CPU类型使用不同的simd指令集来加速。原理是把通过llvm把glsl编译成机器码执行。

前些年,AMD在Linux平台上开源了驱动,但是没有同时发布Vulkan运行环境,开源社区就基于开源驱动和公布的文档,开发了一个叫radv的Vulkan实现,配合valve开发的aco编译器,比后来官方的版本amdvlk性能还要好。可见公开文档和硬件细节的重要性。

不过,在Windows平台上可以通过DirectX的api实现OpenGL。已经有了很多用OpenGL或者Vulkan实现的DirectX,比如 dxvk,wine3d,vk3d。还有用Vulkan实现的OpenGL,zink。说明用一种api模拟另一种api在实践中也是可行的。

编辑于 2021-09-25 16:50

​赞同 20​​11 条评论

​分享

​收藏​喜欢

Xinzhao

CPP程序员 GPU架构师,单车爱好者

4 人赞同了该回答

可以参考MIT的MESA项目,不用硬件加速的方式下提供了一个OpenGL实现。

发布于 2015-03-05 08:31

​赞同 4​​添加评论

​分享

​收藏​喜欢

zxx43

两栖动物研究

1 人赞同了该回答

看这个问题就好了 如何开始用 C++ 写一个光栅化渲染器? - 知乎

发布于 2021-10-02 11:44

​赞同 1​​添加评论

​分享

​收藏​喜欢

胜勋

IQ=135

很难

这就相当于,你要开发显卡驱动

比如,要想实现 glDrawArray 函数,就要自己写代码控制显卡核心,在帧缓冲里一行一行填充RGB值,而如何控制显卡核心?这个就只能问显卡厂商了

太难,一般人还是别妄想了

发布于 2021-09-29 09:11

​赞同​​添加评论

​分享

​收藏​喜欢

知乎用户

去看mesa吧 大部分帮你都写了,你只要填硬件描述符就行,很枯燥的

发布于 2021-12-05 07:54

​赞同​​添加评论

​分享

​收藏​喜欢

Guarneri1743

2 人赞同了该回答

The Mesa 3D Graphics Library​www.mesa3d.org

可以了解下,但真的严格按spec实现一遍会头秃的

发布于 2021-09-29 09:33

​赞同 2​​添加评论

​分享

​收藏​喜欢

喝茶的洋

1 人赞同了该回答

请参考我的cpu3d(百度就行),如果能弄明白的话,那么你基本上从实现opengl到封装成引擎,有了非常充分的认识,而且距离你的梦想这一距离非常近了。

发布于 2021-09-29 20:20

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值