文章目錄
- glBlitFramebufferEXT
- glClearBuffer*
- glBeginConditionalRender
- glCopyImageSubDataNV
轉載請註明出處為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):
- Deferred Rendering和Global Illumination中,GI的效果只在第一幀出現。沒找到原因。
- Detailed Surface和JudaTex Viewer中,紋理顯示混亂。沒找到原因。
- 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一樣,顯示混亂。