X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmesa%2Fdrivers%2Fdri%2Fr300%2Fr300_state.c;h=bbbf674ee1a6142cd88dde0dfbcfdd0d4d103681;hb=a85eb9c0a7eee87b76fc8deec5081628ed3e2ba8;hp=142d34bd83969078d93e302eff1971df4b13c406;hpb=ff04e50e2e4f423b7d8866b85d299c9acce5fed6;p=mesa.git diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 142d34bd839..bbbf674ee1a 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -48,6 +48,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast_setup/swrast_setup.h" #include "array_cache/acache.h" #include "tnl/tnl.h" +#include "texformat.h" #include "radeon_ioctl.h" #include "radeon_state.h" @@ -59,6 +60,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_emit.h" #include "r300_fixed_pipelines.h" + static void r300AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) { r300ContextPtr rmesa = R300_CONTEXT(ctx); @@ -201,6 +203,30 @@ static int blend_factor(GLenum factor, GLboolean is_src) * and GL_FUNC_REVERSE_SUBTRACT will cause wrong results otherwise for * unknown reasons. */ + +/* helper function */ +static void r300_set_blend_cntl(r300ContextPtr rmesa, int func, int eqn, int cbits, int funcA, int eqnA) +{ + GLuint new_ablend, new_cblend; + + #if 0 + fprintf(stderr, "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n", eqnA, funcA, eqn, func, cbits); + #endif + new_ablend = eqnA | funcA; + new_cblend = eqn | func; + if(funcA == func){ + new_cblend |= R300_BLEND_NO_SEPARATE; + } + new_cblend |= cbits; + + if((new_ablend != rmesa->hw.bld.cmd[R300_BLD_ABLEND]) + || (new_cblend != rmesa->hw.bld.cmd[R300_BLD_CBLEND])){ + R300_STATECHANGE(rmesa, bld); + rmesa->hw.bld.cmd[R300_BLD_ABLEND]=new_ablend; + rmesa->hw.bld.cmd[R300_BLD_CBLEND]=new_cblend; + } +} + static void r300_set_blend_state(GLcontext * ctx) { r300ContextPtr rmesa = R300_CONTEXT(ctx); @@ -217,7 +243,6 @@ static void r300_set_blend_state(GLcontext * ctx) (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT); int eqnA = R200_COMB_FCN_ADD_CLAMP; - R300_STATECHANGE(rmesa, bld); if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) { if (ctx->Color._LogicOpEnabled) { @@ -225,8 +250,9 @@ static void r300_set_blend_state(GLcontext * ctx) rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl | R300_ROP_ENABLE; #endif - rmesa->hw.bld.cmd[R300_BLD_ABLEND] = eqn | func; - rmesa->hw.bld.cmd[R300_BLD_CBLEND] = eqn | func; + r300_set_blend_cntl(rmesa, + func, eqn, 0, + func, eqn); return; } else if (ctx->Color.BlendEnabled) { #if 0 @@ -238,8 +264,9 @@ static void r300_set_blend_state(GLcontext * ctx) #if 0 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl; #endif - rmesa->hw.bld.cmd[R300_BLD_ABLEND] = eqn | func; - rmesa->hw.bld.cmd[R300_BLD_CBLEND] = eqn | func; + r300_set_blend_cntl(rmesa, + func, eqn, 0, + func, eqn); return; } } else { @@ -260,6 +287,9 @@ static void r300_set_blend_state(GLcontext * ctx) rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl; rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func; #endif + r300_set_blend_cntl(rmesa, + func, eqn, 0, + func, eqn); return; } } @@ -346,14 +376,12 @@ static void r300_set_blend_state(GLcontext * ctx) return; } - rmesa->hw.bld.cmd[R300_BLD_ABLEND] = eqnA | funcA; - rmesa->hw.bld.cmd[R300_BLD_CBLEND] = eqn | func ; - if(rmesa->hw.bld.cmd[R300_BLD_ABLEND] == rmesa->hw.bld.cmd[R300_BLD_CBLEND]){ - rmesa->hw.bld.cmd[R300_BLD_CBLEND] |= R300_BLEND_UNKNOWN | R300_BLEND_ENABLE | R300_BLEND_NO_SEPARATE; - } else { - rmesa->hw.bld.cmd[R300_BLD_CBLEND] |= R300_BLEND_UNKNOWN | R300_BLEND_ENABLE; - } - + r300_set_blend_cntl(rmesa, + func, eqn, R300_BLEND_UNKNOWN | R300_BLEND_ENABLE, + funcA, eqnA); + r300_set_blend_cntl(rmesa, + func, eqn, R300_BLEND_UNKNOWN | R300_BLEND_ENABLE, + funcA, eqnA); } static void r300BlendEquationSeparate(GLcontext * ctx, @@ -389,9 +417,8 @@ static void r300UpdateCulling(GLcontext* ctx) if (ctx->Polygon.FrontFace == GL_CW) val |= R300_FRONT_FACE_CW; else - val |= R300_FRONT_FACE_CCW; + val |= R300_FRONT_FACE_CCW; } - r300->hw.cul.cmd[R300_CUL_CULL] = val; } @@ -412,8 +439,31 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state) state ? "GL_TRUE" : "GL_FALSE"); switch (cap) { + /* Fast track this one... + */ + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + break; + + case GL_ALPHA_TEST: + R200_STATECHANGE(r300, at); + if (state) { + r300->hw.at.cmd[R300_AT_ALPHA_TEST] |= + R300_ALPHA_TEST_ENABLE; + } else { + r300->hw.at.cmd[R300_AT_ALPHA_TEST] |= + ~R300_ALPHA_TEST_ENABLE; + } + break; + + case GL_BLEND: + case GL_COLOR_LOGIC_OP: + r300_set_blend_state(ctx); + break; + case GL_DEPTH_TEST: - R300_STATECHANGE(r300, zc); + R300_STATECHANGE(r300, zs); if (state) { if (ctx->Depth.Mask) @@ -423,12 +473,57 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state) } else newval = 0; - r300->hw.zc.cmd[R300_ZC_CNTL_0] = newval; + r300->hw.zs.cmd[R300_ZS_CNTL_0] = newval; + break; + + case GL_STENCIL_TEST: + + WARN_ONCE("Do not know how to enable stencil. Help me !\n"); + + if (r300->state.hw_stencil) { + //fprintf(stderr, "Stencil %s\n", state ? "enabled" : "disabled"); + R300_STATECHANGE(r300, zs); + if (state) { + r300->hw.zs.cmd[R300_ZS_CNTL_0] |= + R300_RB3D_STENCIL_ENABLE; + } else { + r300->hw.zs.cmd[R300_ZS_CNTL_0] &= + ~R300_RB3D_STENCIL_ENABLE; + } + } else { + FALLBACK(&r300->radeon, RADEON_FALLBACK_STENCIL, state); + } break; case GL_CULL_FACE: r300UpdateCulling(ctx); break; + + case GL_POLYGON_OFFSET_POINT: + case GL_POLYGON_OFFSET_LINE: + WARN_ONCE("Don't know how to enable polygon offset point/line. Help me !\n"); + + /* Something is apparently blocking these from working */ + R300_STATECHANGE(r300, unk42B4); + if(state){ + r300->hw.unk42B4.cmd[1] |= ~(3<<0); + } else { + r300->hw.unk42B4.cmd[1] &= (3<<0); + } + break; + + case GL_POLYGON_OFFSET_FILL: + R300_STATECHANGE(r300, unk42B4); + if(state){ + r300->hw.unk42B4.cmd[1] |= (3<<0); + } else { + r300->hw.unk42B4.cmd[1] &= ~(3<<0); + } + break; + + case GL_VERTEX_PROGRAM_ARB: + //TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, state); + break; default: radeonEnable(ctx, cap, state); @@ -472,34 +567,37 @@ static void r300DepthFunc(GLcontext* ctx, GLenum func) { r300ContextPtr r300 = R300_CONTEXT(ctx); - R300_STATECHANGE(r300, zc); + R300_STATECHANGE(r300, zs); + + r300->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT); switch(func) { case GL_NEVER: - r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_NEVER; + r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_NEVER << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT; break; case GL_LESS: - r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_LESS; + r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_LESS << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT; break; case GL_EQUAL: - r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_EQUAL; + r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_EQUAL << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT; break; case GL_LEQUAL: - r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_LEQUAL; + r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_LEQUAL << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT; break; case GL_GREATER: - r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_GREATER; + r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_GREATER << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT; break; case GL_NOTEQUAL: - r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_NEQUAL; + r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_NOTEQUAL << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT; break; case GL_GEQUAL: - r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_GEQUAL; + r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_GEQUAL << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT; break; case GL_ALWAYS: - r300->hw.zc.cmd[R300_ZC_CNTL_1] = R300_Z_TEST_ALWAYS; + r300->hw.zs.cmd[R300_ZS_CNTL_1] |= R300_ZS_ALWAYS << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT; break; } + } @@ -515,8 +613,8 @@ static void r300DepthMask(GLcontext* ctx, GLboolean mask) if (!ctx->Depth.Test) return; - R300_STATECHANGE(r300, zc); - r300->hw.zc.cmd[R300_ZC_CNTL_0] = mask + R300_STATECHANGE(r300, zs); + r300->hw.zs.cmd[R300_ZS_CNTL_0] = mask ? R300_RB3D_Z_TEST_AND_WRITE : R300_RB3D_Z_TEST; } @@ -543,9 +641,248 @@ static void r300PointSize(GLcontext * ctx, GLfloat size) { r300ContextPtr r300 = R300_CONTEXT(ctx); + /* TODO: Validate point size */ + R300_STATECHANGE(r300, ps); + r300->hw.ps.cmd[R300_PS_POINTSIZE] = + ((int)(size * 6) << R300_POINTSIZE_X_SHIFT) | + ((int)(size * 6) << R300_POINTSIZE_Y_SHIFT); + +#if 0 /* r200 reg? */ /* This might need fixing later */ R300_STATECHANGE(r300, vps); r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0); +#endif +} + +/* ============================================================= + * Line state + */ +static void r300LineWidth(GLcontext *ctx, GLfloat widthf) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + /* IMHO mesa isnt clamping line widths according to ctx->Const.*LineWidth + before calling this from the dd function table. + Since r300ResetHwState calls these with clamped values, + they must be set properly. */ + + R300_STATECHANGE(r300, lcntl); + r300->hw.lcntl.cmd[1] = (int)(widthf * 6.0); + /* Doesnt look very good without this... */ + r300->hw.lcntl.cmd[1] |= R300_LINE_CNT_UNK1; +} + +/* + +glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); : 00000091 ( 1001 0001) +glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); : 00000001 ( 1) + +glPolygonMode(GL_FRONT, GL_LINE); : 00000111 (1 0001 0001) +glPolygonMode(GL_FRONT, GL_POINT); : 00000101 (1 0000 0001) + +glPolygonMode(GL_BACK, GL_LINE); : 000000a1 ( 1010 0001) +glPolygonMode(GL_BACK, GL_POINT); : 00000021 ( 10 0001) + +*/ + +/* exclusive */ +#define PM_NOT_BACK (1<<8) +#define PM_NOT_FRONT (1<<5) + +#define PM_FRONT_LINE (1<<4) +#define PM_BACK_LINE (1<<7) + +static void r300PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + unsigned long hw_mode=0; + + hw_mode=r300->hw.unk4288.cmd[1]; + hw_mode |= 1; /* enables point mode by default */ + + switch (face) { + case GL_FRONT: + //fprintf(stderr, "front\n"); + hw_mode &= ~PM_NOT_FRONT; + switch (mode) { + case GL_LINE: + hw_mode |= PM_FRONT_LINE; + break; + case GL_POINT: + hw_mode &= ~PM_FRONT_LINE; + break; + case GL_FILL: /* No idea */ + hw_mode = 0; + break; + } + break; + + case GL_BACK: + //fprintf(stderr, "back\n"); + hw_mode &= ~PM_NOT_BACK; + switch (mode) { + case GL_LINE: + hw_mode |= PM_BACK_LINE; + break; + case GL_POINT: + hw_mode &= ~PM_BACK_LINE; + break; + case GL_FILL: /* No idea */ + hw_mode = 0; + break; + } + break; + + case GL_FRONT_AND_BACK: + //fprintf(stderr, "front and back\n"); + hw_mode &= ~PM_NOT_FRONT; + hw_mode &= ~PM_NOT_BACK; + switch (mode) { + case GL_LINE: + hw_mode |= PM_FRONT_LINE; + hw_mode |= PM_BACK_LINE; + break; + case GL_POINT: + hw_mode &= ~PM_FRONT_LINE; + hw_mode &= ~PM_BACK_LINE; + break; + case GL_FILL: + hw_mode = 0; + break; + } + break; + } + + //if( front and back fill) hw_mode=0; + + if(r300->hw.unk4288.cmd[1] != hw_mode){ + R300_STATECHANGE(r300, unk4288); + r300->hw.unk4288.cmd[1] = hw_mode; + } +} + +/* ============================================================= + * Stencil + */ + + static int translate_stencil_func(int func) + { + switch (func) { + case GL_NEVER: + return R300_ZS_NEVER; + break; + case GL_LESS: + return R300_ZS_LESS; + break; + case GL_EQUAL: + return R300_ZS_EQUAL; + break; + case GL_LEQUAL: + return R300_ZS_LEQUAL; + break; + case GL_GREATER: + return R300_ZS_GREATER; + break; + case GL_NOTEQUAL: + return R300_ZS_NOTEQUAL; + break; + case GL_GEQUAL: + return R300_ZS_GEQUAL; + break; + case GL_ALWAYS: + return R300_ZS_ALWAYS; + break; + } + return 0; + } + + static int translate_stencil_op(int op) +{ + switch (op) { + case GL_KEEP: + return R300_ZS_KEEP; + case GL_ZERO: + return R300_ZS_ZERO; + case GL_REPLACE: + return R300_ZS_REPLACE; + case GL_INCR: + return R300_ZS_INCR; + case GL_DECR: + return R300_ZS_DECR; + case GL_INCR_WRAP_EXT: + return R300_ZS_INCR_WRAP; + case GL_DECR_WRAP_EXT: + return R300_ZS_DECR_WRAP; + case GL_INVERT: + return R300_ZS_INVERT; + default: + WARN_ONCE("Do not know how to translate stencil op"); + return R300_ZS_KEEP; + } +} + +static void r300StencilFunc(GLcontext * ctx, GLenum func, + GLint ref, GLuint mask) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + GLuint refmask = ((ctx->Stencil.Ref[0] << R300_RB3D_ZS2_STENCIL_REF_SHIFT) | + (ctx->Stencil. + ValueMask[0] << R300_RB3D_ZS2_STENCIL_MASK_SHIFT)); + GLuint flag; + + R300_STATECHANGE(rmesa, zs); + + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= ~( + (R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) + | (R300_ZS_MASK << R300_RB3D_ZS1_BACK_FUNC_SHIFT)); + rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= ~((R300_ZS_MASK << R300_RB3D_ZS2_STENCIL_REF_SHIFT) | + (R300_ZS_MASK << R300_RB3D_ZS2_STENCIL_MASK_SHIFT)); + + flag = translate_stencil_func(ctx->Stencil.Function[0]); + + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) + | (flag << R300_RB3D_ZS1_BACK_FUNC_SHIFT); + rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask; +} + +static void r300StencilMask(GLcontext * ctx, GLuint mask) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + + R300_STATECHANGE(rmesa, zs); + rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= ~(R300_ZS_MASK << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT); + rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= ctx->Stencil.WriteMask[0] << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT; +} + + +static void r300StencilOp(GLcontext * ctx, GLenum fail, + GLenum zfail, GLenum zpass) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + + R300_STATECHANGE(rmesa, zs); + /* It is easier to mask what's left.. */ + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= (R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT); + + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= + (translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT); + +} + +static void r300ClearStencil(GLcontext * ctx, GLint s) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + + /* Not sure whether this is correct.. */ + R300_STATECHANGE(rmesa, zs); + rmesa->hw.zs.cmd[R300_ZS_CNTL_2] = + ((GLuint) ctx->Stencil.Clear | + (0xff << R200_STENCIL_MASK_SHIFT) | + (ctx->Stencil.WriteMask[0] << R200_STENCIL_WRITEMASK_SHIFT)); } /* ============================================================= @@ -591,7 +928,7 @@ static void r300Viewport(GLcontext * ctx, GLint x, GLint y, * setting below. Could apply deltas to rescue pipelined viewport * values, or keep the originals hanging around. */ - R200_FIREVERTICES(R200_CONTEXT(ctx)); + R300_FIREVERTICES(R300_CONTEXT(ctx)); r300UpdateWindow(ctx); } @@ -600,6 +937,25 @@ static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval) r300UpdateWindow(ctx); } +/* ============================================================= + * Polygon state + */ +static void r300PolygonOffset(GLcontext * ctx, GLfloat factor, GLfloat units) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + GLfloat constant = units * /*rmesa->state.depth.scale*/4; + + factor *= 12; + +/* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */ + + R300_STATECHANGE(rmesa, zbs); + rmesa->hw.zbs.cmd[R300_ZBS_T_FACTOR] = r300PackFloat32(factor); + rmesa->hw.zbs.cmd[R300_ZBS_T_CONSTANT] = r300PackFloat32(constant); + rmesa->hw.zbs.cmd[R300_ZBS_W_FACTOR] = r300PackFloat32(factor); + rmesa->hw.zbs.cmd[R300_ZBS_W_CONSTANT] = r300PackFloat32(constant); +} + /* Routing and texture-related */ void r300_setup_routing(GLcontext *ctx, GLboolean immediate) @@ -609,17 +965,18 @@ void r300_setup_routing(GLcontext *ctx, GLboolean immediate) TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; r300ContextPtr r300 = R300_CONTEXT(ctx); - - + + /* Stage 1 - input to VAP */ - + /* Assign register number automatically, retaining it in rmesa->state.reg */ - + /* Note: immediate vertex data includes all coordinates. To save bandwidth use either VBUF or state-based vertex generation */ - + #define CONFIGURE_AOS(v, o, r, f) \ {\ + if (RADEON_DEBUG & DEBUG_STATE)fprintf(stderr, "Enabling "#r "\n"); \ if(immediate){ \ r300->state.aos[count].element_size=4; \ r300->state.aos[count].stride=4; \ @@ -636,37 +993,103 @@ void r300_setup_routing(GLcontext *ctx, GLboolean immediate) count++; \ reg++; \ } - - /* All offsets are 0 - for use by immediate mode. + + /* All offsets are 0 - for use by immediate mode. Should change later to handle vertex buffers */ - CONFIGURE_AOS(VB->ObjPtr, 0, i_coords, AOS_FORMAT_FLOAT); - CONFIGURE_AOS(VB->ColorPtr[0], 0, i_color[0], AOS_FORMAT_FLOAT_COLOR); + if(r300->current_vp!=NULL){ + + /* VERT_ATTRIB_WEIGHT, VERT_ATTRIB_SIX, VERT_ATTRIB_SEVEN, VERT_ATTRIB_GENERIC0, + VERT_ATTRIB_GENERIC1, VERT_ATTRIB_GENERIC2, VERT_ATTRIB_GENERIC3 */ + r300->state.render_inputs = 0; + + if(r300->current_vp->inputs[VERT_ATTRIB_POS] != -1){ + reg=r300->current_vp->inputs[VERT_ATTRIB_POS]; + CONFIGURE_AOS(VB->ObjPtr, 0, i_coords, AOS_FORMAT_FLOAT); + r300->state.render_inputs |= _TNL_BIT_POS; + } + if(r300->current_vp->inputs[VERT_ATTRIB_NORMAL] != -1){ + reg=r300->current_vp->inputs[VERT_ATTRIB_NORMAL]; + CONFIGURE_AOS(VB->NormalPtr, 0, i_normal, AOS_FORMAT_FLOAT); + r300->state.render_inputs |= _TNL_BIT_NORMAL; + } + if(r300->current_vp->inputs[VERT_ATTRIB_COLOR0] != -1){ + reg=r300->current_vp->inputs[VERT_ATTRIB_COLOR0]; + CONFIGURE_AOS(VB->ColorPtr[0], 0, i_color[0], AOS_FORMAT_FLOAT_COLOR); + r300->state.render_inputs |= _TNL_BIT_COLOR0; + } + if(r300->current_vp->inputs[VERT_ATTRIB_COLOR1] != -1){ + reg=r300->current_vp->inputs[VERT_ATTRIB_COLOR1]; + CONFIGURE_AOS(VB->SecondaryColorPtr[0], 0, i_color[1], AOS_FORMAT_FLOAT_COLOR); + r300->state.render_inputs |= _TNL_BIT_COLOR1; + } + if(r300->current_vp->inputs[VERT_ATTRIB_FOG] != -1){ + reg=r300->current_vp->inputs[VERT_ATTRIB_FOG]; + CONFIGURE_AOS(VB->FogCoordPtr, 0, i_fog, AOS_FORMAT_FLOAT); + r300->state.render_inputs |= _TNL_BIT_FOG; + } + for(i=0;i < ctx->Const.MaxTextureUnits;i++) // tex 7 is last + if(r300->current_vp->inputs[VERT_ATTRIB_TEX0+i] != -1){ + reg=r300->current_vp->inputs[VERT_ATTRIB_TEX0+i]; + CONFIGURE_AOS(VB->TexCoordPtr[i], 0, i_tex[i], AOS_FORMAT_FLOAT); + r300->state.render_inputs |= _TNL_BIT_TEX0<render_inputs & _TNL_BIT_INDEX)) + CONFIGURE_AOS(VB->IndexPtr[0], 0, i_index, AOS_FORMAT_FLOAT); + + if((tnl->render_inputs & _TNL_BIT_POINTSIZE)) + CONFIGURE_AOS(VB->PointSizePtr, 0, i_pointsize, AOS_FORMAT_FLOAT); +#endif + }else{ + + r300->state.render_inputs = tnl->render_inputs; + + if(tnl->render_inputs & _TNL_BIT_POS) + CONFIGURE_AOS(VB->ObjPtr, 0, i_coords, AOS_FORMAT_FLOAT); + if(tnl->render_inputs & _TNL_BIT_NORMAL) + CONFIGURE_AOS(VB->NormalPtr, 0, i_normal, AOS_FORMAT_FLOAT); + + if(tnl->render_inputs & _TNL_BIT_COLOR0) + CONFIGURE_AOS(VB->ColorPtr[0], 0, i_color[0], AOS_FORMAT_FLOAT_COLOR); + if(tnl->render_inputs & _TNL_BIT_COLOR1) + CONFIGURE_AOS(VB->SecondaryColorPtr[0], 0, i_color[1], AOS_FORMAT_FLOAT_COLOR); + + /*if(tnl->render_inputs & _TNL_BIT_FOG) // Causes lock ups when immediate mode is on + CONFIGURE_AOS(VB->FogCoordPtr, 0, i_fog, AOS_FORMAT_FLOAT);*/ + for(i=0;i < ctx->Const.MaxTextureUnits;i++) - if(ctx->Texture.Unit[i].Enabled) + if(tnl->render_inputs & (_TNL_BIT_TEX0<TexCoordPtr[i], 0, i_tex[i], AOS_FORMAT_FLOAT); - - r300->state.aos_count=count; - if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, "aos_count=%d\n", count); + if(tnl->render_inputs & _TNL_BIT_INDEX) + CONFIGURE_AOS(VB->IndexPtr[0], 0, i_index, AOS_FORMAT_FLOAT); + if(tnl->render_inputs & _TNL_BIT_POINTSIZE) + CONFIGURE_AOS(VB->PointSizePtr, 0, i_pointsize, AOS_FORMAT_FLOAT); + } + r300->state.aos_count=count; + + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "aos_count=%d render_inputs=%08x\n", count, r300->state.render_inputs); + + if(count>R300_MAX_AOS_ARRAYS){ fprintf(stderr, "Aieee ! AOS array count exceeded !\n"); exit(-1); } - + /* Implement AOS */ - + /* setup INPUT_ROUTE */ R300_STATECHANGE(r300, vir[0]); for(i=0;i+1state.aos[i].ncomponents-1) + dw=(r300->state.aos[i].ncomponents-1) | ((r300->state.aos[i].reg)<<8) | (r300->state.aos[i].format<<14) - | (((r300->state.aos[i+1].ncomponents-1) + | (((r300->state.aos[i+1].ncomponents-1) | ((r300->state.aos[i+1].reg)<<8) | (r300->state.aos[i+1].format<<14))<<16); - + if(i+2==count){ dw|=(1<<(13+16)); } @@ -683,36 +1106,36 @@ void r300_setup_routing(GLcontext *ctx, GLboolean immediate) /* Set the rest of INPUT_ROUTE_0 to 0 */ //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[0].cmd[R300_VIR_CNTL_0+i]=(0x0); ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = (count+1)>>1; - - + + /* Mesa assumes that all missing components are from (0, 0, 0, 1) */ #define ALL_COMPONENTS ((R300_INPUT_ROUTE_SELECT_X<state.aos[i].ncomponents*3))-1; dw=(ALL_COMPONENTS & mask) | (ALL_DEFAULT & ~mask) | R300_INPUT_ROUTE_ENABLE; - + /* i+1 */ mask=(1<<(r300->state.aos[i+1].ncomponents*3))-1; - dw|=( + dw|=( (ALL_COMPONENTS & mask) | (ALL_DEFAULT & ~mask) | R300_INPUT_ROUTE_ENABLE )<<16; - + r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(i>>1)]=dw; } if(count & 1){ @@ -726,35 +1149,43 @@ void r300_setup_routing(GLcontext *ctx, GLboolean immediate) /* Set the rest of INPUT_ROUTE_1 to 0 */ //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[1].cmd[R300_VIR_CNTL_0+i]=0x0; ((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->unchecked_state.count = (count+1)>>1; - + /* Set up input_cntl */ - + R300_STATECHANGE(r300, vic); r300->hw.vic.cmd[R300_VIC_CNTL_0]=0x5555; /* Hard coded value, no idea what it means */ + + r300->hw.vic.cmd[R300_VIC_CNTL_1]=0; + + if(r300->state.render_inputs & _TNL_BIT_POS) + r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_POS; - r300->hw.vic.cmd[R300_VIC_CNTL_1]=R300_INPUT_CNTL_POS - | R300_INPUT_CNTL_COLOR; + if(r300->state.render_inputs & _TNL_BIT_NORMAL) + r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_NORMAL; + if(r300->state.render_inputs & _TNL_BIT_COLOR0) + r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_COLOR; + for(i=0;i < ctx->Const.MaxTextureUnits;i++) - if(ctx->Texture.Unit[i].Enabled) + if(r300->state.render_inputs & (_TNL_BIT_TEX0<hw.vic.cmd[R300_VIC_CNTL_1]|=(R300_INPUT_CNTL_TC0<hw.vof.cmd[R300_VOF_CNTL_0]=R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT; - + r300->hw.vof.cmd[R300_VOF_CNTL_1]=0; for(i=0;i < ctx->Const.MaxTextureUnits;i++) - if(ctx->Texture.Unit[i].Enabled) + if(r300->state.render_inputs & (_TNL_BIT_TEX0<hw.vof.cmd[R300_VOF_CNTL_1]|=(4<<(3*i)); - + } static r300TexObj default_tex_obj={ filter:R300_TX_MAG_FILTER_LINEAR | R300_TX_MIN_FILTER_LINEAR, pitch: 0x8000, - size: (0xff << R300_TX_WIDTHMASK_SHIFT) + size: (0xff << R300_TX_WIDTHMASK_SHIFT) | (0xff << R300_TX_HEIGHTMASK_SHIFT) | (0x8 << R300_TX_SIZE_SHIFT), format: 0x88a0c, @@ -763,7 +1194,7 @@ static r300TexObj default_tex_obj={ unknown5: 0x0 }; - /* there is probably a system to these value, but, for now, + /* there is probably a system to these value, but, for now, we just try by hand */ static int inline translate_src(int src) @@ -791,125 +1222,71 @@ static int inline translate_src(int src) return 0; } } - -/* I think 357 and 457 are prime numbers.. wiggle them if you get coincidences */ -#define FORMAT_HASH(opRGB, srcRGB, modeRGB, opA, srcA, modeA, format, intFormat) ( \ - (\ - ((opRGB)<<30) | ((opA)<<28) | \ - ((srcRGB)<< 25) | ((srcA)<<22) | \ - ((modeRGB)) \ - ) \ - ^ ((modeA)*357) \ - ^ (((format)) *457) \ - ^ ((intFormat) * 7) \ - ) - -static GLuint translate_texture_format(GLcontext *ctx, GLint tex_unit, GLuint format, GLint IntFormat) + +/* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST. + * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead. + * We need to recalculate wrap modes whenever filter mode is changed because someone might do: + * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle + * combinations where only one of them is nearest. + */ +static unsigned long gen_fixed_filter(unsigned long f) { - const struct gl_texture_unit *texUnit= &ctx->Texture.Unit[tex_unit]; - int i=0; /* number of alpha args .. */ + unsigned long mag, min, needs_fixing=0; + //return f; - /* Size field in format specific first */ - switch(FORMAT_HASH( - texUnit->_CurrentCombine->OperandRGB[i] -GL_SRC_COLOR, - translate_src(texUnit->_CurrentCombine->SourceRGB[i]), - texUnit->_CurrentCombine->ModeRGB, - texUnit->_CurrentCombine->OperandA[i] -GL_SRC_ALPHA, - translate_src(texUnit->_CurrentCombine->SourceA[i]), - texUnit->_CurrentCombine->ModeA, - format, - IntFormat - )){ - case FORMAT_HASH(0, 1, 0x2100, 0, 1, 0x2100, 0x00088047, 0x1908): - /* tested with: - kfiresaver.kss - */ - return 0x7a0c; /* kfiresaver.kss */ - case FORMAT_HASH(0, 1, 0x2100, 0, 1, 0x2100, 0x00088047, 0x8058): - /* tested with: - Quake3demo - */ - return 0x8a0c; /* Quake3demo -small font on the bottom */ - case FORMAT_HASH(0, 1, 0x2100, 0, 1, 0x2100, 0x00077047, 4): - /* tested with: - kfiresaver.kss - */ - return 0x4ba0c; - case FORMAT_HASH(0, 1, 0x2100, 0, 1, 0x2100, 0x00055047, 4): - /* tested with: - kfiresaver.kss - kfountain.kss - */ - return 0x51a0c; - case FORMAT_HASH(0, 1, 0x2100, 0, 4, 0x1e01, 0x00088047, 3): - /* tested with - lesson 06 - lesson 07 - */ - return 0x53a0c; - case FORMAT_HASH(0, 1, 0x2100, 0, 4, 0x1e01, 0x00077047, 0x00000003): - /* Tested with NeHe lesson 08 */ - return 0x53a0c; - //case FORMAT_HASH(0, 1, 0x2100, 0, 4, 0x1e01, 0x00055047, 0): - /* Can't remember what I tested this with.. - try putting return 0 of you see broken textures which - are not being complained about */ - return 0x53a0c; - case FORMAT_HASH(0, 1, 0x2100, 0, 4, 0x1e01, 0x00099047, 0x8051): - //case FORMAT_HASH(0, 1, 0x2100, 0, 4, 0x1e01, 0x00089047, 0x8058): - case FORMAT_HASH(0, 1, 0x2100, 0, 4, 0x1e01, 0x00077047, 0x8051): - /* Tested with: - Quake3demo - */ - return 0x53a0c; - case FORMAT_HASH(0, 1, 0x2100, 0, 1, 0x2100, 0x00055045, 0x00008056): - case FORMAT_HASH(0, 1, 0x2100, 0, 1, 0x2100, 0x00088045, 0x00008056): - return 0x53a23; - case FORMAT_HASH(0, 1, 0x2100, 0, 4, 0x1e01, 0x00099004, 0x00008050): - return 0; - return 0x2a0b; + /* We ignore MIRROR bit so we dont have to do everything twice */ + if((f & ((7-1) << R300_TX_WRAP_S_SHIFT)) == (R300_TX_CLAMP << R300_TX_WRAP_S_SHIFT)){ + needs_fixing |= 1; + } + if((f & ((7-1) << R300_TX_WRAP_T_SHIFT)) == (R300_TX_CLAMP << R300_TX_WRAP_T_SHIFT)){ + needs_fixing |= 2; + } + if((f & ((7-1) << R300_TX_WRAP_Q_SHIFT)) == (R300_TX_CLAMP << R300_TX_WRAP_Q_SHIFT)){ + needs_fixing |= 4; } - // return 0x53a0c; - /* Just key on internal format - useful for quick tryouts*/ + if(!needs_fixing) + return f; - return 0; - #if 1 - switch(IntFormat - ){ - case 0x3: - return 0x53a0c; - case 0x8050: - return 0x2a0b; - case 0x8056: + mag=f & R300_TX_MAG_FILTER_MASK; + min=f & R300_TX_MIN_FILTER_MASK; - return 0x53a23; - case 0x8058: - return 0; - return 0x8a0c; - //fprintf(stderr, "%08x\n", format); - /* Tested with: - Quake3demo - */ - return 0x53a0c; - default: - return 0x53a0c; - } - #endif + /* TODO: Check for anisto filters too */ + if((mag != R300_TX_MAG_FILTER_NEAREST) && (min != R300_TX_MIN_FILTER_NEAREST)) + return f; + /* r300 cant handle these modes hence we force nearest to linear */ + if((mag == R300_TX_MAG_FILTER_NEAREST) && (min != R300_TX_MIN_FILTER_NEAREST)){ + f &= ~R300_TX_MAG_FILTER_NEAREST; + f |= R300_TX_MAG_FILTER_LINEAR; + return f; + } + if((min == R300_TX_MIN_FILTER_NEAREST) && (mag != R300_TX_MAG_FILTER_NEAREST)){ + f &= ~R300_TX_MIN_FILTER_NEAREST; + f |= R300_TX_MIN_FILTER_LINEAR; + return f; + } - { - static int warn_once=1; - if(warn_once){ - fprintf(stderr, "%s:%s Do not know how to translate texture format - help me !\n", - __FILE__, __FUNCTION__); - warn_once=0; - } + /* Both are nearest */ + if(needs_fixing & 1){ + f &= ~((7-1) << R300_TX_WRAP_S_SHIFT); + f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_S_SHIFT; } - return 0; + if(needs_fixing & 2){ + f &= ~((7-1) << R300_TX_WRAP_T_SHIFT); + f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_T_SHIFT; + } + if(needs_fixing & 4){ + f &= ~((7-1) << R300_TX_WRAP_Q_SHIFT); + f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_Q_SHIFT; + } + return f; } - + void r300_setup_textures(GLcontext *ctx) { int i, mtu; @@ -925,96 +1302,54 @@ void r300_setup_textures(GLcontext *ctx) R300_STATECHANGE(r300, tex.format); R300_STATECHANGE(r300, tex.offset); R300_STATECHANGE(r300, tex.unknown4); - R300_STATECHANGE(r300, tex.unknown5); - + R300_STATECHANGE(r300, tex.border_color); + r300->state.texture.tc_count=0; - + r300->hw.txe.cmd[R300_TXE_ENABLE]=0x0; - + mtu = r300->radeon.glCtx->Const.MaxTextureUnits; if (RADEON_DEBUG & DEBUG_STATE) fprintf(stderr, "mtu=%d\n", mtu); - + if(mtu>R300_MAX_TEXTURE_UNITS){ - fprintf(stderr, "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n", + fprintf(stderr, "Aiiee ! mtu=%d is greater than R300_MAX_TEXTURE_UNITS=%d\n", mtu, R300_MAX_TEXTURE_UNITS); exit(-1); } for(i=0;iTexture.Unit[i].Enabled){ + if( ((r300->state.render_inputs & (_TNL_BIT_TEX0<Texture.Unit[i].Enabled)!=0) ) { + WARN_ONCE("Mismatch between render_inputs and ctx->Texture.Unit[i].Enabled value.\n"); + } + if(r300->state.render_inputs & (_TNL_BIT_TEX0<state.texture.unit[i].texobj; + //fprintf(stderr, "format=%08x\n", r300->state.texture.unit[i].format); r300->state.texture.tc_count++; if(t==NULL){ fprintf(stderr, "Texture unit %d enabled, but corresponding texobj is NULL, using default object.\n", i); //exit(-1); t=&default_tex_obj; } + //fprintf(stderr, "t->format=%08x\n", t->format); + if((t->format & 0xffffff00)==0xffffff00){ + WARN_ONCE("unknown texture format (entry %x) encountered. Help me !\n", t->format & 0xff); + //fprintf(stderr, "t->format=%08x\n", t->format); + } if (RADEON_DEBUG & DEBUG_STATE) fprintf(stderr, "Activating texture unit %d\n", i); max_texture_unit=i; r300->hw.txe.cmd[R300_TXE_ENABLE]|=(1<hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=t->filter; - - /* Turn off rest of the bits that are wrong */ - t->filter &= R300_TX_MIN_FILTER_MASK | R300_TX_MAG_FILTER_MASK; - + + r300->hw.tex.filter.cmd[R300_TEX_VALUE_0+i]=gen_fixed_filter(t->filter); /* No idea why linear filtered textures shake when puting random data */ /*r300->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+i]=(rand()%0xffffffff) & (~0x1fff);*/ r300->hw.tex.size.cmd[R300_TEX_VALUE_0+i]=t->size; r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=t->format; + //fprintf(stderr, "t->format=%08x\n", t->format); r300->hw.tex.offset.cmd[R300_TEX_VALUE_0+i]=r300->radeon.radeonScreen->fbLocation+t->offset; r300->hw.tex.unknown4.cmd[R300_TEX_VALUE_0+i]=0x0; - r300->hw.tex.unknown5.cmd[R300_TEX_VALUE_0+i]=0x0; - - - - /* We don't know how to set this yet */ - //value from r300_lib.c for RGB24 - //r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x88a0c; - r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=translate_texture_format(ctx, i, t->format, - r300->state.texture.unit[i].texobj!=NULL?t->base.tObj->Image[0][0]->IntFormat:3); - /* Use the code below to quickly find matching texture - formats. Requires an app that displays the same texture - repeatedly */ - #if 1 - if(r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]==0){ - static int fmt=0x0; - static int k=0; - k++; - if(k>400){ - k=0; - fmt++; - texUnit = &ctx->Texture.Unit[i]; - fprintf(stderr, "Want to set FORMAT_HASH(%d, %d, 0x%04x, %d, %d, 0x%04x, 0x%08x, 0x%08x)\n", - texUnit->_CurrentCombine->OperandRGB[0] -GL_SRC_COLOR, - translate_src(texUnit->_CurrentCombine->SourceRGB[0]), - texUnit->_CurrentCombine->ModeRGB, - texUnit->_CurrentCombine->OperandA[0] -GL_SRC_ALPHA, - translate_src(texUnit->_CurrentCombine->SourceA[0]), - texUnit->_CurrentCombine->ModeA, - t->format, - t->base.tObj->Image[0][0]->IntFormat - ); - fprintf(stderr, "Also known: format_x=%08x border_color=%08x cubic_faces=%08x\n", t->format_x, t->pp_border_color, t->pp_cubic_faces); - fprintf(stderr, "\t_ReallyEnabled=%08x EnvMode=%08x IntFormat=%08x\n", texUnit->_ReallyEnabled, texUnit->EnvMode, t->base.tObj->Image[0][0]->IntFormat); - if(fmt>0xff){ - //exit(-1); - fmt=0; - } - //sleep(1); - fprintf(stderr, "Now trying format %08x\n", - 0x00a0c | (fmt<<12)); - fprintf(stderr, "size=%08x\n", t->size); - } - r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x00a0c | (fmt<<12); - //r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x51a00 | (fmt); - //r300->hw.tex.format.cmd[R300_TEX_VALUE_0+i]=0x53a0c | (fmt<<24); - } - #endif - + r300->hw.tex.border_color.cmd[R300_TEX_VALUE_0+i]=t->pp_border_color; } - } ((drm_r300_cmd_header_t*)r300->hw.tex.filter.cmd)->unchecked_state.count = max_texture_unit+1; ((drm_r300_cmd_header_t*)r300->hw.tex.unknown1.cmd)->unchecked_state.count = max_texture_unit+1; @@ -1022,8 +1357,8 @@ void r300_setup_textures(GLcontext *ctx) ((drm_r300_cmd_header_t*)r300->hw.tex.format.cmd)->unchecked_state.count = max_texture_unit+1; ((drm_r300_cmd_header_t*)r300->hw.tex.offset.cmd)->unchecked_state.count = max_texture_unit+1; ((drm_r300_cmd_header_t*)r300->hw.tex.unknown4.cmd)->unchecked_state.count = max_texture_unit+1; - ((drm_r300_cmd_header_t*)r300->hw.tex.unknown5.cmd)->unchecked_state.count = max_texture_unit+1; - + ((drm_r300_cmd_header_t*)r300->hw.tex.border_color.cmd)->unchecked_state.count = max_texture_unit+1; + if (RADEON_DEBUG & DEBUG_STATE) fprintf(stderr, "TX_ENABLE: %08x max_texture_unit=%d\n", r300->hw.txe.cmd[R300_TXE_ENABLE], max_texture_unit); } @@ -1032,45 +1367,50 @@ void r300_setup_rs_unit(GLcontext *ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); int i; - + /* This needs to be rewritten - it is a hack at best */ - + R300_STATECHANGE(r300, ri); R300_STATECHANGE(r300, rc); R300_STATECHANGE(r300, rr); - + for(i = 1; i <= 8; ++i) r300->hw.ri.cmd[i] = 0x00d10000; r300->hw.ri.cmd[R300_RI_INTERP_1] |= R300_RS_INTERP_1_UNKNOWN; r300->hw.ri.cmd[R300_RI_INTERP_2] |= R300_RS_INTERP_2_UNKNOWN; r300->hw.ri.cmd[R300_RI_INTERP_3] |= R300_RS_INTERP_3_UNKNOWN; - + + #if 1 + for(i = 2; i <= 8; ++i) + r300->hw.ri.cmd[i] |= 4; + #endif + for(i = 1; i <= 8; ++i) r300->hw.rr.cmd[i] = 0; /* textures enabled ? */ if(r300->state.texture.tc_count>0){ - + /* This code only really works with one set of texture coordinates */ - + /* The second constant is needed to get glxgears display anything .. */ - r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7 - | R300_RS_CNTL_0_UNKNOWN_18 + r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7 + | R300_RS_CNTL_0_UNKNOWN_18 | (r300->state.texture.tc_count<hw.rc.cmd[2] = 0xc0; - - + + ((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1; r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x24008; - + } else { - + /* The second constant is needed to get glxgears display anything .. */ r300->hw.rc.cmd[1] = R300_RS_CNTL_0_UNKNOWN_7 | R300_RS_CNTL_0_UNKNOWN_18; r300->hw.rc.cmd[2] = 0; - + ((drm_r300_cmd_header_t*)r300->hw.rr.cmd)->unchecked_state.count = 1; r300->hw.rr.cmd[R300_RR_ROUTE_0] = 0x4000; - + } } @@ -1085,14 +1425,14 @@ void r300_setup_rs_unit(GLcontext *ctx) void static inline setup_vertex_shader_fragment(r300ContextPtr r300, int dest, struct r300_vertex_shader_fragment *vsf) { int i; - + if(vsf->length==0)return; - + if(vsf->length & 0x3){ fprintf(stderr,"VERTEX_SHADER_FRAGMENT must have length divisible by 4\n"); exit(-1); } - + switch((dest>>8) & 0xf){ case 0: R300_STATECHANGE(r300, vpi); @@ -1100,14 +1440,14 @@ void static inline setup_vertex_shader_fragment(r300ContextPtr r300, int dest, s r300->hw.vpi.cmd[R300_VPI_INSTR_0+i+4*(dest & 0xff)]=(vsf->body.d[i]); bump_vpu_count(r300->hw.vpi.cmd, vsf->length+4*(dest & 0xff)); break; - + case 2: R300_STATECHANGE(r300, vpp); for(i=0;ilength;i++) r300->hw.vpp.cmd[R300_VPP_PARAM_0+i+4*(dest & 0xff)]=(vsf->body.d[i]); bump_vpu_count(r300->hw.vpp.cmd, vsf->length+4*(dest & 0xff)); break; - case 4: + case 4: R300_STATECHANGE(r300, vps); for(i=0;ilength;i++) r300->hw.vps.cmd[1+i+4*(dest & 0xff)]=(vsf->body.d[i]); @@ -1119,11 +1459,17 @@ void static inline setup_vertex_shader_fragment(r300ContextPtr r300, int dest, s } } +void r300SetupVertexProgram(r300ContextPtr rmesa); void r300SetupVertexShader(r300ContextPtr rmesa) { GLcontext* ctx = rmesa->radeon.glCtx; + if(rmesa->current_vp != NULL){ + r300SetupVertexProgram(rmesa); + return ; + } + /* Reset state, in case we don't use something */ ((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0; ((drm_r300_cmd_header_t*)rmesa->hw.vpi.cmd)->vpu.count = 0; @@ -1132,7 +1478,7 @@ void r300SetupVertexShader(r300ContextPtr rmesa) /* This needs to be replaced by vertex shader generation code */ - + /* textures enabled ? */ if(rmesa->state.texture.tc_count>0){ rmesa->state.vertex_shader=SINGLE_TEXTURE_VERTEX_SHADER; @@ -1143,23 +1489,23 @@ void r300SetupVertexShader(r300ContextPtr rmesa) rmesa->state.vertex_shader.matrix[0].length=16; memcpy(rmesa->state.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4); - + setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, &(rmesa->state.vertex_shader.program)); - + setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX0, &(rmesa->state.vertex_shader.matrix[0])); #if 0 setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX1, &(rmesa->state.vertex_shader.matrix[0])); setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX2, &(rmesa->state.vertex_shader.matrix[0])); - + setup_vertex_shader_fragment(rmesa, VSF_DEST_VECTOR0, &(rmesa->state.vertex_shader.vector[0])); setup_vertex_shader_fragment(rmesa, VSF_DEST_VECTOR1, &(rmesa->state.vertex_shader.vector[1])); #endif - + #if 0 setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN1, &(rmesa->state.vertex_shader.unknown1)); setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN2, &(rmesa->state.vertex_shader.unknown2)); #endif - + R300_STATECHANGE(rmesa, pvs); rmesa->hw.pvs.cmd[R300_PVS_CNTL_1]=(rmesa->state.vertex_shader.program_start << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) | (rmesa->state.vertex_shader.unknown_ptr1 << R300_PVS_CNTL_1_UNKNOWN_SHIFT) @@ -1168,8 +1514,50 @@ void r300SetupVertexShader(r300ContextPtr rmesa) | (rmesa->state.vertex_shader.param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT); rmesa->hw.pvs.cmd[R300_PVS_CNTL_3]=(rmesa->state.vertex_shader.unknown_ptr2 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT) | (rmesa->state.vertex_shader.unknown_ptr3 << 0); + + /* This is done for vertex shader fragments, but also needs to be done for vap_pvs, + so I leave it as a reminder */ + #if 0 + reg_start(R300_VAP_PVS_WAITIDLE,0); + e32(0x00000000); + #endif +} + +void r300SetupVertexProgram(r300ContextPtr rmesa) +{ + GLcontext* ctx = rmesa->radeon.glCtx; + int inst_count; + int param_count; + + /* Reset state, in case we don't use something */ + ((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0; + ((drm_r300_cmd_header_t*)rmesa->hw.vpi.cmd)->vpu.count = 0; + ((drm_r300_cmd_header_t*)rmesa->hw.vps.cmd)->vpu.count = 0; + + r300VertexProgUpdateParams(ctx, rmesa->current_vp); + + setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, &(rmesa->current_vp->program)); + + setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX0, &(rmesa->current_vp->params)); - /* This is done for vertex shader fragments, but also needs to be done for vap_pvs, + #if 0 + setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN1, &(rmesa->state.vertex_shader.unknown1)); + setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN2, &(rmesa->state.vertex_shader.unknown2)); + #endif + + inst_count=rmesa->current_vp->program.length/4 - 1; + param_count=rmesa->current_vp->params.length/4; + + R300_STATECHANGE(rmesa, pvs); + rmesa->hw.pvs.cmd[R300_PVS_CNTL_1]=(0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) + | (inst_count/*0*/ << R300_PVS_CNTL_1_UNKNOWN_SHIFT) + | (inst_count << R300_PVS_CNTL_1_PROGRAM_END_SHIFT); + rmesa->hw.pvs.cmd[R300_PVS_CNTL_2]=(0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT) + | (param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT); + rmesa->hw.pvs.cmd[R300_PVS_CNTL_3]=(0/*rmesa->state.vertex_shader.unknown_ptr2*/ << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT) + | ((inst_count-rmesa->current_vp->t2rs) /*rmesa->state.vertex_shader.unknown_ptr3*/ << 0); + + /* This is done for vertex shader fragments, but also needs to be done for vap_pvs, so I leave it as a reminder */ #if 0 reg_start(R300_VAP_PVS_WAITIDLE,0); @@ -1177,6 +1565,112 @@ void r300SetupVertexShader(r300ContextPtr rmesa) #endif } + +/* just a skeleton for now.. */ +void r300GenerateTexturePixelShader(r300ContextPtr r300) +{ + int i, mtu; + mtu = r300->radeon.glCtx->Const.MaxTextureUnits; + GLenum envMode; + + int tex_inst=0, alu_inst=0; + + for(i=0;istate.render_inputs & (_TNL_BIT_TEX0<radeon.glCtx->Texture.Unit[i].EnvMode; + //fprintf(stderr, "envMode=%s\n", _mesa_lookup_enum_by_nr(envMode)); + + /* Fetch textured pixel */ + + r300->state.pixel_shader.program.tex.inst[tex_inst]=0x00018000; + tex_inst++; + + switch(r300->radeon.glCtx->Texture.Unit[i]._CurrentCombine->ModeRGB){ + case GL_REPLACE: + WARN_ONCE("ModeA==GL_REPLACE is possibly broken.\n"); + r300->state.pixel_shader.program.alu.inst[alu_inst].inst0= + EASY_PFS_INSTR0(MAD, SRC0C_XYZ, ONE, ZERO); + + r300->state.pixel_shader.program.alu.inst[alu_inst].inst1= + EASY_PFS_INSTR1(0, 0, 0 | PFS_FLAG_CONST, 0 | PFS_FLAG_CONST, NONE, ALL); + break; + case GL_MODULATE: + WARN_ONCE("ModeRGB==GL_MODULATE is possibly broken.\n"); + r300->state.pixel_shader.program.alu.inst[alu_inst].inst0= + EASY_PFS_INSTR0(MAD, SRC0C_XYZ, SRC1C_XYZ, ZERO); + + r300->state.pixel_shader.program.alu.inst[alu_inst].inst1= + EASY_PFS_INSTR1(0, 0, 1, 0 | PFS_FLAG_CONST, NONE, ALL); + + break; + default: + fprintf(stderr, "ModeRGB=%s is not implemented yet !\n", + _mesa_lookup_enum_by_nr(r300->radeon.glCtx->Texture.Unit[i]._CurrentCombine->ModeRGB)); + /* PFS_NOP */ + r300->state.pixel_shader.program.alu.inst[alu_inst].inst0= + EASY_PFS_INSTR0(MAD, SRC0C_XYZ, ONE, ZERO); + + r300->state.pixel_shader.program.alu.inst[alu_inst].inst1= + EASY_PFS_INSTR1(0, 0, 0 | PFS_FLAG_CONST, 0 | PFS_FLAG_CONST, NONE, ALL); + } + switch(r300->radeon.glCtx->Texture.Unit[i]._CurrentCombine->ModeA){ + case GL_REPLACE: + WARN_ONCE("ModeA==GL_REPLACE is possibly broken.\n"); + r300->state.pixel_shader.program.alu.inst[alu_inst].inst2= + EASY_PFS_INSTR2(MAD, SRC0A, ONE, ZERO); + + r300->state.pixel_shader.program.alu.inst[alu_inst].inst3= + EASY_PFS_INSTR3(0, 0, 0| PFS_FLAG_CONST, 0 | PFS_FLAG_CONST, OUTPUT); + + #if 0 + fprintf(stderr, "numArgsA=%d sourceA[0]=%s op=%d\n", + r300->radeon.glCtx->Texture.Unit[i]._CurrentCombine->_NumArgsA, + _mesa_lookup_enum_by_nr(r300->radeon.glCtx->Texture.Unit[i]._CurrentCombine->SourceA[0]), + r300->radeon.glCtx->Texture.Unit[i]._CurrentCombine->OperandA[0]-GL_SRC_ALPHA); + #endif + break; + case GL_MODULATE: + WARN_ONCE("ModeA==GL_MODULATE is possibly broken.\n"); + + r300->state.pixel_shader.program.alu.inst[alu_inst].inst2= + EASY_PFS_INSTR2(MAD, SRC0A, SRC1A, ZERO); + + r300->state.pixel_shader.program.alu.inst[alu_inst].inst3= + EASY_PFS_INSTR3(0, 0, 1, 0 | PFS_FLAG_CONST, OUTPUT); + + break; + default: + fprintf(stderr, "ModeA=%s is not implemented yet !\n", + _mesa_lookup_enum_by_nr(r300->radeon.glCtx->Texture.Unit[i]._CurrentCombine->ModeA)); + /* PFS_NOP */ + r300->state.pixel_shader.program.alu.inst[alu_inst].inst2= + EASY_PFS_INSTR2(MAD, SRC0A, ONE, ZERO); + + r300->state.pixel_shader.program.alu.inst[alu_inst].inst3= + EASY_PFS_INSTR3(0, 0, 0 | PFS_FLAG_CONST, 0 | PFS_FLAG_CONST, OUTPUT); + + } + + alu_inst++; + } + + r300->state.pixel_shader.program.tex.length=tex_inst; + r300->state.pixel_shader.program.tex_offset=0; + r300->state.pixel_shader.program.tex_end=tex_inst-1; + + #if 0 + /* saturate last instruction, like i915 driver does */ + r300->state.pixel_shader.program.alu.inst[alu_inst-1].inst0|=R300_FPI0_OUTC_SAT; + r300->state.pixel_shader.program.alu.inst[alu_inst-1].inst2|=R300_FPI2_OUTA_SAT; + #endif + + r300->state.pixel_shader.program.alu.length=alu_inst; + r300->state.pixel_shader.program.alu_offset=0; + r300->state.pixel_shader.program.alu_end=alu_inst-1; +} + void r300SetupPixelShader(r300ContextPtr rmesa) { int i,k; @@ -1186,6 +1680,7 @@ int i,k; /* textures enabled ? */ if(rmesa->state.texture.tc_count>0){ rmesa->state.pixel_shader=SINGLE_TEXTURE_PIXEL_SHADER; + r300GenerateTexturePixelShader(rmesa); } else { rmesa->state.pixel_shader=FLAT_COLOR_PIXEL_SHADER; } @@ -1200,7 +1695,7 @@ int i,k; for(i=0;istate.pixel_shader.program.alu.length;i++) \ rmesa->hw.st.cmd[R300_FPI_INSTR_0+i]=rmesa->state.pixel_shader.program.alu.inst[i].field;\ rmesa->hw.st.cmd[R300_FPI_CMD_0]=cmducs(reg, rmesa->state.pixel_shader.program.alu.length); - + OUTPUT_FIELD(fpi[0], R300_PFS_INSTR0_0, inst0); OUTPUT_FIELD(fpi[1], R300_PFS_INSTR1_0, inst1); OUTPUT_FIELD(fpi[2], R300_PFS_INSTR2_0, inst2); @@ -1219,7 +1714,7 @@ int i,k; /* PFS_CNTL_0 */ rmesa->hw.fp.cmd[R300_FP_CNTL0]= - (rmesa->state.pixel_shader.program.active_nodes-1) + (rmesa->state.pixel_shader.program.active_nodes-1) | (rmesa->state.pixel_shader.program.first_node_has_tex<<3); /* PFS_CNTL_1 */ rmesa->hw.fp.cmd[R300_FP_CNTL1]=rmesa->state.pixel_shader.program.temp_register_count; @@ -1229,7 +1724,7 @@ int i,k; | (rmesa->state.pixel_shader.program.alu_end << R300_PFS_CNTL_ALU_END_SHIFT) | (rmesa->state.pixel_shader.program.tex_offset << R300_PFS_CNTL_TEX_OFFSET_SHIFT) | (rmesa->state.pixel_shader.program.tex_end << R300_PFS_CNTL_TEX_END_SHIFT); - + R300_STATECHANGE(rmesa, fpp); for(i=0;istate.pixel_shader.param_length;i++){ rmesa->hw.fpp.cmd[R300_FPP_PARAM_0+4*i+0]=r300PackFloat32(rmesa->state.pixel_shader.param[i].x); @@ -1258,6 +1753,7 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) r300ResetHwState(r300); } +void update_zbias(GLcontext * ctx, int prim); /** * Completely recalculates hardware state based on the Mesa state. @@ -1270,8 +1766,19 @@ void r300ResetHwState(r300ContextPtr r300) if (RADEON_DEBUG & DEBUG_STATE) fprintf(stderr, "%s\n", __FUNCTION__); + /* This is a place to initialize registers which + have bitfields accessed by different functions + and not all bits are used */ + #if 0 + r300->hw.zs.cmd[R300_ZS_CNTL_0] = 0; + r300->hw.zs.cmd[R300_ZS_CNTL_1] = 0; + r300->hw.zs.cmd[R300_ZS_CNTL_2] = 0xffff00; + #endif + + /* go and compute register values from GL state */ + r300UpdateWindow(ctx); - + r300ColorMask(ctx, ctx->Color.ColorMask[RCOMP], ctx->Color.ColorMask[GCOMP], @@ -1283,25 +1790,24 @@ void r300ResetHwState(r300ContextPtr r300) r300DepthFunc(ctx, ctx->Depth.Func); r300UpdateCulling(ctx); - - r300_setup_routing(ctx, GL_TRUE); - + r300UpdateTextureState(ctx); + + r300_setup_routing(ctx, GL_TRUE); r300_setup_textures(ctx); r300_setup_rs_unit(ctx); - + r300SetupVertexShader(r300); r300SetupPixelShader(r300); - + r300_set_blend_state(ctx); r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef); -//BEGIN: TODO + /* Initialize magic registers + TODO : learn what they really do, or get rid of + those we don't have to touch */ r300->hw.unk2080.cmd[1] = 0x0030045A; - r300->hw.ovf.cmd[R300_OVF_FMT_0] = 0x00000003; - r300->hw.ovf.cmd[R300_OVF_FMT_1] = 0x00000000; - r300->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA | R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA @@ -1313,8 +1819,11 @@ void r300ResetHwState(r300ContextPtr r300) r300->hw.unk2134.cmd[1] = 0x00FFFFFF; r300->hw.unk2134.cmd[2] = 0x00000000; - +#ifdef MESA_BIG_ENDIAN + r300->hw.unk2140.cmd[1] = 0x00000002; +#else r300->hw.unk2140.cmd[1] = 0x00000000; +#endif #if 0 /* Done in setup routing */ ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = 1; @@ -1326,7 +1835,7 @@ void r300ResetHwState(r300ContextPtr r300) r300->hw.vic.cmd[R300_VIR_CNTL_0] = 0x00000001; r300->hw.vic.cmd[R300_VIR_CNTL_1] = 0x00000405; #endif - + r300->hw.unk21DC.cmd[1] = 0xAAAAAAAA; r300->hw.unk221C.cmd[1] = R300_221C_NORMAL; @@ -1345,12 +1854,12 @@ void r300ResetHwState(r300ContextPtr r300) r300->hw.vof.cmd[R300_VOF_CNTL_0] = R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT | R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT; r300->hw.vof.cmd[R300_VOF_CNTL_1] = 0; /* no textures */ - - + + r300->hw.pvs.cmd[R300_PVS_CNTL_1] = 0; r300->hw.pvs.cmd[R300_PVS_CNTL_2] = 0; r300->hw.pvs.cmd[R300_PVS_CNTL_3] = 0; - #endif + #endif r300->hw.gb_enable.cmd[1] = R300_GB_POINT_STUFF_ENABLE | R300_GB_LINE_STUFF_ENABLE @@ -1378,13 +1887,22 @@ void r300ResetHwState(r300ContextPtr r300) r300->hw.unk4214.cmd[1] = 0x00050005; + r300PointSize(ctx, ctx->Point._Size); +#if 0 r300->hw.ps.cmd[R300_PS_POINTSIZE] = (6 << R300_POINTSIZE_X_SHIFT) | (6 << R300_POINTSIZE_Y_SHIFT); - +#endif + r300->hw.unk4230.cmd[1] = 0x01800000; r300->hw.unk4230.cmd[2] = 0x00020006; r300->hw.unk4230.cmd[3] = r300PackFloat32(1.0 / 192.0); - + + r300LineWidth(ctx, ctx->Line._Width); + +#ifdef EXP_C + static int foobar=0; + r300->hw.lsf.cmd[1] = foobar++; //0x3a088889; +#endif r300->hw.unk4260.cmd[1] = 0; r300->hw.unk4260.cmd[2] = r300PackFloat32(0.0); r300->hw.unk4260.cmd[3] = r300PackFloat32(1.0); @@ -1394,7 +1912,11 @@ void r300ResetHwState(r300ContextPtr r300) r300->hw.unk4274.cmd[3] = 0x00000000; r300->hw.unk4274.cmd[4] = 0x00000000; + r300PolygonMode(ctx, GL_FRONT, ctx->Polygon.FrontMode); + r300PolygonMode(ctx, GL_BACK, ctx->Polygon.BackMode); +#if 0 r300->hw.unk4288.cmd[1] = 0x00000000; +#endif r300->hw.unk4288.cmd[2] = 0x00000001; r300->hw.unk4288.cmd[3] = 0x00000000; r300->hw.unk4288.cmd[4] = 0x00000000; @@ -1402,15 +1924,17 @@ void r300ResetHwState(r300ContextPtr r300) r300->hw.unk42A0.cmd[1] = 0x00000000; + update_zbias(ctx, GL_TRIANGLES);/* FIXME */ +#if 0 r300->hw.unk42B4.cmd[1] = 0x00000000; - +#endif r300->hw.unk42C0.cmd[1] = 0x4B7FFFFF; r300->hw.unk42C0.cmd[2] = 0x00000000; r300->hw.unk43A4.cmd[1] = 0x0000001C; r300->hw.unk43A4.cmd[2] = 0x2DA49525; - + r300->hw.unk43E8.cmd[1] = 0x00FFFFFF; #if 0 @@ -1422,7 +1946,7 @@ void r300ResetHwState(r300ContextPtr r300) r300->hw.fp.cmd[R300_FP_NODE2] = 0; r300->hw.fp.cmd[R300_FP_NODE3] = 0; #endif - + r300->hw.unk46A4.cmd[1] = 0x00001B01; r300->hw.unk46A4.cmd[2] = 0x00001B0F; r300->hw.unk46A4.cmd[3] = 0x00001B0F; @@ -1438,7 +1962,7 @@ void r300ResetHwState(r300ContextPtr r300) r300->hw.fpi[3].cmd[i] = FP_SELA(0,W,NO,FP_TMP(0),0,0); } #endif - + r300->hw.unk4BC0.cmd[1] = 0; r300->hw.unk4BC8.cmd[1] = 0; @@ -1449,6 +1973,7 @@ void r300ResetHwState(r300ContextPtr r300) r300->hw.at.cmd[R300_AT_ALPHA_TEST] = 0; #endif + r300->hw.at.cmd[R300_AT_UNKNOWN] = 0; r300->hw.unk4BD8.cmd[1] = 0; r300->hw.unk4E00.cmd[1] = 0; @@ -1483,13 +2008,14 @@ void r300ResetHwState(r300ContextPtr r300) r300->hw.unk4EA0.cmd[1] = 0x00000000; r300->hw.unk4EA0.cmd[2] = 0xffffffff; - r300->hw.unk4F08.cmd[1] = 0x00FFFF00; - r300->hw.unk4F10.cmd[1] = 0x00000002; // depthbuffer format? r300->hw.unk4F10.cmd[2] = 0x00000000; r300->hw.unk4F10.cmd[3] = 0x00000003; r300->hw.unk4F10.cmd[4] = 0x00000000; + /* experiment a bit */ + r300->hw.unk4F10.cmd[2] = 0x00000001; // depthbuffer format? + r300->hw.zb.cmd[R300_ZB_OFFSET] = r300->radeon.radeonScreen->depthOffset + r300->radeon.radeonScreen->fbLocation; @@ -1518,14 +2044,14 @@ void r300ResetHwState(r300ContextPtr r300) for(i = 1; i < R300_VPP_CMDSIZE; ++i) r300->hw.vpp.cmd[i] = 0; #endif - + r300->hw.vps.cmd[R300_VPS_ZERO_0] = 0; r300->hw.vps.cmd[R300_VPS_ZERO_1] = 0; r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0); r300->hw.vps.cmd[R300_VPS_ZERO_3] = 0; - + //END: TODO - + r300->hw.all_dirty = GL_TRUE; } @@ -1542,7 +2068,7 @@ void r300InitState(r300ContextPtr r300) GLuint depth_fmt; radeonInitState(&r300->radeon); - + switch (ctx->Visual.depthBits) { case 16: r300->state.depth.scale = 1.0 / (GLfloat) 0xffff; @@ -1559,14 +2085,17 @@ void r300InitState(r300ContextPtr r300) ctx->Visual.depthBits); exit(-1); } - + + /* Only have hw stencil when depth buffer is 24 bits deep */ + r300->state.hw_stencil = (ctx->Visual.stencilBits > 0 && + ctx->Visual.depthBits == 24); + memset(&(r300->state.texture), 0, sizeof(r300->state.texture)); r300ResetHwState(r300); } - /** * Initialize driver's state callback functions */ @@ -1575,7 +2104,7 @@ void r300InitStateFuncs(struct dd_function_table* functions) radeonInitStateFuncs(functions); functions->UpdateState = r300InvalidateState; - //functions->AlphaFunc = r300AlphaFunc; + functions->AlphaFunc = r300AlphaFunc; functions->BlendColor = r300BlendColor; functions->BlendEquationSeparate = r300BlendEquationSeparate; functions->BlendFuncSeparate = r300BlendFuncSeparate; @@ -1586,9 +2115,18 @@ void r300InitStateFuncs(struct dd_function_table* functions) functions->CullFace = r300CullFace; functions->FrontFace = r300FrontFace; + /* Stencil related */ + functions->ClearStencil = r300ClearStencil; + functions->StencilFunc = r300StencilFunc; + functions->StencilMask = r300StencilMask; + functions->StencilOp = r300StencilOp; + /* Viewport related */ functions->Viewport = r300Viewport; functions->DepthRange = r300DepthRange; functions->PointSize = r300PointSize; + functions->LineWidth = r300LineWidth; + + functions->PolygonOffset = r300PolygonOffset; + functions->PolygonMode = r300PolygonMode; } -