QVulkanWindowRenderer Class
QVulkanWindowRenderer 类用于实现QVulkanWindow 应用程序特定的渲染逻辑。更多...
Header: | #include <QVulkanWindowRenderer> |
CMake: | find_package(Qt6 REQUIRED COMPONENTS Gui) target_link_libraries(mytarget PRIVATE Qt6::Gui) |
qmake: | QT += gui |
公共函数
virtual | ~QVulkanWindowRenderer() |
virtual void | initResources() |
virtual void | initSwapChainResources() |
virtual void | logicalDeviceLost() |
virtual void | physicalDeviceLost() |
virtual void | preInitResources() |
virtual void | releaseResources() |
virtual void | releaseSwapChainResources() |
virtual void | startNextFrame() = 0 |
详细说明
应用程序通常会同时子类化QVulkanWindow 和 QVulkanWindowRenderer。前者允许处理输入等事件,后者允许实现 Vulkan 资源管理和命令缓冲区构建,从而构成应用程序的渲染。
除了事件处理,QVulkanWindow 子类还负责提供QVulkanWindow::createRenderer() 的实现。这是窗口和呈现器连接的地方。典型的实现方式是创建一个 QVulkanWindowRenderer 子类的新实例。
成员函数文档
[virtual noexcept]
QVulkanWindowRenderer::~QVulkanWindowRenderer()
虚拟析构函数。
[virtual]
void QVulkanWindowRenderer::initResources()
当需要创建呈现器的图形资源时,就会调用这个虚拟函数。
根据QVulkanWindow::PersistentResources 标志、设备丢失情况等的不同,在QVulkanWindow 的生命周期内,该函数可能会被调用多次。不过,在后续调用之前,总是要先调用releaseResources() 。
device()、graphicQueue() 和 graphicsCommandPool() 等访问器仅保证在调用releaseResources() 之前在该函数内部及之后返回有效值。
默认实现为空。
[virtual]
void QVulkanWindowRenderer::initSwapChainResources()
当可以执行与交换链、帧缓冲区或渲染通路相关的初始化时,就会调用该虚拟函数。交换链和相关资源会重置,然后根据窗口大小调整事件重新创建,因此一对initResources() 和releaseResources() 的调用之间可能会有多次 initSwapChainResources() 和releaseSwapChainResources() 的调用。
只有在调用releaseSwapChainResources() 之前,像QVulkanWindow::swapChainImageSize() 这样的访问器才能保证在该函数内部及之后返回有效值。
由于每次调整大小时都会调用该函数,因此这里也是进行大小相关计算(例如投影矩阵)的地方。
默认实现为空。
[virtual]
void QVulkanWindowRenderer::logicalDeviceLost()
当逻辑设备 (VkDevice) 丢失时,即某些操作失败时(VK_ERROR_DEVICE_LOST
),将调用此虚函数。
默认实现为空。
QVulkanWindow 会自动释放所有资源(必要时调用releaseSwapChainResources() 和releaseResources() ),并尝试重新初始化,获取一个新设备。如果物理设备也丢失了,则重新初始化尝试可能会导致physicalDeviceLost()。
另请参阅 physicalDeviceLost()。
[virtual]
void QVulkanWindowRenderer::physicalDeviceLost()
当物理设备丢失,即逻辑设备创建失败,VK_ERROR_DEVICE_LOST
时,将调用该虚拟函数。
默认实现为空。
通常无需在此函数中执行任何特殊操作,因为QVulkanWindow 会在一定时间后自动重试初始化。
另请参阅 logicalDeviceLost()。
[virtual]
void QVulkanWindowRenderer::preInitResources()
在图形初始化(最终调用initResources() )即将开始之前,会调用这个虚拟函数。
通常情况下,无需重新实现此函数。但是,在某些情况下,需要根据物理设备和曲面做出决定。这些决定通常无法在QVulkanWindow 可见之前执行,因为在此阶段无法检索 Vulkan 表面。
相反,应用程序可以重新实现该功能。在这里,QVulkanWindow::physicalDevice() 和QVulkanInstance::surfaceForWindow() 都是有效的,但还没有进行进一步的逻辑设备初始化。
默认实现为空。
[virtual]
void QVulkanWindowRenderer::releaseResources()
当必须释放呈现器的图形资源时,就会调用这个虚拟函数。
实现过程中必须做好准备,在调用该函数后,可能会在稍后调用initResources() 。
QVulkanWindow 在调用该函数之前和之后,渲染器都会等待设备空闲。
默认实现为空。
[virtual]
void QVulkanWindowRenderer::releaseSwapChainResources()
当必须释放与 swapchain、帧缓冲区或 renderpass 相关的资源时,会调用此虚函数。
执行过程中必须做好准备,在调用此函数后,可能会在稍后时间调用新的initSwapChainResources() 函数。
QVulkanWindow 在调用此函数之前和之后,需要等待设备空闲。
默认实现为空。
注意: 在QVulkanWindow 开始释放所有图形资源之前,这是最后一次在所有图形资源保持完好的情况下执行操作。因此,在使用异步、可能是多线程的startNextFrame() 实现时,必须执行阻塞等待,并在从该函数返回之前调用QVulkanWindow::frameReady() ,以防有待提交的帧。
[pure virtual]
void QVulkanWindowRenderer::startNextFrame()
当下一帧的绘制调用要添加到命令缓冲区时,将调用该虚拟函数。
每次调用该函数后都必须调用QVulkanWindow::frameReady() 。否则将导致渲染循环停滞。也可以在从该函数返回后的稍后时间进行调用。这意味着可以启动异步工作,只在工作完成后更新命令缓冲区并通知QVulkanWindow 。
调用此函数时,所有 Vulkan 资源都已初始化并准备就绪。当前帧缓冲区和主命令缓冲区可通过QVulkanWindow::currentFramebuffer() 和QVulkanWindow::currentCommandBuffer() 获取。逻辑设备和活动图形队列可通过QVulkanWindow::device() 和QVulkanWindow::graphicsQueue() 获取。程序实现可以从QVulkanWindow::graphicsCommandPool() 返回的池中创建其他命令缓冲区。为方便起见,主机可见索引和设备本地内存类型索引通过QVulkanWindow::hostVisibleMemoryIndex() 和QVulkanWindow::deviceLocalMemoryIndex() 公开。所有这些访问器都可以被任何线程安全调用。
另请参见 QVulkanWindow::frameReady() 和QVulkanWindow 。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.