RHI学习笔记(2)-Qt6的RHI结构

从前文的分析可以看出,RHI的主要作用就是抹平不同图形API的差异,作为一个抽象层,提供一个统一跨平台的图形渲染接口,同时可以充分利用底层图形API的优势。它抹平平台差异,让开发者可以专注于实现渲染效果,而不用去适配底层平台,而RHI负责底层平台的兼容性。

如图所示,为QRhi系统的基本结构,其核心类为QRhi,在渲染线程QSGRenderThread中通过QSGRhiSupport调用QRhi的create函数进行创建,其中QSGRhiSupport用于获得系统中使用的图形API的类型,可以通过"QSG_INFO"环境变量进行配置,若环境变量为空,则进一步根据平台判断使用的默认API,比如Windows默认使用DirectX等。

QRhi持有QRhiImplementation,在它的create函数中,根据传入的backend类型来创建不同的QRhiImplementation,QRhiImplementation是一个基类,也就是统一了图形API的基础功能,比如创建一个贴图和创建一个采样器等等,QRhi依赖于QRhiResource及其子类,因为其中封装了QRhiImplementation,可以通过对应图形API的创建贴图接口,创建出对应平台的贴图对象,它包含一个QThread对象,用于保存当前线程,它通过QRhiImplementation的implThread变量保存在QRhi中,同时保留着QRhiDriverInfo和QRhiProfiler对象的指针。QRhiProfiler保存当前的Rhi实现的rhiDWhenEnabled,QRhiDriverInfo保留这对应设备的Rhi信息,包括deviceId和vendorId等。

可以看出五个QRhiImplementation的子类各自有各自的个性接口,也有统一的功能,比如完成一次渲染的pass相关的beginPass和endPass等,处理绘制每一帧的beginFrame和endFrame等,处理计算pass的beginComputePass和endComputePass,如果想学习某一个特殊的图形API,可以以其中的一个类为源码来学习,而Rhi的任务恰恰是把不同图形API的所有概念都统一起来,由外部开发者处理调用,使用QRhi,你只需要了解一套概念即可。

随着现代底层图形API的兴起,仅仅完成渲染任务已经不足以满足开发者对于Rhi的要求,Rhi需要更多的考虑控制底层,如显存管理和命令缓冲等,现代底层API最重要的特性就是可以控制底层GPU显存的分配,处理资源分配和设置渲染屏障,这时候Rhi由一个抽象封装层变为更多的资源管理器的角色,因此QRhi的设计也考虑了这一点,除了QRhiImplementation这个核心类,QRhi的结构中还有一个重要角色就是QRhiResource。

这里以贴图类QRhiTexture为例,介绍资源管理的基本结构,作为QRhiImplementation的持有者,QRhi负责获得对应图形API的QRhiImplementation,比如Windows上DirectX类,通过QRhi的newTexture调用QRhiImplementation的createTexture,在QRhiD3D11的createTexture中,创建DirectX对应的QRhiD3D11Texture,QRhiD3D11Texture中隐藏了DirectX的贴图的具体细节。

QRhiResource掌管了渲染中的多个概念,见表2-1

|------------------------|-------------------------------------------------------|
| 名称 | 功能 |
| Texture | 贴图,渲染中的基础概念,即渲染在屏幕上的图片信息 |
| Sampler | 采样器对象定义了采集纹理时所用的过滤器和寻址模式 |
| RenderBuffer | 绘图操作和内存传输等在命令缓冲区对象中记录要执行的所有操作,可以支持该命令在子线程中完成 |
| RenderPassDescriptor | 描述了渲染通道(Render Pass)的全部配置,包括附件格式、子通道(Subpass)布局、依赖关系等 |
| RenderTarget | 指定颜色、深度、模板缓冲区等输出目标 |
| TextureRenderTarget | 纹理信息输出目标 |
| ShaderResourceBindings | 将着色器程序与GPU资源,比如缓冲区、纹理、采样器等建立绑定的信息 |
| GraphicsPipeline | 图形渲染管线信息 |
| SwapChain | 图形API中连接GPU渲染输出与显示设备的信息,负责管理一组后台缓冲区与前台缓冲区 |
| ComputePipeline | 计算管线信息 |
| CommandBuffer | 渲染命令缓冲区 |
| Buffer | 缓冲区信息(如顶点缓存信息等) |

随着图形API更贴近底层,更加直接的操纵底层数据等特性,Rhi的设计将更偏重于资源管理,因此QRhiResource包含了现代图形API的大部分特性,因此它也是我们学习现代图形API的很好的参考教程,后续将通过QRhiResource子类的管理和调用方式的分析,更加深入的了解Qt6的Rhi系统。

相关推荐
NoteDeep 深度笔记26 分钟前
排期看不出冲突?把任务表切成甘特图
笔记·个人开发·甘特图·笔记应用·深度笔记·云笔记
霍霍的袁2 小时前
【C++11】左值右值引用与移动语义详细笔记(左值右值、右值引用、移动构造、移动赋值、引用折叠、万能转发)
c++·笔记·学习·visual studio
MandalaO_O2 小时前
SpringMVC 异常处理 & 拦截器
笔记
李永奉3 小时前
杰理可视化SDK开发-音频录制功能使用教程
笔记·单片机·嵌入式硬件·mcu·物联网·音视频
ysu_03143 小时前
【C++ 进阶之路】(二)从内联函数到类与对象:深挖内存对齐、this 指针与三大默认成员函数
开发语言·数据结构·c++·笔记·面向对象·this
叼烟扛炮3 小时前
Linux 学习笔记(三十二):线程控制——创建、等待与分离
linux·运维·服务器·笔记·学习·1024程序员节
Nuanyt3 小时前
LeetCode Hot 100 · 双指针 3 题 Java
java·笔记·算法·leetcode·双指针
深圳老胡4 小时前
FDC2212 + STM32G030 液面探测:IIC 读数跳动导致下探深度不一致的排查与解决
笔记·stm32·单片机·代码规范·1024程序员节
程序边界4 小时前
一台数据集成软件的拆解笔记(上):把 KFS 装起来、跑起来,再挑一堆毛病
笔记·原型模式
叼烟扛炮4 小时前
Linux 学习笔记(二十九):进程信号(上)—— 信号捕捉与异步魔法
linux·运维·笔记·学习·1024程序员节