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.
This commit is contained in:
Ben Skeggs 2012-04-13 17:50:37 +10:00
parent 2e47d01c9e
commit f3d8bd3f7b
8 changed files with 207 additions and 292 deletions

View 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;

View 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))

View 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 (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);

View 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);
}

View 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);
/* 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);
}

View 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);
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);
}
}

View 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;
}

View 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