📄 r200_state.c
字号:
break; case GL_EXP: rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_EXP; c.f = 0.0; d.f = -ctx->Fog.Density; break; case GL_EXP2: rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_EXP2; c.f = 0.0; d.f = -(ctx->Fog.Density * ctx->Fog.Density); break; default: return; } break; case GL_FOG_DENSITY: switch (ctx->Fog.Mode) { case GL_EXP: c.f = 0.0; d.f = -ctx->Fog.Density; break; case GL_EXP2: c.f = 0.0; d.f = -(ctx->Fog.Density * ctx->Fog.Density); break; default: break; } break; case GL_FOG_START: case GL_FOG_END: if (ctx->Fog.Mode == GL_LINEAR) { if (ctx->Fog.Start == ctx->Fog.End) { c.f = 1.0F; d.f = 1.0F; } else { c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start); d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start); } } break; case GL_FOG_COLOR: R200_STATECHANGE( rmesa, ctx ); UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color ); i = r200PackColor( 4, col[0], col[1], col[2], 0 ); rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_COLOR_MASK; rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= i; break; case GL_FOG_COORD_SRC: { GLuint out_0 = rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0]; GLuint fog = rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR]; fog &= ~R200_FOG_USE_MASK; if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) { fog |= R200_FOG_USE_VTX_FOG; out_0 |= R200_VTX_DISCRETE_FOG; } else { fog |= R200_FOG_USE_SPEC_ALPHA; out_0 &= ~R200_VTX_DISCRETE_FOG; } if ( fog != rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] ) { R200_STATECHANGE( rmesa, ctx ); rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = fog; } if (out_0 != rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0]) { R200_STATECHANGE( rmesa, vtx ); rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] = out_0; } break; } default: return; } if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) { R200_STATECHANGE( rmesa, fog ); rmesa->hw.fog.cmd[FOG_C] = c.i; rmesa->hw.fog.cmd[FOG_D] = d.i; }}/* ============================================================= * Scissoring */static GLboolean intersect_rect( drm_clip_rect_t *out, drm_clip_rect_t *a, drm_clip_rect_t *b ){ *out = *a; if ( b->x1 > out->x1 ) out->x1 = b->x1; if ( b->y1 > out->y1 ) out->y1 = b->y1; if ( b->x2 < out->x2 ) out->x2 = b->x2; if ( b->y2 < out->y2 ) out->y2 = b->y2; if ( out->x1 >= out->x2 ) return GL_FALSE; if ( out->y1 >= out->y2 ) return GL_FALSE; return GL_TRUE;}void r200RecalcScissorRects( r200ContextPtr rmesa ){ drm_clip_rect_t *out; int i; /* Grow cliprect store? */ if (rmesa->state.scissor.numAllocedClipRects < rmesa->numClipRects) { while (rmesa->state.scissor.numAllocedClipRects < rmesa->numClipRects) { rmesa->state.scissor.numAllocedClipRects += 1; /* zero case */ rmesa->state.scissor.numAllocedClipRects *= 2; } if (rmesa->state.scissor.pClipRects) FREE(rmesa->state.scissor.pClipRects); rmesa->state.scissor.pClipRects = MALLOC( rmesa->state.scissor.numAllocedClipRects * sizeof(drm_clip_rect_t) ); if ( rmesa->state.scissor.pClipRects == NULL ) { rmesa->state.scissor.numAllocedClipRects = 0; return; } } out = rmesa->state.scissor.pClipRects; rmesa->state.scissor.numClipRects = 0; for ( i = 0 ; i < rmesa->numClipRects ; i++ ) { if ( intersect_rect( out, &rmesa->pClipRects[i], &rmesa->state.scissor.rect ) ) { rmesa->state.scissor.numClipRects++; out++; } }}static void r200UpdateScissor( GLcontext *ctx ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); if ( rmesa->dri.drawable ) { __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; int x = ctx->Scissor.X; int y = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height; int w = ctx->Scissor.X + ctx->Scissor.Width - 1; int h = dPriv->h - ctx->Scissor.Y - 1; rmesa->state.scissor.rect.x1 = x + dPriv->x; rmesa->state.scissor.rect.y1 = y + dPriv->y; rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; r200RecalcScissorRects( rmesa ); }}static void r200Scissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); if ( ctx->Scissor.Enabled ) { R200_FIREVERTICES( rmesa ); /* don't pipeline cliprect changes */ r200UpdateScissor( ctx ); }}/* ============================================================= * Culling */static void r200CullFace( GLcontext *ctx, GLenum unused ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL]; GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL]; s |= R200_FFACE_SOLID | R200_BFACE_SOLID; t &= ~(R200_CULL_FRONT | R200_CULL_BACK); if ( ctx->Polygon.CullFlag ) { switch ( ctx->Polygon.CullFaceMode ) { case GL_FRONT: s &= ~R200_FFACE_SOLID; t |= R200_CULL_FRONT; break; case GL_BACK: s &= ~R200_BFACE_SOLID; t |= R200_CULL_BACK; break; case GL_FRONT_AND_BACK: s &= ~(R200_FFACE_SOLID | R200_BFACE_SOLID); t |= (R200_CULL_FRONT | R200_CULL_BACK); break; } } if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) { R200_STATECHANGE(rmesa, set ); rmesa->hw.set.cmd[SET_SE_CNTL] = s; } if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) { R200_STATECHANGE(rmesa, tcl ); rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t; }}static void r200FrontFace( GLcontext *ctx, GLenum mode ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); R200_STATECHANGE( rmesa, set ); rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_FFACE_CULL_DIR_MASK; R200_STATECHANGE( rmesa, tcl ); rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_CULL_FRONT_IS_CCW; switch ( mode ) { case GL_CW: rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_FFACE_CULL_CW; break; case GL_CCW: rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_FFACE_CULL_CCW; rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_CULL_FRONT_IS_CCW; break; }}/* ============================================================= * Point state */static void r200PointSize( GLcontext *ctx, GLfloat size ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); R200_STATECHANGE( rmesa, cst ); rmesa->hw.cst.cmd[CST_RE_POINTSIZE] &= ~0xffff; rmesa->hw.cst.cmd[CST_RE_POINTSIZE] |= ((GLuint)(ctx->Point.Size * 16.0));}/* ============================================================= * Line state */static void r200LineWidth( GLcontext *ctx, GLfloat widthf ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); R200_STATECHANGE( rmesa, lin ); R200_STATECHANGE( rmesa, set ); /* Line width is stored in U6.4 format. */ rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] &= ~0xffff; rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint)(ctx->Line._Width * 16.0); if ( widthf > 1.0 ) { rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_WIDELINE_ENABLE; } else { rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_WIDELINE_ENABLE; }}static void r200LineStipple( GLcontext *ctx, GLint factor, GLushort pattern ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); R200_STATECHANGE( rmesa, lin ); rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] = ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern));}/* ============================================================= * Masks */static void r200ColorMask( GLcontext *ctx, GLboolean r, GLboolean g, GLboolean b, GLboolean a ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); GLuint mask = r200PackColor( rmesa->r200Screen->cpp, ctx->Color.ColorMask[RCOMP], ctx->Color.ColorMask[GCOMP], ctx->Color.ColorMask[BCOMP], ctx->Color.ColorMask[ACOMP] ); GLuint flag = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] & ~R200_PLANE_MASK_ENABLE; if (!(r && g && b && a)) flag |= R200_PLANE_MASK_ENABLE; if ( rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] != flag ) { R200_STATECHANGE( rmesa, ctx ); rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = flag; } if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) { R200_STATECHANGE( rmesa, msk ); rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask; }}/* ============================================================= * Polygon state */static void r200PolygonOffset( GLcontext *ctx, GLfloat factor, GLfloat units ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); float_ui32_type constant = { units * rmesa->state.depth.scale }; float_ui32_type factoru = { factor };/* factor *= 2; *//* constant *= 2; *//* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */ R200_STATECHANGE( rmesa, zbs ); rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR] = factoru.ui32; rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;}static void r200PolygonStipple( GLcontext *ctx, const GLubyte *mask ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); GLuint i; drm_radeon_stipple_t stipple; /* Must flip pattern upside down. */ for ( i = 0 ; i < 32 ; i++ ) { 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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -