diff options
author | Eric Anholt <[email protected]> | 2010-04-28 12:39:39 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2010-04-29 08:34:14 -0700 |
commit | 084d8fdd36bbf04520f59fecfad54be0695531f2 (patch) | |
tree | 453452b66f40dd52c60bc3bdd357f9772f63df88 | |
parent | ba6d8448e11048687d2aa44a519c09b98fff1e94 (diff) |
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.
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vs_emit.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index eeb3f366a41..e83c9bf1051 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -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: |