📄 r200_state.c
字号:
rmesa->state.stipple.mask[31 - i] = ((GLuint *) mask)[i]; } /* TODO: push this into cmd mechanism */ R200_FIREVERTICES( rmesa ); LOCK_HARDWARE( rmesa ); /* FIXME: Use window x,y offsets into stipple RAM. */ stipple.mask = rmesa->state.stipple.mask; drmCommandWrite( rmesa->dri.fd, DRM_RADEON_STIPPLE, &stipple, sizeof(stipple) ); UNLOCK_HARDWARE( rmesa );}static void r200PolygonMode( GLcontext *ctx, GLenum face, GLenum mode ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); GLboolean flag = (ctx->_TriangleCaps & DD_TRI_UNFILLED) != 0; /* Can't generally do unfilled via tcl, but some good special * cases work. */ TCL_FALLBACK( ctx, R200_TCL_FALLBACK_UNFILLED, flag); if (rmesa->TclFallback) { r200ChooseRenderState( ctx ); r200ChooseVertexState( ctx ); }}/* ============================================================= * Rendering attributes * * We really don't want to recalculate all this every time we bind a * texture. These things shouldn't change all that often, so it makes * sense to break them out of the core texture state update routines. *//* Examine lighting and texture state to determine if separate specular * should be enabled. */static void r200UpdateSpecular( GLcontext *ctx ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); u_int32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL]; R200_STATECHANGE( rmesa, tcl ); R200_STATECHANGE( rmesa, vtx ); rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~(3<<R200_VTX_COLOR_0_SHIFT); rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~(3<<R200_VTX_COLOR_1_SHIFT); rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_COLOR_0; rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_COLOR_1; rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LIGHTING_ENABLE; p &= ~R200_SPECULAR_ENABLE; rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_DIFFUSE_SPECULAR_COMBINE; if (ctx->Light.Enabled && ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) { rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT) | (R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT)); rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_0; rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_1; rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHTING_ENABLE; p |= R200_SPECULAR_ENABLE; rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_DIFFUSE_SPECULAR_COMBINE; } else if (ctx->Light.Enabled) { rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT)); rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_0; rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHTING_ENABLE; } else if (ctx->Fog.ColorSumEnabled ) { rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT) | (R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT)); p |= R200_SPECULAR_ENABLE; } else { rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT)); } if (ctx->Fog.Enabled) { rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= ((R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT)); rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_1; } if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) { R200_STATECHANGE( rmesa, ctx ); rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p; } /* Update vertex/render formats */ if (rmesa->TclFallback) { r200ChooseRenderState( ctx ); r200ChooseVertexState( ctx ); }}/* ============================================================= * Materials *//* Update on colormaterial, material emmissive/ambient, * lightmodel.globalambient */static void update_global_ambient( GLcontext *ctx ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); float *fcmd = (float *)R200_DB_STATE( glt ); /* Need to do more if both emmissive & ambient are PREMULT: * I believe this is not nessary when using source_material. This condition thus * will never happen currently, and the function has no dependencies on materials now */ if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] & ((3 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) | (3 << R200_FRONT_AMBIENT_SOURCE_SHIFT))) == 0) { COPY_3V( &fcmd[GLT_RED], ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]); ACC_SCALE_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient, ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]); } else { COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient ); } R200_DB_STATECHANGE(rmesa, &rmesa->hw.glt);}/* Update on change to * - light[p].colors * - light[p].enabled */static void update_light_colors( GLcontext *ctx, GLuint p ){ struct gl_light *l = &ctx->Light.Light[p];/* fprintf(stderr, "%s\n", __FUNCTION__); */ if (l->Enabled) { r200ContextPtr rmesa = R200_CONTEXT(ctx); float *fcmd = (float *)R200_DB_STATE( lit[p] ); COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient ); COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse ); COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular ); R200_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] ); }}static void r200ColorMaterial( GLcontext *ctx, GLenum face, GLenum mode ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1]; light_model_ctl1 &= ~((0xf << R200_FRONT_EMISSIVE_SOURCE_SHIFT) | (0xf << R200_FRONT_AMBIENT_SOURCE_SHIFT) | (0xf << R200_FRONT_DIFFUSE_SOURCE_SHIFT) | (0xf << R200_FRONT_SPECULAR_SOURCE_SHIFT) | (0xf << R200_BACK_EMISSIVE_SOURCE_SHIFT) | (0xf << R200_BACK_AMBIENT_SOURCE_SHIFT) | (0xf << R200_BACK_DIFFUSE_SOURCE_SHIFT) | (0xf << R200_BACK_SPECULAR_SOURCE_SHIFT)); if (ctx->Light.ColorMaterialEnabled) { GLuint mask = ctx->Light.ColorMaterialBitmask; if (mask & MAT_BIT_FRONT_EMISSION) { light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << R200_FRONT_EMISSIVE_SOURCE_SHIFT); } else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_EMISSIVE_SOURCE_SHIFT); if (mask & MAT_BIT_FRONT_AMBIENT) { light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << R200_FRONT_AMBIENT_SOURCE_SHIFT); } else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_AMBIENT_SOURCE_SHIFT); if (mask & MAT_BIT_FRONT_DIFFUSE) { light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << R200_FRONT_DIFFUSE_SOURCE_SHIFT); } else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_DIFFUSE_SOURCE_SHIFT); if (mask & MAT_BIT_FRONT_SPECULAR) { light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << R200_FRONT_SPECULAR_SOURCE_SHIFT); } else { light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_SPECULAR_SOURCE_SHIFT); } if (mask & MAT_BIT_BACK_EMISSION) { light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << R200_BACK_EMISSIVE_SOURCE_SHIFT); } else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_EMISSIVE_SOURCE_SHIFT); if (mask & MAT_BIT_BACK_AMBIENT) { light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << R200_BACK_AMBIENT_SOURCE_SHIFT); } else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_AMBIENT_SOURCE_SHIFT); if (mask & MAT_BIT_BACK_DIFFUSE) { light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << R200_BACK_DIFFUSE_SOURCE_SHIFT); } else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_DIFFUSE_SOURCE_SHIFT); if (mask & MAT_BIT_BACK_SPECULAR) { light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << R200_BACK_SPECULAR_SOURCE_SHIFT); } else { light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_SPECULAR_SOURCE_SHIFT); } } else { /* Default to SOURCE_MATERIAL: */ light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) | (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_AMBIENT_SOURCE_SHIFT) | (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_DIFFUSE_SOURCE_SHIFT) | (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_SPECULAR_SOURCE_SHIFT) | (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_EMISSIVE_SOURCE_SHIFT) | (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_AMBIENT_SOURCE_SHIFT) | (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_DIFFUSE_SOURCE_SHIFT) | (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_SPECULAR_SOURCE_SHIFT); } if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1]) { R200_STATECHANGE( rmesa, tcl ); rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] = light_model_ctl1; } }void r200UpdateMaterial( GLcontext *ctx ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); GLfloat (*mat)[4] = ctx->Light.Material.Attrib; GLfloat *fcmd = (GLfloat *)R200_DB_STATE( mtl[0] ); GLfloat *fcmd2 = (GLfloat *)R200_DB_STATE( mtl[1] ); GLuint mask = ~0; /* Might be possible and faster to update everything unconditionally? */ if (ctx->Light.ColorMaterialEnabled) mask &= ~ctx->Light.ColorMaterialBitmask; if (R200_DEBUG & DEBUG_STATE) fprintf(stderr, "%s\n", __FUNCTION__); if (mask & MAT_BIT_FRONT_EMISSION) { fcmd[MTL_EMMISSIVE_RED] = mat[MAT_ATTRIB_FRONT_EMISSION][0]; fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1]; fcmd[MTL_EMMISSIVE_BLUE] = mat[MAT_ATTRIB_FRONT_EMISSION][2]; fcmd[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_FRONT_EMISSION][3]; } if (mask & MAT_BIT_FRONT_AMBIENT) { fcmd[MTL_AMBIENT_RED] = mat[MAT_ATTRIB_FRONT_AMBIENT][0]; fcmd[MTL_AMBIENT_GREEN] = mat[MAT_ATTRIB_FRONT_AMBIENT][1]; fcmd[MTL_AMBIENT_BLUE] = mat[MAT_ATTRIB_FRONT_AMBIENT][2]; fcmd[MTL_AMBIENT_ALPHA] = mat[MAT_ATTRIB_FRONT_AMBIENT][3]; } if (mask & MAT_BIT_FRONT_DIFFUSE) { fcmd[MTL_DIFFUSE_RED] = mat[MAT_ATTRIB_FRONT_DIFFUSE][0]; fcmd[MTL_DIFFUSE_GREEN] = mat[MAT_ATTRIB_FRONT_DIFFUSE][1]; fcmd[MTL_DIFFUSE_BLUE] = mat[MAT_ATTRIB_FRONT_DIFFUSE][2]; fcmd[MTL_DIFFUSE_ALPHA] = mat[MAT_ATTRIB_FRONT_DIFFUSE][3]; } if (mask & MAT_BIT_FRONT_SPECULAR) { fcmd[MTL_SPECULAR_RED] = mat[MAT_ATTRIB_FRONT_SPECULAR][0]; fcmd[MTL_SPECULAR_GREEN] = mat[MAT_ATTRIB_FRONT_SPECULAR][1]; fcmd[MTL_SPECULAR_BLUE] = mat[MAT_ATTRIB_FRONT_SPECULAR][2]; fcmd[MTL_SPECULAR_ALPHA] = mat[MAT_ATTRIB_FRONT_SPECULAR][3]; } if (mask & MAT_BIT_FRONT_SHININESS) { fcmd[MTL_SHININESS] = mat[MAT_ATTRIB_FRONT_SHININESS][0]; } if (mask & MAT_BIT_BACK_EMISSION) { fcmd2[MTL_EMMISSIVE_RED] = mat[MAT_ATTRIB_BACK_EMISSION][0]; fcmd2[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_BACK_EMISSION][1]; fcmd2[MTL_EMMISSIVE_BLUE] = mat[MAT_ATTRIB_BACK_EMISSION][2]; fcmd2[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_BACK_EMISSION][3]; } if (mask & MAT_BIT_BACK_AMBIENT) { fcmd2[MTL_AMBIENT_RED] = mat[MAT_ATTRIB_BACK_AMBIENT][0]; fcmd2[MTL_AMBIENT_GREEN] = mat[MAT_ATTRIB_BACK_AMBIENT][1]; fcmd2[MTL_AMBIENT_BLUE] = mat[MAT_ATTRIB_BACK_AMBIENT][2]; fcmd2[MTL_AMBIENT_ALPHA] = mat[MAT_ATTRIB_BACK_AMBIENT][3]; } if (mask & MAT_BIT_BACK_DIFFUSE) { fcmd2[MTL_DIFFUSE_RED] = mat[MAT_ATTRIB_BACK_DIFFUSE][0]; fcmd2[MTL_DIFFUSE_GREEN] = mat[MAT_ATTRIB_BACK_DIFFUSE][1]; fcmd2[MTL_DIFFUSE_BLUE] = mat[MAT_ATTRIB_BACK_DIFFUSE][2]; fcmd2[MTL_DIFFUSE_ALPHA] = mat[MAT_ATTRIB_BACK_DIFFUSE][3]; } if (mask & MAT_BIT_BACK_SPECULAR) { fcmd2[MTL_SPECULAR_RED] = mat[MAT_ATTRIB_BACK_SPECULAR][0]; fcmd2[MTL_SPECULAR_GREEN] = mat[MAT_ATTRIB_BACK_SPECULAR][1]; fcmd2[MTL_SPECULAR_BLUE] = mat[MAT_ATTRIB_BACK_SPECULAR][2]; fcmd2[MTL_SPECULAR_ALPHA] = mat[MAT_ATTRIB_BACK_SPECULAR][3]; } if (mask & MAT_BIT_BACK_SHININESS) { fcmd2[MTL_SHININESS] = mat[MAT_ATTRIB_BACK_SHININESS][0]; } R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[0] ); R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[1] ); /* currently material changes cannot trigger a global ambient change, I believe this is correct update_global_ambient( ctx ); */}/* _NEW_LIGHT * _NEW_MODELVIEW * _MESA_NEW_NEED_EYE_COORDS * * Uses derived state from mesa: * _VP_inf_norm * _h_inf_norm * _Position * _NormDirection * _ModelViewInvScale * _NeedEyeCoords * _EyeZDir * * which are calculated in light.c and are correct for the current * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW * and _MESA_NEW_NEED_EYE_COORDS. */static void update_light( GLcontext *ctx ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); /* Have to check these, or have an automatic shortcircuit mechanism * to remove noop statechanges. (Or just do a better job on the * front end). */ { GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]; if (ctx->_NeedEyeCoords) tmp &= ~R200_LIGHT_IN_MODELSPACE; else tmp |= R200_LIGHT_IN_MODELSPACE; if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]) { R200_STATECHANGE( rmesa, tcl ); rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] = tmp; } } { GLfloat *fcmd = (GLfloat *)R200_DB_STATE( eye ); fcmd[EYE_X] = ctx->_EyeZDir[0]; fcmd[EYE_Y] = ctx->_EyeZDir[1]; fcmd[EYE_Z] = - ctx->_EyeZDir[2]; fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale; R200_DB_STATECHANGE( rmesa, &rmesa->hw.eye ); } if (ctx->Light.Enabled) { GLint p; for (p = 0 ; p < MAX_LIGHTS; p++) { if (ctx->Light.Light[p].Enabled) { struct gl_light *l = &ctx->Light.Light[p]; GLfloat *fcmd = (GLfloat *)R200_DB_STATE( lit[p] ); if (l->EyePosition[3] == 0.0) { COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm ); COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm ); fcmd[LIT_POSITION_W] = 0; fcmd[LIT_DIRECTION_W] = 0; } else { COPY_4V( &fcmd[LIT_POSITION_X], l->_Position ); fcmd[LIT_DIRECTION_X] = -l->_NormDirection[0]; fcmd[LIT_DIRECTION_Y] = -l->_NormDirection[1]; fcmd[LIT_DIRECTION_Z] = -l->_NormDirection[2]; fcmd[LIT_DIRECTION_W] = 0; } R200_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] ); } } }}static void r200Lightfv( GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); GLint p = light - GL_LIGHT0; struct gl_light *l = &ctx->Light.Light[p];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -