我已经在这里回答了在 Windows 上,OpenGL 与 DirectX 有何不同?
以下是其中一个答案的完整引用
这个问题几乎不可能回答,因为 OpenGL 本身只是一个前端 API,只要实现符合规范并且结果符合此规范,就可以按照您喜欢的任何方式完成。
问题可能是:OpenGL 驱动程序如何在最低级别工作。现在这又是不可能的,因为驱动程序与某些硬件密切相关,这可能会再次执行开发人员设计的操作。
所以问题应该是:“它在 OpenGL 和图形系统的幕后平均看起来如何?”。让我们从下往上看:
在最低级别有一些图形设备。现在这些 GPU 提供了一组寄存器来控制它们的操作(这些寄存器完全取决于设备)有一些用于着色器的程序内存、用于输入数据(顶点、纹理等)的大容量内存以及用于其余部分的 I/O 通道它接收/发送数据和命令流的系统。
图形驱动程序跟踪 GPU 状态和使用 GPU 的所有资源应用程序。它还负责转换或任何其他处理应用程序发送的数据(将纹理转换为 GPU 支持的像素格式,在 GPU 的机器代码中编译着色器)。此外,它还为应用程序提供了一些抽象的、依赖于驱动程序的接口。
然后是依赖于驱动程序的 OpenGL 客户端库/驱动程序。在 Windows 上,它由代理通过 opengl32.dll 加载,在 Unix 系统上,它位于两个位置:
- X11 GLX 模块和驱动依赖 GLX 驱动
- 和 /usr/lib/libGL.so 可能包含一些依赖于驱动程序的东西,用于直接渲染
在 MacOS X 上,这恰好是“OpenGL 框架”。
正是这部分将 OpenGL 调用转换为对 (2) 中描述的驱动程序部分中的驱动程序特定函数的调用。
最后是实际的 OpenGL API 库,Windows 中的 opengl32.dll 和 Unix 中的 /usr/lib/libGL.so;这主要只是将命令传递给正确的 OpenGL 实现。
实际通信是如何发生的不能一概而论:
在 Unix 中,3<->4 连接可能发生在套接字上(是的,它可能,并且如果你愿意,它确实会通过网络)或通过共享内存。在 Windows 中,接口库和驱动程序客户端都加载到进程地址空间中,因此没有太多的通信,而是简单的函数调用和变量/指针传递。在 MacOS X 中,这类似于 Windows,只是 OpenGL 接口和驱动程序客户端之间没有分离(这就是为什么 MacOS X 跟上新的 OpenGL 版本的速度如此缓慢的原因,它总是需要完整的操作系统升级才能提供新的框架)。
3<->2 之间的通信可以通过 ioctl、读/写,或者通过将一些内存映射到进程地址空间并配置 MMU 以在对该内存进行更改时触发一些驱动程序代码。这在任何操作系统上都非常相似,因为您总是必须跨越内核/用户空间边界:最终您会经历一些系统调用。
系统和 GPU 之间的通信通过外围总线及其定义的访问方法发生,因此 PCI、AGP、PCI-E 等通过端口 I/O、内存映射 I/O、DMA、IRQ 工作。