OpenGL驱动的陷阱:ATI篇,再续

转载请注明出处为KlayGE游戏引擎,本文地址为http://www.klayge.org/2012/02/13/opengl%e9%a9%b1%e5%8a%a8%e7%9a%84%e9%99%b7%e9%98%b1%ef%bc%9aati%e7%af%87%ef%bc%8c%e5%86%8d%e7%bb%ad/

 

AMD的OpenGL驱动问题很多,是个众所周知的事情。以前我也写过《OpenGL驱动的陷阱:ATI篇》和《OpenGL驱动的陷阱:ATI篇,后续》来阐述这个问题,当时最新的驱动是Catalyst 10.10。过了一年多的时间,AMD的驱动和KlayGE的代码都有了不少变化,情况又如何呢?

失败的例子

在去年的驱动上,发现的问题主要有三个(ticket #58):

  1. Deferred Rendering和Global Illumination中,GI的效果只在第一帧出现。没找到原因。
  2. Detailed Surface和JudaTex Viewer中,纹理显示混乱。没找到原因。
  3. GPU Particle System和Particle editor中,粒子没有显示出来。GS编译失败。

更新到Catalyst 12.1后(也可能在11.12或者11.11就更新了,我没测试),问题1直接得到解决,问题3的GS也能编译成功,但仍没有粒子显示,并且在 validate shader的时候打印GS输出的component过多。于是我把GL_GEOMETRY_VERTICES_OUT_EXT强制设置成32后问题解 决。由于GLSL里面不能像HLSL,用[maxvertexcount(4)]这样的方式在shader里指定最大顶点输出个数,必须通过调用 glProgramParameteriEXT(glsl_program, GL_GEOMETRY_VERTICES_OUT_EXT, n)来设定。把n定在32,而不是1024这样的大数字之后GLSL program的link和validate都能顺利通过。当然,这个问题的最终解决方案还是应该在未来的HLSL bytecode to GLSL编译器里完成。

对于问题2,我曾经花了很多时间都没找出原因。后来偶然发现AMD的驱动上返回的PS最大纹理单元只有16(虽然它的硬件至少支持32),而 Juda Texture用到了17个纹理单元。所以一改成根据最大纹理单元数自动调整Juda Texture的shader,这个问题就迎刃而解了。

失败的函数

这几个函数是在原先的测试中发现过陷阱,这次再重新测试。

glBlitFramebufferEXT

问题依旧。

glClearBuffer*

已经正常了!

glBeginConditionalRender

本以为所有的例子终于再次都能跑的时候,Deferred Rendering和Post Processing又挂了,都是渲染几帧之后就驱动失去响应,自动重启GPU的大毛病。和前文提 到的症状类似,于是轻车熟路地把OGLConditionalRender::BeginConditionalRender和 EndConditionalRender注掉,问题解决。所以还是AMD驱动的那个老毛病,glBeginConditionalRender和 glEndConditionalRender必须配对调用,否则一定会失去响应。在去年的驱动上,这会直接死机,必须强制关机才行。现在好多了,只要等 几秒钟,让驱动重启即可。

glCopyImageSubDataNV

这是个新问题。在Catalyst 12.1上,增加了GL_NV_copy_image这个扩展的支持(是的,NV的扩展,也许没多久就会改成EXT甚至ARB)。但测试发现其结果和用glBlitFramebufferEXT一样,显示混乱。

posted on 2012-02-13 15:04  龚敏敏  阅读(3362)  评论(0编辑  收藏  举报