i965: Use immediate float operands for some VS instructions.

We could use this to reduce constant register pressure, but for now it
makes the resulting program assembly much more readable.
This commit is contained in:
Eric Anholt
2010-04-28 12:39:39 -07:00
parent ba6d8448e1
commit 084d8fdd36
+86
View File
@@ -37,6 +37,43 @@
#include "brw_context.h"
#include "brw_vs.h"
/* Return the SrcReg index of the channels that can be immediate float operands
* instead of usage of PROGRAM_CONSTANT values through push/pull.
*/
static GLboolean
brw_vs_arg_can_be_immediate(enum prog_opcode opcode, int arg)
{
int opcode_array[] = {
[OPCODE_ADD] = 2,
[OPCODE_CMP] = 3,
[OPCODE_DP3] = 2,
[OPCODE_DP4] = 2,
[OPCODE_DPH] = 2,
[OPCODE_MAX] = 1,
[OPCODE_MIN] = 2,
[OPCODE_MUL] = 2,
[OPCODE_SEQ] = 2,
[OPCODE_SGE] = 2,
[OPCODE_SGT] = 2,
[OPCODE_SLE] = 2,
[OPCODE_SLT] = 2,
[OPCODE_SNE] = 2,
[OPCODE_XPD] = 2,
};
/* These opcodes get broken down in a way that allow two
* args to be immediates.
*/
if (opcode == OPCODE_MAD || opcode == OPCODE_LRP) {
if (arg == 1 || arg == 2)
return GL_TRUE;
}
if (opcode > ARRAY_SIZE(opcode_array))
return GL_FALSE;
return arg == opcode_array[opcode] - 1;
}
static struct brw_reg get_tmp( struct brw_vs_compile *c )
{
@@ -983,6 +1020,55 @@ get_src_reg( struct brw_vs_compile *c,
const GLint index = inst->SrcReg[argIndex].Index;
const GLboolean relAddr = inst->SrcReg[argIndex].RelAddr;
if (brw_vs_arg_can_be_immediate(inst->Opcode, argIndex)) {
const struct prog_src_register *src = &inst->SrcReg[argIndex];
if (src->Swizzle == MAKE_SWIZZLE4(SWIZZLE_ZERO,
SWIZZLE_ZERO,
SWIZZLE_ZERO,
SWIZZLE_ZERO)) {
return brw_imm_f(0.0f);
} else if (src->Swizzle == MAKE_SWIZZLE4(SWIZZLE_ONE,
SWIZZLE_ONE,
SWIZZLE_ONE,
SWIZZLE_ONE)) {
if (src->Negate)
return brw_imm_f(-1.0F);
else
return brw_imm_f(1.0F);
} else if (src->File == PROGRAM_CONSTANT) {
const struct gl_program_parameter_list *params;
float f;
int component = -1;
switch (src->Swizzle) {
case SWIZZLE_XXXX:
component = 0;
break;
case SWIZZLE_YYYY:
component = 1;
break;
case SWIZZLE_ZZZZ:
component = 2;
break;
case SWIZZLE_WWWW:
component = 3;
break;
}
if (component >= 0) {
params = c->vp->program.Base.Parameters;
f = params->ParameterValues[src->Index][component];
if (src->Abs)
f = fabs(f);
if (src->Negate)
f = -f;
return brw_imm_f(f);
}
}
}
switch (file) {
case PROGRAM_TEMPORARY:
case PROGRAM_INPUT: