nouveau: rework and simplify nv04/nv05 driver a bit
authorBen Skeggs <bskeggs@redhat.com>
Fri, 13 Apr 2012 07:50:37 +0000 (17:50 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 13 Apr 2012 16:56:12 +0000 (02:56 +1000)
TEXTURED_TRIANGLE and MULTITEX_TRIANGLE are both a bit special in that if
you use any other graph object in the meantime they'll forget their state
and spew a lovely METHOD_CNT error at you when you try to draw.

The pre-newlib driver has a flush_notify() hook which does this state
re-emit, and a number of random workarounds like extra flushes and state
dirtying after various operations to solve this issue.

I'm taking a slightly different approach to things instead, which has the
nice side-effect of removing the divergent code-paths for ttri/mtri, the
flush/dirty workarounds and the need for flush_notify.  Also gives a few
FPS boost in OA, yay.

src/mesa/drivers/dri/nouveau/nv04_context.c
src/mesa/drivers/dri/nouveau/nv04_context.h
src/mesa/drivers/dri/nouveau/nv04_render.c
src/mesa/drivers/dri/nouveau/nv04_state_fb.c
src/mesa/drivers/dri/nouveau/nv04_state_frag.c
src/mesa/drivers/dri/nouveau/nv04_state_raster.c
src/mesa/drivers/dri/nouveau/nv04_state_tex.c
src/mesa/drivers/dri/nouveau/nv04_surface.c

index 921f474ce7e6d46ac9fa6538dd5f4e04fab65a07..9472bdd7b51939dc590433c1e843690be7453330 100644 (file)
@@ -66,26 +66,9 @@ nv04_context_engine(struct gl_context *ctx)
                fahrenheit = hw->eng3d;
 
        if (fahrenheit != nctx->eng3d) {
-               nctx->eng3d = fahrenheit;
-
                BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);
                PUSH_DATA (push, fahrenheit->handle);
-
-               if (nv04_mtex_engine(fahrenheit)) {
-                       context_dirty_i(ctx, TEX_ENV, 0);
-                       context_dirty_i(ctx, TEX_ENV, 1);
-                       context_dirty_i(ctx, TEX_OBJ, 0);
-                       context_dirty_i(ctx, TEX_OBJ, 1);
-                       context_dirty(ctx, CONTROL);
-                       context_dirty(ctx, BLEND);
-               } else {
-                       nouveau_bufctx_reset(to_nouveau_context(ctx)->hw.
-                                            bufctx, BUFCTX_TEX(1));
-                       context_dirty_i(ctx, TEX_ENV, 0);
-                       context_dirty_i(ctx, TEX_OBJ, 0);
-                       context_dirty(ctx, CONTROL);
-                       context_dirty(ctx, BLEND);
-               }
+               nctx->eng3d = fahrenheit;
        }
 
        return fahrenheit;
index 589aab27b74230c683aadc79c109b450f07ea5ed..b63024c14287e2c7b3d5baa16fddf768a8994b61 100644 (file)
@@ -35,6 +35,17 @@ struct nv04_context {
        struct nouveau_object *eng3d;
        struct nouveau_surface dummy_texture;
        float viewport[16];
+
+       uint32_t colorkey;
+       struct nouveau_surface *texture[2];
+       uint32_t format[2];
+       uint32_t filter[2];
+       uint32_t alpha[2];
+       uint32_t color[2];
+       uint32_t factor;
+       uint32_t blend;
+       uint32_t ctrl[3];
+       uint32_t fog;
 };
 #define to_nv04_context(ctx) ((struct nv04_context *)(ctx))
 
index 31b18bc0616e9684073ed0219e7a3d5687a9987c..30e9f9aad964cffb6a87986f23cae1e872c30de7 100644 (file)
@@ -93,15 +93,93 @@ swtnl_choose_attrs(struct gl_context *ctx)
 
 /* TnL renderer entry points */
 
+static void
+swtnl_restart_ttri(struct nv04_context *nv04, struct nouveau_pushbuf *push)
+{
+       BEGIN_NV04(push, NV04_TTRI(COLORKEY), 7);
+       PUSH_DATA (push, nv04->colorkey);
+       PUSH_RELOC(push, nv04->texture[0]->bo, nv04->texture[0]->offset,
+                        NOUVEAU_BO_LOW, 0, 0);
+       PUSH_RELOC(push, nv04->texture[0]->bo, nv04->format[0], NOUVEAU_BO_OR,
+                        NV04_TEXTURED_TRIANGLE_FORMAT_DMA_A,
+                        NV04_TEXTURED_TRIANGLE_FORMAT_DMA_B);
+       PUSH_DATA (push, nv04->filter[0]);
+       PUSH_DATA (push, nv04->blend);
+       PUSH_DATA (push, nv04->ctrl[0] & ~0x3e000000);
+       PUSH_DATA (push, nv04->fog);
+}
+
+static void
+swtnl_restart_mtri(struct nv04_context *nv04, struct nouveau_pushbuf *push)
+{
+       BEGIN_NV04(push, NV04_MTRI(OFFSET(0)), 8);
+       PUSH_RELOC(push, nv04->texture[0]->bo, nv04->texture[0]->offset,
+                        NOUVEAU_BO_LOW, 0, 0);
+       PUSH_RELOC(push, nv04->texture[1]->bo, nv04->texture[1]->offset,
+                        NOUVEAU_BO_LOW, 0, 0);
+       PUSH_RELOC(push, nv04->texture[0]->bo, nv04->format[0], NOUVEAU_BO_OR,
+                        NV04_TEXTURED_TRIANGLE_FORMAT_DMA_A,
+                        NV04_TEXTURED_TRIANGLE_FORMAT_DMA_B);
+       PUSH_RELOC(push, nv04->texture[1]->bo, nv04->format[1], NOUVEAU_BO_OR,
+                        NV04_TEXTURED_TRIANGLE_FORMAT_DMA_A,
+                        NV04_TEXTURED_TRIANGLE_FORMAT_DMA_B);
+       PUSH_DATA (push, nv04->filter[0]);
+       PUSH_DATA (push, nv04->filter[1]);
+       PUSH_DATA (push, nv04->alpha[0]);
+       PUSH_DATA (push, nv04->color[0]);
+       BEGIN_NV04(push, NV04_MTRI(COMBINE_ALPHA(1)), 8);
+       PUSH_DATA (push, nv04->alpha[1]);
+       PUSH_DATA (push, nv04->color[1]);
+       PUSH_DATA (push, nv04->factor);
+       PUSH_DATA (push, nv04->blend & ~0x0000000f);
+       PUSH_DATA (push, nv04->ctrl[0]);
+       PUSH_DATA (push, nv04->ctrl[1]);
+       PUSH_DATA (push, nv04->ctrl[2]);
+       PUSH_DATA (push, nv04->fog);
+}
+
+static inline bool
+swtnl_restart(struct gl_context *ctx, int multi, unsigned vertex_size)
+{
+       const int tex_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
+       struct nv04_context *nv04 = to_nv04_context(ctx);
+       struct nouveau_pushbuf *push = context_push(ctx);
+       struct nouveau_pushbuf_refn refs[] = {
+               { nv04->texture[0]->bo, tex_flags },
+               { nv04->texture[1]->bo, tex_flags },
+       };
+
+       /* wait for enough space for state, and at least one whole primitive */
+       if (nouveau_pushbuf_space(push, 32 + (4 * vertex_size), 4, 0) ||
+           nouveau_pushbuf_refn (push, refs, multi ? 2 : 1))
+               return false;
+
+       /* emit engine state */
+       if (multi)
+               swtnl_restart_mtri(nv04, push);
+       else
+               swtnl_restart_ttri(nv04, push);
+
+       return true;
+}
+
 static void
 swtnl_start(struct gl_context *ctx)
 {
+       struct nouveau_object *eng3d = nv04_context_engine(ctx);
        struct nouveau_pushbuf *push = context_push(ctx);
+       unsigned vertex_size;
 
        nouveau_pushbuf_bufctx(push, push->user_priv);
        nouveau_pushbuf_validate(push);
 
        swtnl_choose_attrs(ctx);
+
+       vertex_size = TNL_CONTEXT(ctx)->clipspace.vertex_size / 4;
+       if (eng3d->oclass == NV04_MULTITEX_TRIANGLE_CLASS)
+               swtnl_restart(ctx, 1, vertex_size);
+       else
+               swtnl_restart(ctx, 0, vertex_size);
 }
 
 static void
@@ -110,7 +188,6 @@ swtnl_finish(struct gl_context *ctx)
        struct nouveau_pushbuf *push = context_push(ctx);
 
        nouveau_pushbuf_bufctx(push, NULL);
-       PUSH_KICK(push);
 }
 
 static void
@@ -126,22 +203,23 @@ swtnl_reset_stipple(struct gl_context *ctx)
 /* Primitive rendering */
 
 #define BEGIN_PRIMITIVE(n)                                             \
+       struct nouveau_object *eng3d = to_nv04_context(ctx)->eng3d;     \
        struct nouveau_pushbuf *push = context_push(ctx);               \
-       struct nouveau_object *fahrenheit = nv04_context_engine(ctx);   \
-       int vertex_len = TNL_CONTEXT(ctx)->clipspace.vertex_size / 4;   \
+       int vertex_size = TNL_CONTEXT(ctx)->clipspace.vertex_size / 4;  \
+       int multi = (eng3d->oclass == NV04_MULTITEX_TRIANGLE_CLASS);    \
+                                                                       \
+       if (PUSH_AVAIL(push) < 32 + (n * vertex_size)) {                \
+               if (!swtnl_restart(ctx, multi, vertex_size))            \
+                       return;                                         \
+       }                                                               \
                                                                        \
-       if (nv04_mtex_engine(fahrenheit))                               \
-               BEGIN_NV04(push, NV04_MTRI(TLMTVERTEX_SX(0)),           \
-                          n * vertex_len);                             \
-       else                                                            \
-               BEGIN_NV04(push, NV04_TTRI(TLVERTEX_SX(0)),             \
-                          n * vertex_len);                             \
+       BEGIN_NV04(push, NV04_TTRI(TLVERTEX_SX(0)), n * vertex_size);
 
 #define OUT_VERTEX(i)                                                  \
-       PUSH_DATAp(push, _tnl_get_vertex(ctx, i), vertex_len);
+       PUSH_DATAp(push, _tnl_get_vertex(ctx, i), vertex_size);
 
 #define END_PRIMITIVE(draw)                                            \
-       if (nv04_mtex_engine(fahrenheit)) {                             \
+       if (multi) {                                                    \
                BEGIN_NV04(push, NV04_MTRI(DRAWPRIMITIVE(0)), 1);       \
                PUSH_DATA (push, draw);                                 \
        } else {                                                        \
@@ -162,13 +240,6 @@ swtnl_line(struct gl_context *ctx, GLuint v1, GLuint v2)
 static void
 swtnl_triangle(struct gl_context *ctx, GLuint v1, GLuint v2, GLuint v3)
 {
-       context_emit(ctx, TEX_OBJ0);
-       context_emit(ctx, TEX_OBJ1);
-       context_emit(ctx, TEX_ENV0);
-       context_emit(ctx, TEX_ENV1);
-       context_emit(ctx, CONTROL);
-       context_emit(ctx, BLEND);
-
        BEGIN_PRIMITIVE(3);
        OUT_VERTEX(v1);
        OUT_VERTEX(v2);
@@ -179,13 +250,6 @@ swtnl_triangle(struct gl_context *ctx, GLuint v1, GLuint v2, GLuint v3)
 static void
 swtnl_quad(struct gl_context *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4)
 {
-       context_emit(ctx, TEX_OBJ0);
-       context_emit(ctx, TEX_OBJ1);
-       context_emit(ctx, TEX_ENV0);
-       context_emit(ctx, TEX_ENV1);
-       context_emit(ctx, CONTROL);
-       context_emit(ctx, BLEND);
-
        BEGIN_PRIMITIVE(4);
        OUT_VERTEX(v1);
        OUT_VERTEX(v2);
index 91bd0518fa14a20ef806f0d08649a6301d52a7a5..6129b6d3ff1e16df35534a7d3cfb2155b8111604 100644 (file)
@@ -106,12 +106,4 @@ nv04_emit_scissor(struct gl_context *ctx, int emit)
        BEGIN_NV04(push, NV04_SF3D(CLIP_HORIZONTAL), 2);
        PUSH_DATA (push, w << 16 | x);
        PUSH_DATA (push, h << 16 | y);
-
-       /* Messing with surf3d invalidates the engine state. */
-       context_dirty_i(ctx, TEX_ENV, 0);
-       context_dirty_i(ctx, TEX_ENV, 1);
-       context_dirty_i(ctx, TEX_OBJ, 0);
-       context_dirty_i(ctx, TEX_OBJ, 1);
-       context_dirty(ctx, CONTROL);
-       context_dirty(ctx, BLEND);
 }
index ef4c557cb5772d4967d20a082a25db8ed61fc90e..85d81664909ade31688d84b7b5f0844d8d30cae5 100644 (file)
@@ -234,19 +234,28 @@ setup_combiner(struct combiner_state *rc)
        }
 }
 
+static unsigned
+get_texenv_mode(unsigned mode)
+{
+       switch (mode) {
+       case GL_REPLACE:
+               return 0x1;
+       case GL_DECAL:
+               return 0x3;
+       case GL_MODULATE:
+               return 0x4;
+       default:
+               assert(0);
+       }
+}
+
 void
 nv04_emit_tex_env(struct gl_context *ctx, int emit)
 {
+       struct nv04_context *nv04 = to_nv04_context(ctx);
        const int i = emit - NOUVEAU_STATE_TEX_ENV0;
-       struct nouveau_pushbuf *push = context_push(ctx);
-       struct nouveau_object *fahrenheit = nv04_context_engine(ctx);
        struct combiner_state rc_a = {}, rc_c = {};
 
-       if (!nv04_mtex_engine(fahrenheit)) {
-               context_dirty(ctx, BLEND);
-               return;
-       }
-
        /* Compute the new combiner state. */
        if (ctx->Texture.Unit[i]._ReallyEnabled) {
                INIT_COMBINER(A, ctx, &rc_a, i);
@@ -275,12 +284,16 @@ nv04_emit_tex_env(struct gl_context *ctx, int emit)
                UNSIGNED_OP(&rc_c);
        }
 
-       /* Write the register combiner state out to the hardware. */
-       BEGIN_NV04(push, NV04_MTRI(COMBINE_ALPHA(i)), 2);
-       PUSH_DATA (push, rc_a.hw);
-       PUSH_DATA (push, rc_c.hw);
-
-       BEGIN_NV04(push, NV04_MTRI(COMBINE_FACTOR), 1);
-       PUSH_DATA (push, pack_rgba_f(MESA_FORMAT_ARGB8888,
-                                    ctx->Texture.Unit[0].EnvColor));
+       /* calculate non-multitex state */
+       nv04->blend &= ~NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_MAP__MASK;
+       if (ctx->Texture._EnabledUnits)
+               nv04->blend |= get_texenv_mode(ctx->Texture.Unit[0].EnvMode);
+       else
+               nv04->blend |= get_texenv_mode(GL_MODULATE);
+
+       /* update calculated multitex state */
+       nv04->alpha[i] = rc_a.hw;
+       nv04->color[i] = rc_c.hw;
+       nv04->factor   = pack_rgba_f(MESA_FORMAT_ARGB8888,
+                                    ctx->Texture.Unit[0].EnvColor);
 }
index f8abda1b9cba1b5326faf4a329e2e7c42bd80b1e..ecede6703d26ff57edec9103c9035a643328d453 100644 (file)
@@ -81,21 +81,6 @@ get_stencil_op(unsigned op)
        }
 }
 
-static unsigned
-get_texenv_mode(unsigned mode)
-{
-       switch (mode) {
-       case GL_REPLACE:
-               return 0x1;
-       case GL_DECAL:
-               return 0x3;
-       case GL_MODULATE:
-               return 0x4;
-       default:
-               assert(0);
-       }
-}
-
 static unsigned
 get_blend_func(unsigned func)
 {
@@ -136,115 +121,69 @@ nv04_defer_control(struct gl_context *ctx, int emit)
 void
 nv04_emit_control(struct gl_context *ctx, int emit)
 {
-       struct nouveau_pushbuf *push = context_push(ctx);
-       struct nouveau_object *fahrenheit = nv04_context_engine(ctx);
-
-       if (nv04_mtex_engine(fahrenheit)) {
-               int cull_mode = ctx->Polygon.CullFaceMode;
-               int front_face = ctx->Polygon.FrontFace;
-               uint32_t ctrl0 = 1 << 30 |
-                       NV04_MULTITEX_TRIANGLE_CONTROL0_ORIGIN_CORNER;
-               uint32_t ctrl1 = 0, ctrl2 = 0;
-
-               /* Color mask. */
-               if (ctx->Color.ColorMask[0][RCOMP])
-                       ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_RED_WRITE;
-               if (ctx->Color.ColorMask[0][GCOMP])
-                       ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_GREEN_WRITE;
-               if (ctx->Color.ColorMask[0][BCOMP])
-                       ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_BLUE_WRITE;
-               if (ctx->Color.ColorMask[0][ACOMP])
-                       ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_ALPHA_WRITE;
-
-               /* Dithering. */
-               if (ctx->Color.DitherFlag)
-                       ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_DITHER_ENABLE;
-
-               /* Cull mode. */
-               if (!ctx->Polygon.CullFlag)
-                       ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_NONE;
-               else if (cull_mode == GL_FRONT_AND_BACK)
-                       ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_BOTH;
-               else
-                       ctrl0 |= (cull_mode == GL_FRONT) ^ (front_face == GL_CCW) ?
-                               NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_CW :
-                               NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_CCW;
-
-               /* Depth test. */
-               if (ctx->Depth.Test)
-                       ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_Z_ENABLE;
-
-               if (ctx->Depth.Mask)
-                       ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_Z_WRITE;
-
-               ctrl0 |= get_comparison_op(ctx->Depth.Func) << 16;
-
-               /* Alpha test. */
-               if (ctx->Color.AlphaEnabled)
-                       ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_ALPHA_ENABLE;
-
-               ctrl0 |= get_comparison_op(ctx->Color.AlphaFunc) << 8 |
-                       FLOAT_TO_UBYTE(ctx->Color.AlphaRef);
-
-               /* Stencil test. */
-               if (ctx->Stencil.WriteMask[0])
-                       ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_STENCIL_WRITE;
-
-               if (ctx->Stencil.Enabled)
-                       ctrl1 |= NV04_MULTITEX_TRIANGLE_CONTROL1_STENCIL_ENABLE;
+       struct nv04_context *nv04 = to_nv04_context(ctx);
+       int cull = ctx->Polygon.CullFaceMode;
+       int front = ctx->Polygon.FrontFace;
 
-               ctrl1 |= get_comparison_op(ctx->Stencil.Function[0]) << 4 |
-                       ctx->Stencil.Ref[0] << 8 |
-                       ctx->Stencil.ValueMask[0] << 16 |
-                       ctx->Stencil.WriteMask[0] << 24;
-
-               ctrl2 |= get_stencil_op(ctx->Stencil.ZPassFunc[0]) << 8 |
-                       get_stencil_op(ctx->Stencil.ZFailFunc[0]) << 4 |
-                       get_stencil_op(ctx->Stencil.FailFunc[0]);
-
-               BEGIN_NV04(push, NV04_MTRI(CONTROL0), 3);
-               PUSH_DATA (push, ctrl0);
-               PUSH_DATA (push, ctrl1);
-               PUSH_DATA (push, ctrl2);
-
-       } else {
-               int cull_mode = ctx->Polygon.CullFaceMode;
-               int front_face = ctx->Polygon.FrontFace;
-               uint32_t ctrl = 1 << 30 |
+       nv04->ctrl[0] = NV04_TEXTURED_TRIANGLE_CONTROL_Z_FORMAT_FIXED |
                        NV04_TEXTURED_TRIANGLE_CONTROL_ORIGIN_CORNER;
-
-               /* Dithering. */
-               if (ctx->Color.DitherFlag)
-                       ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE;
-
-               /* Cull mode. */
-               if (!ctx->Polygon.CullFlag)
-                       ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_NONE;
-               else if (cull_mode == GL_FRONT_AND_BACK)
-                       ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_BOTH;
-               else
-                       ctrl |= (cull_mode == GL_FRONT) ^ (front_face == GL_CCW) ?
-                               NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CW :
-                               NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CCW;
-
-               /* Depth test. */
-               if (ctx->Depth.Test)
-                       ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE;
-               if (ctx->Depth.Mask)
-                       ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_WRITE;
-
-               ctrl |= get_comparison_op(ctx->Depth.Func) << 16;
-
-               /* Alpha test. */
-               if (ctx->Color.AlphaEnabled)
-                       ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE;
-
-               ctrl |= get_comparison_op(ctx->Color.AlphaFunc) << 8 |
-                       FLOAT_TO_UBYTE(ctx->Color.AlphaRef);
-
-               BEGIN_NV04(push, NV04_TTRI(CONTROL), 1);
-               PUSH_DATA (push, ctrl);
-       }
+       nv04->ctrl[1] = 0;
+       nv04->ctrl[2] = 0;
+
+       /* Dithering. */
+       if (ctx->Color.DitherFlag)
+               nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE;
+
+       /* Cull mode. */
+       if (!ctx->Polygon.CullFlag)
+               nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_NONE;
+       else if (cull == GL_FRONT_AND_BACK)
+               nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_BOTH;
+       else
+               nv04->ctrl[0] |= (cull == GL_FRONT) ^ (front == GL_CCW) ?
+                                NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CW :
+                                NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CCW;
+
+       /* Depth test. */
+       if (ctx->Depth.Test)
+               nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE;
+       if (ctx->Depth.Mask)
+               nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_WRITE;
+
+       nv04->ctrl[0] |= get_comparison_op(ctx->Depth.Func) << 16;
+
+       /* Alpha test. */
+       if (ctx->Color.AlphaEnabled)
+               nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE;
+
+       nv04->ctrl[0] |= get_comparison_op(ctx->Color.AlphaFunc) << 8 |
+                        FLOAT_TO_UBYTE(ctx->Color.AlphaRef);
+
+       /* Color mask. */
+       if (ctx->Color.ColorMask[0][RCOMP])
+               nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_RED_WRITE;
+       if (ctx->Color.ColorMask[0][GCOMP])
+               nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_GREEN_WRITE;
+       if (ctx->Color.ColorMask[0][BCOMP])
+               nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_BLUE_WRITE;
+       if (ctx->Color.ColorMask[0][ACOMP])
+               nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_ALPHA_WRITE;
+
+       /* Stencil test. */
+       if (ctx->Stencil.WriteMask[0])
+               nv04->ctrl[0] |= NV04_MULTITEX_TRIANGLE_CONTROL0_STENCIL_WRITE;
+
+       if (ctx->Stencil.Enabled)
+               nv04->ctrl[1] |= NV04_MULTITEX_TRIANGLE_CONTROL1_STENCIL_ENABLE;
+
+       nv04->ctrl[1] |= get_comparison_op(ctx->Stencil.Function[0]) << 4 |
+                        ctx->Stencil.Ref[0] << 8 |
+                        ctx->Stencil.ValueMask[0] << 16 |
+                        ctx->Stencil.WriteMask[0] << 24;
+
+       nv04->ctrl[2] |= get_stencil_op(ctx->Stencil.ZPassFunc[0]) << 8 |
+                        get_stencil_op(ctx->Stencil.ZFailFunc[0]) << 4 |
+                        get_stencil_op(ctx->Stencil.FailFunc[0]);
 }
 
 void
@@ -256,77 +195,32 @@ nv04_defer_blend(struct gl_context *ctx, int emit)
 void
 nv04_emit_blend(struct gl_context *ctx, int emit)
 {
-       struct nouveau_pushbuf *push = context_push(ctx);
-       struct nouveau_object *fahrenheit = nv04_context_engine(ctx);
-
-       if (nv04_mtex_engine(fahrenheit)) {
-               uint32_t blend = 0x2 << 4 |
-                       NV04_MULTITEX_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE;
-
-               /* Alpha blending. */
-               blend |= get_blend_func(ctx->Color.Blend[0].DstRGB) << 28 |
-                       get_blend_func(ctx->Color.Blend[0].SrcRGB) << 24;
-
-               if (ctx->Color.BlendEnabled)
-                       blend |= NV04_MULTITEX_TRIANGLE_BLEND_BLEND_ENABLE;
-
-               /* Shade model. */
-               if (ctx->Light.ShadeModel == GL_SMOOTH)
-                       blend |= NV04_MULTITEX_TRIANGLE_BLEND_SHADE_MODE_GOURAUD;
-               else
-                       blend |= NV04_MULTITEX_TRIANGLE_BLEND_SHADE_MODE_FLAT;
-
-               /* Secondary color */
-               if (_mesa_need_secondary_color(ctx))
-                       blend |= NV04_MULTITEX_TRIANGLE_BLEND_SPECULAR_ENABLE;
-
-               /* Fog. */
-               if (ctx->Fog.Enabled)
-                       blend |= NV04_MULTITEX_TRIANGLE_BLEND_FOG_ENABLE;
-
-               BEGIN_NV04(push, NV04_MTRI(BLEND), 1);
-               PUSH_DATA (push, blend);
-
-               BEGIN_NV04(push, NV04_MTRI(FOGCOLOR), 1);
-               PUSH_DATA (push, pack_rgba_f(MESA_FORMAT_ARGB8888,
-                                            ctx->Fog.Color));
-
-       } else {
-               uint32_t blend = 0x2 << 4 |
-                       NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE;
-
-               /* Alpha blending. */
-               blend |= get_blend_func(ctx->Color.Blend[0].DstRGB) << 28 |
-                       get_blend_func(ctx->Color.Blend[0].SrcRGB) << 24;
-
-               if (ctx->Color.BlendEnabled)
-                       blend |= NV04_TEXTURED_TRIANGLE_BLEND_BLEND_ENABLE;
+       struct nv04_context *nv04 = to_nv04_context(ctx);
 
-               /* Shade model. */
-               if (ctx->Light.ShadeModel == GL_SMOOTH)
-                       blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD;
-               else
-                       blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT;
+       nv04->blend &= NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_MAP__MASK;
+       nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_MASK_BIT_MSB |
+                      NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE;
 
-               /* Texture environment. */
-               if (ctx->Texture._EnabledUnits)
-                       blend |= get_texenv_mode(ctx->Texture.Unit[0].EnvMode);
-               else
-                       blend |= get_texenv_mode(GL_MODULATE);
+       /* Alpha blending. */
+       nv04->blend |= get_blend_func(ctx->Color.Blend[0].DstRGB) << 28 |
+                      get_blend_func(ctx->Color.Blend[0].SrcRGB) << 24;
 
-               /* Secondary color */
-               if (_mesa_need_secondary_color(ctx))
-                       blend |= NV04_TEXTURED_TRIANGLE_BLEND_SPECULAR_ENABLE;
+       if (ctx->Color.BlendEnabled)
+               nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_BLEND_ENABLE;
 
-               /* Fog. */
-               if (ctx->Fog.Enabled)
-                       blend |= NV04_TEXTURED_TRIANGLE_BLEND_FOG_ENABLE;
+       /* Shade model. */
+       if (ctx->Light.ShadeModel == GL_SMOOTH)
+               nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD;
+       else
+               nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT;
 
-               BEGIN_NV04(push, NV04_TTRI(BLEND), 1);
-               PUSH_DATA (push, blend);
+       /* Secondary color */
+       if (_mesa_need_secondary_color(ctx))
+               nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_SPECULAR_ENABLE;
 
-               BEGIN_NV04(push, NV04_TTRI(FOGCOLOR), 1);
-               PUSH_DATA (push, pack_rgba_f(MESA_FORMAT_ARGB8888,
-                                            ctx->Fog.Color));
+       /* Fog. */
+       if (ctx->Fog.Enabled) {
+               nv04->blend |= NV04_TEXTURED_TRIANGLE_BLEND_FOG_ENABLE;
+               nv04->fog = pack_rgba_f(MESA_FORMAT_ARGB8888, ctx->Fog.Color);
        }
 }
index cc35d2545e213aaf0cf4e9453aeb477e2549bf58..807e2f3dec92f759442a64847ef8a7d17dfc2cda 100644 (file)
@@ -59,18 +59,11 @@ get_tex_format(struct gl_texture_image *ti)
 void
 nv04_emit_tex_obj(struct gl_context *ctx, int emit)
 {
+       struct nv04_context *nv04 = to_nv04_context(ctx);
        const int i = emit - NOUVEAU_STATE_TEX_OBJ0;
-       struct nouveau_pushbuf *push = context_push(ctx);
-       struct nouveau_object *fahrenheit = nv04_context_engine(ctx);
-       const int bo_flags = NOUVEAU_BO_RD | NOUVEAU_BO_GART | NOUVEAU_BO_VRAM;
        struct nouveau_surface *s;
        uint32_t format = 0xa0, filter = 0x1010;
 
-       PUSH_RESET(push, BUFCTX_TEX(i));
-
-       if (i && !nv04_mtex_engine(fahrenheit))
-               return;
-
        if (ctx->Texture.Unit[i]._ReallyEnabled) {
                struct gl_texture_object *t = ctx->Texture.Unit[i]._Current;
                struct gl_texture_image *ti = t->Image[0][t->BaseLevel];
@@ -115,35 +108,7 @@ nv04_emit_tex_obj(struct gl_context *ctx, int emit)
                        NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST;
        }
 
-       if (nv04_mtex_engine(fahrenheit)) {
-               BEGIN_NV04(push, NV04_MTRI(OFFSET(i)), 1);
-               PUSH_MTHDl(push, NV04_MTRI(OFFSET(i)), BUFCTX_TEX(i),
-                                s->bo, s->offset, bo_flags);
-
-               BEGIN_NV04(push, NV04_MTRI(FORMAT(i)), 1);
-               PUSH_MTHD (push, NV04_MTRI(FORMAT(i)), BUFCTX_TEX(i),
-                                s->bo, format, bo_flags | NOUVEAU_BO_OR,
-                                NV04_MULTITEX_TRIANGLE_FORMAT_DMA_A,
-                                NV04_MULTITEX_TRIANGLE_FORMAT_DMA_B);
-
-               BEGIN_NV04(push, NV04_MTRI(FILTER(i)), 1);
-               PUSH_DATA (push, filter);
-
-       } else {
-               BEGIN_NV04(push, NV04_TTRI(OFFSET), 1);
-               PUSH_MTHDl(push, NV04_TTRI(OFFSET), BUFCTX_TEX(0),
-                                s->bo, s->offset, bo_flags);
-
-               BEGIN_NV04(push, NV04_TTRI(FORMAT), 1);
-               PUSH_MTHD (push, NV04_TTRI(FORMAT), BUFCTX_TEX(0),
-                                s->bo, format, bo_flags | NOUVEAU_BO_OR,
-                                NV04_TEXTURED_TRIANGLE_FORMAT_DMA_A,
-                                NV04_TEXTURED_TRIANGLE_FORMAT_DMA_B);
-
-               BEGIN_NV04(push, NV04_TTRI(COLORKEY), 1);
-               PUSH_DATA (push, 0);
-
-               BEGIN_NV04(push, NV04_TTRI(FILTER), 1);
-               PUSH_DATA (push, filter);
-       }
+       nv04->texture[i] = s;
+       nv04->format[i] = format;
+       nv04->filter[i] = filter;
 }
index 239d77039b36a70dc8eee0f93e5a72aa4cf8caa4..522c94819c076fafdb71fa7cd409aacae803e14c 100644 (file)
@@ -267,7 +267,6 @@ nv04_surface_copy_swizzle(struct gl_context *ctx,
        if (context_chipset(ctx) < 0x10) {
                BEGIN_NV04(push, NV01_SUBC(SURF, OBJECT), 1);
                PUSH_DATA (push, hw->surf3d->handle);
-               PUSH_KICK(push);
        }
 }
 
@@ -312,9 +311,6 @@ nv04_surface_copy_m2mf(struct gl_context *ctx,
                dst_offset += dst->pitch * count;
                h -= count;
        }
-
-       if (context_chipset(ctx) < 0x10)
-               PUSH_KICK(push);
 }
 
 typedef unsigned (*get_offset_t)(struct nouveau_surface *s,
@@ -453,9 +449,6 @@ nv04_surface_fill(struct gl_context *ctx,
        BEGIN_NV04(push, NV04_GDI(UNCLIPPED_RECTANGLE_POINT(0)), 2);
        PUSH_DATA (push, (dx << 16) | dy);
        PUSH_DATA (push, ( w << 16) |  h);
-
-       if (context_chipset(ctx) < 0x10)
-               PUSH_KICK(push);
 }
 
 void