2010-12-01 10 views
0

Ich habe ein Problem und ich kann meinen Kopf nicht umschließen, also hoffte ich, dass jemand hier mir helfen könnte.ARB Fragment If/Else

Ich schreibe einen Compiler für miniGLSL, und so weit so gut. Ich bin an dem Punkt, wo ich zu einem ARB-Fragment-Programm ausgeben muss, aber das Problem ist, dass der ARB, den ich zielen muss, keine Verzweigung unterstützt. (Eine vollständige Liste der unterstützten Anweisungen finden Sie hier http://petewarden.com/notes/archives/2005/05/fragment_progra_2.html).

Um if/else zu simulieren, benutze ich das CMP-Programm wie folgt (angenommen 0 oder größer = wahr, sonst falsch. // stellt Kommentare dar, wie # hier schlechte Formatierung verursacht):

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

in 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 

Dies ist, wo ich bekommen, bevor ich meinen Code erkennen, wirklich hässlich bekommen beginnen wird. Jede Ebene von if/else wird fortwährend Stapelvergleiche einführen, und zusätzlich verlangt die letzte Ebene von mir, cond2 neu zu bewerten oder ein anderes Register zu verwenden. Ich weiß, dass ich hier wahrscheinlich etwas falsch mache, aber ich bin mir nicht sicher was. Ich habe versucht, Zähler zu verwenden, habe versucht, das Ergebnis der vorherigen Stufen von if/else Block, anding, oring usw. hinzuzufügen, aber ich kann keine gute Lösung finden, wie man if/else Blöcke in ARB Fragment Assembly konvertiert, das nicht funktioniert. t wirklich auf immer größeren Stapeln von CMP-Anweisungen. Hat jemand eine Idee, wie man das einfacher macht, damit mein Compiler das programmatisch ausgeben kann? Ich mache mir zu diesem Zeitpunkt nicht viele Gedanken über die Optimierung, ich möchte es nur zur Arbeit bringen.

Dank

Antwort

0

nehmen csc467 bei UofT Ursache, wenn Sie in Ihrer Klasse im sind lol.

Also das ist, wie ich denke, das sollte umgesetzt werden, ich dachte nur darüber so nicht sicher, ob es richtig ist.

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

und von dem, was ich hier http://www.cs.uaf.edu/~olawlor/ref/gl/glfp/ lesen Sie die Zeichen einer Eingangs-Flip können aber, wenn sie nicht der Fall ist, dann Müll meiner Idee ist

firstIf:

// Bedingung berechnet SLT a, b , Zustand1;

// berechne den Ausdruck 1 + 1 es ändert keines der Register ADD 1, 1, temp; cmp -Bedingung, Temperatur, a, a // wenn die Bedingung wahr ist - (Bedingung) = -1 // so dass Sie 1 speichern + 1 in einem anderen Sie ein Geschäft in einem

secondIf:

// Berechne den Zustand SLT f, g, condition2;

// jetzt, weil Sie hatte previus condition1 Sie sie zusammen hinzufügen müssen, wenn beide wahr sind // nur dann ausführen cod

TEMP combinedCon1; TEMP temp2 = {2.0}; ADD Bedingung1, Bedingung2, kombiniertCon1;
SGE combinedCon1, TEMP2, combinedCon1 // wenn die beiden subexpresiions addiert == 2 // dann 1 sonst 0

// berechnen 2 + 3 ADD 2, 3, Temperatur;

// Zuordnung durchführen, wenn combineCon1 == 1 CMP-combineCon1, temp, c, c;

// jetzt können Sie tun, sonst mit CMP-Befehl so gleiche Schritten folgen nur ein paar Dinge austauschen,

so zum Beispiel, wenn Sie ("else a = 2") haben; seine CMP-Bedingung1, a, temp, a; anstelle von CMP-condition1, temp, a, a;

// so hoffentlich funktioniert dies so jedes Mal, wenn Sie haben eine weitere verschachtelte Bedingung, die Sie & & sie haben und das Ergebnis in einem CMP-Befehl verwenden ..

Ich denke, das sollte funktionieren, nicht sicher,