0

我有一个问题,我似乎无法解决它,所以我希望这里的某个人能够帮助我。

我正在为 miniGLSL 编写一个编译器,到目前为止一切都很好。我现在需要输出到 ARB 片段程序,但问题是,我必须定位的 ARB 不支持分支。(支持指令的完整列表可在此处找到http://petewarden.com/notes/archives/2005/05/fragment_progra_2.html)。

为了模拟 if/else,我一直在使用 CMP 程序,如下所示(假设 0 或更大 = true,否则为 false。// 表示注释,因为 # 导致此处格式错误):

if (a < b)
  a = 1 + 1;
  if (f < g)
    c = 2 + 3;
else
  if (h < i)
    b = 1 + 2;
  else
    d = 2 + 3;

进入 ARB 片段:

TEMP cond1, cond2, cond3, tempvar1, tempvar2, tempvar3, tempvar4, a, b, c, d, e, f, g;
//TOP IF
//condition a < b
SLT a, b, cond1;
SUB cond1, 1.0, cond1;

//Assign if true
ADD 1.0, 1.0, tempvar1;
CMP cond1, a, tempvar1, a;

//Condition f < g
SLT f, g, cond2;
SUB cond2, 1.0, cond2;
//if top level if was false, assign false, otherwise assign it to itself
CMP cond1, -1.0, cond2, cond2;
//Assignment
ADD 2.0, 3.0, tempvar2;
CMP cond2, c, tempvar2, c;

//TOP ELSE
//if h < i
SLT h, i, cond2;
SUB cond2, 1.0, cond2;
//If top level if was true, make false
CMP cond1, cond2, -1.0, cond2;
CMP cond2, tempvar3, b, b;
//Else
//if top level if was true, and previous if was false, make true

这是关于在我意识到我的代码将开始变得非常丑陋之前我得到的地方。每个级别的 if/else 都将引入不断堆叠的比较,此外,最后一个 else 要求我重新评估 cond2,或使用另一个寄存器。我知道我可能在这里做错了什么,但我不确定是什么。我尝试过使用计数器,尝试添加 if/else 块、anding、oring 等先前阶段的结果,但我找不到如何将 if/else 块转换为 ARB 片段程序集的好的解决方案。 t 真的在越来越多的 CMP 声明堆栈上。有谁知道如何使这更简单,以便我的编译器可以以编程方式输出?在这一点上,我不太担心优化,我只是想让它发挥作用。

谢谢

4

1 回答 1

0

如果你在你的班级大声笑,我会在 uoft 上学习 csc467。

所以这就是我认为应该实现的方式,我只是想了一下,所以不确定它是否正确。

例如:如果 (a < b) a = 1 + 1; 如果 (f < g) c = 2 + 3; 否则如果 (h < i) b = 1 + 2; 否则 d = 2 + 3;

从我在这里读到的http://www.cs.uaf.edu/~olawlor/ref/gl/glfp/ 你可以翻转输入的符号,但如果不是这样,那么我的想法就是垃圾

首先如果:

//计算条件SLT a, b, condition1;

// 计算表达式 1+1 它不会改变任何寄存器 ADD 1 ,1 , temp; cmp -condition , temp , a ,a // 如果条件为真 -(condition) = -1 <0 //所以你将 1+1 存储在 a 中,否则你将 a 存储在 a

第二如果:

//计算条件 SLT f , g , condition2;

//现在因为你有以前的条件1,如果两者都为真,你需要将它们加在一起 ​​//只有然后执行 cod

TEMP combineCon1 ; 温度 temp2 = {2.0}; 添加条件1,条件2,组合Con1;
SGE combinedCon1 , temp2, combinedCon1 // 如果两个子表达式加在一起 ​​== 2 //则为 1 否则为 0

//计算 2+3 ADD 2, 3, temp;

//如果 combineCon1 ==1 则执行赋值 CMP -combineCon1 , temp , c ,c ;

//现在您可以使用 CMP 指令执行其他操作,因此按照相同的步骤仅交换一些内容,

例如,如果您有 ("else a = 2" ); 它的 CMP -condition1 , a , temp ,a ; 而不是 CMP -condition1 , temp, a ,a ;

// 所以希望这可以工作,所以每次你有另一个嵌套条件时,你必须 && 他们并在 CMP 指令中使用结果..

我认为这应该可行,不确定

于 2010-12-02T05:17:58.560 回答