Qt for Windows - 图形加速

为了让 Qt Quick 工作,需要一个支持 Direct3D 11、Direct3D 12、Vulkan 1.0 或更高版本的图形驱动程序。截至 Qt 6,Windows 上 Qt Quick 的默认设置是 Direct3D 11。这不同于 Qt 5,其中默认是 OpenGL,无论是直接还是通过 ANGLE(OpenGL 到 Direct3D 翻译器)实现的。ANGLE 在 Qt 6 中不再随产品提供。

要强制使用 Direct3D 的软件光栅化器(WARP),请将环境变量 QSG_RHI_PREFER_SOFTWARE_RENDERER 设置为 1。在某些情况下,Qt Quick 将自动执行此回退,以便在无需额外配置的情况下运行 Qt 应用程序。当驱动程序未提供足够的 D3D11 功能时会发生这种情况,通常在缺乏适当 GPU 加速和透传的虚拟机中发生。当不确定正在使用哪种图形设备,或者解决问题和向 Qt 报告问题时,请将环境变量 QSG_INFO=1 设置在运行应用程序中,并检查调试输出。运行 qtdiag 工具也可以提供有用的信息,因为它列出了所有可用的 3D API。

要请求使用 Vulkan、OpenGL 或 Direct3D 12,请将环境变量 QSG_RHI_BACKEND 设置为 vulkanopengld3d12,或者使用 main() 中的等效 C++ API。请注意,这些 3D API 中的一些可能需要安装相应的驱动程序。

虽然并不是 Qt Quick 的默认设置,但 OpenGL 仍在许多 Qt 应用程序中被广泛使用,例如在基于 QWidget 的应用程序(如构建在 QOpenGLWindowQOpenGLWidget 上)中使用。以下部分涵盖了一些 Qt 构建中 OpenGL 的特定内容。

动态加载 OpenGL

Qt 支持在运行时选择和加载 OpenGL 实现。此模式是默认的,可以通过将 -opengl dynamic 传递到配置脚本中来明确请求。

configure -opengl dynamic

此配置是最灵活的,因为在构建时没有关于 OpenGL 实现的隐式依赖项或假设。它允许强大的应用程序部署。当给定环境无法提供适当的 OpenGL 2.0 实现时,它将自动回退以加载 opengl32.dll 的替代方案,其默认名称为 opengl32sw.dll。预构建的 Qt 软件包在该名称下提供 Mesa llvmpipe 的构建,这是一个 OpenGL 的软件光栅化器实现。

当使用-opengl dynamic配置时,Qt以及使用qmakeCMake构建的应用都不会链接到opengl32.lib。相反,库在运行时选择和加载。默认情况下,Qt将确定系统的opengl32.dll是否提供OpenGL 2函数。如果存在,使用opengl32.dll,否则尝试加载opengl32sw.dll。下面有详细说明。

通过QT_OPENGL环境变量和以下应用程序属性可以配置加载机制:

  • Qt::AA_UseDesktopOpenGL 等同于将QT_OPENGL设置为desktop
  • Qt::AA_UseOpenGLES 在Qt 6中无效果。
  • Qt::AA_UseSoftwareOpenGL 等同于将QT_OPENGL设置为software

当明确请求某种配置时,应用程序启动时不进行检查,也就是说,不会检查系统提供的opengl32.dll。

动态加载对包含原生OpenGL调用的应用程序影响很大:它们可能会因为链接器没有自动指定opengl32.lib而链接失败。相反,应用程序应通过QOpenGLFunctions类使用OpenGL函数。这样就消除了对OpenGL库的直接依赖,并且在运行时会将所有调用路由到Qt选择的实现。或者,如果应用程序将opengl32.lib添加到它们的.pro项目文件中:LIBS += opengl32.lib(Visual Studio)或LIBS += -lopengl32(MinGW),则可以自由地直接调用OpenGL函数。从应用程序的角度来看,结果是等效于Qt的-opengl desktop构建配置。

Qt::AA_UseSoftwareOpenGL是特殊的,因为它会尝试加载一个具有非标准名称的OpenGL实现。默认名称是opengl32sw.dll。这允许以该名称提供仅软件的OpenGL实现,例如Mesa with llvmpipe的构建。如果需要,可以通过设置QT_OPENGL_DLL环境变量来覆盖文件名。

可以提供一种JSON格式的配置文件,指定根据显卡和驱动程序版本使用哪个OpenGL实现。位置由环境变量QT_OPENGL_BUGLIST给出。相对路径使用QLibraryInfo::SettingsPathQStandardPaths::ConfigLocation解析。该文件使用Chromium项目中使用的驱动程序错误列表的格式。它由一组匹配条件列表和功能关键词列表组成。通常,设备ID和厂商ID用于匹配特定的显卡。它们可以在qtdiag6dxdiag工具的输出中找到。

以下功能关键词与选择OpenGL实现有关

注意:在Qt 6中,接受与遗留ANGLE相关的关键词(disable_angledisable_d3d11disable_d3d9),但不起作用。

  • disable_desktopgl - 禁用OpenGL。这确保Qt不尝试使用常规OpenGL(opengl32.dll),并立即启动ANGLE。这有助于防止不稳定的OpenGL驱动程序崩溃应用程序。
  • disable_rotation - 强制应用程序始终以横向模式运行。当使用软件OpenGL实现时,没有效果。这是为有旋转问题的驱动程序设计的。
  • disable_program_cache - 禁止在磁盘上存储着色器程序二进制文件。

一个示例文件如下:

{
"entries": [
{
  "id": 1,
  "description": "Disable D3D11 on older nVidia drivers",
  "os": {
    "type": "win"
  },
  "vendor_id": "0x10de",
  "device_id": ["0x0DE9"],
  "driver_version": {
    "op": "<=",
    "value": "8.17.12.6973"
  },
  "features": [
    "disable_d3d11"
  ]
},
...

如果没有指定QT_OPENGL_BUGLIST,则将使用内置列表。这通常包括一些较老、功能较弱的显卡,其中设置了disable_desktopgl,以防止Qt使用它们的桌面OpenGL实现,而是立即尝试加载基于软件的替代库。

在实际应用中,最常见组合预期如下

  • disable_desktopgl - 如果系统提供OpenGL 2.0或更高版本,但驱动程序已知不稳定且易崩溃。
  • disable_desktopgl,disable_angle - 当不希望使用加速路径时。这确保了Qt尝试的只有软件光栅化器(opengl32sw.dll)。在虚拟机以及部署在广泛旧系统上的应用程序中可能很有用。

用于匹配特定卡或驱动程序的支持键如下。请注意,其中一些是特定于Qt的。

  • os.type - 操作系统:winlinuxmacosxandroid
  • os.version - 内核版本
  • os.release - 指定Windows上的操作系统版本列表:xpvista788.110
  • vendor_id - 从适配器标识符中的供应商
  • device_id - PCI设备ID列表。
  • driver_version - 从适配器标识符中获取的驱动程序版本
  • driver_description - 当值为适配器标识符中驱动程序描述的子串时匹配
  • gl_vendor - 当值为GL_VENDOR字符串的子串时匹配

要将所有黑名单禁用,请将环境变量QT_NO_OPENGL_BUGLIST设置为任何值。这将跳过读取任何配置文件,而是假设禁用所有内容,无论驱动程序或操作系统如何。

注意:虽然通常不需要,但在某些虚拟环境中,特别是存在多个、可能虚拟的图形适配器时,QT_NO_OPENGL_BUGLIST可能会变得相关。如果来自如qt.qpa.gl类别的日志表明驱动程序和显示适配器的检测导致禁用OpenGL不正确,那么建议设置此环境变量以使应用程序能够正常运行。此环境变量是在Qt 5.15中引入的。

对opengl32.dll的直接依赖关系

默认动态OpenGL构建的替代方法是直接依赖opengl32.dll。对于此模式,将命令行选项-opengl desktop传递给configure脚本。

configure -opengl desktop

注意:在Windows上不支持EGL和OpenGL ES。在Qt 6中,Windows上的OpenGL始终意味着使用WGL作为窗口系统接口。

在such Qt构建中,许多Qt共享库和Qt应用程序都将依赖opengl32.dll,因此无法使用其他库。

© 2024 Qt公司有限。此处包含的文档贡献是各自拥有者的版权。本处提供的文档是根据由自由软件基金会发布的GNU自由文档许可证版本1.3的条款许可的。Qt及相应的商标是Qt公司(芬兰)以及其他国家的商标。所有其他商标均为各自拥有者的财产。