program: Remove condition-code and precision support.
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Acked-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
parent
9e11ff7e11
commit
7b50b0457d
|
@ -552,8 +552,6 @@ static void emit_dst( struct prog_dst_register *dst,
|
|||
dst->Index = reg.idx;
|
||||
/* allow zero as a shorthand for xyzw */
|
||||
dst->WriteMask = mask ? mask : WRITEMASK_XYZW;
|
||||
dst->CondMask = COND_TR; /* always pass cond test */
|
||||
dst->CondSwizzle = SWIZZLE_NOOP;
|
||||
/* Check that bitfield sizes aren't exceeded */
|
||||
assert(dst->Index == reg.idx);
|
||||
}
|
||||
|
|
|
@ -105,7 +105,6 @@ public:
|
|||
this->file = file;
|
||||
this->index = 0;
|
||||
this->writemask = writemask;
|
||||
this->cond_mask = COND_TR;
|
||||
this->reladdr = NULL;
|
||||
}
|
||||
|
||||
|
@ -114,7 +113,6 @@ public:
|
|||
this->file = PROGRAM_UNDEFINED;
|
||||
this->index = 0;
|
||||
this->writemask = 0;
|
||||
this->cond_mask = COND_TR;
|
||||
this->reladdr = NULL;
|
||||
}
|
||||
|
||||
|
@ -123,7 +121,6 @@ public:
|
|||
gl_register_file file; /**< PROGRAM_* from Mesa */
|
||||
int index; /**< temporary index, VERT_ATTRIB_*, VARYING_SLOT_*, etc. */
|
||||
int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
|
||||
GLuint cond_mask:4;
|
||||
/** Register index should be offset by the integer in this reg. */
|
||||
src_reg *reladdr;
|
||||
};
|
||||
|
@ -144,7 +141,6 @@ dst_reg::dst_reg(src_reg reg)
|
|||
this->file = reg.file;
|
||||
this->index = reg.index;
|
||||
this->writemask = WRITEMASK_XYZW;
|
||||
this->cond_mask = COND_TR;
|
||||
this->reladdr = reg.reladdr;
|
||||
}
|
||||
|
||||
|
@ -159,7 +155,6 @@ public:
|
|||
src_reg src[3];
|
||||
/** Pointer to the ir source this tree came from for debugging */
|
||||
ir_instruction *ir;
|
||||
GLboolean cond_update;
|
||||
bool saturate;
|
||||
int sampler; /**< sampler index */
|
||||
int tex_target; /**< One of TEXTURE_*_INDEX */
|
||||
|
@ -2769,12 +2764,10 @@ get_mesa_program(struct gl_context *ctx,
|
|||
i = 0;
|
||||
foreach_in_list(const ir_to_mesa_instruction, inst, &v.instructions) {
|
||||
mesa_inst->Opcode = inst->op;
|
||||
mesa_inst->CondUpdate = inst->cond_update;
|
||||
if (inst->saturate)
|
||||
mesa_inst->Saturate = GL_TRUE;
|
||||
mesa_inst->DstReg.File = inst->dst.file;
|
||||
mesa_inst->DstReg.Index = inst->dst.index;
|
||||
mesa_inst->DstReg.CondMask = inst->dst.cond_mask;
|
||||
mesa_inst->DstReg.WriteMask = inst->dst.writemask;
|
||||
mesa_inst->DstReg.RelAddr = inst->dst.reladdr != NULL;
|
||||
mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src[0]);
|
||||
|
|
|
@ -328,66 +328,6 @@ fetch_texel(struct gl_context *ctx,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test value against zero and return GT, LT, EQ or UN if NaN.
|
||||
*/
|
||||
static inline GLuint
|
||||
generate_cc(float value)
|
||||
{
|
||||
if (value != value)
|
||||
return COND_UN; /* NaN */
|
||||
if (value > 0.0F)
|
||||
return COND_GT;
|
||||
if (value < 0.0F)
|
||||
return COND_LT;
|
||||
return COND_EQ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test if the ccMaskRule is satisfied by the given condition code.
|
||||
* Used to mask destination writes according to the current condition code.
|
||||
*/
|
||||
static inline GLboolean
|
||||
test_cc(GLuint condCode, GLuint ccMaskRule)
|
||||
{
|
||||
switch (ccMaskRule) {
|
||||
case COND_EQ: return (condCode == COND_EQ);
|
||||
case COND_NE: return (condCode != COND_EQ);
|
||||
case COND_LT: return (condCode == COND_LT);
|
||||
case COND_GE: return (condCode == COND_GT || condCode == COND_EQ);
|
||||
case COND_LE: return (condCode == COND_LT || condCode == COND_EQ);
|
||||
case COND_GT: return (condCode == COND_GT);
|
||||
case COND_TR: return GL_TRUE;
|
||||
case COND_FL: return GL_FALSE;
|
||||
default: return GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 gl_program_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.
|
||||
|
@ -418,30 +358,6 @@ store_vector4(const struct prog_instruction *inst,
|
|||
value = clampedValue;
|
||||
}
|
||||
|
||||
if (dstReg->CondMask != COND_TR) {
|
||||
/* condition codes may turn off some writes */
|
||||
if (writeMask & WRITEMASK_X) {
|
||||
if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 0)],
|
||||
dstReg->CondMask))
|
||||
writeMask &= ~WRITEMASK_X;
|
||||
}
|
||||
if (writeMask & WRITEMASK_Y) {
|
||||
if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 1)],
|
||||
dstReg->CondMask))
|
||||
writeMask &= ~WRITEMASK_Y;
|
||||
}
|
||||
if (writeMask & WRITEMASK_Z) {
|
||||
if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 2)],
|
||||
dstReg->CondMask))
|
||||
writeMask &= ~WRITEMASK_Z;
|
||||
}
|
||||
if (writeMask & WRITEMASK_W) {
|
||||
if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 3)],
|
||||
dstReg->CondMask))
|
||||
writeMask &= ~WRITEMASK_W;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NAN_CHECK
|
||||
assert(!IS_INF_OR_NAN(value[0]));
|
||||
assert(!IS_INF_OR_NAN(value[0]));
|
||||
|
@ -457,24 +373,6 @@ store_vector4(const struct prog_instruction *inst,
|
|||
dst[2] = value[2];
|
||||
if (writeMask & WRITEMASK_W)
|
||||
dst[3] = value[3];
|
||||
|
||||
if (inst->CondUpdate) {
|
||||
if (writeMask & WRITEMASK_X)
|
||||
machine->CondCodes[0] = generate_cc(value[0]);
|
||||
if (writeMask & WRITEMASK_Y)
|
||||
machine->CondCodes[1] = generate_cc(value[1]);
|
||||
if (writeMask & WRITEMASK_Z)
|
||||
machine->CondCodes[2] = generate_cc(value[2]);
|
||||
if (writeMask & WRITEMASK_W)
|
||||
machine->CondCodes[3] = generate_cc(value[3]);
|
||||
#if DEBUG_PROG
|
||||
printf("CondCodes=(%s,%s,%s,%s) for:\n",
|
||||
_mesa_condcode_string(machine->CondCodes[0]),
|
||||
_mesa_condcode_string(machine->CondCodes[1]),
|
||||
_mesa_condcode_string(machine->CondCodes[2]),
|
||||
_mesa_condcode_string(machine->CondCodes[3]));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -572,31 +470,25 @@ _mesa_execute_program(struct gl_context * ctx,
|
|||
case OPCODE_BRK: /* break out of loop (conditional) */
|
||||
assert(program->Instructions[inst->BranchTarget].Opcode
|
||||
== OPCODE_ENDLOOP);
|
||||
if (eval_condition(machine, inst)) {
|
||||
/* break out of loop */
|
||||
/* pc++ at end of for-loop will put us after the ENDLOOP inst */
|
||||
pc = inst->BranchTarget;
|
||||
}
|
||||
/* break out of loop */
|
||||
/* pc++ at end of for-loop will put us after the ENDLOOP inst */
|
||||
pc = inst->BranchTarget;
|
||||
break;
|
||||
case OPCODE_CONT: /* continue loop (conditional) */
|
||||
assert(program->Instructions[inst->BranchTarget].Opcode
|
||||
== OPCODE_ENDLOOP);
|
||||
if (eval_condition(machine, inst)) {
|
||||
/* continue at ENDLOOP */
|
||||
/* Subtract 1 here since we'll do pc++ at end of for-loop */
|
||||
pc = inst->BranchTarget - 1;
|
||||
}
|
||||
/* continue at ENDLOOP */
|
||||
/* Subtract 1 here since we'll do pc++ at end of for-loop */
|
||||
pc = inst->BranchTarget - 1;
|
||||
break;
|
||||
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; /* next inst */
|
||||
/* Subtract 1 here since we'll do pc++ at end of for-loop */
|
||||
pc = inst->BranchTarget - 1;
|
||||
/* 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; /* next inst */
|
||||
/* Subtract 1 here since we'll do pc++ at end of for-loop */
|
||||
pc = inst->BranchTarget - 1;
|
||||
break;
|
||||
case OPCODE_CMP:
|
||||
{
|
||||
|
@ -778,9 +670,6 @@ _mesa_execute_program(struct gl_context * ctx,
|
|||
fetch_vector1(&inst->SrcReg[0], machine, a);
|
||||
cond = (a[0] != 0.0F);
|
||||
}
|
||||
else {
|
||||
cond = eval_condition(machine, inst);
|
||||
}
|
||||
if (DEBUG_PROG) {
|
||||
printf("IF: %d\n", cond);
|
||||
}
|
||||
|
@ -1066,13 +955,11 @@ _mesa_execute_program(struct gl_context * ctx,
|
|||
}
|
||||
break;
|
||||
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 */
|
||||
}
|
||||
/* subtract one because of pc++ in the for loop */
|
||||
pc = machine->CallStack[--machine->StackDepth] - 1;
|
||||
if (machine->StackDepth == 0) {
|
||||
return GL_TRUE; /* Per GL_NV_vertex_program2 spec */
|
||||
}
|
||||
/* subtract one because of pc++ in the for loop */
|
||||
pc = machine->CallStack[--machine->StackDepth] - 1;
|
||||
break;
|
||||
case OPCODE_RSQ: /* 1 / sqrt() */
|
||||
{
|
||||
|
|
|
@ -63,7 +63,6 @@ struct gl_program_machine
|
|||
GLfloat Temporaries[MAX_PROGRAM_TEMPS][4];
|
||||
GLfloat Outputs[MAX_PROGRAM_OUTPUTS][4];
|
||||
GLfloat (*EnvParams)[4]; /**< Vertex or Fragment env parameters */
|
||||
GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */
|
||||
GLint AddressReg[MAX_PROGRAM_ADDRESS_REGS][4];
|
||||
GLfloat SystemValues[SYSTEM_VALUE_MAX][4];
|
||||
|
||||
|
|
|
@ -52,11 +52,8 @@ _mesa_init_instructions(struct prog_instruction *inst, GLuint count)
|
|||
|
||||
inst[i].DstReg.File = PROGRAM_UNDEFINED;
|
||||
inst[i].DstReg.WriteMask = WRITEMASK_XYZW;
|
||||
inst[i].DstReg.CondMask = COND_TR;
|
||||
inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP;
|
||||
|
||||
inst[i].Saturate = GL_FALSE;
|
||||
inst[i].Precision = FLOAT32;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -91,32 +91,6 @@
|
|||
/*@}*/
|
||||
|
||||
|
||||
/**
|
||||
* Condition codes
|
||||
*/
|
||||
/*@{*/
|
||||
#define COND_GT 1 /**< greater than zero */
|
||||
#define COND_EQ 2 /**< equal to zero */
|
||||
#define COND_LT 3 /**< less than zero */
|
||||
#define COND_UN 4 /**< unordered (NaN) */
|
||||
#define COND_GE 5 /**< greater than or equal to zero */
|
||||
#define COND_LE 6 /**< less than or equal to zero */
|
||||
#define COND_NE 7 /**< not equal to zero */
|
||||
#define COND_TR 8 /**< always true */
|
||||
#define COND_FL 9 /**< always false */
|
||||
/*@}*/
|
||||
|
||||
|
||||
/**
|
||||
* Instruction precision for GL_NV_fragment_program
|
||||
*/
|
||||
/*@{*/
|
||||
#define FLOAT32 0x1
|
||||
#define FLOAT16 0x2
|
||||
#define FIXED12 0x4
|
||||
/*@}*/
|
||||
|
||||
|
||||
/**
|
||||
* Per-component negation masks
|
||||
*/
|
||||
|
@ -246,26 +220,6 @@ struct prog_dst_register
|
|||
GLuint Index:INST_INDEX_BITS; /**< Unsigned, never negative */
|
||||
GLuint WriteMask:4;
|
||||
GLuint RelAddr:1;
|
||||
|
||||
/**
|
||||
* \name Conditional destination update control.
|
||||
*
|
||||
* \since
|
||||
* NV_fragment_program_option, NV_vertex_program2, NV_vertex_program2_option.
|
||||
*/
|
||||
/*@{*/
|
||||
/**
|
||||
* Takes one of the 9 possible condition values (EQ, FL, GT, GE, LE, LT,
|
||||
* NE, TR, or UN). Dest reg is only written to if the matching
|
||||
* (swizzled) condition code value passes. When a conditional update mask
|
||||
* is not specified, this will be \c COND_TR.
|
||||
*/
|
||||
GLuint CondMask:4;
|
||||
|
||||
/**
|
||||
* Condition code swizzle value.
|
||||
*/
|
||||
GLuint CondSwizzle:12;
|
||||
};
|
||||
|
||||
|
||||
|
@ -278,44 +232,14 @@ struct prog_instruction
|
|||
struct prog_src_register SrcReg[3];
|
||||
struct prog_dst_register DstReg;
|
||||
|
||||
/**
|
||||
* Indicates that the instruction should update the condition code
|
||||
* register.
|
||||
*
|
||||
* \since
|
||||
* NV_fragment_program_option, NV_vertex_program2, NV_vertex_program2_option.
|
||||
*/
|
||||
GLuint CondUpdate:1;
|
||||
|
||||
/**
|
||||
* If prog_instruction::CondUpdate is \c GL_TRUE, this value selects the
|
||||
* condition code register that is to be updated.
|
||||
*
|
||||
* In GL_NV_fragment_program or GL_NV_vertex_program2 mode, only condition
|
||||
* code register 0 is available. In GL_NV_vertex_program3 mode, condition
|
||||
* code registers 0 and 1 are available.
|
||||
*
|
||||
* \since
|
||||
* NV_fragment_program_option, NV_vertex_program2, NV_vertex_program2_option.
|
||||
*/
|
||||
GLuint CondDst:1;
|
||||
|
||||
/**
|
||||
* Saturate each value of the vectored result to the range [0,1].
|
||||
*
|
||||
* \since
|
||||
* NV_fragment_program_option, NV_vertex_program3.
|
||||
* ARB_fragment_program
|
||||
*/
|
||||
GLuint Saturate:1;
|
||||
|
||||
/**
|
||||
* Per-instruction selectable precision: FLOAT32, FLOAT16, FIXED12.
|
||||
*
|
||||
* \since
|
||||
* NV_fragment_program_option.
|
||||
*/
|
||||
GLuint Precision:3;
|
||||
|
||||
/**
|
||||
* \name Extra fields for TEX, TXB, TXD, TXL, TXP instructions.
|
||||
*/
|
||||
|
|
|
@ -60,10 +60,7 @@ get_src_arg_mask(const struct prog_instruction *inst,
|
|||
assert(arg < _mesa_num_inst_src_regs(inst->Opcode));
|
||||
|
||||
/* Form the dst register, find the written channels */
|
||||
if (inst->CondUpdate) {
|
||||
channel_mask = WRITEMASK_XYZW;
|
||||
}
|
||||
else {
|
||||
{
|
||||
switch (inst->Opcode) {
|
||||
case OPCODE_MOV:
|
||||
case OPCODE_MIN:
|
||||
|
@ -302,17 +299,6 @@ _mesa_remove_dead_code_global(struct gl_program *prog)
|
|||
printf("abort remove dead code (indirect temp)\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (inst->CondUpdate) {
|
||||
/* If we're writing to this register and setting condition
|
||||
* codes we cannot remove the instruction. Prevent removal
|
||||
* by setting the 'read' flag.
|
||||
*/
|
||||
tempRead[index][0] = GL_TRUE;
|
||||
tempRead[index][1] = GL_TRUE;
|
||||
tempRead[index][2] = GL_TRUE;
|
||||
tempRead[index][3] = GL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -461,12 +447,10 @@ can_downward_mov_be_modifed(const struct prog_instruction *mov)
|
|||
{
|
||||
return
|
||||
mov->Opcode == OPCODE_MOV &&
|
||||
mov->CondUpdate == GL_FALSE &&
|
||||
mov->SrcReg[0].RelAddr == 0 &&
|
||||
mov->SrcReg[0].Negate == 0 &&
|
||||
mov->SrcReg[0].Abs == 0 &&
|
||||
mov->DstReg.RelAddr == 0 &&
|
||||
mov->DstReg.CondMask == COND_TR;
|
||||
mov->DstReg.RelAddr == 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -784,8 +768,7 @@ _mesa_remove_extra_moves(struct gl_program *prog)
|
|||
|
||||
if (prevInst->DstReg.File == PROGRAM_TEMPORARY &&
|
||||
prevInst->DstReg.Index == id &&
|
||||
prevInst->DstReg.RelAddr == 0 &&
|
||||
prevInst->DstReg.CondMask == COND_TR) {
|
||||
prevInst->DstReg.RelAddr == 0) {
|
||||
|
||||
const GLuint dst_mask = prevInst->DstReg.WriteMask;
|
||||
enum inst_use next_use = find_next_use(prog, i+1, id, dst_mask);
|
||||
|
|
|
@ -502,24 +502,6 @@ _mesa_writemask_string(GLuint writeMask)
|
|||
}
|
||||
|
||||
|
||||
const char *
|
||||
_mesa_condcode_string(GLuint condcode)
|
||||
{
|
||||
switch (condcode) {
|
||||
case COND_GT: return "GT";
|
||||
case COND_EQ: return "EQ";
|
||||
case COND_LT: return "LT";
|
||||
case COND_UN: return "UN";
|
||||
case COND_GE: return "GE";
|
||||
case COND_LE: return "LE";
|
||||
case COND_NE: return "NE";
|
||||
case COND_TR: return "TR";
|
||||
case COND_FL: return "FL";
|
||||
default: return "cond???";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fprint_dst_reg(FILE * f,
|
||||
const struct prog_dst_register *dstReg,
|
||||
|
@ -531,13 +513,6 @@ fprint_dst_reg(FILE * f,
|
|||
dstReg->Index, mode, dstReg->RelAddr, prog),
|
||||
_mesa_writemask_string(dstReg->WriteMask));
|
||||
|
||||
if (dstReg->CondMask != COND_TR) {
|
||||
fprintf(f, " (%s.%s)",
|
||||
_mesa_condcode_string(dstReg->CondMask),
|
||||
_mesa_swizzle_string(dstReg->CondSwizzle,
|
||||
GL_FALSE, GL_FALSE));
|
||||
}
|
||||
|
||||
#if 0
|
||||
fprintf(f, "%s[%d]%s",
|
||||
_mesa_register_file_name((gl_register_file) dstReg->File),
|
||||
|
@ -592,8 +567,6 @@ _mesa_fprint_alu_instruction(FILE *f,
|
|||
GLuint j;
|
||||
|
||||
fprintf(f, "%s", opcode_string);
|
||||
if (inst->CondUpdate)
|
||||
fprintf(f, ".C");
|
||||
|
||||
/* frag prog only */
|
||||
if (inst->Saturate)
|
||||
|
@ -714,19 +687,9 @@ _mesa_fprint_instruction_opt(FILE *f,
|
|||
fprint_comment(f, inst);
|
||||
break;
|
||||
case OPCODE_IF:
|
||||
if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
|
||||
/* Use ordinary register */
|
||||
fprintf(f, "IF ");
|
||||
fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
|
||||
fprintf(f, "; ");
|
||||
}
|
||||
else {
|
||||
/* Use cond codes */
|
||||
fprintf(f, "IF (%s%s);",
|
||||
_mesa_condcode_string(inst->DstReg.CondMask),
|
||||
_mesa_swizzle_string(inst->DstReg.CondSwizzle,
|
||||
0, GL_FALSE));
|
||||
}
|
||||
fprintf(f, "IF ");
|
||||
fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
|
||||
fprintf(f, "; ");
|
||||
fprintf(f, " # (if false, goto %d)", inst->BranchTarget);
|
||||
fprint_comment(f, inst);
|
||||
return indent + 3;
|
||||
|
@ -744,10 +707,8 @@ _mesa_fprint_instruction_opt(FILE *f,
|
|||
break;
|
||||
case OPCODE_BRK:
|
||||
case OPCODE_CONT:
|
||||
fprintf(f, "%s (%s%s); # (goto %d)",
|
||||
fprintf(f, "%s; # (goto %d)",
|
||||
_mesa_opcode_string(inst->Opcode),
|
||||
_mesa_condcode_string(inst->DstReg.CondMask),
|
||||
_mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
|
||||
inst->BranchTarget);
|
||||
fprint_comment(f, inst);
|
||||
break;
|
||||
|
@ -767,9 +728,7 @@ _mesa_fprint_instruction_opt(FILE *f,
|
|||
fprint_comment(f, inst);
|
||||
break;
|
||||
case OPCODE_RET:
|
||||
fprintf(f, "RET (%s%s)",
|
||||
_mesa_condcode_string(inst->DstReg.CondMask),
|
||||
_mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
|
||||
fprintf(f, "RET");
|
||||
fprint_comment(f, inst);
|
||||
break;
|
||||
|
||||
|
|
|
@ -161,9 +161,6 @@ exp [Ee][-+]?[0-9]+
|
|||
frac "."[0-9]+
|
||||
dot "."[ \t]*
|
||||
|
||||
sz [HRX]?
|
||||
szf [HR]?
|
||||
cc C?
|
||||
sat (_SAT)?
|
||||
|
||||
%option prefix="_mesa_program_lexer_"
|
||||
|
@ -184,59 +181,59 @@ OUTPUT { return OUTPUT; }
|
|||
PARAM { return PARAM; }
|
||||
TEMP { yylval->integer = at_temp; return TEMP; }
|
||||
|
||||
ABS{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, ABS, 3); }
|
||||
ADD{sz}{cc}{sat} { return_opcode( 1, BIN_OP, ADD, 3); }
|
||||
ABS{sat} { return_opcode( 1, VECTOR_OP, ABS, 3); }
|
||||
ADD{sat} { return_opcode( 1, BIN_OP, ADD, 3); }
|
||||
ARL { return_opcode(require_ARB_vp, ARL, ARL, 3); }
|
||||
|
||||
CMP{sat} { return_opcode(require_ARB_fp, TRI_OP, CMP, 3); }
|
||||
COS{szf}{cc}{sat} { return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); }
|
||||
COS{sat} { return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); }
|
||||
|
||||
DDX{szf}{cc}{sat} { return_opcode(require_NV_fp, VECTOR_OP, DDX, 3); }
|
||||
DDY{szf}{cc}{sat} { return_opcode(require_NV_fp, VECTOR_OP, DDY, 3); }
|
||||
DP3{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DP3, 3); }
|
||||
DP4{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DP4, 3); }
|
||||
DPH{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DPH, 3); }
|
||||
DST{szf}{cc}{sat} { return_opcode( 1, BIN_OP, DST, 3); }
|
||||
DDX{sat} { return_opcode(require_NV_fp, VECTOR_OP, DDX, 3); }
|
||||
DDY{sat} { return_opcode(require_NV_fp, VECTOR_OP, DDY, 3); }
|
||||
DP3{sat} { return_opcode( 1, BIN_OP, DP3, 3); }
|
||||
DP4{sat} { return_opcode( 1, BIN_OP, DP4, 3); }
|
||||
DPH{sat} { return_opcode( 1, BIN_OP, DPH, 3); }
|
||||
DST{sat} { return_opcode( 1, BIN_OP, DST, 3); }
|
||||
|
||||
EX2{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, EX2, 3); }
|
||||
EX2{sat} { return_opcode( 1, SCALAR_OP, EX2, 3); }
|
||||
EXP { return_opcode(require_ARB_vp, SCALAR_OP, EXP, 3); }
|
||||
|
||||
FLR{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, FLR, 3); }
|
||||
FRC{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, FRC, 3); }
|
||||
FLR{sat} { return_opcode( 1, VECTOR_OP, FLR, 3); }
|
||||
FRC{sat} { return_opcode( 1, VECTOR_OP, FRC, 3); }
|
||||
|
||||
KIL { return_opcode(require_ARB_fp, KIL, KIL, 3); }
|
||||
|
||||
LIT{szf}{cc}{sat} { return_opcode( 1, VECTOR_OP, LIT, 3); }
|
||||
LG2{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, LG2, 3); }
|
||||
LIT{sat} { return_opcode( 1, VECTOR_OP, LIT, 3); }
|
||||
LG2{sat} { return_opcode( 1, SCALAR_OP, LG2, 3); }
|
||||
LOG { return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); }
|
||||
LRP{sz}{cc}{sat} { return_opcode(require_ARB_fp, TRI_OP, LRP, 3); }
|
||||
LRP{sat} { return_opcode(require_ARB_fp, TRI_OP, LRP, 3); }
|
||||
|
||||
MAD{sz}{cc}{sat} { return_opcode( 1, TRI_OP, MAD, 3); }
|
||||
MAX{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MAX, 3); }
|
||||
MIN{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MIN, 3); }
|
||||
MOV{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, MOV, 3); }
|
||||
MUL{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MUL, 3); }
|
||||
MAD{sat} { return_opcode( 1, TRI_OP, MAD, 3); }
|
||||
MAX{sat} { return_opcode( 1, BIN_OP, MAX, 3); }
|
||||
MIN{sat} { return_opcode( 1, BIN_OP, MIN, 3); }
|
||||
MOV{sat} { return_opcode( 1, VECTOR_OP, MOV, 3); }
|
||||
MUL{sat} { return_opcode( 1, BIN_OP, MUL, 3); }
|
||||
|
||||
POW{szf}{cc}{sat} { return_opcode( 1, BINSC_OP, POW, 3); }
|
||||
POW{sat} { return_opcode( 1, BINSC_OP, POW, 3); }
|
||||
|
||||
RCP{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, RCP, 3); }
|
||||
RSQ{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, RSQ, 3); }
|
||||
RCP{sat} { return_opcode( 1, SCALAR_OP, RCP, 3); }
|
||||
RSQ{sat} { return_opcode( 1, SCALAR_OP, RSQ, 3); }
|
||||
|
||||
SCS{sat} { return_opcode(require_ARB_fp, SCALAR_OP, SCS, 3); }
|
||||
SEQ{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SEQ, 3); }
|
||||
SGE{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SGE, 3); }
|
||||
SGT{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SGT, 3); }
|
||||
SIN{szf}{cc}{sat} { return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); }
|
||||
SLE{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SLE, 3); }
|
||||
SLT{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SLT, 3); }
|
||||
SNE{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SNE, 3); }
|
||||
SUB{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SUB, 3); }
|
||||
SEQ{sat} { return_opcode(require_NV_fp, BIN_OP, SEQ, 3); }
|
||||
SGE{sat} { return_opcode( 1, BIN_OP, SGE, 3); }
|
||||
SGT{sat} { return_opcode(require_NV_fp, BIN_OP, SGT, 3); }
|
||||
SIN{sat} { return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); }
|
||||
SLE{sat} { return_opcode(require_NV_fp, BIN_OP, SLE, 3); }
|
||||
SLT{sat} { return_opcode( 1, BIN_OP, SLT, 3); }
|
||||
SNE{sat} { return_opcode(require_NV_fp, BIN_OP, SNE, 3); }
|
||||
SUB{sat} { return_opcode( 1, BIN_OP, SUB, 3); }
|
||||
SWZ{sat} { return_opcode( 1, SWZ, SWZ, 3); }
|
||||
|
||||
TEX{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); }
|
||||
TXB{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); }
|
||||
TXD{cc}{sat} { return_opcode(require_NV_fp, TXD_OP, TXD, 3); }
|
||||
TXP{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); }
|
||||
TEX{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); }
|
||||
TXB{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); }
|
||||
TXD{sat} { return_opcode(require_NV_fp, TXD_OP, TXD, 3); }
|
||||
TXP{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); }
|
||||
|
||||
XPD{sat} { return_opcode( 1, BIN_OP, XPD, 3); }
|
||||
|
||||
|
|
|
@ -212,8 +212,6 @@ static struct asm_instruction *asm_instruction_copy_ctor(
|
|||
%type <sym> addrReg
|
||||
%type <swiz_mask> addrComponent addrWriteMask
|
||||
|
||||
%type <dst_reg> ccMaskRule ccTest ccMaskRule2 ccTest2 optionalCcMask
|
||||
|
||||
%type <result> resultBinding resultColBinding
|
||||
%type <integer> optFaceType optColorType
|
||||
%type <integer> optResultFaceType optResultColorType
|
||||
|
@ -631,12 +629,10 @@ swizzleSrcReg: optionalSign srcReg swizzleSuffix
|
|||
|
||||
;
|
||||
|
||||
maskedDstReg: dstReg optionalMask optionalCcMask
|
||||
maskedDstReg: dstReg optionalMask
|
||||
{
|
||||
$$ = $1;
|
||||
$$.WriteMask = $2.mask;
|
||||
$$.CondMask = $3.CondMask;
|
||||
$$.CondSwizzle = $3.CondSwizzle;
|
||||
|
||||
if ($$.File == PROGRAM_OUTPUT) {
|
||||
/* Technically speaking, this should check that it is in
|
||||
|
@ -1022,79 +1018,6 @@ optionalMask: MASK4 | MASK3 | MASK2 | MASK1
|
|||
| { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
|
||||
;
|
||||
|
||||
optionalCcMask: '(' ccTest ')'
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
| '(' ccTest2 ')'
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
|
|
||||
{
|
||||
$$.CondMask = COND_TR;
|
||||
$$.CondSwizzle = SWIZZLE_NOOP;
|
||||
}
|
||||
;
|
||||
|
||||
ccTest: ccMaskRule swizzleSuffix
|
||||
{
|
||||
$$ = $1;
|
||||
$$.CondSwizzle = $2.swizzle;
|
||||
}
|
||||
;
|
||||
|
||||
ccTest2: ccMaskRule2 swizzleSuffix
|
||||
{
|
||||
$$ = $1;
|
||||
$$.CondSwizzle = $2.swizzle;
|
||||
}
|
||||
;
|
||||
|
||||
ccMaskRule: IDENTIFIER
|
||||
{
|
||||
const int cond = _mesa_parse_cc($1);
|
||||
if ((cond == 0) || ($1[2] != '\0')) {
|
||||
char *const err_str =
|
||||
make_error_string("invalid condition code \"%s\"", $1);
|
||||
|
||||
yyerror(& @1, state, (err_str != NULL)
|
||||
? err_str : "invalid condition code");
|
||||
|
||||
if (err_str != NULL) {
|
||||
free(err_str);
|
||||
}
|
||||
|
||||
YYERROR;
|
||||
}
|
||||
|
||||
$$.CondMask = cond;
|
||||
$$.CondSwizzle = SWIZZLE_NOOP;
|
||||
}
|
||||
;
|
||||
|
||||
ccMaskRule2: USED_IDENTIFIER
|
||||
{
|
||||
const int cond = _mesa_parse_cc($1);
|
||||
if ((cond == 0) || ($1[2] != '\0')) {
|
||||
char *const err_str =
|
||||
make_error_string("invalid condition code \"%s\"", $1);
|
||||
|
||||
yyerror(& @1, state, (err_str != NULL)
|
||||
? err_str : "invalid condition code");
|
||||
|
||||
if (err_str != NULL) {
|
||||
free(err_str);
|
||||
}
|
||||
|
||||
YYERROR;
|
||||
}
|
||||
|
||||
$$.CondMask = cond;
|
||||
$$.CondSwizzle = SWIZZLE_NOOP;
|
||||
}
|
||||
;
|
||||
|
||||
namingStatement: ATTRIB_statement
|
||||
| PARAM_statement
|
||||
| TEMP_statement
|
||||
|
@ -2241,9 +2164,6 @@ asm_instruction_set_operands(struct asm_instruction *inst,
|
|||
inst->Base.DstReg = *dst;
|
||||
}
|
||||
|
||||
/* The only instruction that doesn't have any source registers is the
|
||||
* condition-code based KIL instruction added by NV_fragment_program_option.
|
||||
*/
|
||||
if (src0 != NULL) {
|
||||
inst->Base.SrcReg[0] = src0->Base;
|
||||
inst->SrcReg[0] = *src0;
|
||||
|
@ -2299,10 +2219,7 @@ asm_instruction_copy_ctor(const struct prog_instruction *base,
|
|||
if (inst) {
|
||||
_mesa_init_instructions(& inst->Base, 1);
|
||||
inst->Base.Opcode = base->Opcode;
|
||||
inst->Base.CondUpdate = base->CondUpdate;
|
||||
inst->Base.CondDst = base->CondDst;
|
||||
inst->Base.Saturate = base->Saturate;
|
||||
inst->Base.Precision = base->Precision;
|
||||
|
||||
asm_instruction_set_operands(inst, dst, src0, src1, src2);
|
||||
}
|
||||
|
@ -2317,8 +2234,6 @@ init_dst_reg(struct prog_dst_register *r)
|
|||
memset(r, 0, sizeof(*r));
|
||||
r->File = PROGRAM_UNDEFINED;
|
||||
r->WriteMask = WRITEMASK_XYZW;
|
||||
r->CondMask = COND_TR;
|
||||
r->CondSwizzle = SWIZZLE_NOOP;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2339,8 +2254,6 @@ set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index)
|
|||
r->File = file;
|
||||
r->Index = index;
|
||||
r->WriteMask = WRITEMASK_XYZW;
|
||||
r->CondMask = COND_TR;
|
||||
r->CondSwizzle = SWIZZLE_NOOP;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -38,46 +38,10 @@ _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
|
|||
const char *suffix,
|
||||
struct prog_instruction *inst)
|
||||
{
|
||||
inst->CondUpdate = 0;
|
||||
inst->CondDst = 0;
|
||||
inst->Saturate = GL_FALSE;
|
||||
inst->Precision = FLOAT32;
|
||||
|
||||
|
||||
/* The first possible suffix element is the precision specifier from
|
||||
* NV_fragment_program_option.
|
||||
*/
|
||||
if (state->option.NV_fragment) {
|
||||
switch (suffix[0]) {
|
||||
case 'H':
|
||||
inst->Precision = FLOAT16;
|
||||
suffix++;
|
||||
break;
|
||||
case 'R':
|
||||
inst->Precision = FLOAT32;
|
||||
suffix++;
|
||||
break;
|
||||
case 'X':
|
||||
inst->Precision = FIXED12;
|
||||
suffix++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The next possible suffix element is the condition code modifier selection
|
||||
* from NV_fragment_program_option.
|
||||
*/
|
||||
if (state->option.NV_fragment) {
|
||||
if (suffix[0] == 'C') {
|
||||
inst->CondUpdate = 1;
|
||||
suffix++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* The final possible suffix element is the saturation selector from
|
||||
/* The only possible suffix element is the saturation selector from
|
||||
* ARB_fragment_program.
|
||||
*/
|
||||
if (state->mode == ARB_fragment) {
|
||||
|
@ -94,60 +58,6 @@ _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
|
|||
}
|
||||
|
||||
|
||||
int
|
||||
_mesa_parse_cc(const char *s)
|
||||
{
|
||||
int cond = 0;
|
||||
|
||||
switch (s[0]) {
|
||||
case 'E':
|
||||
if (s[1] == 'Q') {
|
||||
cond = COND_EQ;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
if (s[1] == 'L') {
|
||||
cond = COND_FL;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
if (s[1] == 'E') {
|
||||
cond = COND_GE;
|
||||
} else if (s[1] == 'T') {
|
||||
cond = COND_GT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
if (s[1] == 'E') {
|
||||
cond = COND_LE;
|
||||
} else if (s[1] == 'T') {
|
||||
cond = COND_LT;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
if (s[1] == 'E') {
|
||||
cond = COND_NE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
if (s[1] == 'R') {
|
||||
cond = COND_TR;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ((cond == 0) || (s[2] != '\0')) ? 0 : cond;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_mesa_ARBvp_parse_option(struct asm_parser_state *state, const char *option)
|
||||
{
|
||||
|
@ -269,17 +179,6 @@ _mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option)
|
|||
state->option.DrawBuffers = 1;
|
||||
return 1;
|
||||
}
|
||||
} else if (strncmp(option, "NV_fragment_program", 19) == 0) {
|
||||
option += 19;
|
||||
|
||||
/* Other NV_fragment_program strings may be supported later.
|
||||
*/
|
||||
if (option[0] == '\0') {
|
||||
if (state->ctx->Extensions.NV_fragment_program_option) {
|
||||
state->option.NV_fragment = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -286,17 +286,4 @@ extern int _mesa_ARBfp_parse_option(struct asm_parser_state *state,
|
|||
extern int _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
|
||||
const char *suffix, struct prog_instruction *inst);
|
||||
|
||||
/**
|
||||
* Parses a condition code name
|
||||
*
|
||||
* The condition code names (e.g., \c LT, \c GT, \c NE) were added to assembly
|
||||
* shaders with the \c GL_NV_fragment_program_option extension. This function
|
||||
* converts a string representation into one of the \c COND_ macros.
|
||||
*
|
||||
* \return
|
||||
* One of the \c COND_ macros defined in prog_instruction.h on success or zero
|
||||
* on failure.
|
||||
*/
|
||||
extern int _mesa_parse_cc(const char *s);
|
||||
|
||||
/*@}*/
|
||||
|
|
|
@ -166,7 +166,6 @@ public:
|
|||
this->index = index;
|
||||
this->index2D = 0;
|
||||
this->writemask = writemask;
|
||||
this->cond_mask = COND_TR;
|
||||
this->reladdr = NULL;
|
||||
this->reladdr2 = NULL;
|
||||
this->has_index2 = false;
|
||||
|
@ -180,7 +179,6 @@ public:
|
|||
this->index = 0;
|
||||
this->index2D = 0;
|
||||
this->writemask = writemask;
|
||||
this->cond_mask = COND_TR;
|
||||
this->reladdr = NULL;
|
||||
this->reladdr2 = NULL;
|
||||
this->has_index2 = false;
|
||||
|
@ -195,7 +193,6 @@ public:
|
|||
this->index = 0;
|
||||
this->index2D = 0;
|
||||
this->writemask = 0;
|
||||
this->cond_mask = COND_TR;
|
||||
this->reladdr = NULL;
|
||||
this->reladdr2 = NULL;
|
||||
this->has_index2 = false;
|
||||
|
@ -208,7 +205,6 @@ public:
|
|||
int index; /**< temporary index, VERT_ATTRIB_*, VARYING_SLOT_*, etc. */
|
||||
int index2D;
|
||||
int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
|
||||
GLuint cond_mask:4;
|
||||
int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */
|
||||
/** Register index should be offset by the integer in this reg. */
|
||||
st_src_reg *reladdr;
|
||||
|
@ -239,7 +235,6 @@ st_dst_reg::st_dst_reg(st_src_reg reg)
|
|||
this->file = reg.file;
|
||||
this->index = reg.index;
|
||||
this->writemask = WRITEMASK_XYZW;
|
||||
this->cond_mask = COND_TR;
|
||||
this->reladdr = reg.reladdr;
|
||||
this->index2D = reg.index2D;
|
||||
this->reladdr2 = reg.reladdr2;
|
||||
|
@ -3675,7 +3670,6 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
|
|||
l.index = storage->index;
|
||||
l.reladdr = NULL;
|
||||
l.writemask = WRITEMASK_XYZW;
|
||||
l.cond_mask = COND_TR;
|
||||
|
||||
for (i = 0; i < type_size(param->type); i++) {
|
||||
emit_asm(ir, TGSI_OPCODE_MOV, l, r);
|
||||
|
|
|
@ -189,12 +189,6 @@ init_machine(struct gl_context *ctx, struct gl_program_machine *machine,
|
|||
|
||||
machine->CurElement = col;
|
||||
|
||||
/* init condition codes */
|
||||
machine->CondCodes[0] = COND_EQ;
|
||||
machine->CondCodes[1] = COND_EQ;
|
||||
machine->CondCodes[2] = COND_EQ;
|
||||
machine->CondCodes[3] = COND_EQ;
|
||||
|
||||
/* init call stack */
|
||||
machine->StackDepth = 0;
|
||||
|
||||
|
|
|
@ -232,12 +232,6 @@ init_machine(struct gl_context *ctx, struct gl_program_machine *machine,
|
|||
|
||||
machine->NumDeriv = 0;
|
||||
|
||||
/* init condition codes */
|
||||
machine->CondCodes[0] = COND_EQ;
|
||||
machine->CondCodes[1] = COND_EQ;
|
||||
machine->CondCodes[2] = COND_EQ;
|
||||
machine->CondCodes[3] = COND_EQ;
|
||||
|
||||
/* init call stack */
|
||||
machine->StackDepth = 0;
|
||||
|
||||
|
|
Loading…
Reference in New Issue