From f3d8bd3f7b9f5c6387cd5e629a82db9ad9a1e652 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 13 Apr 2012 17:50:37 +1000 Subject: [PATCH] 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 - .../drivers/dri/nouveau/nv04_state_frag.c | 41 ++- .../drivers/dri/nouveau/nv04_state_raster.c | 256 +++++------------- src/mesa/drivers/dri/nouveau/nv04_state_tex.c | 43 +-- src/mesa/drivers/dri/nouveau/nv04_surface.c | 7 - 8 files changed, 207 insertions(+), 292 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 @@ -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 (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); \ + if (PUSH_AVAIL(push) < 32 + (n * vertex_size)) { \ + if (!swtnl_restart(ctx, multi, vertex_size)) \ + return; \ + } \ + \ + 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); + /* 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); - BEGIN_NV04(push, NV04_MTRI(COMBINE_FACTOR), 1); - PUSH_DATA (push, pack_rgba_f(MESA_FORMAT_ARGB8888, - ctx->Texture.Unit[0].EnvColor)); + /* 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 @@ -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); + struct nv04_context *nv04 = to_nv04_context(ctx); + int cull = ctx->Polygon.CullFaceMode; + int front = ctx->Polygon.FrontFace; - 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; - - 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; + nv04->ctrl[1] = 0; + nv04->ctrl[2] = 0; - /* Dithering. */ - if (ctx->Color.DitherFlag) - ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE; + /* Dithering. */ + if (ctx->Color.DitherFlag) + nv04->ctrl[0] |= 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; + /* 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) - ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE; - if (ctx->Depth.Mask) - ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_WRITE; + /* 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; - ctrl |= get_comparison_op(ctx->Depth.Func) << 16; + nv04->ctrl[0] |= get_comparison_op(ctx->Depth.Func) << 16; - /* Alpha test. */ - if (ctx->Color.AlphaEnabled) - ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE; + /* Alpha test. */ + if (ctx->Color.AlphaEnabled) + nv04->ctrl[0] |= NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE; - ctrl |= get_comparison_op(ctx->Color.AlphaFunc) << 8 | - FLOAT_TO_UBYTE(ctx->Color.AlphaRef); + nv04->ctrl[0] |= get_comparison_op(ctx->Color.AlphaFunc) << 8 | + FLOAT_TO_UBYTE(ctx->Color.AlphaRef); - BEGIN_NV04(push, NV04_TTRI(CONTROL), 1); - PUSH_DATA (push, ctrl); - } + /* 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); + struct nv04_context *nv04 = to_nv04_context(ctx); - if (nv04_mtex_engine(fahrenheit)) { - uint32_t blend = 0x2 << 4 | - NV04_MULTITEX_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE; + 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; - /* Alpha blending. */ - blend |= get_blend_func(ctx->Color.Blend[0].DstRGB) << 28 | - get_blend_func(ctx->Color.Blend[0].SrcRGB) << 24; + /* Alpha blending. */ + nv04->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; + if (ctx->Color.BlendEnabled) + nv04->blend |= NV04_TEXTURED_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; + /* 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; - /* Secondary color */ - if (_mesa_need_secondary_color(ctx)) - blend |= NV04_MULTITEX_TRIANGLE_BLEND_SPECULAR_ENABLE; + /* Secondary color */ + if (_mesa_need_secondary_color(ctx)) + nv04->blend |= NV04_TEXTURED_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; - - /* 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; - - /* Texture environment. */ - if (ctx->Texture._EnabledUnits) - blend |= get_texenv_mode(ctx->Texture.Unit[0].EnvMode); - else - blend |= get_texenv_mode(GL_MODULATE); - - /* Secondary color */ - if (_mesa_need_secondary_color(ctx)) - blend |= NV04_TEXTURED_TRIANGLE_BLEND_SPECULAR_ENABLE; - - /* Fog. */ - if (ctx->Fog.Enabled) - blend |= NV04_TEXTURED_TRIANGLE_BLEND_FOG_ENABLE; - - BEGIN_NV04(push, NV04_TTRI(BLEND), 1); - PUSH_DATA (push, blend); - - 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