dri/nouveau: Implement texcoord generation.
authorFrancisco Jerez <currojerez@riseup.net>
Thu, 18 Mar 2010 13:18:55 +0000 (14:18 +0100)
committerFrancisco Jerez <currojerez@riseup.net>
Thu, 18 Mar 2010 14:02:36 +0000 (15:02 +0100)
src/mesa/drivers/dri/nouveau/nouveau_gldefs.h
src/mesa/drivers/dri/nouveau/nouveau_state.c
src/mesa/drivers/dri/nouveau/nouveau_util.h
src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c
src/mesa/drivers/dri/nouveau/nv10_context.c
src/mesa/drivers/dri/nouveau/nv10_state_tex.c
src/mesa/drivers/dri/nouveau/nv10_state_tnl.c
src/mesa/drivers/dri/nouveau/nv20_context.c
src/mesa/drivers/dri/nouveau/nv20_driver.h
src/mesa/drivers/dri/nouveau/nv20_state_tex.c
src/mesa/drivers/dri/nouveau/nv20_state_tnl.c

index 00007a9a351681d9256f2330b29e53b264841b9c..fbeed3baeabb127970bf82ac4fc68f6533df0b09 100644 (file)
@@ -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
index 603a46ed242a1ec80c5810fa5ef5009cc12372dd..ef2cc787de735518209f88b2a0df7017c4043e9f 100644 (file)
@@ -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
index d6007aba2b9e847b1cc50b63ffa2aeacd51c2085..584cb80ef62fa3e8479d8428f91b9f1d09103abd 100644 (file)
@@ -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
index f20a7df45ec5e4ae2dedce5594043de559c9e564..0c29eec8eec0840414272a0bd94273b6d594fb4b 100644 (file)
@@ -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));
index d008063d3c45bcb6549100d67dd4891541830be2..b6d10361de0bcbf954c2b5d2b796de6195251286 100644 (file)
@@ -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);
 
index 92148722af719235d57eb879e656b62e33ae8c05..35f41d7295b139530d8dea196cb36da8e986a9d5 100644 (file)
 #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
index 406e24c455d3d73bb658b072080cb046af26d774..2624c9bf305ac91f5380c3570f2cd15d0cd779a2 100644 (file)
@@ -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,
index 99df34716fcaddd06a3af45a309b14a542126e2e..789dcaa6b46383bfc51857a56564655e62664fb8 100644 (file)
@@ -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,
index 05770b2d6cfd736dd7d8bc793a3255c5281bdf1b..8adecef2c4eee867a9c63818c5c6a2a3b4af2bed 100644 (file)
@@ -67,6 +67,9 @@ void
 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);
 
index d7ac4c57bce2e75d9fc06a10b38679bee5058619..bb8a79c2c92a9aafbf95038f4157f6159163475a 100644 (file)
 #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)
 {
index 43f8c7231226fc8712919f4e0a9d680690f1cf56..df22adf272977d84686267094114ab8a7746c306 100644 (file)
@@ -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,