⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r200_state.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
	 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 + -