Qt for Windows - 图形加速

For Qt Quick to work, a graphics driver that supports Direct 3D 11, Direct3D 12, Vulkan 1.0, or OpenGL 2.1 or higher is required. As of Qt 6, the default for Qt Quick on Windows is Direct3D 11. This is different from Qt 5, where the default was OpenGL, either directly, or through ANGLE, an OpenGL to Direct3D translator. ANGLE is no longer shipped with Qt in Qt 6.

要强制使用 Direct3D 的软件光栅化器 (WARP), 设置环境变量 QSG_RHI_PREFER_SOFTWARE_RENDERER to 1 . In some cases Qt Quick will perform such a fallback automatically, in order to allow running Qt applications without additional configuration. This happens when the drivers do not provide a sufficient level of D3D11 functionality, and occurs typically in virtual machines that do not have proper GPU acceleration and passthrough implemented. When in doubt what graphics device is being used, and when troubleshooting or reporting problems to Qt, run the application with the environment variable QSG_INFO=1 set and inspect the debug output. Running the qtdiag tool can also provide useful information since it enumerates all available 3D APIs.

To request using Vulkan, OpenGL, or Direct 3D 12, set the environment variable QSG_RHI_BACKEND to vulkan or opengl or d3d12 ,或使用等效 C++ API in main() . Note that some of these 3D APIs may require the appropriate drivers to be installed.

虽然不是默认对于 Qt Quick ,OpenGL 仍常用于很多 Qt 应用程序中,例如在 QWidget 基的应用程序构建于 QOpenGLWindow or QOpenGLWidget 。下列章节涵盖了 Qt 构建的一些 OpenGL 细节。

动态加载 OpenGL

Qt 支持在运行时选择并加载 OpenGL 这是默认模式,且可以明确请求通过传递 -opengl dynamic 给 configure 脚本。

configure -opengl dynamic
					

这种配置最灵活,因为构建期间未硬编码 OpenGL 实现的依赖 (或假定)。它允许健壮的应用程序部署。当给定环境无法提供适当的 OpenGL 2.0 实现时,它会自动回退到加载替代 opengl32.dll ,默认名称为 opengl32sw.dll 。预构建 Qt 包随附 Mesa llvmpipe 构建,OpenGL 的软件光栅化器实现,使用该名称。

当配置采用 -opengl dynamic ,不管 Qt 还是应用程序构建使用 qmake or CMake 将链接到 opengl32.lib。取而代之,将在运行时选择并加载库。默认情况下,Qt 将确定系统的 opengl32.dll 是否提供 OpenGL 2 功能。若存在,则使用 opengl32.dll,否则试图加载 opengl32sw.dll 。详见下文。

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

  • Qt::AA_UseDesktopOpenGL 相当于设置 QT_OPENGL to desktop .
  • Qt::AA_UseOpenGLES 在 Qt 6 没有效果。
  • Qt::AA_UseSoftwareOpenGL 相当于设置 QT_OPENGL to software .

当明确请求某个配置时,不会进行任何校验在应用程序启动时,也就是说,将不审查系统提供的 opengl32.dll。

动态加载对包含本机 OpenGL 调用的应用程序有显著影响:可能无法链接它们,由于不会将 opengl32.lib 自动指定给链接器。相反,期望应用程序使用 OpenGL 函数凭借 QOpenGLFunctions 类。因此,会移除 OpenGL 库的直接依赖,且运行期间的所有调用会被路由到由 Qt 选择的实现。另外,应用程序可以自由地直接调用 OpenGL 函数,若他们将 opengl32.lib 添加到其 .pro 工程文件: LIBS += opengl32.lib (Visual Studio) 或 LIBS += -lopengl32 (MinGW)。从应用程序角度,结果相当于 -opengl desktop Qt 构建配置。

Qt::AA_UseSoftwareOpenGL 的特殊之处是它会试着采用非标准名称来加载 OpenGL 实现。默认名称为 opengl32sw.dll 。这允许随附仅软件 OpenGL 实现,例如构建 Mesa 采用 llvmpipe ,在此名称下。若有必要,可以覆盖文件名通过设置 QT_OPENGL_DLL 环境变量。

根据图形卡和驱动程序版本,提供 JSON 格式配置文件以指定要使用哪种 OpenGL 实现是可能的。位置的给定通过环境变量 QT_OPENGL_BUGLIST 。相对路径的解析使用 QLibraryInfo::SettingsPath or QStandardPaths::ConfigLocation 。文件利用驱动程序 Bug 列表所使用的格式,在 Chromium 工程 。它由条目的列表组成,各条目指定一组条件和特征关键词的列表。通常,使用设备 ID 和供应商 ID 相匹配的特定图形卡。可以找到它们,在输出的 qtdiag6 or dxdiag 工具。

以下特征关键词与选取 OpenGL 实现相关:

注意: 在 Qt 6,传统 ANGLE 相关关键字 ( disable_angle , disable_d3d11 , disable_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 - 操作系统: win , linux , macosx , android
  • os.version - 内核版本
  • os.release - 指定 Windows 操作系统发行列表: xp , vista , 7 , 8 , 8.1 , 10 .
  • vendor_id - 来自适配器标识符的供应商
  • device_id - PCI 设备 ID 列表。
  • driver_version - 来自适配器标识符的驱动程序版本
  • driver_description - 匹配,当值是来自适配器标识符的驱动程序所描述的子字符串时
  • gl_vendor - 匹配,当值是子字符串对于 GL_VENDOR string

要禁用所有黑名单,设置环境变量 QT_NO_OPENGL_BUGLIST 为任意值。这会跳过读取任何配置文件,且假定未禁用任何内容,不管是驱动程序还是 OS。

注意: 虽然通常不需要, QT_NO_OPENGL_BUGLIST 在某些虚拟环境中可以变得相关,其中存在多个 (可能虚拟的) 图形适配器。若若日志按类别像 qt.qpa.gl 指示由于驱动程序和显示适配器的检测导致错误禁用 OpenGL,那么,推荐设置此环境变量以使应用程序能够正常运行。该环境变量在 Qt 5.15 引入。

直接依赖 opengl32.dll

替代默认 dynamic OpenGL 构建直接依赖 opengl32.dll。此模式是传递命令行选项 -opengl desktop 给 configure 脚本。

configure -opengl desktop
					

注意: 在 Windows,不支持使用 EGL 和 OpenGL ES。在 Qt 6,OpenGL on Windows 始终隐含将 WGL 用作窗口系统接口。

在这种 Qt 构建中,很多 Qt 共享库和 Qt 应用程序也将依赖 opengl32.dll。因此,使用替代库不可能。