Simplify code with eval_condition(). Implement conditional BRK.
This commit is contained in:
@@ -417,6 +417,29 @@ test_cc(GLuint condCode, GLuint ccMaskRule)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Evaluate the 4 condition codes against a predicate and return GL_TRUE
|
||||
* or GL_FALSE to indicate result.
|
||||
*/
|
||||
static INLINE GLboolean
|
||||
eval_condition(const struct fp_machine *machine,
|
||||
const struct prog_instruction *inst)
|
||||
{
|
||||
const GLuint swizzle = inst->DstReg.CondSwizzle;
|
||||
const GLuint condMask = inst->DstReg.CondMask;
|
||||
if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
|
||||
return GL_TRUE;
|
||||
}
|
||||
else {
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Store 4 floats into a register. Observe the instructions saturate and
|
||||
* set-condition-code flags.
|
||||
@@ -687,40 +710,28 @@ execute_program( GLcontext *ctx,
|
||||
case OPCODE_ENDSUB: /* end subroutine */
|
||||
break;
|
||||
case OPCODE_BRA: /* conditional branch */
|
||||
{
|
||||
/* NOTE: The branch is conditional! */
|
||||
const GLuint swizzle = inst->DstReg.CondSwizzle;
|
||||
const GLuint condMask = inst->DstReg.CondMask;
|
||||
if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
|
||||
/* take branch */
|
||||
pc = inst->BranchTarget - 1;
|
||||
}
|
||||
if (eval_condition(machine, inst)) {
|
||||
/* take branch */
|
||||
pc = inst->BranchTarget - 1;
|
||||
}
|
||||
break;
|
||||
case OPCODE_BRK: /* break out of loop */
|
||||
case OPCODE_BRK: /* break out of loop (conditional) */
|
||||
/* fall-through */
|
||||
case OPCODE_CONT: /* continue loop */
|
||||
case OPCODE_CONT: /* continue loop (conditional) */
|
||||
/* Subtract 1 here since we'll do pc++ at end of for-loop */
|
||||
pc = inst->BranchTarget - 1;
|
||||
if (eval_condition(machine, inst)) {
|
||||
/* take branch */
|
||||
pc = inst->BranchTarget - 1;
|
||||
}
|
||||
break;
|
||||
case OPCODE_CAL: /* Call subroutine */
|
||||
{
|
||||
/* NOTE: The call is conditional! */
|
||||
const GLuint swizzle = inst->DstReg.CondSwizzle;
|
||||
const GLuint condMask = inst->DstReg.CondMask;
|
||||
if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
|
||||
if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) {
|
||||
return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
|
||||
}
|
||||
machine->CallStack[machine->StackDepth++] = pc + 1;
|
||||
pc = inst->BranchTarget; /* XXX - 1 ??? */
|
||||
case OPCODE_CAL: /* Call subroutine (conditional) */
|
||||
if (eval_condition(machine, inst)) {
|
||||
/* call the subroutine */
|
||||
if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) {
|
||||
return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
|
||||
}
|
||||
machine->CallStack[machine->StackDepth++] = pc + 1;
|
||||
pc = inst->BranchTarget; /* XXX - 1 ??? */
|
||||
}
|
||||
break;
|
||||
case OPCODE_CMP:
|
||||
@@ -871,29 +882,20 @@ execute_program( GLcontext *ctx,
|
||||
}
|
||||
break;
|
||||
case OPCODE_IF:
|
||||
{
|
||||
const GLuint swizzle = inst->DstReg.CondSwizzle;
|
||||
const GLuint condMask = inst->DstReg.CondMask;
|
||||
if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
|
||||
/* do if-clause (just continue execution) */
|
||||
}
|
||||
else {
|
||||
/* go to the instruction after ELSE or ENDIF */
|
||||
assert(inst->BranchTarget >= 0);
|
||||
pc = inst->BranchTarget - 1;
|
||||
}
|
||||
if (eval_condition(machine, inst)) {
|
||||
/* do if-clause (just continue execution) */
|
||||
}
|
||||
break;
|
||||
case OPCODE_ELSE:
|
||||
{
|
||||
/* goto ENDIF */
|
||||
else {
|
||||
/* go to the instruction after ELSE or ENDIF */
|
||||
assert(inst->BranchTarget >= 0);
|
||||
pc = inst->BranchTarget - 1;
|
||||
}
|
||||
break;
|
||||
case OPCODE_ELSE:
|
||||
/* goto ENDIF */
|
||||
assert(inst->BranchTarget >= 0);
|
||||
pc = inst->BranchTarget - 1;
|
||||
break;
|
||||
case OPCODE_ENDIF:
|
||||
/* nothing */
|
||||
break;
|
||||
@@ -908,16 +910,9 @@ execute_program( GLcontext *ctx,
|
||||
store_vector4( inst, machine, result );
|
||||
}
|
||||
break;
|
||||
case OPCODE_KIL_NV: /* NV_f_p only */
|
||||
{
|
||||
const GLuint swizzle = inst->DstReg.CondSwizzle;
|
||||
const GLuint condMask = inst->DstReg.CondMask;
|
||||
if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
case OPCODE_KIL_NV: /* NV_f_p only (conditional) */
|
||||
if (eval_condition(machine, inst)) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
break;
|
||||
case OPCODE_KIL: /* ARB_f_p only */
|
||||
@@ -1203,20 +1198,12 @@ execute_program( GLcontext *ctx,
|
||||
store_vector4( inst, machine, result );
|
||||
}
|
||||
break;
|
||||
case OPCODE_RET: /* return from subroutine */
|
||||
{
|
||||
/* NOTE: The return is conditional! */
|
||||
const GLuint swizzle = inst->DstReg.CondSwizzle;
|
||||
const GLuint condMask = inst->DstReg.CondMask;
|
||||
if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
|
||||
test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
|
||||
if (machine->StackDepth == 0) {
|
||||
return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
|
||||
}
|
||||
pc = machine->CallStack[--machine->StackDepth];
|
||||
case OPCODE_RET: /* return from subroutine (conditional) */
|
||||
if (eval_condition(machine, inst)) {
|
||||
if (machine->StackDepth == 0) {
|
||||
return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
|
||||
}
|
||||
pc = machine->CallStack[--machine->StackDepth];
|
||||
}
|
||||
break;
|
||||
case OPCODE_RFL: /* reflection vector */
|
||||
|
Reference in New Issue
Block a user