Mesa (master): dri/nouveau: Implement texcoord generation.

Francisco Jerez currojerez at kemper.freedesktop.org
Thu Mar 18 07:13:30 PDT 2010


Module: Mesa
Branch: master
Commit: c944fb5ffe7cf16154d6395001f43a6c965cab1f
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c944fb5ffe7cf16154d6395001f43a6c965cab1f

Author: Francisco Jerez <currojerez at riseup.net>
Date:   Thu Mar 18 14:18:55 2010 +0100

dri/nouveau: Implement texcoord generation.

---

 src/mesa/drivers/dri/nouveau/nouveau_gldefs.h |   19 +++++++++++++
 src/mesa/drivers/dri/nouveau/nouveau_state.c  |   17 +++++++++++-
 src/mesa/drivers/dri/nouveau/nouveau_util.h   |   18 +++++++++++++
 src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c  |    4 ++-
 src/mesa/drivers/dri/nouveau/nv10_context.c   |    2 +-
 src/mesa/drivers/dri/nouveau/nv10_state_tex.c |   33 +++++++++++++++++++++++
 src/mesa/drivers/dri/nouveau/nv10_state_tnl.c |    6 +++-
 src/mesa/drivers/dri/nouveau/nv20_context.c   |   14 +++++-----
 src/mesa/drivers/dri/nouveau/nv20_driver.h    |    3 ++
 src/mesa/drivers/dri/nouveau/nv20_state_tex.c |   35 +++++++++++++++++++++++++
 src/mesa/drivers/dri/nouveau/nv20_state_tnl.c |    6 +++-
 11 files changed, 143 insertions(+), 14 deletions(-)

diff --git a/src/mesa/drivers/dri/nouveau/nouveau_gldefs.h b/src/mesa/drivers/dri/nouveau/nouveau_gldefs.h
index 00007a9..fbeed3b 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_gldefs.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_gldefs.h
@@ -260,4 +260,23 @@ nvgl_filter_mode(unsigned filter)
 	}
 }
 
+static inline unsigned
+nvgl_texgen_mode(unsigned mode)
+{
+	switch (mode) {
+	case GL_EYE_LINEAR:
+		return 0x2400;
+	case GL_OBJECT_LINEAR:
+		return 0x2401;
+	case GL_SPHERE_MAP:
+		return 0x2402;
+	case GL_NORMAL_MAP:
+		return 0x8511;
+	case GL_REFLECTION_MAP:
+		return 0x8512;
+	default:
+		assert(0);
+	}
+}
+
 #endif
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c
index 603a46e..ef2cc78 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_state.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c
@@ -234,6 +234,13 @@ nouveau_enable(GLcontext *ctx, GLenum cap, GLboolean state)
 		context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
 		context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
 		break;
+	case GL_TEXTURE_GEN_S:
+	case GL_TEXTURE_GEN_T:
+	case GL_TEXTURE_GEN_R:
+	case GL_TEXTURE_GEN_Q:
+		context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit);
+		context_dirty(ctx, MODELVIEW);
+		break;
 	}
 }
 
@@ -368,7 +375,15 @@ static void
 nouveau_tex_gen(GLcontext *ctx, GLenum coord, GLenum pname,
 		const GLfloat *params)
 {
-	context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit);
+	switch (pname) {
+	case GL_TEXTURE_GEN_MODE:
+		context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit);
+		context_dirty(ctx, MODELVIEW);
+		break;
+	default:
+		context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit);
+		break;
+	}
 }
 
 static void
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_util.h b/src/mesa/drivers/dri/nouveau/nouveau_util.h
index d6007ab..584cb80 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_util.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_util.h
@@ -191,4 +191,22 @@ is_texture_source(int s)
 	return s == GL_TEXTURE || (s >= GL_TEXTURE0 && s <= GL_TEXTURE31);
 }
 
+static inline struct gl_texgen *
+get_texgen_coord(struct gl_texture_unit *u, int i)
+{
+	return ((struct gl_texgen *[])
+		{ &u->GenS, &u->GenT, &u->GenR, &u->GenQ }) [i];
+}
+
+static inline float *
+get_texgen_coeff(struct gl_texgen *c)
+{
+	if (c->Mode == GL_OBJECT_LINEAR)
+		return c->ObjectPlane;
+	else if (c->Mode == GL_EYE_LINEAR)
+		return c->EyePlane;
+	else
+		return NULL;
+}
+
 #endif
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c
index f20a7df..0c29eec 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c
@@ -224,9 +224,11 @@ vbo_choose_attrs(GLcontext *ctx, const struct gl_client_array **arrays)
 	if (ctx->Fog.Enabled && ctx->Fog.FogCoordinateSource == GL_FOG_COORD)
 		vbo_emit_attr(ctx, arrays, VERT_ATTRIB_FOG);
 
-	if (ctx->Light.Enabled) {
+	if (ctx->Light.Enabled ||
+	    (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS))
 		vbo_emit_attr(ctx, arrays, VERT_ATTRIB_NORMAL);
 
+	if (ctx->Light.Enabled) {
 		vbo_emit_attr(ctx, arrays, MAT(FRONT_AMBIENT));
 		vbo_emit_attr(ctx, arrays, MAT(FRONT_DIFFUSE));
 		vbo_emit_attr(ctx, arrays, MAT(FRONT_SPECULAR));
diff --git a/src/mesa/drivers/dri/nouveau/nv10_context.c b/src/mesa/drivers/dri/nouveau/nv10_context.c
index d008063..b6d1036 100644
--- a/src/mesa/drivers/dri/nouveau/nv10_context.c
+++ b/src/mesa/drivers/dri/nouveau/nv10_context.c
@@ -212,7 +212,7 @@ nv10_hwctx_init(GLcontext *ctx)
 	OUT_RING(chan, 0);
 	BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE_ENABLE, 1);
 	OUT_RING(chan, 0);
-	BEGIN_RING(chan, celsius, NV10TCL_TX_GEN_S(0), 8);
+	BEGIN_RING(chan, celsius, NV10TCL_TX_GEN_MODE_S(0), 8);
 	for (i = 0; i < 8; i++)
 		OUT_RING(chan, 0);
 
diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_tex.c b/src/mesa/drivers/dri/nouveau/nv10_state_tex.c
index 9214872..35f41d7 100644
--- a/src/mesa/drivers/dri/nouveau/nv10_state_tex.c
+++ b/src/mesa/drivers/dri/nouveau/nv10_state_tex.c
@@ -32,11 +32,44 @@
 #include "nouveau_util.h"
 #include "nv10_driver.h"
 
+#define TX_GEN_MODE(i, j) (NV10TCL_TX_GEN_MODE_S(i) + 4 * (j))
+#define TX_GEN_COEFF(i, j) (NV10TCL_TX_GEN_COEFF_S_A(i) + 16 * (j))
 #define TX_MATRIX(i) (NV10TCL_TX0_MATRIX(0) + 64 * (i))
 
 void
 nv10_emit_tex_gen(GLcontext *ctx, int emit)
 {
+	const int i = emit - NOUVEAU_STATE_TEX_GEN0;
+	struct nouveau_context *nctx = to_nouveau_context(ctx);
+	struct nouveau_channel *chan = context_chan(ctx);
+	struct nouveau_grobj *celsius = context_eng3d(ctx);
+	struct gl_texture_unit *unit = &ctx->Texture.Unit[i];
+	int j;
+
+	for (j = 0; j < 4; j++) {
+		if (nctx->fallback == HWTNL && (unit->TexGenEnabled & 1 << j)) {
+			struct gl_texgen *coord = get_texgen_coord(unit, j);
+			float *k = get_texgen_coeff(coord);
+
+			if (k) {
+				BEGIN_RING(chan, celsius,
+					   TX_GEN_COEFF(i, j), 4);
+				OUT_RINGf(chan, k[0]);
+				OUT_RINGf(chan, k[1]);
+				OUT_RINGf(chan, k[2]);
+				OUT_RINGf(chan, k[3]);
+			}
+
+			BEGIN_RING(chan, celsius, TX_GEN_MODE(i, j), 1);
+			OUT_RING(chan, nvgl_texgen_mode(coord->Mode));
+
+		} else {
+			BEGIN_RING(chan, celsius, TX_GEN_MODE(i, j), 1);
+			OUT_RING(chan, 0);
+		}
+	}
+
+	context_dirty_i(ctx, TEX_MAT, i);
 }
 
 void
diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c b/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c
index 406e24c..2624c9b 100644
--- a/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c
+++ b/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c
@@ -474,12 +474,14 @@ nv10_emit_modelview(GLcontext *ctx, int emit)
 	if (nctx->fallback != HWTNL)
 		return;
 
-	if (ctx->Light._NeedEyeCoords || ctx->Fog.Enabled) {
+	if (ctx->Light._NeedEyeCoords || ctx->Fog.Enabled ||
+	    (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD)) {
 		BEGIN_RING(chan, celsius, NV10TCL_MODELVIEW0_MATRIX(0), 16);
 		OUT_RINGm(chan, m->m);
 	}
 
-	if (ctx->Light.Enabled) {
+	if (ctx->Light.Enabled ||
+	    (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD)) {
 		int i, j;
 
 		BEGIN_RING(chan, celsius,
diff --git a/src/mesa/drivers/dri/nouveau/nv20_context.c b/src/mesa/drivers/dri/nouveau/nv20_context.c
index 99df347..789dcaa 100644
--- a/src/mesa/drivers/dri/nouveau/nv20_context.c
+++ b/src/mesa/drivers/dri/nouveau/nv20_context.c
@@ -297,9 +297,9 @@ nv20_hwctx_init(GLcontext *ctx)
 	BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_STIPPLE_ENABLE, 1);
 	OUT_RING  (chan, 0);
 
-	BEGIN_RING(chan, kelvin, NV20TCL_TX_GEN_S(0),
-		   4 * NV20TCL_TX_GEN_S__SIZE);
-	for (i=0; i < 4 * NV20TCL_TX_GEN_S__SIZE; i++)
+	BEGIN_RING(chan, kelvin, NV20TCL_TX_GEN_MODE_S(0),
+		   4 * NV20TCL_TX_GEN_MODE_S__SIZE);
+	for (i=0; i < 4 * NV20TCL_TX_GEN_MODE_S__SIZE; i++)
 		OUT_RING(chan, 0);
 
 	BEGIN_RING(chan, kelvin, NV20TCL_FOG_EQUATION_CONSTANT, 3);
@@ -497,10 +497,10 @@ const struct nouveau_driver nv20_driver = {
 		nv20_emit_tex_env,
 		nv20_emit_tex_env,
 		nv20_emit_tex_env,
-		nv10_emit_tex_gen,
-		nv10_emit_tex_gen,
-		nv10_emit_tex_gen,
-		nv10_emit_tex_gen,
+		nv20_emit_tex_gen,
+		nv20_emit_tex_gen,
+		nv20_emit_tex_gen,
+		nv20_emit_tex_gen,
 		nv20_emit_tex_mat,
 		nv20_emit_tex_mat,
 		nv20_emit_tex_mat,
diff --git a/src/mesa/drivers/dri/nouveau/nv20_driver.h b/src/mesa/drivers/dri/nouveau/nv20_driver.h
index 05770b2..8adecef 100644
--- a/src/mesa/drivers/dri/nouveau/nv20_driver.h
+++ b/src/mesa/drivers/dri/nouveau/nv20_driver.h
@@ -68,6 +68,9 @@ nv20_emit_frag(GLcontext *ctx, int emit);
 
 /* nv20_state_tex.c */
 void
+nv20_emit_tex_gen(GLcontext *ctx, int emit);
+
+void
 nv20_emit_tex_mat(GLcontext *ctx, int emit);
 
 void
diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_tex.c b/src/mesa/drivers/dri/nouveau/nv20_state_tex.c
index d7ac4c5..bb8a79c 100644
--- a/src/mesa/drivers/dri/nouveau/nv20_state_tex.c
+++ b/src/mesa/drivers/dri/nouveau/nv20_state_tex.c
@@ -32,9 +32,44 @@
 #include "nouveau_util.h"
 #include "nv20_driver.h"
 
+#define TX_GEN_MODE(i, j) (NV20TCL_TX_GEN_MODE_S(i) + 4 * (j))
+#define TX_GEN_COEFF(i, j) (NV20TCL_TX_GEN_COEFF_S_A(i) + 16 * (j))
 #define TX_MATRIX(i) (NV20TCL_TX0_MATRIX(0) + 64 * (i))
 
 void
+nv20_emit_tex_gen(GLcontext *ctx, int emit)
+{
+	const int i = emit - NOUVEAU_STATE_TEX_GEN0;
+	struct nouveau_context *nctx = to_nouveau_context(ctx);
+	struct nouveau_channel *chan = context_chan(ctx);
+	struct nouveau_grobj *kelvin = context_eng3d(ctx);
+	struct gl_texture_unit *unit = &ctx->Texture.Unit[i];
+	int j;
+
+	for (j = 0; j < 4; j++) {
+		if (nctx->fallback == HWTNL && (unit->TexGenEnabled & 1 << j)) {
+			struct gl_texgen *coord = get_texgen_coord(unit, j);
+			float *k = get_texgen_coeff(coord);
+
+			if (k) {
+				BEGIN_RING(chan, kelvin, TX_GEN_COEFF(i, j), 4);
+				OUT_RINGf(chan, k[0]);
+				OUT_RINGf(chan, k[1]);
+				OUT_RINGf(chan, k[2]);
+				OUT_RINGf(chan, k[3]);
+			}
+
+			BEGIN_RING(chan, kelvin, TX_GEN_MODE(i, j), 1);
+			OUT_RING(chan, nvgl_texgen_mode(coord->Mode));
+
+		} else {
+			BEGIN_RING(chan, kelvin, TX_GEN_MODE(i, j), 1);
+			OUT_RING(chan, 0);
+		}
+	}
+}
+
+void
 nv20_emit_tex_mat(GLcontext *ctx, int emit)
 {
 	const int i = emit - NOUVEAU_STATE_TEX_MAT0;
diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_tnl.c b/src/mesa/drivers/dri/nouveau/nv20_state_tnl.c
index 43f8c72..df22adf 100644
--- a/src/mesa/drivers/dri/nouveau/nv20_state_tnl.c
+++ b/src/mesa/drivers/dri/nouveau/nv20_state_tnl.c
@@ -359,12 +359,14 @@ nv20_emit_modelview(GLcontext *ctx, int emit)
 	if (nctx->fallback != HWTNL)
 		return;
 
-	if (ctx->Light._NeedEyeCoords || ctx->Fog.Enabled) {
+	if (ctx->Light._NeedEyeCoords || ctx->Fog.Enabled ||
+	    (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD)) {
 		BEGIN_RING(chan, kelvin, NV20TCL_MODELVIEW0_MATRIX(0), 16);
 		OUT_RINGm(chan, m->m);
 	}
 
-	if (ctx->Light.Enabled) {
+	if (ctx->Light.Enabled ||
+	    (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD)) {
 		int i, j;
 
 		BEGIN_RING(chan, kelvin,



More information about the mesa-commit mailing list