Mesa (master): i965: Allow FS constants to be used as immediates instead of push/pull.
Eric Anholt
anholt at kemper.freedesktop.org
Mon Mar 22 22:05:33 UTC 2010
Module: Mesa
Branch: master
Commit: 4fc57322258a750c0a9cabc77372b5ccde1fa877
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=4fc57322258a750c0a9cabc77372b5ccde1fa877
Author: Eric Anholt <eric at anholt.net>
Date: Fri Mar 19 12:34:53 2010 -0700
i965: Allow FS constants to be used as immediates instead of push/pull.
The hope is to later take advantage of the reduced constant usage to
free up regs. This only covers the GLSL path at the moment, because
the brw_wm_emit path doesn't get the information as to whether a float
value is a constant or a uniform.
---
src/mesa/drivers/dri/i965/brw_wm.h | 2 +-
src/mesa/drivers/dri/i965/brw_wm_emit.c | 38 +++++++++++++++++++++++++++++++
src/mesa/drivers/dri/i965/brw_wm_glsl.c | 25 +++++++++++++++-----
3 files changed, 58 insertions(+), 7 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index 47b764d..5aade1c 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -286,7 +286,7 @@ void brw_wm_pass0( struct brw_wm_compile *c );
void brw_wm_pass1( struct brw_wm_compile *c );
void brw_wm_pass2( struct brw_wm_compile *c );
void brw_wm_emit( struct brw_wm_compile *c );
-
+GLboolean brw_wm_arg_can_be_immediate(enum prog_opcode, int arg);
void brw_wm_print_value( struct brw_wm_compile *c,
struct brw_wm_value *value );
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index 5abc067..f79de5d 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -61,6 +61,44 @@ static INLINE struct brw_reg sechalf( struct brw_reg reg )
return reg;
}
+/* Return the SrcReg index of the channels that can be immediate float operands
+ * instead of usage of PROGRAM_CONSTANT values through push/pull.
+ */
+GLboolean
+brw_wm_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] = 2,
+ [OPCODE_MIN] = 2,
+ [OPCODE_MOV] = 1,
+ [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;
+}
/**
* Computes the screen-space x,y position of the pixels.
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index d9d6dda..d78fb4e 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -570,12 +570,25 @@ static struct brw_reg get_src_reg(struct brw_wm_compile *c,
const GLuint nr = 1;
const GLuint component = GET_SWZ(src->Swizzle, channel);
- /* Extended swizzle terms */
- if (component == SWIZZLE_ZERO) {
- return brw_imm_f(0.0F);
- }
- else if (component == SWIZZLE_ONE) {
- return brw_imm_f(1.0F);
+ /* Only one immediate value can be used per native opcode, and it
+ * has be in the src1 slot, so not all Mesa instructions will get
+ * to take advantage of immediate constants.
+ */
+ if (brw_wm_arg_can_be_immediate(inst->Opcode, srcRegIndex)) {
+ const struct gl_program_parameter_list *params;
+
+ params = c->fp->program.Base.Parameters;
+
+ /* Extended swizzle terms */
+ if (component == SWIZZLE_ZERO) {
+ return brw_imm_f(0.0F);
+ } else if (component == SWIZZLE_ONE) {
+ return brw_imm_f(1.0F);
+ }
+
+ if (src->File == PROGRAM_CONSTANT) {
+ return brw_imm_f(params->ParameterValues[src->Index][component]);
+ }
}
if (c->fp->use_const_buffer &&
More information about the mesa-commit
mailing list