GLubyte refByte;
CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
-
+
R300_STATECHANGE(rmesa, at);
pp_misc &= ~(R300_ALPHA_TEST_OP_MASK | R300_REF_ALPHA_MASK);
break;
case GL_ALPHA_TEST:
- R200_STATECHANGE(r300, at);
+ R300_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->hw.at.cmd[R300_AT_ALPHA_TEST] &=
~R300_ALPHA_TEST_ENABLE;
}
break;
}
for(i=0; i < mtu; i++) {
-
+ /*if(ctx->Texture.Unit[i].Enabled == 0)
+ continue;*/
if( ((r300->state.render_inputs & (_TNL_BIT_TEX0<<i))!=0) != ((ctx->Texture.Unit[i].Enabled)!=0) ) {
WARN_ONCE("Mismatch between render_inputs and ctx->Texture.Unit[i].Enabled value.\n");
}
void r300SetupVertexProgram(r300ContextPtr rmesa);
+/* just a skeleton for now.. */
+
+/* Generate a vertex shader that simply transforms vertex and texture coordinates,
+ while leaving colors intact. Nothing fancy (like lights)
+
+ If implementing lights make a copy first, so it is easy to switch between the two versions */
+void r300GenerateSimpleVertexShader(r300ContextPtr r300)
+{
+ int i;
+
+ /* Allocate parameters */
+ r300->state.vap_param.transform_offset=0x0; /* transform matrix */
+ r300->state.vertex_shader.param_offset=0x0;
+ r300->state.vertex_shader.param_count=0x4; /* 4 vector values - 4x4 matrix */
+
+ r300->state.vertex_shader.program_start=0x0;
+ r300->state.vertex_shader.unknown_ptr1=0x4; /* magic value ? */
+ r300->state.vertex_shader.program_end=0x0;
+
+ r300->state.vertex_shader.unknown_ptr2=0x0; /* magic value */
+ r300->state.vertex_shader.unknown_ptr3=0x4; /* magic value */
+
+ /* Initialize matrix and vector parameters.. these should really be restructured */
+ /* TODO: fix vertex_shader structure */
+ r300->state.vertex_shader.matrix[0].length=16;
+ r300->state.vertex_shader.matrix[1].length=0;
+ r300->state.vertex_shader.matrix[2].length=0;
+ r300->state.vertex_shader.vector[0].length=0;
+ r300->state.vertex_shader.vector[1].length=0;
+ r300->state.vertex_shader.unknown1.length=0;
+ r300->state.vertex_shader.unknown2.length=0;
+
+#define WRITE_OP(oper,source1,source2,source3) {\
+ r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].op=(oper); \
+ r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src1=(source1); \
+ r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src2=(source2); \
+ r300->state.vertex_shader.program.body.i[r300->state.vertex_shader.program_end].src3=(source3); \
+ r300->state.vertex_shader.program_end++; \
+ }
+
+ /* Multiply vertex coordinates with transform matrix */
+
+ WRITE_OP(
+ EASY_VSF_OP(MUL, 0, ALL, TMP),
+ VSF_PARAM(3),
+ VSF_ATTR_W(0),
+ EASY_VSF_SOURCE(0, W, W, W, W, NONE, NONE)
+ )
+
+ WRITE_OP(
+ EASY_VSF_OP(MUL, 1, ALL, RESULT),
+ VSF_REG(1),
+ VSF_ATTR_UNITY(1),
+ VSF_UNITY(1)
+ )
+
+ WRITE_OP(
+ EASY_VSF_OP(MAD, 0, ALL, TMP),
+ VSF_PARAM(2),
+ VSF_ATTR_Z(0),
+ VSF_TMP(0)
+ )
+
+ WRITE_OP(
+ EASY_VSF_OP(MAD, 0, ALL, TMP),
+ VSF_PARAM(1),
+ VSF_ATTR_Y(0),
+ VSF_TMP(0)
+ )
+
+ WRITE_OP(
+ EASY_VSF_OP(MAD, 0, ALL, RESULT),
+ VSF_PARAM(0),
+ VSF_ATTR_X(0),
+ VSF_TMP(0)
+ )
+
+ /* Pass through texture coordinates, if any */
+ for(i=0;i < r300->radeon.glCtx->Const.MaxTextureUnits;i++)
+ if(r300->state.render_inputs & (_TNL_BIT_TEX0<<i)){
+ // fprintf(stderr, "i_tex[%d]=%d\n", i, r300->state.vap_reg.i_tex[i]);
+ WRITE_OP(
+ EASY_VSF_OP(MUL, 2+i, ALL, RESULT),
+ VSF_REG(r300->state.vap_reg.i_tex[i]),
+ VSF_ATTR_UNITY(r300->state.vap_reg.i_tex[i]),
+ VSF_UNITY(r300->state.vap_reg.i_tex[i])
+ )
+ }
+
+ r300->state.vertex_shader.program_end--; /* r300 wants program length to be one more - no idea why */
+ r300->state.vertex_shader.program.length=(r300->state.vertex_shader.program_end+1)*4;
+
+ r300->state.vertex_shader.unknown_ptr1=r300->state.vertex_shader.program_end; /* magic value ? */
+ r300->state.vertex_shader.unknown_ptr2=r300->state.vertex_shader.program_end; /* magic value ? */
+ r300->state.vertex_shader.unknown_ptr3=r300->state.vertex_shader.program_end; /* magic value ? */
+
+}
+
+
void r300SetupVertexShader(r300ContextPtr rmesa)
{
GLcontext* ctx = rmesa->radeon.glCtx;
+ LOCAL_VARS
if(rmesa->current_vp != NULL){
r300SetupVertexProgram(rmesa);
/* This needs to be replaced by vertex shader generation code */
+#if 0
/* textures enabled ? */
if(rmesa->state.texture.tc_count>0){
rmesa->state.vertex_shader=SINGLE_TEXTURE_VERTEX_SHADER;
} else {
rmesa->state.vertex_shader=FLAT_COLOR_VERTEX_SHADER;
}
+#endif
+ r300GenerateSimpleVertexShader(rmesa);
rmesa->state.vertex_shader.matrix[0].length=16;
memcpy(rmesa->state.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4);
GLcontext* ctx = rmesa->radeon.glCtx;
int inst_count;
int param_count;
+ LOCAL_VARS
+
/* Reset state, in case we don't use something */
((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0;
break;
default:
- fprintf(stderr, "ModeRGB=%s is not implemented yet !\n",
+ WARN_ONCE("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=
break;
default:
- fprintf(stderr, "ModeA=%s is not implemented yet !\n",
+ WARN_ONCE("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=
r300ResetHwState(r300);
}
-void update_zbias(GLcontext * ctx, int prim);
-
+/* Checks that r300ResetHwState actually modifies all states.
+ Should probably be burried in somewhere else as this file is getting longish. */
+void verify_r300ResetHwState(r300ContextPtr r300, int stage)
+{
+ struct r300_state_atom* atom;
+ int i;
+ drm_r300_cmd_header_t cmd;
+
+ if(stage){ /* mess around with states */
+ unsigned long fp1, cb1;
+
+ fp1=r300->hw.fp.cmd[R300_FP_CMD_1]; /* some special cases... */
+ cb1=r300->hw.cb.cmd[R300_CB_CMD_1];
+
+ fprintf(stderr, "verify begin:\n");
+
+ foreach(atom, &r300->hw.atomlist) {
+ for(i=1; i < (*atom->check)(r300, atom); i++)
+ atom->cmd[i]=0xdeadbeef;
+ }
+ r300->hw.fp.cmd[R300_FP_CMD_1]=fp1;
+ r300->hw.cb.cmd[R300_CB_CMD_1]=cb1;
+
+ foreach(atom, &r300->hw.atomlist) {
+ cmd.u=atom->cmd[0];
+ switch(cmd.header.cmd_type){
+ case R300_CMD_UNCHECKED_STATE:
+ case R300_CMD_VPU:
+ case R300_CMD_PACKET3:
+ case R300_CMD_END3D:
+ case R300_CMD_CP_DELAY:
+ case R300_CMD_DMA_DISCARD:
+ break;
+ default: fprintf(stderr, "unknown cmd_type %d in atom %s\n",
+ cmd.header.cmd_type, atom->name);
+ }
+
+ }
+ } else { /* check that they were set */
+ foreach(atom, &r300->hw.atomlist) {
+ for(i=1; i < (*atom->check)(r300, atom); i++)
+ if(atom->cmd[i]==0xdeadbeef)
+ fprintf(stderr, "atom %s is untouched\n", atom->name);
+ }
+ }
+}
+
/**
* Completely recalculates hardware state based on the Mesa state.
*/
if (RADEON_DEBUG & DEBUG_STATE)
fprintf(stderr, "%s\n", __FUNCTION__);
+ //verify_r300ResetHwState(r300, 1);
+
/* This is a place to initialize registers which
have bitfields accessed by different functions
and not all bits are used */
r300SetupPixelShader(r300);
r300_set_blend_state(ctx);
- r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
+ r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
+ r300Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled);
+
/* Initialize magic registers
TODO : learn what they really do, or get rid of
those we don't have to touch */
r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
| R300_GB_TILE_PIPE_COUNT_R300
| R300_GB_TILE_SIZE_16;
+ else if (GET_CHIP(r300->radeon.radeonScreen) == RADEON_CHIP_R420)
+ r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
+ | R300_GB_TILE_PIPE_COUNT_R420
+ | R300_GB_TILE_SIZE_16;
else
r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
| R300_GB_TILE_PIPE_COUNT_RV300
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;
r300->hw.unk42A0.cmd[1] = 0x00000000;
- update_zbias(ctx, GL_TRIANGLES);/* FIXME */
-#if 0
- r300->hw.unk42B4.cmd[1] = 0x00000000;
-#endif
+ r300PolygonOffset(ctx, ctx->Polygon.OffsetFactor, ctx->Polygon.OffsetUnits);
+ r300Enable(ctx, GL_POLYGON_OFFSET_POINT, ctx->Polygon.OffsetPoint);
+ r300Enable(ctx, GL_POLYGON_OFFSET_LINE, ctx->Polygon.OffsetLine);
+ r300Enable(ctx, GL_POLYGON_OFFSET_FILL, ctx->Polygon.OffsetFill);
+
r300->hw.unk42C0.cmd[1] = 0x4B7FFFFF;
r300->hw.unk42C0.cmd[2] = 0x00000000;
r300->hw.unk4BC8.cmd[2] = 0;
r300->hw.unk4BC8.cmd[3] = 0;
- //r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
-#if 0
- r300->hw.at.cmd[R300_AT_ALPHA_TEST] = 0;
-#endif
r300->hw.at.cmd[R300_AT_UNKNOWN] = 0;
r300->hw.unk4BD8.cmd[1] = 0;
#endif
r300BlendColor(ctx, ctx->Color.BlendColor);
-#if 0
- r300->hw.unk4E10.cmd[1] = 0;
-#endif
r300->hw.unk4E10.cmd[2] = 0;
r300->hw.unk4E10.cmd[3] = 0;
-
- r300->hw.cb.cmd[R300_CB_OFFSET] =
- r300->radeon.radeonScreen->backOffset +
- r300->radeon.radeonScreen->fbLocation;
- r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.radeonScreen->backPitch
- | R300_COLOR_UNKNOWN_22_23;
-
+
+ /* Again, r300ClearBuffer uses this */
+ if(ctx->Visual.doubleBufferMode){
+ r300->hw.cb.cmd[R300_CB_OFFSET] =
+ r300->radeon.radeonScreen->backOffset +
+ r300->radeon.radeonScreen->fbLocation;
+ r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.radeonScreen->backPitch
+ | R300_COLOR_UNKNOWN_22_23;
+ } else {
+ r300->hw.cb.cmd[R300_CB_OFFSET] =
+ r300->radeon.radeonScreen->frontOffset +
+ r300->radeon.radeonScreen->fbLocation;
+ r300->hw.cb.cmd[R300_CB_PITCH] = r300->radeon.radeonScreen->frontPitch
+ | R300_COLOR_UNKNOWN_22_23;
+
+ }
+
r300->hw.unk4E50.cmd[1] = 0;
r300->hw.unk4E50.cmd[2] = 0;
r300->hw.unk4E50.cmd[3] = 0;
r300->hw.vps.cmd[R300_VPS_ZERO_3] = 0;
//END: TODO
-
+ //verify_r300ResetHwState(r300, 0);
r300->hw.all_dirty = GL_TRUE;
}
ctx->Visual.depthBits == 24);
memset(&(r300->state.texture), 0, sizeof(r300->state.texture));
-
+
r300ResetHwState(r300);
}