显卡中如何处理 Direct3D 和 OpenGL 指令?

Posted

技术标签:

【中文标题】显卡中如何处理 Direct3D 和 OpenGL 指令?【英文标题】:How are Direct3D and OpenGL instructions handled in a graphics card? 【发布时间】:2011-09-15 04:20:19 【问题描述】:

我试图更好地了解 GPU 的工作原理,但我对它们如何处理 Direct3D 或 OpenGL 等高级 API 感到困惑。经常看到显卡宣传它们支持 Direct3D 和 OpenGL 硬件加速。这是否意味着它们直接在硬件中处理 Direct3D 和 OpenGL 指令? 我无法找到明确的证据证明这一点,或者它们被编译为 GPU 可以处理的程序集表示。如果有这样的转变,谁会这样做?软件库(Direct3D/OpenGL)、驱动程序还是 GPU 本身? 在同一行上,图形管道在哪里定义?在 gpu 硬件、驱动程序或软件库中?这特别让我对可编程管道的想法感到困惑。

是否有一个很好的资源可以让我找到有关这些详细信息的信息?

【问题讨论】:

【参考方案1】:

您提出了一个非常广泛而复杂的问题。实际上,您已经提出了几个广泛而复杂的问题。

对任何硬件的操作具有最终控制权的软件称为硬件的“驱动程序”。自然,对于图形硬件,这称为“图形驱动程序”。与所有驱动程序一样,图形驱动程序实际上是操作系统的可安装部分;操作系统允许图形驱动程序完成其工作并与硬件对话。两者携手合作。

实际上有两种 D3D 或 OpenGL(之前称为“API”)调用:与驱动程序通信的调用和不与驱动程序通信的调用。每个实际绘制东西的调用都需要(最终)与驱动程序对话,但设置稍后绘制调用的调用可能只是在本地存储数据。

当您进行绘图调用时,API 会进行一些检查,以确保您作为用户进行了有效的渲染调用。如果是这样,API 有一些关于做什么的选项。事实证明,直接与驾驶员交谈需要很长时间,无论您在开始交谈时发出多少命令。因此,经常发生的情况是 API 存储了您的渲染调用并立即返回。然后,可能在另一个线程中,它可能会查看已存储了多少渲染调用。如果有“足够”,那么它会将它们转发给驱动程序。这称为“编组”。

驱动程序的工作是接收这些已转发的调用并将它们转换为 GPU 将执行的操作。

在同一行,图形管线定义在哪里?在 gpu 硬件、驱动程序或软件库中?

如今这实际上是一个非常棘手的问题,并且每一代硬件都变得越来越棘手。

在过去,图形管道的构建是由 GPU 硬件严格控制的。如今,尽管有一些硬件控制,但事实并非如此。在现代硬件(支持 OpenGL 3.0 或 Direct3D10 或更高版本)上,如果您可以直接访问图形驱动程序,那么理论上可以设计一个使用稍微改变的图形管道版本的 API。因此,API 决定了图形管道的大部分外观。

渲染管道中的每个阶段都将来自宝贵阶段的某些值作为输入,并生成一些值作为输出。如果从输入生成输出的机制涉及执行用户提供的程序(称为“着色器”),则该阶段是“可编程的”。因此(目前)还没有可编程流水线之类的东西;只是固定流水线的可编程阶段。

【讨论】:

非常感谢。我很清楚我的问题有多广泛......对此感到抱歉,但感谢您抽出时间给我这么好的答案。它澄清了很多事情。如果我做对了,API 会验证调用,对它们进行分组,并最终通过发送累积调用的系统调用调用驱动程序。这个到达驱动程序的调用看起来更像是汇编、高级 direct3d/opengl 命令还是两者都不是? 驱动程序只是一个 .dll 或操作系统加载的其他形式的库。它只是普通代码,它像普通代码一样获取函数调用。传递给驱动程序的数据结构是什么样的取决于实现(即使对于同一操作系统上的驱动程序也会发生变化),并且最终与实际上没有编写驱动程序的任何人无关。 对不起,我来晚了,但有一个后续问题:API(OpenGL 或 DirectX)如何知道如何与所有不同的驱动程序通信?有Nvidia驱动,AMD/ATI驱动,每个驱动有多少个版本?应用程序链接到一组版本,例如OpenGL,所以如果我更新我的驱动程序,旧版本的 OpenGL 怎么知道如何与我的驱动程序通信?驱动程序和 OpenGL 之间的协调是如何工作的?【参考方案2】:

没有 D3D 或 OGL 指令之类的东西。 Direct3D 或 OpenGL 将调用图形驱动程序,它们将执行他们需要做的任何事情来实现它。这对于着色器来说并非完全正确,它们在 API (D3D/OGL) 级别确实具有统一的字节码,在这种情况下,API 提供了一个编译器,但就我而言,这些都是知道,在执行之前仍然以依赖于硬件的方式进行转换。当然,Direct3D 和 OpenGL 还包含用户模式组件以提高性能或提供更好的接口——例如,它们会批量调用内核以减少上下文切换。

GPU 制造的现实是微软和 nVidia/ATi 齐心协力,思考他们想要什么以及实现什么是可行的,并提出一个组规范,因为现实是,如果主要硬件和软件供应商没有合作。没有人会购买不支持 DirectX 的 GPU,也不会购买没有 GPU 实现 DirectX 的 Windows。当然,“nobody”是相对的——但这对所有相关人员来说都是一个巨大的损失,当然,如果你有一个只构建到 D3D10 API 的游戏,那么支持 D3D10 的驱动程序是运行游戏的必要条件- 通过增加可以运行的软件范围来有效地增加产品的价值,这是一个卖点。这意味着由硬件供应商或软件供应商定义之间的语义差异实际上是最小的 - 特别是因为 PC 上仅有的两个真正的 3D 渲染 API,OpenGL 和 Direct3D,遵循非常相似的图形管道模型,只要我知道。

但是,对于新的可编程 GPU,您可能会争辩说图形管道实际上并不存在 - 如果您有耐心对其进行编程,DX11 设备可以用于您可以想到的任何图形管道。

最终,GPU 受到强大的驱动程序级抽象的保护。它实现了一个 C 风格的接口,并且该实现中允许或需要的任何东西都可以。之后的一切都是完全由实现定义的。

您可以查看 MSDN 文档以了解编写图形驱动程序。我看过,但手头没有链接,它描述了您必须遵守的接口和其他内容。

【讨论】:

这确实很有意义。看看司机应该如何写作应该可以非常准确地回答我所有的问题。我去看看【参考方案3】:

你已经得到了两个非常好的答案。但也许最好的办法是阅读 AMD/ATI GPU 的实际编程文档:http://developer.amd.com/documentation/guides/pages/default.aspx#open_gpu

很遗憾,NVidia 不会发布他们的。

【讨论】:

以上是关于显卡中如何处理 Direct3D 和 OpenGL 指令?的主要内容,如果未能解决你的问题,请参考以下文章

Rust 中如何处理分布式内存并行性? [关闭]

复制控制函数中如何处理 C++ 数组成员?

SpringBoot.09.SpringBoot中如何处理Filter抛出的异常

Sencha Touch V2 中如何处理方向变化

Pandas中如何处理大数据?

20 个案例教你在 Java 8 中如何处理日期和时间?