From: Brian Date: Tue, 2 Oct 2007 20:05:21 +0000 (-0600) Subject: Implement CAL/RET and a call stack for subroutines. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4ad80ad5cfdb9bc23eee15938645a334d227cd72;p=mesa.git Implement CAL/RET and a call stack for subroutines. The glsl/brick.c shader demo runs now. --- diff --git a/src/mesa/pipe/tgsi/exec/tgsi_exec.c b/src/mesa/pipe/tgsi/exec/tgsi_exec.c index 27154d68839..d757df48d8d 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 0f2dd7d9874..ae5ce8a7c93 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 5c987436bed..431b82a98f4 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(