cg:顶点输出结构被不同的成员顺序破坏了?配置文件违规或cg错误?

时间:2013-12-06 00:09:22

标签: debugging fragment-shader vertex-shader cg

我一直在修补Retroarch的cg着色器,我遇到了出现的是Cg Toolkit的编译器或代码生成器中的一个奇怪的错误......或者其他东西。考虑一下这里发现的模拟CRT电视的三遍着色器:https://github.com/libretro/common-shaders/tree/master/crt/crt-interlaced-halation

特别考虑最后一遍: https://github.com/libretro/common-shaders/blob/master/crt/crt-interlaced-halation/crt-interlaced-halation-pass2.cg

目前,着色器输出按预期工作。如果您在此文件的顶部注释掉“#define CURVATURE”(模拟CRT电视的曲率),则着色器输出也会按预期工作。但是,这里顶点着色器输出结构的成员顺序非常特别:

struct out_vertex {
    float4 position : POSITION;
    float4 color : COLOR;
    float2 texCoord : TEXCOORD0;
        float2 one;
        float mod_factor;
        float2 ilfac;
        float3 stretch;
        float2 sinangle;
        float2 cosangle;
};

如果您将订单重新排列为以下内容,则输出会损坏:

struct out_vertex {
    float4 position : POSITION;
    float4 color : COLOR;
    float2 texCoord : TEXCOORD0;
        float2 cosangle;
        float2 one;
        float mod_factor;
        float2 ilfac;
        float3 stretch;
        float2 sinangle;
};

我的桌面的nvidia卡给了我一个黑色的屏幕,我的笔记本电脑的ATI卡给了我奇怪的文物,其中纹理坐标似乎被打破(也许)。因此,错误的确切性质取决于GPU或驱动程序,但错误的存在是供应商/驱动程序无关的...所以它似乎是cg编译器中的一个错误导致变化的属性变得腐败。你可以得到的腐败种类几乎没有尽头。例如,其他成员重新排列搞乱了“mod_factor”变量(存储输出的x像素坐标)之类的东西,这会导致交替的洋红色/绿色像素色调卡在一个或另一个上,用整个图像覆盖整个图像。相同的色调。除了光晕/绽放贡献等,还有一些会导致黑屏。

如果您重新启用“#define CURVATURE”,则此特定着色器中不会出现此问题,但它与“平面”代码路径中的错误没有任何关系:实际上,在片段着色器的部分中在“#ifdef CURVATURE”块中,您实际上可以用“xy = VAR.texCoord;”替换最终值。 (与未弯曲版本使用的值相同),您将获得平坦的输出而没有任何错误。 (编辑:哎呀,这对于这个特定的着色器实际上并不是这样,但它是在我自己的版本中。我应该在对这个“简化”示例进行相同的评估之前先检查一下。)实际上,平坦的代码路径触发了损坏但弯曲的代码路径似乎并没有表明它与曲线代码路径有关,而是在片段着色器中读取更多不同的属性(也许读取顺序或用法很重要)太......?),但我还没有找到押韵或理由。我有自己截然不同的分叉WIP,同样奇怪的问题也会影响弯曲的代码路径,但我宁愿把它保留给自己,直到它准备就绪。

所以,我想我有几个问题:

  • 还有其他人见过这样的事吗?
  • 这种非确定性是否仅仅是与未明确与任何语义明确关联的输出结构成员所期望的?
  • 这个腐败可能来自我不知道的cg着色器配置文件限制吗?我不知道Retroarch编译的着色器配置文件是什么,但如果顶点输出结构的大小超过某个允许的最大大小,我可以看到这种损坏。
  • 我可能会忽略其他任何可能性吗?我考虑过驱动程序错误,但是一旦我意识到它影响了nvidia和ATI硬件,就会出现问题。不过,我想在通知nvidia Cg Toolkit似乎有一个bug之前做我的作业......

感谢您的任何见解! :)

1 个答案:

答案 0 :(得分:0)

事实证明,问题与依赖cg的自动分配语义有关。我将从上面复制/粘贴我的评论:

  

我开始认为问题可能与此有关   依靠cg来自动分配语义:例如,如果cg关联   一个具有完整浮点范围的值,该语义可以锁定到[0.0,   1.0],这显然会引发问题。 mod_factor,ilfac和stretch都属于那个类别,并且是sinangle和cosangle   可能在[-1,1],所以同样可能适用于他们。该   语义分配很可能受到死代码的影响   消除,这可以解释有和没有的差异   “#define CURVATURE。”我不得不测试这个假设......

根据配置文件,只有有限数量的语义可用(参见this specification),并且(我可能会弄错)Retroarch似乎使用较低的配置文件,其中只有以下内容可供使用:

  • POSITION:必须设置为剪辑空间顶点位置,不仅因为它通知了光栅化器,还因为它甚至无法从片段着色器中读取。
  • COLOR0和COLOR1:值被限制在[0,1]范围内。
  • TEXCOORD0-7:对任何标量或向量浮点值都是安全的
  • FOG:对任何标量浮点值都是安全的

BCOL0 / BCOL1语义可能也会在支持它们的配置文件中进行限制,而PSIZE和CLP0-5可能不会。整个教训似乎是让cg编译器为[0,1]范围之外的值自动分配语义就像玩俄罗斯轮盘赌一样,因为你永远不知道它们是否最终会与被钳位的语义相关联,并且自动分配将根据着色器代码的细节而改变。因此,您需要仔细管理语义,以便可能在[0,1]之外的值与TEXCOORD0-7或FOG(对于标量浮点数)配对。