[独立游戏开发] OpenGL转Vulkan的感想

作者: Dreamtowards分类: 野生技能协会 发布时间: 2023-06-23 12:17:41 浏览:18376 次

[独立游戏开发] OpenGL转Vulkan的感想

你个斑马:
对现代gpu硬件特性没深入理解以及老图形api和现代api的所有区别就别用现代图形api,老api的驱动帮你做的优化比乱用现代api的提升多得多。我举几个例子,多线程提交渲染命令这个真的有用么?在什么情况下才有用?或者说能发挥超过老api的水平?流水线状态为什么在现代图形api里要剥出来?和状态机api有什么性能差别?为什么现代图形api有不同类型的命令队列?这些队列到底和什么硬件特性有关?对应哪些gpu硬件?写unity的都知道要降drawcall,这个反应到图形api上是什么?在新老api上这个操作的效果如何?

【回复】感谢您的反馈,我相信你说的opengl的优化通常做的比我好。这次我做vk是为了学习和挑战。接下来我尝试反思和回答你的拷问: 1. 【多线程提交渲染命令】: 其实我想的是多线程*录制*渲染指令 而仅1个线程(异步)提交指令。关于多线程录制指令 因为我们场景中物体很多(以后的大型地形 各种物品) 遍历&录指令需要一定的CPU时间 所以如果1线程录地形渲染 1线程录实体渲染 这样多线程录就可以节省宝贵的CPU主线程时间。 2. 【vk的管线状态为何分离出来 而不像gl那样全局状态机】 (1) 因为以便更好的性能优化 自从管线状态从创建后就不可更改(大部分) 给(驱动)优化留了更多空间 (2) 更好的编程逻辑性 每个管线的状态都是独立的 减少了全局混乱 也更好错误检测 3. 【为何vk有多种queue】 (1) 因为以便并行执行 如一个queue做渲染,另一个做数据传输,再一个做计算 它们可同时执行(如果真的有多个物理列队的话)。(2) 更好的利用GPU特性 比如数据传输的queue要比graphics queue的数据传输性能更好..(真的吗) 而compute queue可以专注地做计算或独立存在(比如用于纯计算的gpu就可以没有图形列队),而且不同queue可能对应不同gpu硬件部分 (具体对应哪些硬件我还不知道) 4. 【关于为什么降drawcall, vk和gl的区别】 我还没搞清,不过vk和gl的drawcall好像都是异步的 只是录个指令?,但是等到真正执行时(vkQueueSubmit, glFlush) 每个drawcall都要执行一遍管线 所以有一定开销。而gl开销相对大一点 因为管线状态可变?
【回复】回复 @Dreamtowards :拷问谈不上,其实问的都是一些基础问题。我这里抛砖引玉,说一些东西,之前的一个问题可能会涉及好几个点,你可以找资料看一下: 1.gl状态机的改变可能导致驱动那里实时生成一个新的pso,当然这不是必然的,驱动通常会录制下之前创建过的pso,但实时创建确实会造成性能消耗。但现代api剥出来后甚至可以在运行前完成。 2.了解一下GPU流水线的各个状态对应GPU上哪些硬件,这里建议学一下cuda,有助于理解和学习。比如着色器运行在流处理器上,纹理加载在纹理单元上,采样由tmu单元完成,光栅化由光栅引擎做,像素着色器之后的步骤由rop做。 3.现代GPU是多引擎的,不同引擎可以并行工作,而进入队列的命令还要下发给不同引擎,队列和引擎间还有一些对应关系,这种对列关系在不同GPU上是不同的,各家GPU通常有官方性能优化文档进行说明。此外并行队列的任务可能会下发给引擎是引起冲突,队列并不直接对应硬件。 4.GPU是带宽敏感处理器(CPU是延迟敏感),过细的drawcall可能导致带宽利用率不够,此外在gl那里可能导致1中说的gl反复创建pso
【回复】额,我不是很想抬杠啊。但是我觉得其实学习现代图形接口的过程也是在对现代图像处理硬件的一个学习过程。我觉得还是多鼓励一下up比较好>.< 其次我听up在视频中说的内容让我觉得up本人可能并没有对vulkan中的管线,descriptor有一个比较高效的理解。我严重怀疑up想到多线程记录命令的原因是他把管线的生成和渲染整到一个线程了。 Descriptor 才是最逆天的(笑)
sselecirPyM:
没做过vulkan,分享一点dx12的开发经验吧。 我的dx12应用程序在使用constant buffer(对应opengl的ubo )时,只使用了一个buffer。具体做法是先创建一个巨大的buffer,需要使用时记录初始偏移量,往上传缓冲区写数据,然后增加偏移量。同时记录渲染指令。然后在缓冲区用完时偏移量归零。在这样的优化下,我的应用程序拷贝命令很少,也不需要额外的命令同步。最后我把拷贝和渲染命令混在一起就像普通的函数调用那样。

【回复】说的是录制指令的commandBuffer嘛,不知道你说的是不是VkcommandBuffer里面的信号量。。semaphore和fence,控制信号把一堆命令一起打包送到gpu命令队列。东西挺复杂的我弄好久也没弄明白
【回复】回复 @超级闪电踢 :现代的api比如dx11 dx12需要显式的执行上传命令,我觉得太麻烦写了一个draw函数参数里面直接传数组(在cpu端的数组)。某种程度上确实是混合执行的。
【回复】拷贝和渲染命令混合是什么意思
BA7LYA:
Google有个Angle项目,是用OpenGL封装的Vulkan。

【回复】那个angle好像是OpenGL ES (up to 3.2)的一系列实现。然而原生GL3.3几乎都在各个平台被支持了,又为何要用这个Angle的GLES呢..
【回复】ANGLE要多线程使用需要打开全局锁,用OpenGL ES也不能自己完全控制渲染资源,这样就不能发挥Vulkan的优势了。
【回复】我早就用在IOS游戏里了还挺稳定
zomb_676:
vulkan也在慢慢进步吧,比如https://www.khronos.org/blog/you-can-use-vulkan-without-pipelines-today vulkan的复杂,只能说学过的都懂,太复杂了。 但是里面一些显示的操作,至少能避免?减少吧。 OpenGL那种,有的时候一台机器上跑的好好的,换一台就不知道为什么渲染错误了 这种错误调试起来真的太折磨了,更多时候你没法亲自到错误的机器上调试

【回复】回复 @酒生神 :你好似在放屁,不管什么东西用久了都会简单,但完全不能否则vulkan的入门难度。初学者还是老老实实opengl起步,等摸到opengl的瓶颈了再慢慢想vk迁移才是正道
【回复】回复 @不能生孩子的男人 :opengl都能炸的话,我的建议是重修图形学、高等代数和C++[笑哭]
【回复】当然,我觉得OpenGL那车非DSA的函数,真的是太折磨了,一个操作不小心,十万八千里外的东西飘走了 而DSA在macos上的支持,几乎就是0 而且Vulkan能够直接选择使用哪一张GPU,我记得OpenGL上只能靠厂商扩展来着,而且还不一定有
Boikinov:
用Vulkan自建引擎的话可以用VMA库 Vulkan Memory Allocator 帮你解决各种资源管理上的代码 节省大量初期的底层实现 之前VMA是AMD的开源库 现在已经被Vulkan官方收入了

【回复】回复 @那天夜晚的星光 :d3d12ma感觉并不友好,不适合小buffer管理,它内部默认创建大heap给你用placedresource子分配管理,但placedresource是64k对齐的这对于小于64k的buffer并不友好。所以大部分针对小buffer会自己实现一套
【回复】DX12也有AMD弄的D3D12MA https://gpuopen.com/d3d12-memory-allocator/
【回复】回复 @Futalihua官方号 : MIT开源,只有一个头文件的header only库
xingrui94:
MacOS上也可以用OpenGL或者vulkan 么?能用最新版本不!?但我听这个风扇声音很大呀[笑哭]

【回复】macOS 能用 OpenGL 4.2 以下的 API,当然也能用苹果内建的 Metal,想在 macOS 上写 Vulkan 要通过一个库转成 Metal 的API,基本只能算一个 Vulkan 子集(不过支持大部分特性,实际开发过程中基本没影响)
【回复】macos官方最新只支持gl4.1,而vulkan是通过molton icd基于metal封装的一个vk驱动
【回复】我目前在mac上用xcode写opengl
wicast:
我个人建议如果不追求光追一类特别新的功能,可以考虑webgpu,api够现代操作上也没有vk繁琐,而且未来也会有光追。实现上dawn、wgpu二选一

【回复】回复 @活不过20就嗝屁 : 这种想法太古板了,别光看到web就以为一定要和web扯上关系。首先这玩意可以脱离浏览器直接使用,而webgpu本质上是RHI的最佳实践,vk有些脑溢血设计在webgpu下修正了。rust那边很多开源项目都已经拿webgpu作为渲染层了
【回复】为了学wgpu,特意去学rust,结果掉到坑里了,至今还没没爬出来
【回复】回复 @wicast :那我完全搞错了[笑哭],webgpu是一个api标准啊,这样就懂了。又搜了一下,我之前看到的是chrome支持了webgpu,再往前是看到有个团队Orillusion基于webgpu做了个渲染引擎
账号已注销:
用vulkan写渲染器就好像在用汇编,执行效率当然高但是开发效率就大大降低了,GL和DX11才是轻松又好用的API

【回复】回复 @拈花把酒丶 : VK是连写引擎的高手都不得不承认是非常复杂难用的东西,只有大厂喜欢。个人忙目追求是很不划算的,我的话,推荐OPENGL和DX11,如果不打算上苹果机,那完全不需要学习metal。事实上,linux的游戏市场也超级小,只有steam在热心搞这些,真正的游戏大头还得是WINDOWS
【回复】[doge]这就是为啥大厂很喜欢vk,一个容易移植多平台,一个有真大神确实能优化引擎效率,再一个就是技术壁垒
【回复】回复 @买了游戏机不知道玩啥 : 因此,DX和OPENGL就是最优的解决方法。跨平台交给OPENGL,微软平台交给DX,NS交给OPENGL(已经看了主页介绍,OPENGL是支持NS的)完。 VK不需要学,虽然它很快,很底层,支持多线程渲染,但是太复杂难用,而且XBOX和PS4,PS5都用不了。
石头下的心:
这是在自己搓引擎吗?[笑哭] 大佬为啥不用成熟的游戏引擎

【回复】在懵懂的时候,觉得自己造的就是最好的,没事,等开发完就会发现,还不如用现有的引擎
【回复】回复 @同学你的梦掉了 :造轮子其实是另一个赛道。 有时候你只想实现一个简单的效果验证,但要丢一整个框架就没必要了。 只能说,还是看各自的想法了
【回复】造轮子的要么是萌新要么是大佬[吃瓜]
DerivedCat:
vulkan作为现代api,也一直在发展,比1.0时代应该是好用不少,make your life easier[tv_点赞]1. Bindless texture. 绑一个全局纹理数组,后面只用传index,再也不用挨个绑纹理了。有一个小坑:如果同时有sampler1d,2d,3d,cube,它们可以混放在一个纹理数组里,但glsl里声明descriptor时要声明4个不同名的sampler array. 2. Vma库,很多引擎都在用的内存管理库,不用写allocator了,而且常用的4种memory类型:可映射/不可映射显存,上传用/下载用内存,vma库可以自动寻找并处理退化情形。3. 更加dynamic的渲染方式,dynamic viewport,最新的dynamic rendering,帮你摆脱笨重的管线。4. 如果经常用同步原语,synchronization2扩展一定不能错过,timeline semaphore是原始semaphore的上位替代,支持单个queue里的wait-before-signal,一个batch提交一堆无序的command buffer也不用担心蛋疼的死锁了[tv_可爱]

vbfool:
vulkan毕竟更灵活,我以前有过用DX9去写GPU动画,往Shader里传骨骼顶点数据结果骨骼太多参数放不开(数组最大128),换成DX11才放开了,Vulkan的限制应该会更少的吧。

【回复】DX11已经很可以了,优化好了甚至可以和12拼一拼。vk虽然好但是太复杂了,一般人用不了,还容易出错。
macsnake:
VK包装好了以后用起来比opengl更顺手,因为不用考虑状态问题,只是个人感受。[doge]

Jiacpt:
如果又做游戏又做引擎,感觉忙不过来呀

【回复】回复 @阿修罗的修炼场 :epic当年那也是几十人团队,创始人自己写核心代码。这还是那个年代的3D引擎比较简陋,现在都是大公司才保留私有引擎的开发和维护。就算是用商业游戏引擎也得是主流的,比如3d游戏就是u3d或者虚幻,最不抵也得是cocos吧。重生工作室用的起源引擎因为太老了,不得不重写一半以上的代码,又浪费了他们极大精力
【回复】回复 @Futalihua官方号 :哥们,你写一个引擎的工作量能搞好几个游戏
【回复】回复 @炽东原_ : 因为从头开始写游戏(其实写游戏的过程中就是在写引擎)可以积累技术沉淀,也就是说引擎这个东西可以重用,写完一个游戏,再做同一个游戏就不需要那么麻烦了。以前本来就没有引擎这个东西,现在不过是工业化模块化了,为了方便,所以都在做什么泛用性引擎,如果是定制化的比如你做FPS引擎,你压根不需要做成虚幻5这样臃肿巨大。复杂的引擎。可以简化很多东西。
山海半生漂泊:
哥要分清楚你是要做游戏还是要做引擎

Aspectol:
可能你开发一套库,封装vulkan要更有效率一些。vulkan开发能提高的性能也就10%到20%。如果不是有特殊的需求,为了这点提升,实现相同的目的下,折腾比opengl多出两三倍的代码量实属得不偿失。

【回复】回复 @某公主链接福瑞的小号 :vulkan能达到dx12的渲染性能了吗?
【回复】本来就是很鸡肋,弄不好比DXII还弱
Lightly-Light:
vulkan的Pipeline太麻烦了,同一套shader换个顶点绑定就得重新创建一个(优化项),然后是uniform,从descriptor到shader中的uniform中间太多东西了,还有cmdbuf和renderpass的subpass,各种PipelineBarrier转换ImageLayout,搞得人脑袋大

【回复】现代gpu都这样的 这么简单,多规范 好用还简单
nxcy2:
webgpu是各种图形api的兼容层,可以用于原生和web程序,比vk简单

已经是开摆了:
什么,是在学vulkan?那写createinfo一点很熟练吧?[doge]

游戏开发 游戏 游戏引擎 独立游戏 独立游戏开发 自研 体素 Voxel vulkan OpenGL

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!