📄 radeon_state.c
字号:
light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << RADEON_DIFFUSE_SOURCE_SHIFT); } else { light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << RADEON_DIFFUSE_SOURCE_SHIFT); } if (mask & MAT_BIT_FRONT_SPECULAR) { light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << RADEON_SPECULAR_SOURCE_SHIFT); } else { light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << RADEON_SPECULAR_SOURCE_SHIFT); } } else { /* Default to MULT: */ light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << RADEON_EMISSIVE_SOURCE_SHIFT) | (RADEON_LM_SOURCE_STATE_MULT << RADEON_AMBIENT_SOURCE_SHIFT) | (RADEON_LM_SOURCE_STATE_MULT << RADEON_DIFFUSE_SOURCE_SHIFT) | (RADEON_LM_SOURCE_STATE_MULT << RADEON_SPECULAR_SOURCE_SHIFT); } if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) { RADEON_STATECHANGE( rmesa, tcl ); rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl1; }}void radeonUpdateMaterial( GLcontext *ctx ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLfloat (*mat)[4] = ctx->Light.Material.Attrib; GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl ); GLuint mask = ~0; if (ctx->Light.ColorMaterialEnabled) mask &= ~ctx->Light.ColorMaterialBitmask; if (RADEON_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]; } RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl ); check_twoside_fallback( ctx );/* 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 ){ radeonContextPtr rmesa = RADEON_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]; if (ctx->_NeedEyeCoords) tmp &= ~RADEON_LIGHT_IN_MODELSPACE; else tmp |= RADEON_LIGHT_IN_MODELSPACE; /* Leave this test disabled: (unexplained q3 lockup) (even with new packets) */ if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) { RADEON_STATECHANGE( rmesa, tcl ); rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp; } } { GLfloat *fcmd = (GLfloat *)RADEON_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; RADEON_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 *)RADEON_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; } RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] ); } } }}static void radeonLightfv( GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLint p = light - GL_LIGHT0; struct gl_light *l = &ctx->Light.Light[p]; GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd; switch (pname) { case GL_AMBIENT: case GL_DIFFUSE: case GL_SPECULAR: update_light_colors( ctx, p ); break; case GL_SPOT_DIRECTION: /* picked up in update_light */ break; case GL_POSITION: { /* positions picked up in update_light, but can do flag here */ GLuint flag; GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2; /* FIXME: Set RANGE_ATTEN only when needed */ if (p&1) flag = RADEON_LIGHT_1_IS_LOCAL; else flag = RADEON_LIGHT_0_IS_LOCAL; RADEON_STATECHANGE(rmesa, tcl); if (l->EyePosition[3] != 0.0F) rmesa->hw.tcl.cmd[idx] |= flag; else rmesa->hw.tcl.cmd[idx] &= ~flag; break; } case GL_SPOT_EXPONENT: RADEON_STATECHANGE(rmesa, lit[p]); fcmd[LIT_SPOT_EXPONENT] = params[0]; break; case GL_SPOT_CUTOFF: { GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT; GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2; RADEON_STATECHANGE(rmesa, lit[p]); fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff; RADEON_STATECHANGE(rmesa, tcl); if (l->SpotCutoff != 180.0F) rmesa->hw.tcl.cmd[idx] |= flag; else rmesa->hw.tcl.cmd[idx] &= ~flag; break; } case GL_CONSTANT_ATTENUATION: RADEON_STATECHANGE(rmesa, lit[p]); fcmd[LIT_ATTEN_CONST] = params[0]; if ( params[0] == 0.0 ) fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX; else fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0]; break; case GL_LINEAR_ATTENUATION: RADEON_STATECHANGE(rmesa, lit[p]); fcmd[LIT_ATTEN_LINEAR] = params[0]; break; case GL_QUADRATIC_ATTENUATION: RADEON_STATECHANGE(rmesa, lit[p]); fcmd[LIT_ATTEN_QUADRATIC] = params[0]; break; default: return; } /* Set RANGE_ATTEN only when needed */ switch (pname) { case GL_POSITION: case GL_CONSTANT_ATTENUATION: case GL_LINEAR_ATTENUATION: case GL_QUADRATIC_ATTENUATION: { GLuint *icmd = (GLuint *)RADEON_DB_STATE( tcl ); GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2; GLuint atten_flag = ( p&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN; GLuint atten_const_flag = ( p&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN; if ( l->EyePosition[3] == 0.0F || ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) && fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) { /* Disable attenuation */ icmd[idx] &= ~atten_flag; } else { if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) { /* Enable only constant portion of attenuation calculation */ icmd[idx] |= ( atten_flag | atten_const_flag ); } else { /* Enable full attenuation calculation */ icmd[idx] &= ~atten_const_flag; icmd[idx] |= atten_flag; } } RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tcl ); break; } default: break; }} static void radeonLightModelfv( GLcontext *ctx, GLenum pname, const GLfloat *param ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); switch (pname) { case GL_LIGHT_MODEL_AMBIENT: update_global_ambient( ctx ); break; case GL_LIGHT_MODEL_LOCAL_VIEWER: RADEON_STATECHANGE( rmesa, tcl ); if (ctx->Light.Model.LocalViewer) rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER; else rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER; break; case GL_LIGHT_MODEL_TWO_SIDE: RADEON_STATECHANGE( rmesa, tcl ); if (ctx->Light.Model.TwoSide) rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE; else rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE; check_twoside_fallback( ctx ); if (rmesa->TclFallback) { radeonChooseRenderState( ctx ); radeonChooseVertexState( ctx ); } break; case GL_LIGHT_MODEL_COLOR_CONTROL: radeonUpdateSpecular(ctx); break; default: break; }}static void radeonShadeModel( GLcontext *ctx, GLenum mode ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL]; s &= ~(RADEON_DIFFUSE_SHADE_MASK | RADEON_ALPHA_SHADE_MASK | RADEON_SPECULAR_SHADE_MASK | RADEON_FOG_SHADE_MASK); switch ( mode ) { case GL_FLAT: s |= (RADEON_DIFFUSE_SHADE_FLAT | RADEON_ALPHA_SHADE_FLAT | RADEON_SPECULAR_SHADE_FLAT | RADEON_FOG_SHADE_FLAT); break; case GL_SMOOTH: s |= (RADEON_DIFFUSE_SHADE_GOURAUD | RADEON_ALPHA_SHADE_GOURAUD | RADEON_SPECULAR_SHADE_GOURAUD | RADEON_FOG_SHADE_GOURAUD); break; default: return; } if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) { RADEON_STATECHANGE( rmesa, set ); rmesa->hw.set.cmd[SET_SE_CNTL] = s; }}/* ============================================================= * User clip planes */static void radeonClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq ){ GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0; radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p]; RADEON_STATECHANGE( rmesa, ucp[p] ); rmesa->hw.ucp[p].cmd[UCP_X] = ip[0]; rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1]; rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2]; rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];}static void radeonUpdateClipPlanes( GLcontext *ctx ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLuint p; for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p]; RADEON_STATECHANGE( rmesa, ucp[p] ); rmesa->hw.ucp[p].cmd[UCP_X] = ip[0]; rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1]; rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2]; rmesa->hw.ucp[p].cmd[UCP_W] = ip[3]; } }}/* ============================================================= * Stencil */static voidradeonStencilFuncSeparate( GLcontext *ctx, GLenum face, GLenum func, GLint ref, GLuint mask ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << RADEON_STENCIL_REF_SHIFT) | ((ctx->Stencil.ValueMask[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT)); RADEON_STATECHANGE( rmesa, ctx ); RADEON_STATECHANGE( rmesa, msk ); rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_STENCIL_TEST_MASK; rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(RADEON_STENCIL_REF_MASK| RADEON_STENCIL_VALUE_MASK); switch ( ctx->Stencil.Function[0] ) { case GL_NEVER: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEVER; break; case GL_LESS: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LESS; break; case GL_EQUAL: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_EQUAL; break; case GL_LEQUAL: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LEQUAL; break; case GL_GREATER: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GREATER; break; case GL_NOTEQUAL: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEQUAL; break; case GL_GEQUAL: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GEQUAL; break; case GL_ALWAYS: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_ALWAYS; break; } rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -