aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers
diff options
context:
space:
mode:
authorBen Skeggs <[email protected]>2012-04-13 17:50:37 +1000
committerBen Skeggs <[email protected]>2012-04-14 02:56:12 +1000
commitf3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652 (patch)
tree7708f8b86ab74d0d62585e0c2a8eb3321e7c81c8 /src/mesa/drivers
parent2e47d01c9e5325906cf3bb979279599991c6328e (diff)
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.
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r--src/mesa/drivers/dri/nouveau/nv04_context.c19
-rw-r--r--src/mesa/drivers/dri/nouveau/nv04_context.h11
-rw-r--r--src/mesa/drivers/dri/nouveau/nv04_render.c114
-rw-r--r--src/mesa/drivers/dri/nouveau/nv04_state_fb.c8
-rw-r--r--src/mesa/drivers/dri/nouveau/nv04_state_frag.c43
-rw-r--r--src/mesa/drivers/dri/nouveau/nv04_state_raster.c270
-rw-r--r--src/mesa/drivers/dri/nouveau/nv04_state_tex.c43
-rw-r--r--src/mesa/drivers/dri/nouveau/nv04_surface.c7
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 921f474ce7e..9472bdd7b51 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 589aab27b74..b63024c1428 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 31b18bc0616..30e9f9aad96 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 91bd0518fa1..6129b6d3ff1 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 ef4c557cb57..85d81664909 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 f8abda1b9cb..ecede6703d2 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 cc35d2545e2..807e2f3dec9 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 239d77039b3..522c94819c0 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