Mesa (master): nouveau: rework and simplify nv04/nv05 driver a bit

Ben Skeggs darktama at kemper.freedesktop.org
Fri Apr 13 17:12:41 UTC 2012


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

Author: Ben Skeggs <bskeggs at redhat.com>
Date:   Fri Apr 13 17:50:37 2012 +1000

nouveau: rework and simplify nv04/nv05 driver a bit

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      |   19 +--
 src/mesa/drivers/dri/nouveau/nv04_context.h      |   11 +
 src/mesa/drivers/dri/nouveau/nv04_render.c       |  114 +++++++--
 src/mesa/drivers/dri/nouveau/nv04_state_fb.c     |    8 -
 src/mesa/drivers/dri/nouveau/nv04_state_frag.c   |   43 +++--
 src/mesa/drivers/dri/nouveau/nv04_state_raster.c |  270 +++++++---------------
 src/mesa/drivers/dri/nouveau/nv04_state_tex.c    |   43 +---
 src/mesa/drivers/dri/nouveau/nv04_surface.c      |    7 -
 8 files changed, 215 insertions(+), 300 deletions(-)

diff --git a/src/mesa/drivers/dri/nouveau/nv04_context.c b/src/mesa/drivers/dri/nouveau/nv04_context.c
index 921f474..9472bdd 100644
--- a/src/mesa/drivers/dri/nouveau/nv04_context.c
+++ b/src/mesa/drivers/dri/nouveau/nv04_context.c
@@ -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;
diff --git a/src/mesa/drivers/dri/nouveau/nv04_context.h b/src/mesa/drivers/dri/nouveau/nv04_context.h
index 589aab2..b63024c 100644
--- a/src/mesa/drivers/dri/nouveau/nv04_context.h
+++ b/src/mesa/drivers/dri/nouveau/nv04_context.h
@@ -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))
 
diff --git a/src/mesa/drivers/dri/nouveau/nv04_render.c b/src/mesa/drivers/dri/nouveau/nv04_render.c
index 31b18bc..30e9f9a 100644
--- a/src/mesa/drivers/dri/nouveau/nv04_render.c
+++ b/src/mesa/drivers/dri/nouveau/nv04_render.c
@@ -94,14 +94,92 @@ 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);
diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_fb.c b/src/mesa/drivers/dri/nouveau/nv04_state_fb.c
index 91bd051..6129b6d 100644
--- a/src/mesa/drivers/dri/nouveau/nv04_state_fb.c
+++ b/src/mesa/drivers/dri/nouveau/nv04_state_fb.c
@@ -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);
 }
diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_frag.c b/src/mesa/drivers/dri/nouveau/nv04_state_frag.c
index ef4c557..85d8166 100644
--- a/src/mesa/drivers/dri/nouveau/nv04_state_frag.c
+++ b/src/mesa/drivers/dri/nouveau/nv04_state_frag.c
@@ -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);
 }
diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_raster.c b/src/mesa/drivers/dri/nouveau/nv04_state_raster.c
index f8abda1..ecede67 100644
--- a/src/mesa/drivers/dri/nouveau/nv04_state_raster.c
+++ b/src/mesa/drivers/dri/nouveau/nv04_state_raster.c
@@ -82,21 +82,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)
 {
 	switch (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);
 	}
 }
diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_tex.c b/src/mesa/drivers/dri/nouveau/nv04_state_tex.c
index cc35d25..807e2f3 100644
--- a/src/mesa/drivers/dri/nouveau/nv04_state_tex.c
+++ b/src/mesa/drivers/dri/nouveau/nv04_state_tex.c
@@ -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;
 }
diff --git a/src/mesa/drivers/dri/nouveau/nv04_surface.c b/src/mesa/drivers/dri/nouveau/nv04_surface.c
index 239d770..522c948 100644
--- a/src/mesa/drivers/dri/nouveau/nv04_surface.c
+++ b/src/mesa/drivers/dri/nouveau/nv04_surface.c
@@ -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




More information about the mesa-commit mailing list