mesa: Branch 'master' - 9 commits

Ben Skeggs darktama at kemper.freedesktop.org
Tue Jan 30 14:40:43 UTC 2007


 src/mesa/drivers/dri/nouveau/nouveau_shader.c   |    9 
 src/mesa/drivers/dri/nouveau/nouveau_shader.h   |    8 
 src/mesa/drivers/dri/nouveau/nouveau_shader_0.c |  289 ++++++++++++++++++------
 src/mesa/drivers/dri/nouveau/nv30_fragprog.c    |   20 +
 src/mesa/drivers/dri/nouveau/nv30_state.c       |   27 +-
 src/mesa/drivers/dri/nouveau/nv30_vertprog.c    |    3 
 src/mesa/drivers/dri/nouveau/nv40_vertprog.c    |    7 
 7 files changed, 288 insertions(+), 75 deletions(-)

New commits:
diff-tree a4ddd64f3659b9db7719d3746c1469ece6bb44c5 (from f9345c7c4e22cd40d2efda73f1b044ab808f2c78)
Author: Ben Skeggs <darktama at iinet.net.au>
Date:   Tue Jan 30 16:51:50 2007 +1100

    nouveau: argh

diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c
index e1e0da9..96a07fd 100644
--- a/src/mesa/drivers/dri/nouveau/nv30_state.c
+++ b/src/mesa/drivers/dri/nouveau/nv30_state.c
@@ -244,7 +244,7 @@ static void nv30Enable(GLcontext *ctx, G
 			OUT_RING_CACHE(state);
 			break;
 		case GL_FOG:
-			if (!NOUVEAU_CARD_USING_SHADERS)
+			if (NOUVEAU_CARD_USING_SHADERS)
 				break;
 			BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
 			OUT_RING_CACHE(state);
diff-tree f9345c7c4e22cd40d2efda73f1b044ab808f2c78 (from d2c4d9ff9beb36895bb8ee7aabb65e70c3068816)
Author: Ben Skeggs <darktama at iinet.net.au>
Date:   Tue Jan 30 16:49:27 2007 +1100

    nouveau: misc NV40 fixes

diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c
index db13ec7..e1e0da9 100644
--- a/src/mesa/drivers/dri/nouveau/nv30_state.c
+++ b/src/mesa/drivers/dri/nouveau/nv30_state.c
@@ -244,6 +244,8 @@ static void nv30Enable(GLcontext *ctx, G
 			OUT_RING_CACHE(state);
 			break;
 		case GL_FOG:
+			if (!NOUVEAU_CARD_USING_SHADERS)
+				break;
 			BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE, 1);
 			OUT_RING_CACHE(state);
 			break;
@@ -736,9 +738,13 @@ void (*TexParameter)(GLcontext *ctx, GLe
 static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat)
 {
         nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
-        BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16);
-        /*XXX: This SHOULD work.*/
-        OUT_RING_CACHEp(mat->m, 16);
+
+	if (!NOUVEAU_CARD_USING_SHADERS) {
+		BEGIN_RING_CACHE(NvSub3D,
+				 NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16);
+		/*XXX: This SHOULD work.*/
+		OUT_RING_CACHEp(mat->m, 16);
+	}
 }
 
 static void nv30WindowMoved(nouveauContextPtr nmesa)
diff-tree d2c4d9ff9beb36895bb8ee7aabb65e70c3068816 (from ede8017d2c6c2f6da4c75c9ce0cc4d748e870973)
Author: Ben Skeggs <darktama at iinet.net.au>
Date:   Tue Jan 30 16:00:20 2007 +1100

    nouveau: NV40 glClipPlane support.

diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h
index 68007dd..b2df354 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h
@@ -32,6 +32,7 @@ typedef union {
 	struct {
 		uint32_t vp_in_reg;
 		uint32_t vp_out_reg;
+		uint32_t clip_enables;
 	} NV30VP;
 } nvsCardPriv;
 
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
index fb6e0b0..73c1f7c 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
@@ -811,12 +811,65 @@ pass0_build_attrib_map(nouveauShader *nv
 }
 
 static void
-pass0_prealloc_mesa_consts(nouveauShader *nvs)
+pass0_vp_insert_ff_clip_planes(GLcontext *ctx, nouveauShader *nvs)
+{
+	struct gl_program *prog = &nvs->mesa.vp.Base;
+	nvsFragmentHeader *parent = nvs->program_tree;
+	nvsInstruction *nvsinst;
+	GLuint fpos = 0;
+	nvsRegister opos, epos, eqn, mv[4];
+	GLint tokens[6] = { STATE_MATRIX, STATE_MODELVIEW, 0, 0, 0, 0 };
+	GLint id;
+	int i;
+
+	/* modelview transform */
+	pass0_make_reg(nvs, &opos, NVS_FILE_ATTRIB, NVS_FR_POSITION);
+	pass0_make_reg(nvs, &epos, NVS_FILE_TEMP  , -1);
+	for (i=0; i<4; i++) {
+		tokens[3] = tokens[4] = i;
+		id = _mesa_add_state_reference(prog->Parameters, tokens);
+		pass0_make_reg(nvs, &mv[i], NVS_FILE_CONST, id);
+	}
+	ARITHu(NVS_OP_DP4, epos, SMASK_X, 0, opos, mv[0], nvr_unused);
+	ARITHu(NVS_OP_DP4, epos, SMASK_Y, 0, opos, mv[1], nvr_unused);
+	ARITHu(NVS_OP_DP4, epos, SMASK_Z, 0, opos, mv[2], nvr_unused);
+	ARITHu(NVS_OP_DP4, epos, SMASK_W, 0, opos, mv[3], nvr_unused);
+
+	/* Emit code to emulate fixed-function glClipPlane */
+	for (i=0; i<6; i++) {
+		GLuint clipmask = SMASK_X;
+		nvsRegister clip;
+
+		if (!(ctx->Transform.ClipPlanesEnabled & (1<<i)))
+			continue;
+
+		/* Point a const at a user clipping plane */
+		tokens[0] = STATE_CLIPPLANE;
+		tokens[1] = i;
+		id = _mesa_add_state_reference(prog->Parameters, tokens);
+		pass0_make_reg(nvs, &eqn , NVS_FILE_CONST , id);
+		pass0_make_reg(nvs, &clip, NVS_FILE_RESULT, NVS_FR_CLIP0 + i);
+
+		/*XXX: something else needs to take care of modifying the
+		 *     instructions to write to the correct hw clip register.
+		 */
+		switch (i) {
+		case 0: case 3:	clipmask = SMASK_Y; break;
+		case 1: case 4: clipmask = SMASK_Z; break;
+		case 2: case 5: clipmask = SMASK_W; break;
+		}
+
+		/* Emit transform */
+		ARITHu(NVS_OP_DP4, clip, clipmask, 0, epos, eqn, nvr_unused);
+	}
+}
+
+static void
+pass0_rebase_mesa_consts(nouveauShader *nvs)
 {
 	struct pass0_rec *rec = nvs->pass_rec;
 	struct gl_program *prog = &nvs->mesa.vp.Base;
 	struct prog_instruction *inst = prog->Instructions;
-	struct gl_program_parameter_list *plist = prog->Parameters;
 	int i;
 
 	/*XXX: not a good idea, params->hw_index is malloc'd */
@@ -848,10 +901,23 @@ pass0_prealloc_mesa_consts(nouveauShader
 
 		inst++;
 	}
-	
+}
+
+static void
+pass0_resolve_mesa_consts(nouveauShader *nvs)
+{
+	struct pass0_rec *rec = nvs->pass_rec;
+	struct gl_program *prog = &nvs->mesa.vp.Base;
+	struct gl_program_parameter_list *plist = prog->Parameters;
+	int i;
+
 	/* Init all const tracking/alloc info from the parameter list, rather
-	 * than doing it as we translate the program.  Otherwise we can't get
-	 * at the correct constant info when relative addressing is being used.
+	 * than doing it as we translate the program.  Otherwise:
+	 *   1) we can't get at the correct constant info when relative
+	 *      addressing is being used due to src->Index not pointing
+	 *      at the exact const;
+	 *   2) as we add extra consts to the program, mesa will call realloc()
+	 *      and we get invalid pointers to the const data.
 	 */
 	rec->mesa_const_last = plist->NumParameters + rec->mesa_const_base;
 	nvs->param_high = rec->mesa_const_last;
@@ -907,12 +973,10 @@ nouveau_shader_pass0(GLcontext *ctx, nou
 
 		if (vp->IsPositionInvariant)
 			_mesa_insert_mvp_code(ctx, vp);
-		pass0_prealloc_mesa_consts(nvs);
+		pass0_rebase_mesa_consts(nvs);
 
-#if 0
-		if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED)
-			pass0_insert_ff_clip_planes();
-#endif
+		if (!prog->String && ctx->Transform.ClipPlanesEnabled)
+			pass0_vp_insert_ff_clip_planes(ctx, nvs);
 
 		pass0_build_attrib_map(nvs, vp);
 		break;
@@ -921,7 +985,7 @@ nouveau_shader_pass0(GLcontext *ctx, nou
 
 		if (fp->FogOption != GL_NONE)
 			_mesa_append_fog_code(ctx, fp);
-		pass0_prealloc_mesa_consts(nvs);
+		pass0_rebase_mesa_consts(nvs);
 		break;
 	default:
 		fprintf(stderr, "Unknown program type %d", prog->Target);
@@ -932,6 +996,8 @@ nouveau_shader_pass0(GLcontext *ctx, nou
 	nvs->func->card_priv = &nvs->card_priv;
 
 	ret = pass0_translate_instructions(nvs, 0, 0, nvs->program_tree);
+	if (ret)
+		pass0_resolve_mesa_consts(nvs);
 	/*XXX: if (!ret) DESTROY TREE!!! */
 
 	FREE(rec);
diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c
index 55b6463..db13ec7 100644
--- a/src/mesa/drivers/dri/nouveau/nv30_state.c
+++ b/src/mesa/drivers/dri/nouveau/nv30_state.c
@@ -127,6 +127,11 @@ static void nv30ClearStencil(GLcontext *
 static void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
 {
 	nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+	if (NOUVEAU_CARD_USING_SHADERS)
+		return;
+
+	plane -= GL_CLIP_PLANE0;
 	BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4);
 	OUT_RING_CACHEf(equation[0]);
 	OUT_RING_CACHEf(equation[1]);
@@ -208,8 +213,14 @@ static void nv30Enable(GLcontext *ctx, G
 		case GL_CLIP_PLANE3:
 		case GL_CLIP_PLANE4:
 		case GL_CLIP_PLANE5:
-			BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1);
-			OUT_RING_CACHE(state);
+			if (NOUVEAU_CARD_USING_SHADERS) {
+				nouveauShader *nvs = (nouveauShader *)ctx->VertexProgram._Current;
+				if (nvs)
+					nvs->translated = GL_FALSE;
+			} else {
+				BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1);
+				OUT_RING_CACHE(state);
+			}
 			break;
 		case GL_COLOR_LOGIC_OP:
 			BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1);
diff --git a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c
index afcacf3..d023e84 100644
--- a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c
+++ b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c
@@ -33,6 +33,9 @@ NV30VPUploadToHW(GLcontext *ctx, nouveau
    BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2);
    OUT_RING(nvs->card_priv.NV30VP.vp_in_reg);
    OUT_RING(nvs->card_priv.NV30VP.vp_out_reg);
+
+   BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_CLIPPING_PLANES, 1);
+   OUT_RING_CACHE  (nvs->card_priv.NV30VP.clip_enables);
 }
 
 static void
diff --git a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c
index 6cb7e1c..d054140 100644
--- a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c
+++ b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c
@@ -86,6 +86,7 @@ NV40VPTranslateResultReg(nvsFunc *shader
 					  unsigned int *mask_ret)
 {
 	unsigned int *out_reg = &shader->card_priv->NV30VP.vp_out_reg;
+	unsigned int *clip_en = &shader->card_priv->NV30VP.clip_enables;
 
 	*mask_ret = 0xf;
 
@@ -111,14 +112,17 @@ NV40VPTranslateResultReg(nvsFunc *shader
 		return NV40_VP_INST_DEST_FOGC;
 	case NVS_FR_CLIP0:
 		(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0;
+		(*clip_en) |= 0x00000002;
 		*mask_ret = 0x4;
 		return NV40_VP_INST_DEST_FOGC;
 	case NVS_FR_CLIP1:
 		(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1;
+		(*clip_en) |= 0x00000020;
 		*mask_ret = 0x2;
 		return NV40_VP_INST_DEST_FOGC;
 	case NVS_FR_CLIP2:
 		(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2;
+		(*clip_en) |= 0x00000200;
 		*mask_ret = 0x1;
 		return NV40_VP_INST_DEST_FOGC;
 	case NVS_FR_POINTSZ:
@@ -127,13 +131,16 @@ NV40VPTranslateResultReg(nvsFunc *shader
 		return NV40_VP_INST_DEST_PSZ;
 	case NVS_FR_CLIP3:
 		(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3;
+		(*clip_en) |= 0x00002000;
 		*mask_ret = 0x4;
 		return NV40_VP_INST_DEST_PSZ;
 	case NVS_FR_CLIP4:
+		(*clip_en) |= 0x00020000;
 		(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4;
 		*mask_ret = 0x2;
 		return NV40_VP_INST_DEST_PSZ;
 	case NVS_FR_CLIP5:
+		(*clip_en) |= 0x00200000;
 		(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5;
 		*mask_ret = 0x1;
 		return NV40_VP_INST_DEST_PSZ;
diff-tree ede8017d2c6c2f6da4c75c9ce0cc4d748e870973 (from de0cf18b096822cf8e113a46f12740ebeb10f8df)
Author: Ben Skeggs <darktama at iinet.net.au>
Date:   Tue Jan 30 12:33:00 2007 +1100

    nouveau: rework shader param handling
    
    Conflicts:
    
    	src/mesa/drivers/dri/nouveau/nouveau_shader_0.c

diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c
index cdb79fc..c78b72b 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c
@@ -126,15 +126,16 @@ nvsUpdateShader(GLcontext *ctx, nouveauS
    /* Update state parameters */
    plist = nvs->mesa.vp.Base.Parameters;
    _mesa_load_state_parameters(ctx, plist);
-   for (i=0; i<plist->NumParameters; i++) {
+   for (i=0; i<nvs->param_high; i++) {
+      if (!nvs->params[i].in_use)
+	 continue;
+
       if (!nvs->on_hardware) {
 	 /* if we've been kicked off the hardware there's no guarantee our
 	  * consts are still there.. reupload them all
 	  */
 	 nvs->func->UpdateConst(ctx, nvs, i);
-      } else if (plist->Parameters[i].Type == PROGRAM_STATE_VAR) {
-	 if (!nvs->params[i].source_val) /* this is a workaround when consts aren't alloc'd from id=0.. */
-	    continue;
+      } else if (nvs->params[i].source_val) {
 	 /* update any changed state parameters */
 	 if (!TEST_EQ_4V(nvs->params[i].val, nvs->params[i].source_val))
 	    nvs->func->UpdateConst(ctx, nvs, i);
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h
index e2515c1..68007dd 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h
@@ -58,6 +58,8 @@ typedef struct _nouveauShader {
    int		vp_attrib_map[NVS_MAX_ATTRIBS];
 
    struct {
+      GLboolean in_use;
+
       GLfloat  *source_val;	/* NULL if invariant */
       float	val[4];
       /* Hardware-specific tracking, currently only nv30_fragprog
@@ -66,6 +68,7 @@ typedef struct _nouveauShader {
       int	*hw_index;
       int        hw_index_cnt;
    } params[NVS_MAX_CONSTS];
+   int param_high;
 
    /* Pass-private data */
    void *pass_rec;
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
index 9f32cd8..fb6e0b0 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
@@ -113,6 +113,10 @@ static nvsCond _tx_mesa_condmask[] = {
 struct pass0_rec {
    int nvs_ipos;
    int next_temp;
+
+   int mesa_const_base;
+   int mesa_const_last;
+
    int swzconst_done;
    int swzconst_id;
    nvsRegister const_half;
@@ -308,8 +312,8 @@ pass0_make_dst_reg(nvsPtr nvs, nvsRegist
 static void
 pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src)
 {
+	struct pass0_rec *rec = nvs->pass_rec;
 	struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base;
-	struct gl_program_parameter_list *p = mesa->Parameters;
 	int i;
 
 	*reg = nvr_unused;
@@ -332,34 +336,16 @@ pass0_make_src_reg(nvsPtr nvs, nvsRegist
 				NVS_FR_UNKNOWN;
 		}
 		break;
-	/* All const types seem to get shoved into here, not really sure why */
 	case PROGRAM_STATE_VAR:
-		switch (p->Parameters[src->Index].Type) {
-		case PROGRAM_NAMED_PARAM:
-		case PROGRAM_CONSTANT:
-			nvs->params[src->Index].source_val = NULL;
-			COPY_4V(nvs->params[src->Index].val,
-				p->ParameterValues[src->Index]); 
-			break;
-		case PROGRAM_STATE_VAR:
-			nvs->params[src->Index].source_val =
-				p->ParameterValues[src->Index];
-			break;
-		default:
-			fprintf(stderr, "Unknown parameter type %d\n",
-					p->Parameters[src->Index].Type);
-			assert(0);
-			break;
+	case PROGRAM_NAMED_PARAM:
+	case PROGRAM_CONSTANT:
+		reg->file    = NVS_FILE_CONST;
+		reg->index   = src->Index + rec->mesa_const_base;
+		reg->indexed = src->RelAddr;
+		if (reg->indexed) {
+			reg->addr_reg  = 0;
+			reg->addr_comp = NVS_SWZ_X;
 		}
-
-		if (src->RelAddr) {
-			reg->indexed	= 1;
-			reg->addr_reg	= 0;
-			reg->addr_comp	= NVS_SWZ_X;
-		} else
-			reg->indexed = 0;
-		reg->file  = NVS_FILE_CONST;
-		reg->index = src->Index;
 		break;
 	case PROGRAM_TEMPORARY:
 		reg->file  = NVS_FILE_TEMP;
@@ -568,7 +554,6 @@ pass0_emulate_instruction(nouveauShader 
 	nvsFunc *shader = nvs->func;
 	nvsRegister src[3], dest, temp;
 	nvsInstruction *nvsinst;
-	struct pass0_rec *rec = nvs->pass_rec;
 	unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask);
 	int i, sat;
 
@@ -825,6 +810,73 @@ pass0_build_attrib_map(nouveauShader *nv
 	}
 }
 
+static void
+pass0_prealloc_mesa_consts(nouveauShader *nvs)
+{
+	struct pass0_rec *rec = nvs->pass_rec;
+	struct gl_program *prog = &nvs->mesa.vp.Base;
+	struct prog_instruction *inst = prog->Instructions;
+	struct gl_program_parameter_list *plist = prog->Parameters;
+	int i;
+
+	/*XXX: not a good idea, params->hw_index is malloc'd */
+	memset(nvs->params, 0x00, sizeof(nvs->params));
+
+	/* When doing relative addressing on constants, the hardware needs us
+	 * to fill the "const id" field with a positive value.  Determine the
+	 * most negative index that is used so that all accesses to a
+	 * mesa-provided constant can be rebased to a positive index.
+	 */
+	while (inst->Opcode != OPCODE_END) {
+		for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) {
+			struct prog_src_register *src = &inst->SrcReg[i];
+
+			switch (src->File) {
+			case PROGRAM_STATE_VAR:
+			case PROGRAM_CONSTANT:
+			case PROGRAM_NAMED_PARAM:
+				if (src->RelAddr && src->Index < 0) {
+					int base = src->Index * -1;
+					if (rec->mesa_const_base < base)
+						rec->mesa_const_base = base;
+				}
+				break;
+			default:
+				break;
+			}
+		}
+
+		inst++;
+	}
+	
+	/* Init all const tracking/alloc info from the parameter list, rather
+	 * than doing it as we translate the program.  Otherwise we can't get
+	 * at the correct constant info when relative addressing is being used.
+	 */
+	rec->mesa_const_last = plist->NumParameters + rec->mesa_const_base;
+	nvs->param_high = rec->mesa_const_last;
+	for (i=0; i<plist->NumParameters; i++) {
+		int hw = rec->mesa_const_base + i;
+
+		switch (plist->Parameters[i].Type) {
+		case PROGRAM_NAMED_PARAM:
+		case PROGRAM_STATE_VAR:
+			nvs->params[hw].in_use     = GL_TRUE;
+			nvs->params[hw].source_val = plist->ParameterValues[i];
+			COPY_4V(nvs->params[hw].val, plist->ParameterValues[i]);
+			break;
+		case PROGRAM_CONSTANT:
+			nvs->params[hw].in_use     = GL_TRUE;
+			nvs->params[hw].source_val = NULL;
+			COPY_4V(nvs->params[hw].val, plist->ParameterValues[i]);
+			break;
+		default:
+			assert(0);
+			break;
+		}
+	}
+}
+
 GLboolean
 nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs)
 {
@@ -835,12 +887,28 @@ nouveau_shader_pass0(GLcontext *ctx, nou
 	struct pass0_rec *rec;
 	int ret = GL_FALSE;
 
+	rec = CALLOC_STRUCT(pass0_rec);
+	if (!rec)
+		return GL_FALSE;
+
+	rec->next_temp = prog->NumTemporaries;
+	nvs->pass_rec  = rec;
+		
+	nvs->program_tree = (nvsFragmentHeader*)
+		pass0_create_subroutine(nvs, "program body");
+	if (!nvs->program_tree) {
+		FREE(rec);
+		return GL_FALSE;
+	}
+
 	switch (prog->Target) {
 	case GL_VERTEX_PROGRAM_ARB:
 		nvs->func = &nmesa->VPfunc;
 
 		if (vp->IsPositionInvariant)
 			_mesa_insert_mvp_code(ctx, vp);
+		pass0_prealloc_mesa_consts(nvs);
+
 #if 0
 		if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED)
 			pass0_insert_ff_clip_planes();
@@ -853,29 +921,20 @@ nouveau_shader_pass0(GLcontext *ctx, nou
 
 		if (fp->FogOption != GL_NONE)
 			_mesa_append_fog_code(ctx, fp);
+		pass0_prealloc_mesa_consts(nvs);
 		break;
 	default:
 		fprintf(stderr, "Unknown program type %d", prog->Target);
+		FREE(rec);
+		/* DESTROY TREE!! */
 		return GL_FALSE;
 	}
 	nvs->func->card_priv = &nvs->card_priv;
 
-	rec = CALLOC_STRUCT(pass0_rec);
-	if (rec) {
-		rec->next_temp = prog->NumTemporaries;
-		nvs->pass_rec  = rec;
-		
-		nvs->program_tree = (nvsFragmentHeader*)
-			pass0_create_subroutine(nvs, "program body");
-		if (nvs->program_tree) {
-			ret = pass0_translate_instructions(nvs,
-							   0, 0,
-							   nvs->program_tree);
-			/*XXX: if (!ret) DESTROY TREE!!! */
-		}
-		FREE(rec);
-	}
+	ret = pass0_translate_instructions(nvs, 0, 0, nvs->program_tree);
+	/*XXX: if (!ret) DESTROY TREE!!! */
 
+	FREE(rec);
 	return ret;
 }
 
diff-tree de0cf18b096822cf8e113a46f12740ebeb10f8df (from 2d8b31610917e5e14a242725b047a21f6d2c14e0)
Author: Ben Skeggs <darktama at iinet.net.au>
Date:   Mon Jan 29 17:08:45 2007 +1100

    nouveau: oops, build attrib map after we know how the final shader will look..

diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
index b96cf95..9f32cd8 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
@@ -839,14 +839,14 @@ nouveau_shader_pass0(GLcontext *ctx, nou
 	case GL_VERTEX_PROGRAM_ARB:
 		nvs->func = &nmesa->VPfunc;
 
-		pass0_build_attrib_map(nvs, vp);
-
 		if (vp->IsPositionInvariant)
 			_mesa_insert_mvp_code(ctx, vp);
 #if 0
 		if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED)
 			pass0_insert_ff_clip_planes();
 #endif
+
+		pass0_build_attrib_map(nvs, vp);
 		break;
 	case GL_FRAGMENT_PROGRAM_ARB:
 		nvs->func = &nmesa->FPfunc;
diff-tree 2d8b31610917e5e14a242725b047a21f6d2c14e0 (from 7fbf8d3324868e6920243e3b1abdeb6e398ea715)
Author: Ben Skeggs <darktama at iinet.net.au>
Date:   Sat Jan 27 18:54:42 2007 +1100

    nouveau: remove an unused table

diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
index fc55056..b96cf95 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
@@ -54,18 +54,6 @@ static nvsFixedReg _tx_mesa_fp_dst_reg[F
    NVS_FR_UNKNOWN /* DEPR */
 };
 
-static nvsFixedReg _tx_mesa_vp_src_reg[VERT_ATTRIB_MAX] = {
-   NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1,
-   NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN,
-   NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3,
-   NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7,
-/* Generic attribs 0-15, aliased to the above */
-   NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1,
-   NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN,
-   NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3,
-   NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7
-};
-
 static nvsFixedReg _tx_mesa_fp_src_reg[FRAG_ATTRIB_MAX] = {
    NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD,
    NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3,
@@ -815,7 +803,7 @@ pass0_build_attrib_map(nouveauShader *nv
 			else
 				hw = in;
 		} else {
-			/* ARBvp: may alias
+			/* ARBvp: may alias (but we won't)
 			 * GL2.0: must not alias
 			 */
 			if (in >= VERT_ATTRIB_GENERIC0)
diff-tree 7fbf8d3324868e6920243e3b1abdeb6e398ea715 (from cafbc459f51ce6645e1fc4b6b2b7ec34efedd874)
Author: Ben Skeggs <darktama at iinet.net.au>
Date:   Sat Jan 27 18:51:19 2007 +1100

    nouveau: oops

diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
index 81ed012..fc55056 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
@@ -322,6 +322,7 @@ pass0_make_src_reg(nvsPtr nvs, nvsRegist
 {
 	struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base;
 	struct gl_program_parameter_list *p = mesa->Parameters;
+	int i;
 
 	*reg = nvr_unused;
 
@@ -329,9 +330,14 @@ pass0_make_src_reg(nvsPtr nvs, nvsRegist
 	case PROGRAM_INPUT:
 		reg->file = NVS_FILE_ATTRIB;
 		if (mesa->Target == GL_VERTEX_PROGRAM_ARB) {
-			reg->index = (src->Index < VERT_ATTRIB_MAX) ?
-				_tx_mesa_vp_src_reg[src->Index] :
-				NVS_FR_UNKNOWN;
+			for (i=0; i<NVS_MAX_ATTRIBS; i++) {
+				if (nvs->vp_attrib_map[i] == src->Index) {
+					reg->index = i;
+					break;
+				}
+			}
+			if (i==NVS_MAX_ATTRIBS)
+				reg->index = NVS_FR_UNKNOWN;
 		} else {
 			reg->index = (src->Index < FRAG_ATTRIB_MAX) ?
 				_tx_mesa_fp_src_reg[src->Index] :
diff-tree cafbc459f51ce6645e1fc4b6b2b7ec34efedd874 (from 0c5b42a99182be05a72c78fa9340b75f3be81220)
Author: Ben Skeggs <darktama at iinet.net.au>
Date:   Sat Jan 27 18:36:01 2007 +1100

    nouveau: maintain a map of which vtxprog input corresponds to which array

diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h
index 82eb27b..e2515c1 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h
@@ -55,6 +55,7 @@ typedef struct _nouveauShader {
    int		inst_count;
 
    nvsCardPriv card_priv;
+   int		vp_attrib_map[NVS_MAX_ATTRIBS];
 
    struct {
       GLfloat  *source_val;	/* NULL if invariant */
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
index 3bcc2ba..81ed012 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
@@ -787,6 +787,50 @@ pass0_translate_instructions(nouveauShad
 	return GL_TRUE;
 }
 
+static void
+pass0_build_attrib_map(nouveauShader *nvs, struct gl_vertex_program *vp)
+{
+	GLuint inputs_read = vp->Base.InputsRead;
+	GLuint input_alloc = ~0xFFFF;
+	int i;
+
+	for (i=0; i<NVS_MAX_ATTRIBS; i++)
+		nvs->vp_attrib_map[i] = -1;
+
+	while (inputs_read) {
+		int in = ffs(inputs_read) - 1;
+		int hw;
+		inputs_read &= ~(1<<in);
+
+		if (vp->IsNVProgram) {
+			/* NVvp: must alias */
+			if (in >= VERT_ATTRIB_GENERIC0)
+				hw = in - VERT_ATTRIB_GENERIC0;
+			else
+				hw = in;
+		} else {
+			/* ARBvp: may alias
+			 * GL2.0: must not alias
+			 */
+			if (in >= VERT_ATTRIB_GENERIC0)
+				hw = ffs(~input_alloc) - 1;
+			else 
+				hw = in;
+			input_alloc |= (1<<hw);
+		}
+
+		nvs->vp_attrib_map[hw] = in;
+	}
+
+	if (NOUVEAU_DEBUG & DEBUG_SHADERS) {
+		printf("vtxprog attrib map:\n");
+		for (i=0; i<NVS_MAX_ATTRIBS; i++) {
+			printf(" hw:%d = attrib:%d\n",
+					i, nvs->vp_attrib_map[i]);
+		}
+	}
+}
+
 GLboolean
 nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs)
 {
@@ -801,6 +845,8 @@ nouveau_shader_pass0(GLcontext *ctx, nou
 	case GL_VERTEX_PROGRAM_ARB:
 		nvs->func = &nmesa->VPfunc;
 
+		pass0_build_attrib_map(nvs, vp);
+
 		if (vp->IsPositionInvariant)
 			_mesa_insert_mvp_code(ctx, vp);
 #if 0
diff-tree 0c5b42a99182be05a72c78fa9340b75f3be81220 (from aa397fe47212d7686efe423aedd10f2c57f2c2b9)
Author: Ben Skeggs <darktama at iinet.net.au>
Date:   Mon Jan 29 16:39:19 2007 +1100

    nouveau: unhardcode some more NV30TCL_FP_CONTROL values

diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h
index 7329ccd..82eb27b 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h
@@ -26,7 +26,8 @@ typedef struct _nvs_fragment_header {
 
 typedef union {
 	struct {
-		uint32_t fp_control;
+		GLboolean uses_kil;
+		GLuint    num_regs;
 	} NV30FP;
 	struct {
 		uint32_t vp_in_reg;
diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c
index 3c7501d..02bd801 100644
--- a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c
+++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c
@@ -24,6 +24,7 @@ static void
 NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
 {
    nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+   nvsCardPriv *priv = &nvs->card_priv;
    uint32_t offset;
 
    if (!nvs->program_buffer)
@@ -46,8 +47,9 @@ NV30FPUploadToHW(GLcontext *ctx, nouveau
     */
    BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1);
    OUT_RING       (offset | 1);
-   BEGIN_RING_SIZE(NvSub3D, 0x1d60, 1);
-   OUT_RING       (nvs->card_priv.NV30FP.fp_control | 0x03000000);
+   BEGIN_RING_SIZE(NvSub3D, 0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1);
+   OUT_RING       ((priv->NV30FP.uses_kil <<  7) |
+		   (priv->NV30FP.num_regs << 24));
 }
 
 static void
@@ -95,7 +97,7 @@ static void
 NV30FPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot)
 {
    if (opcode == NV30_FP_OP_OPCODE_KIL)
-      shader->card_priv->NV30FP.fp_control |= (1<<7);
+      shader->card_priv->NV30FP.uses_kil = GL_TRUE;
    shader->inst[0] &= ~NV30_FP_OP_OPCODE_MASK;
    shader->inst[0] |= (opcode << NV30_FP_OP_OPCODE_SHIFT);
 }
@@ -146,6 +148,16 @@ NV30FPSetCondition(nvsFunc *shader, int 
 }
 
 static void
+NV30FPSetHighReg(nvsFunc *shader, int id)
+{
+   if (shader->card_priv->NV30FP.num_regs < (id+1)) {
+      if (id == 0)
+	 id = 1; /* necessary? */
+      shader->card_priv->NV30FP.num_regs = (id+1);
+   }
+}
+
+static void
 NV30FPSetResult(nvsFunc *shader, nvsRegister *reg, unsigned int mask, int slot)
 {
    unsigned int hwreg;
@@ -163,6 +175,7 @@ NV30FPSetResult(nvsFunc *shader, nvsRegi
       shader->inst[0] &= ~NV30_FP_OP_UNK0_7;
       hwreg = reg->index;
    }
+   NV30FPSetHighReg(shader, hwreg);
    shader->inst[0] &= ~NV30_FP_OP_OUT_REG_SHIFT;
    shader->inst[0] |= (hwreg  << NV30_FP_OP_OUT_REG_SHIFT);
 }
@@ -176,6 +189,7 @@ NV30FPSetSource(nvsFunc *shader, nvsRegi
    case NVS_FILE_TEMP:
       hwsrc |= (NV30_FP_REG_TYPE_TEMP << NV30_FP_REG_TYPE_SHIFT);
       hwsrc |= (reg->index << NV30_FP_REG_SRC_SHIFT);
+      NV30FPSetHighReg(shader, reg->index);
       break;
    case NVS_FILE_ATTRIB:
       {



More information about the mesa-commit mailing list