私は問題を抱えていて、頭を抱えているようには見えないので、ここの誰かが私を助けてくれることを願っていました.
私は 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 ステートメントのスタック上にあります。私のコンパイラがこれをプログラムで出力できるように、これをより簡単にする方法を知っている人はいますか? 現時点では、最適化についてあまり心配していません。ただ機能させたいだけです。
ありがとう