mesa: Branch 'master'

Nicolai Hähnle nh at kemper.freedesktop.org
Mon Mar 19 23:02:45 UTC 2007


 src/mesa/drivers/dri/r300/r300_context.h  |   20 ++---
 src/mesa/drivers/dri/r300/r300_fragprog.c |  114 +++++++++++++-----------------
 2 files changed, 61 insertions(+), 73 deletions(-)

New commits:
diff-tree 61821a41c07b6b383a275acf31ade56af2ecfb3c (from 5a6547878373798113f8b55b912abc5bfb93add5)
Author: Nicolai Haehnle <nhaehnle at gmail.com>
Date:   Mon Mar 19 23:32:36 2007 +0100

    r300: Cleanup fragment program constant allocation, share constants
    
    The constant/parameter allocation was significantly simplified, removing
    one unnecessary copy operation of parameters. The dirty state tracking is
    unchanged and far from optimal, since all state is always re-fetched.
    
    Constants and parameters are now emitted only once, which significantly
    reduces the resource pressure on larger programs.

diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
index 29436ab..bbe44f5 100644
--- a/src/mesa/drivers/dri/r300/r300_context.h
+++ b/src/mesa/drivers/dri/r300/r300_context.h
@@ -767,23 +767,21 @@ struct r300_fragment_program {
 	int tex_offset;
 	int tex_end;
 
-	/* Hardware constants */
-	GLfloat constant[PFS_NUM_CONST_REGS][4];
+	/* Hardware constants.
+	 * Contains a pointer to the value. The destination of the pointer
+	 * is supposed to be updated when GL state changes.
+	 * Typically, this is either a pointer into
+	 * gl_program_parameter_list::ParameterValues, or a pointer to a
+	 * global constant (e.g. for sin/cos-approximation)
+	 */
+	const GLfloat* constant[PFS_NUM_CONST_REGS];
 	int const_nr;
 
-	/* Tracked parameters */
-	struct {
-		int idx;			/* hardware index */
-		GLfloat *values;	/* pointer to values */
-	} param[PFS_NUM_CONST_REGS];
-	int param_nr;
-	GLboolean params_uptodate;
-
 	int max_temp_idx;
 
 	/* the index of the sin constant is stored here */
 	GLint const_sin[2];
-	
+
 	GLuint optimization;
 };
 
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c
index 1d462eb..2145c48 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog.c
@@ -468,47 +468,39 @@ static void free_temp(struct r300_fragme
 	}
 }
 
-static GLuint emit_param4fv(struct r300_fragment_program *rp,
-			    GLfloat *values)
+/**
+ * Emit a hardware constant/parameter.
+ *
+ * \p cp Stable pointer to an array of 4 floats.
+ *  The pointer must be stable in the sense that it remains to be valid
+ *  and hold the contents of the constant/parameter throughout the lifetime
+ *  of the fragment program (actually, up until the next time the fragment
+ *  program is translated).
+ */
+static GLuint emit_const4fv(struct r300_fragment_program *rp, const GLfloat* cp)
 {
-	GLuint r = undef;
-	GLuint index;
-	int pidx;
+	GLuint reg = undef;
+	int index;
 
-	pidx = rp->param_nr++;
-	index = rp->const_nr++;
-	if (pidx >= PFS_NUM_CONST_REGS || index >= PFS_NUM_CONST_REGS) {
-		ERROR("Out of const/param slots!\n");
-		return r;
+	for(index = 0; index < rp->const_nr; ++index) {
+		if (rp->constant[index] == cp)
+			break;
 	}
 
-	rp->param[pidx].idx = index;
-	rp->param[pidx].values = values;
-	rp->params_uptodate = GL_FALSE;
-
-	REG_SET_TYPE(r, REG_TYPE_CONST);
-	REG_SET_INDEX(r, index);
-	REG_SET_VALID(r, GL_TRUE);
-	return r;
-}
-
-static GLuint emit_const4fv(struct r300_fragment_program *rp, const GLfloat* cp)
-{
-	GLuint r = undef;
-	GLuint index;
+	if (index >= rp->const_nr) {
+		if (index >= PFS_NUM_CONST_REGS) {
+			ERROR("Out of hw constants!\n");
+			return reg;
+		}
 
-	index = rp->const_nr++;
-	if (index >= PFS_NUM_CONST_REGS) {
-		ERROR("Out of hw constants!\n");
-		return r;
+		rp->const_nr++;
+		rp->constant[index] = cp;
 	}
 
-	COPY_4V(rp->constant[index], cp);
-
-	REG_SET_TYPE(r, REG_TYPE_CONST);
-	REG_SET_INDEX(r, index);
-	REG_SET_VALID(r, GL_TRUE);
-	return r;
+	REG_SET_TYPE(reg, REG_TYPE_CONST);
+	REG_SET_INDEX(reg, index);
+	REG_SET_VALID(reg, GL_TRUE);
+	return reg;
 }
 
 static inline GLuint negate(GLuint r)
@@ -762,16 +754,16 @@ static GLuint t_src(struct r300_fragment
 		REG_SET_TYPE(r, REG_TYPE_INPUT);
 		break;
 	case PROGRAM_LOCAL_PARAM:
-		r = emit_param4fv(rp,
+		r = emit_const4fv(rp,
 				  rp->mesa_program.Base.LocalParams[fpsrc.Index]);
 		break;
 	case PROGRAM_ENV_PARAM:
-		r = emit_param4fv(rp,
+		r = emit_const4fv(rp,
 				  rp->ctx->FragmentProgram.Parameters[fpsrc.Index]);
 		break;
 	case PROGRAM_STATE_VAR:
 	case PROGRAM_NAMED_PARAM:
-		r = emit_param4fv(rp,
+		r = emit_const4fv(rp,
 				  rp->mesa_program.Base.Parameters->ParameterValues[fpsrc.Index]);
 		break;
 	default:
@@ -1393,22 +1385,27 @@ static GLuint get_attrib(struct r300_fra
 }
 #endif
 
+static GLfloat SinCosConsts[2][4] = {
+	{
+		1.273239545,  // 4/PI
+		-0.405284735, // -4/(PI*PI)
+		3.141592654,  // PI
+		0.2225        // weight
+	},
+	{
+		0.75,
+		0.0,
+		0.159154943,  // 1/(2*PI)
+		6.283185307   // 2*PI
+	}
+};
+
+
 static void make_sin_const(struct r300_fragment_program *rp)
 {
-	if(rp->const_sin[0] == -1){
-	    GLfloat cnstv[4];
-
-	    cnstv[0] = 1.273239545; // 4/PI
-	    cnstv[1] =-0.405284735; // -4/(PI*PI)
-	    cnstv[2] = 3.141592654; // PI
-	    cnstv[3] = 0.2225;      // weight
-	    rp->const_sin[0] = emit_const4fv(rp, cnstv);
-
-	    cnstv[0] = 0.75;
-	    cnstv[1] = 0.0;
-	    cnstv[2] = 0.159154943; // 1/(2*PI)
-	    cnstv[3] = 6.283185307; // 2*PI
-	    rp->const_sin[1] = emit_const4fv(rp, cnstv);
+	if(rp->const_sin[0] == -1) {
+		rp->const_sin[0] = emit_const4fv(rp, SinCosConsts[0]);
+		rp->const_sin[1] = emit_const4fv(rp, SinCosConsts[1]);
 	}
 }
 
@@ -1434,6 +1431,8 @@ static void make_sin_const(struct r300_f
  * emit_arith is a bit too conservative because it doesn't understand
  * partial writes to the vector component.
  */
+static const GLfloat LitConst[4] = { 127.999999, 127.999999, 127.999999, -127.999999 };
+
 static void emit_lit(struct r300_fragment_program *rp,
 		GLuint dest,
 		int mask,
@@ -1441,12 +1440,11 @@ static void emit_lit(struct r300_fragmen
 		int flags)
 {
 	COMPILE_STATE;
-	static const GLfloat cnstv[4] = { 127.999999, 127.999999, 127.999999, -127.999999 };
 	GLuint cnst;
 	int needTemporary;
 	GLuint temp;
 
-	cnst = emit_const4fv(rp, cnstv);
+	cnst = emit_const4fv(rp, LitConst);
 
 	needTemporary = 0;
 	if ((mask & WRITEMASK_XYZW) != WRITEMASK_XYZW) {
@@ -2123,8 +2121,6 @@ static void init_program(r300ContextPtr 
 	rp->cur_node   = 0;
 	rp->first_node_has_tex = 0;
 	rp->const_nr   = 0;
-	rp->param_nr   = 0;
-	rp->params_uptodate = GL_FALSE;
 	rp->max_temp_idx = 0;
 	rp->node[0].alu_end = -1;
 	rp->node[0].tex_end = -1;
@@ -2231,16 +2227,10 @@ static void init_program(r300ContextPtr 
 static void update_params(struct r300_fragment_program *rp)
 {
 	struct gl_fragment_program *mp = &rp->mesa_program;
-	int i;
 
 	/* Ask Mesa nicely to fill in ParameterValues for us */
-	if (rp->param_nr)
+	if (mp->Base.Parameters)
 		_mesa_load_state_parameters(rp->ctx, mp->Base.Parameters);
-
-	for (i=0;i<rp->param_nr;i++)
-		COPY_4V(rp->constant[rp->param[i].idx], rp->param[i].values);
-
-	rp->params_uptodate = GL_TRUE;
 }
 
 void r300_translate_fragment_shader(r300ContextPtr r300, struct r300_fragment_program *rp)



More information about the mesa-commit mailing list