📄 r200_state.c
字号:
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_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_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 || ctx->VertexProgram.Enabled) { 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); GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd; R200_STATECHANGE( rmesa, cst ); R200_STATECHANGE( rmesa, ptp ); rmesa->hw.cst.cmd[CST_RE_POINTSIZE] &= ~0xffff; rmesa->hw.cst.cmd[CST_RE_POINTSIZE] |= ((GLuint)(ctx->Point.Size * 16.0));/* this is the size param of the point size calculation (point size reg value is not used when calculation is active). */ fcmd[PTP_VPORT_SCALE_PTSIZE] = ctx->Point.Size;}static void r200PointParameter( GLcontext *ctx, GLenum pname, const GLfloat *params){ r200ContextPtr rmesa = R200_CONTEXT(ctx); GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd; switch (pname) { case GL_POINT_SIZE_MIN: /* Can clamp both in tcl and setup - just set both (as does fglrx) */ R200_STATECHANGE( rmesa, lin ); R200_STATECHANGE( rmesa, ptp ); rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] &= 0xffff; rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint)(ctx->Point.MinSize * 16.0) << 16; fcmd[PTP_CLAMP_MIN] = ctx->Point.MinSize; break; case GL_POINT_SIZE_MAX: R200_STATECHANGE( rmesa, cst ); R200_STATECHANGE( rmesa, ptp ); rmesa->hw.cst.cmd[CST_RE_POINTSIZE] &= 0xffff; rmesa->hw.cst.cmd[CST_RE_POINTSIZE] |= (GLuint)(ctx->Point.MaxSize * 16.0) << 16; fcmd[PTP_CLAMP_MAX] = ctx->Point.MaxSize; break; case GL_POINT_DISTANCE_ATTENUATION: R200_STATECHANGE( rmesa, vtx ); R200_STATECHANGE( rmesa, spr ); R200_STATECHANGE( rmesa, ptp ); GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd; rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] &= ~(R200_PS_MULT_MASK | R200_PS_LIN_ATT_ZERO | R200_PS_SE_SEL_STATE); /* can't rely on ctx->Point._Attenuated here and test for NEW_POINT in r200ValidateState looks like overkill */ if (ctx->Point.Params[0] != 1.0 || ctx->Point.Params[1] != 0.0 || ctx->Point.Params[2] != 0.0 || (ctx->VertexProgram.Enabled && ctx->VertexProgram.PointSizeEnabled)) { /* all we care for vp would be the ps_se_sel_state setting */ fcmd[PTP_ATT_CONST_QUAD] = ctx->Point.Params[2]; fcmd[PTP_ATT_CONST_LIN] = ctx->Point.Params[1]; fcmd[PTP_ATT_CONST_CON] = ctx->Point.Params[0]; rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_MULT_ATTENCONST; if (ctx->Point.Params[1] == 0.0) rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_LIN_ATT_ZERO;/* FIXME: setting this here doesn't look quite ok - we only want to do that if we're actually drawing points probably */ rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_PT_SIZE; rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= R200_VTX_POINT_SIZE; } else { rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_SE_SEL_STATE | R200_PS_MULT_CONST; rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_PT_SIZE; rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~R200_VTX_POINT_SIZE; } break; case GL_POINT_FADE_THRESHOLD_SIZE: /* don't support multisampling, so doesn't matter. */ break; /* can't do these but don't need them. case GL_POINT_SPRITE_R_MODE_NV: case GL_POINT_SPRITE_COORD_ORIGIN: */ default: fprintf(stderr, "bad pname parameter in r200PointParameter\n"); return; }}/* ============================================================= * 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. * Same min/max limits for AA, non-AA lines. */ rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] &= ~0xffff; rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint) (CLAMP(widthf, ctx->Const.MinLineWidth, ctx->Const.MaxLineWidth) * 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++ ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -