summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2007-10-02 14:05:21 -0600
committerBrian <brian.paul@tungstengraphics.com>2007-10-02 14:05:21 -0600
commit4ad80ad5cfdb9bc23eee15938645a334d227cd72 (patch)
tree12595830401aa347415b37eb27f08f7a14a67a4d
parent5e49ec339df1d23b1f1790c49c9f102098f42c0d (diff)
Implement CAL/RET and a call stack for subroutines.
The glsl/brick.c shader demo runs now.
-rw-r--r--src/mesa/pipe/tgsi/exec/tgsi_exec.c48
-rw-r--r--src/mesa/pipe/tgsi/exec/tgsi_exec.h4
-rw-r--r--src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c7
3 files changed, 37 insertions, 22 deletions
diff --git a/src/mesa/pipe/tgsi/exec/tgsi_exec.c b/src/mesa/pipe/tgsi/exec/tgsi_exec.c
index 27154d6883..d757df48d8 100644
--- a/src/mesa/pipe/tgsi/exec/tgsi_exec.c
+++ b/src/mesa/pipe/tgsi/exec/tgsi_exec.c
@@ -1903,12 +1903,18 @@ exec_instruction(
break;
case TGSI_OPCODE_CAL:
- assert (0);
+ /* note that PC was already incremented above */
+ mach->CallStack[mach->CallStackTop++] = *pc;
+ *pc = inst->InstructionExtLabel.Label;
break;
case TGSI_OPCODE_RET:
- /* XXX: end of shader! */
- /*assert (0);*/
+ assert(mach->CallStackTop >= 0);
+ if (mach->CallStackTop == 0) {
+ /* XXX error? */
+ return;
+ }
+ *pc = mach->CallStack[--mach->CallStackTop];
break;
case TGSI_OPCODE_SSG:
@@ -2041,13 +2047,6 @@ exec_instruction(
UPDATE_EXEC_MASK(mach);
break;
- case TGSI_OPCODE_ENDLOOP:
- /* pop LoopMask */
- assert(mach->LoopStackTop > 0);
- mach->LoopMask = mach->LoopStack[--mach->LoopStackTop];
- UPDATE_EXEC_MASK(mach);
- break;
-
case TGSI_OPCODE_ENDREP:
assert (0);
break;
@@ -2171,9 +2170,11 @@ exec_instruction(
break;
case TGSI_OPCODE_BGNSUB:
- assert( 0 );
+ /* no-op */
break;
+ case TGSI_OPCODE_ENDLOOP:
+ /* fall-through (for now at least) */
case TGSI_OPCODE_ENDLOOP2:
if (mach->LoopMask) {
/* repeat loop: jump to instruction just past BGNLOOP */
@@ -2219,6 +2220,9 @@ exec_instruction(
void
tgsi_exec_machine_run( struct tgsi_exec_machine *mach )
{
+ uint i;
+ int pc = 0;
+
#if XXX_SSE
mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0;
#else
@@ -2226,6 +2230,9 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach )
mach->CondMask = 0xf;
mach->LoopMask = 0xf;
mach->ExecMask = 0xf;
+ assert(mach->CondStackTop == 0);
+ assert(mach->LoopStackTop == 0);
+ assert(mach->CallStackTop == 0);
mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0;
mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] = 0;
@@ -2236,18 +2243,15 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach )
}
- {
- uint i;
- int pc = 0;
-
- for (i = 0; i < mach->NumDeclarations; i++) {
- exec_declaration( mach, mach->Declarations+i );
- }
+ /* execute declarations (interpolants) */
+ for (i = 0; i < mach->NumDeclarations; i++) {
+ exec_declaration( mach, mach->Declarations+i );
+ }
- while (pc != -1) {
- assert(pc < mach->NumInstructions);
- exec_instruction( mach, mach->Instructions + pc, &pc );
- }
+ /* execute instructions, until pc is set to -1 */
+ while (pc != -1) {
+ assert(pc < mach->NumInstructions);
+ exec_instruction( mach, mach->Instructions + pc, &pc );
}
#endif
diff --git a/src/mesa/pipe/tgsi/exec/tgsi_exec.h b/src/mesa/pipe/tgsi/exec/tgsi_exec.h
index 0f2dd7d987..ae5ce8a7c9 100644
--- a/src/mesa/pipe/tgsi/exec/tgsi_exec.h
+++ b/src/mesa/pipe/tgsi/exec/tgsi_exec.h
@@ -99,6 +99,7 @@ struct tgsi_exec_labels
#define TGSI_EXEC_MAX_COND_NESTING 10
#define TGSI_EXEC_MAX_LOOP_NESTING 10
+#define TGSI_EXEC_MAX_CALL_NESTING 10
/**
@@ -149,6 +150,9 @@ struct tgsi_exec_machine
uint LoopStack[TGSI_EXEC_MAX_LOOP_NESTING];
int LoopStackTop;
+ uint CallStack[TGSI_EXEC_MAX_CALL_NESTING];
+ int CallStackTop;
+
struct tgsi_full_instruction *Instructions;
uint NumInstructions;
diff --git a/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c b/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c
index 5c987436be..431b82a98f 100644
--- a/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c
+++ b/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c
@@ -271,6 +271,10 @@ compile_instruction(
case OPCODE_BRK:
fullinst->Instruction.Opcode = TGSI_OPCODE_BRK;
break;
+ case OPCODE_CAL:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_CAL;
+ fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
+ break;
case OPCODE_CMP:
fullinst->Instruction.Opcode = TGSI_OPCODE_CMP;
break;
@@ -382,6 +386,9 @@ compile_instruction(
case OPCODE_RCP:
fullinst->Instruction.Opcode = TGSI_OPCODE_RCP;
break;
+ case OPCODE_RET:
+ fullinst->Instruction.Opcode = TGSI_OPCODE_RET;
+ break;
case OPCODE_RSQ:
fullinst->Instruction.Opcode = TGSI_OPCODE_RSQ;
tgsi_util_set_full_src_register_sign_mode(