ARB 片段 If/Else
我遇到了一个问题,但我似乎无法解决它,所以我希望这里有人能够帮助我。
我正在为 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 片段汇编确实是在越来越大的 CMP 语句堆栈上。有谁知道如何使其更简单,以便我的编译器可以以编程方式输出它?此时我不太担心优化,我只是想让它发挥作用。
谢谢
I have a problem and I can't seem to wrap my head around it, so I was hoping someon here might be able to help me out.
I'm writing a compiler for miniGLSL, and so far so good. I'm at the point where I need to output to an ARB fragment program, but the problem is, the ARB I have to target doesn't support branching. (A full list of supported instructions can be found here http://petewarden.com/notes/archives/2005/05/fragment_progra_2.html ).
In order to simulate if/else, I've been making use of the CMP program as follows (assuming 0 or greater = true, otherwise, false. // represents comments as # causes bad formatting on here):
if (a < b)
a = 1 + 1;
if (f < g)
c = 2 + 3;
else
if (h < i)
b = 1 + 2;
else
d = 2 + 3;
into ARB fragment:
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
This is about where I get before i realize my code is going to start getting really ugly. Each level of if/else is going to introduce continually stacking compares, and additionally, the last else requires me to re-evaluate cond2, or use another register. I know I'm probably doing something wrong here, but I'm not sure what. I've tried using counters, tried adding the result of previous stages of if/else block, anding, oring, etc. but I can't find a good solution to how to convert if/else blocks into ARB fragment assembly that doesn't really on increasingly large stacks of CMP statements. Does any one have an idea how to make this simpler so my compiler can output this programmatically? I'm not worried to much about optimization at this point, I just want to get it to work.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
正在 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/
你可以翻转输入的符号,但如果不是这样,那么我的想法
首先是垃圾If:
//计算条件
SLT a、b、条件1;
// 计算表达式 1+1 它不会改变任何寄存器
添加 1 ,1 , 温度;
cmp -condition , temp , a ,a // 如果条件为 true -(condition) = -1 <0
//所以你将1+1存储在a中,否则你将a存储在
第二个中If:
//计算条件
SLT f , g , 条件2;
//现在因为你有之前的条件1,如果两者都为真,你需要将它们加在一起
//然后才执行 cod
TEMP合并Con1 ;
温度 temp2 = {2.0};
添加条件1、条件2、组合Con1;
SGE组合Con1,temp2,组合Con1 //如果两个子表达式相加== 2 //则1 else 0
//计算2+3
添加 2、3、温度;
//如果combineCon1 ==1则执行赋值
CMP -combineCon1,温度,c,c;
//现在您可以使用 CMP 指令执行 else 操作,因此按照相同的步骤仅交换一些内容,
例如,如果您有 ("else a = 2" );其 CMP -条件 1 , a , temp ,a ;
而不是 CMP -condition1 、 temp、a 、a ;
// 所以希望这能起作用,所以每次你有另一个嵌套条件时,你都必须 &&它们并在 CMP 指令中使用结果。
我认为这应该有效,但不确定
are taking csc467 at uoft cause if you are im in your class lol.
So this is how I think this should be implemented , I just thought about it so not sure if its corrext.
example:
if (a < b)
a = 1 + 1;
if (f < g)
c = 2 + 3;
else
if (h < i)
b = 1 + 2;
else
d = 2 + 3;
and from what i read here http://www.cs.uaf.edu/~olawlor/ref/gl/glfp/
you can flip the sign of an input but if its not the case then my idea is garbage
firstIf:
//calculate condition
SLT a, b, condition1;
// calculate expression 1+1 it doesnt change any of the registers
ADD 1 ,1 , temp;
cmp -condition , temp , a ,a // if condition was true -(condition) = -1 <0
//so you store 1+1 in a else you store a in a
secondIf:
//calculate condition
SLT f , g , condition2;
//now because you had previus condition1 you need to add them together if both are true
//only then execute cod
TEMP combinedCon1 ;
TEMP temp2 = {2.0};
ADD condition1, condition2, combinedCon1;
SGE combinedCon1 , temp2, combinedCon1 // if the two subexpresiions added together == 2 //then 1 else 0
//calculate 2+3
ADD 2, 3, temp;
//perform assignment if combineCon1 ==1
CMP -combineCon1 , temp , c ,c ;
//now you can do else with CMP instruction so follow same steps only interchange a few things,
so for example if you have ("else a = 2" ); its CMP -condition1 , a , temp ,a ;
instead of CMP -condition1 , temp, a ,a ;
// so hopefully this works so every time you have another nested condition you have to && them and use the result in a CMP instruction..
I think this should work , not sure