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 フラグメント アセンブリに変換する方法の適切な解決策が見つかりません。実際には、ますます大きくなる CMP ステートメントのスタック上にあります。私のコンパイラがこれをプログラムで出力できるように、これをより簡単にする方法を知っている人はいますか? 現時点では、最適化についてあまり心配していません。ただ機能させたいだけです。

ありがとう

4

1 に答える 1

0

あなたがあなたのクラスにいるなら、uoftの原因でcsc467を取っています笑。

だから、これは私がこれを実装する必要があると思う方法です。私はそれについて考えただけなので、正しいかどうかわかりません。

例: if (a < b) a = 1 + 1; もし (f < g) c = 2 + 3; それ以外の場合 (h < i) b = 1 + 2; それ以外の場合は d = 2 + 3;

そして、私がここで読んだものからhttp://www.cs.uaf.edu/~olalawlor/ref/gl/glfp/ 入力の符号を反転できますが、そうでない場合、私の考えはゴミです

最初の場合:

//条件 SLT a, b, condition1 を計算します。

// 式 1+1 を計算します ADD 1 ,1 , temp; のいずれのレジスタも変更しません。cmp -condition , temp , a ,a // 条件が true の場合 -(condition) = -1 <0 //つまり、1+1 を a に格納する else を a に格納する

2番目の場合:

// 条件 SLT f , g , condition2 を計算します。

//前の condition1 があったので、両方が true の場合はそれらを追加する必要があります //その後で cod を実行します

TEMP 結合コン 1 ; TEMP temp2 = {2.0}; 条件 1、条件 2、結合されたコン 1 を追加します。
SGE combinedCon1 , temp2, combinedCon1 // 2 つの部分式が一緒に追加された場合 == 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 に答える