Initial support of loop and subroutine instructions.
New high-level flow-control instructions, both at IR level and GPU instructions for looping and subroutines.
This commit is contained in:
@@ -120,9 +120,13 @@ static const struct instruction_info InstInfo[MAX_OPCODE] = {
|
||||
{ OPCODE_ARL, "ARL", 1 },
|
||||
{ OPCODE_ARL_NV, "ARL", 1 },
|
||||
{ OPCODE_ARR, "ARL", 1 },
|
||||
{ OPCODE_BGNLOOP,"BGNLOOP", 0 },
|
||||
{ OPCODE_BGNSUB, "BGNSUB", 0 },
|
||||
{ OPCODE_BRA, "BRA", 0 },
|
||||
{ OPCODE_BRK, "BRK", 0 },
|
||||
{ OPCODE_CAL, "CAL", 0 },
|
||||
{ OPCODE_CMP, "CMP", 3 },
|
||||
{ OPCODE_CONT, "CONT", 1 },
|
||||
{ OPCODE_COS, "COS", 1 },
|
||||
{ OPCODE_DDX, "DDX", 1 },
|
||||
{ OPCODE_DDY, "DDY", 1 },
|
||||
@@ -133,6 +137,8 @@ static const struct instruction_info InstInfo[MAX_OPCODE] = {
|
||||
{ OPCODE_ELSE, "ELSE", 0 },
|
||||
{ OPCODE_END, "END", 0 },
|
||||
{ OPCODE_ENDIF, "ENDIF", 0 },
|
||||
{ OPCODE_ENDLOOP,"ENDLOOP", 0 },
|
||||
{ OPCODE_ENDSUB, "ENDSUB", 0 },
|
||||
{ OPCODE_EX2, "EX2", 1 },
|
||||
{ OPCODE_EXP, "EXP", 1 },
|
||||
{ OPCODE_FLR, "FLR", 1 },
|
||||
|
||||
@@ -143,9 +143,13 @@ typedef enum prog_opcode {
|
||||
OPCODE_ARL, /* X X */
|
||||
OPCODE_ARL_NV, /* 2 */
|
||||
OPCODE_ARR, /* 2 */
|
||||
OPCODE_BGNLOOP, /* opt */
|
||||
OPCODE_BGNSUB, /* opt */
|
||||
OPCODE_BRA, /* 2 X */
|
||||
OPCODE_BRK, /* 2 opt */
|
||||
OPCODE_CAL, /* 2 2 */
|
||||
OPCODE_CMP, /* X */
|
||||
OPCODE_CONT, /* opt */
|
||||
OPCODE_COS, /* X 2 X X */
|
||||
OPCODE_DDX, /* X X */
|
||||
OPCODE_DDY, /* X X */
|
||||
@@ -154,13 +158,15 @@ typedef enum prog_opcode {
|
||||
OPCODE_DPH, /* X X 1.1 */
|
||||
OPCODE_DST, /* X X X X */
|
||||
OPCODE_ELSE, /* X */
|
||||
OPCODE_END, /* X X X X X */
|
||||
OPCODE_ENDIF, /* X */
|
||||
OPCODE_END, /* X X X X opt */
|
||||
OPCODE_ENDIF, /* opt */
|
||||
OPCODE_ENDLOOP, /* opt */
|
||||
OPCODE_ENDSUB, /* opt */
|
||||
OPCODE_EX2, /* X X 2 X X */
|
||||
OPCODE_EXP, /* X X X */
|
||||
OPCODE_FLR, /* X X 2 X X */
|
||||
OPCODE_FRC, /* X X 2 X X */
|
||||
OPCODE_IF, /* X */
|
||||
OPCODE_IF, /* opt */
|
||||
OPCODE_INT, /* X */
|
||||
OPCODE_KIL, /* X */
|
||||
OPCODE_KIL_NV, /* X X */
|
||||
|
||||
@@ -1463,7 +1463,7 @@ _slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper)
|
||||
|
||||
|
||||
/**
|
||||
* Generate IR tree for an if/then/else conditional.
|
||||
* Generate IR tree for an if/then/else conditional using BRAnch instructions.
|
||||
*/
|
||||
static slang_ir_node *
|
||||
_slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper)
|
||||
@@ -1513,7 +1513,8 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper)
|
||||
|
||||
|
||||
/**
|
||||
* Use high-level IF/ELSE/ENDIF instructions
|
||||
* Generate IR tree for an if/then/else conditional using high-level
|
||||
* IF/ELSE/ENDIF instructions
|
||||
*/
|
||||
static slang_ir_node *
|
||||
_slang_gen_if2(slang_assemble_ctx * A, const slang_operation *oper)
|
||||
|
||||
@@ -297,6 +297,32 @@ slang_print_ir(const slang_ir_node *n, int indent)
|
||||
printf("ENDIF\n");
|
||||
break;
|
||||
|
||||
case IR_BEGIN_SUB:
|
||||
printf("BEGIN_SUB\n");
|
||||
break;
|
||||
case IR_END_SUB:
|
||||
printf("END_SUB\n");
|
||||
break;
|
||||
case IR_RETURN:
|
||||
printf("RETURN\n");
|
||||
break;
|
||||
case IR_CALL:
|
||||
printf("CALL\n");
|
||||
break;
|
||||
|
||||
case IR_BEGIN_LOOP:
|
||||
printf("BEGIN_LOOP\n");
|
||||
break;
|
||||
case IR_END_LOOP:
|
||||
printf("END_LOOP\n");
|
||||
break;
|
||||
case IR_CONT:
|
||||
printf("CONT\n");
|
||||
break;
|
||||
case IR_BREAK:
|
||||
printf("BREAK\n");
|
||||
break;
|
||||
|
||||
case IR_VAR:
|
||||
printf("VAR %s%s at %s store %p\n",
|
||||
(n->Var ? (char *) n->Var->a_name : "TEMP"),
|
||||
@@ -313,9 +339,6 @@ slang_print_ir(const slang_ir_node *n, int indent)
|
||||
printf("FIELD %s of\n", n->Target);
|
||||
slang_print_ir(n->Children[0], indent+3);
|
||||
break;
|
||||
case IR_CALL:
|
||||
printf("ASMCALL %s(%d args)\n", n->Target, 0/*XXX*/);
|
||||
break;
|
||||
case IR_FLOAT:
|
||||
printf("FLOAT %f %f %f %f\n",
|
||||
n->Value[0], n->Value[1], n->Value[2], n->Value[3]);
|
||||
|
||||
@@ -46,15 +46,27 @@ typedef enum
|
||||
IR_NOP = 0,
|
||||
IR_SEQ, /* sequence (eval left, then right) */
|
||||
IR_SCOPE, /* new variable scope (one child) */
|
||||
|
||||
IR_LABEL, /* target of a jump or cjump */
|
||||
IR_JUMP, /* unconditional jump */
|
||||
IR_CJUMP0, /* conditional jump if zero */
|
||||
IR_CJUMP1, /* conditional jump if one (or non-zero) */
|
||||
IR_COND, /* conditional expression */
|
||||
IR_COND, /* conditional expression/predicate */
|
||||
|
||||
IR_IF, /* high-level IF */
|
||||
IR_ELSE, /* high-level ELSE */
|
||||
IR_ENDIF, /* high-level ENDIF */
|
||||
IR_CALL, /* call subroutine */
|
||||
|
||||
IR_BEGIN_SUB, /* begin subroutine */
|
||||
IR_END_SUB, /* end subroutine */
|
||||
IR_RETURN, /* return from subroutine */
|
||||
IR_CALL, /* call subroutine */
|
||||
|
||||
IR_BEGIN_LOOP,/* begin loop */
|
||||
IR_END_LOOP, /* end loop */
|
||||
IR_CONT, /* continue loop */
|
||||
IR_BREAK, /* break loop */
|
||||
|
||||
IR_MOVE,
|
||||
IR_ADD,
|
||||
IR_SUB,
|
||||
@@ -90,17 +102,22 @@ typedef enum
|
||||
IR_NOISE3, /* noise(x, y, z) */
|
||||
IR_NOISE4, /* noise(x, y, z, w) */
|
||||
IR_NOT, /* logical not */
|
||||
|
||||
IR_VAR, /* variable reference */
|
||||
IR_VAR_DECL,/* var declaration */
|
||||
|
||||
IR_ELEMENT, /* array element */
|
||||
IR_FIELD, /* struct field */
|
||||
IR_SWIZZLE, /* swizzled storage access */
|
||||
|
||||
IR_TEX, /* texture lookup */
|
||||
IR_TEXB, /* texture lookup with LOD bias */
|
||||
IR_TEXP, /* texture lookup with projection */
|
||||
|
||||
IR_FLOAT,
|
||||
IR_FIELD,
|
||||
IR_I_TO_F, /* int[4] to float[4] conversion */
|
||||
IR_F_TO_I, /* float[4] to int[4] conversion */
|
||||
|
||||
IR_KILL /* fragment kill/discard */
|
||||
} slang_ir_opcode;
|
||||
|
||||
|
||||
@@ -675,6 +675,14 @@ execute_program( GLcontext *ctx,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OPCODE_BGNLOOP: /* begin loop */
|
||||
break;
|
||||
case OPCODE_ENDLOOP: /* end loop */
|
||||
break;
|
||||
case OPCODE_BGNSUB: /* begin subroutine */
|
||||
break;
|
||||
case OPCODE_ENDSUB: /* end subroutine */
|
||||
break;
|
||||
case OPCODE_BRA: /* conditional branch */
|
||||
{
|
||||
/* NOTE: The branch is conditional! */
|
||||
@@ -692,6 +700,9 @@ execute_program( GLcontext *ctx,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OPCODE_BRK: /* break out of loop */
|
||||
/* assert inside loop */
|
||||
break;
|
||||
case OPCODE_CAL: /* Call subroutine */
|
||||
{
|
||||
/* NOTE: The call is conditional! */
|
||||
@@ -722,6 +733,8 @@ execute_program( GLcontext *ctx,
|
||||
store_vector4( inst, machine, result );
|
||||
}
|
||||
break;
|
||||
case OPCODE_CONT: /* continue loop */
|
||||
break;
|
||||
case OPCODE_COS:
|
||||
{
|
||||
GLfloat a[4], result[4];
|
||||
|
||||
@@ -736,9 +736,13 @@ static void (* const opcode_func[MAX_OPCODE+3])(struct arb_vp_machine *, union i
|
||||
do_NOP,/*ARL*/
|
||||
do_NOP,/*ARL_NV*/
|
||||
do_NOP,/*ARR*/
|
||||
do_NOP,/*BGNLOOP*/
|
||||
do_NOP,/*BGNSUB*/
|
||||
do_NOP,/*BRA*/
|
||||
do_NOP,/*BRK*/
|
||||
do_NOP,/*CAL*/
|
||||
do_NOP,/*CMP*/
|
||||
do_NOP,/*CONT*/
|
||||
do_NOP,/*COS*/
|
||||
do_NOP,/*DDX*/
|
||||
do_NOP,/*DDY*/
|
||||
@@ -749,6 +753,8 @@ static void (* const opcode_func[MAX_OPCODE+3])(struct arb_vp_machine *, union i
|
||||
do_NOP,/*ELSE*/
|
||||
do_NOP,/*END*/
|
||||
do_NOP,/*ENDIF*/
|
||||
do_NOP,/*ENDLOOP*/
|
||||
do_NOP,/*ENDSUB*/
|
||||
do_EX2,
|
||||
do_EXP,
|
||||
do_FLR,
|
||||
|
||||
Reference in New Issue
Block a user