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

📄 radeon_state.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
      }      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 radeonUpdateScissor( GLcontext *ctx ){   radeonContextPtr rmesa = RADEON_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;      radeonRecalcScissorRects( rmesa );   }}static void radeonScissor( GLcontext *ctx,			   GLint x, GLint y, GLsizei w, GLsizei h ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   if ( ctx->Scissor.Enabled ) {      RADEON_FIREVERTICES( rmesa );	/* don't pipeline cliprect changes */      radeonUpdateScissor( ctx );   }}/* ============================================================= * Culling */static void radeonCullFace( GLcontext *ctx, GLenum unused ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];   GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL];   s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID;   t &= ~(RADEON_CULL_FRONT | RADEON_CULL_BACK);   if ( ctx->Polygon.CullFlag ) {      switch ( ctx->Polygon.CullFaceMode ) {      case GL_FRONT:	 s &= ~RADEON_FFACE_SOLID;	 t |= RADEON_CULL_FRONT;	 break;      case GL_BACK:	 s &= ~RADEON_BFACE_SOLID;	 t |= RADEON_CULL_BACK;	 break;      case GL_FRONT_AND_BACK:	 s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID);	 t |= (RADEON_CULL_FRONT | RADEON_CULL_BACK);	 break;      }   }   if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {      RADEON_STATECHANGE(rmesa, set );      rmesa->hw.set.cmd[SET_SE_CNTL] = s;   }   if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) {      RADEON_STATECHANGE(rmesa, tcl );      rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t;   }}static void radeonFrontFace( GLcontext *ctx, GLenum mode ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   RADEON_STATECHANGE( rmesa, set );   rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_FFACE_CULL_DIR_MASK;   RADEON_STATECHANGE( rmesa, tcl );   rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_CULL_FRONT_IS_CCW;   switch ( mode ) {   case GL_CW:      rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CW;      break;   case GL_CCW:      rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CCW;      rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_CULL_FRONT_IS_CCW;      break;   }}/* ============================================================= * Line state */static void radeonLineWidth( GLcontext *ctx, GLfloat widthf ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   RADEON_STATECHANGE( rmesa, lin );   RADEON_STATECHANGE( rmesa, set );   /* Line width is stored in U6.4 format.    */   rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (GLuint)(widthf * 16.0);   if ( widthf > 1.0 ) {      rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_WIDELINE_ENABLE;   } else {      rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_WIDELINE_ENABLE;   }}static void radeonLineStipple( GLcontext *ctx, GLint factor, GLushort pattern ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   RADEON_STATECHANGE( rmesa, lin );   rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] =       ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern));}/* ============================================================= * Masks */static void radeonColorMask( GLcontext *ctx,			     GLboolean r, GLboolean g,			     GLboolean b, GLboolean a ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   GLuint mask = radeonPackColor( rmesa->radeonScreen->cpp,				  ctx->Color.ColorMask[RCOMP],				  ctx->Color.ColorMask[GCOMP],				  ctx->Color.ColorMask[BCOMP],				  ctx->Color.ColorMask[ACOMP] );   if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) {      RADEON_STATECHANGE( rmesa, msk );      rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask;   }}/* ============================================================= * Polygon state */static void radeonPolygonOffset( GLcontext *ctx,				 GLfloat factor, GLfloat units ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   float_ui32_type constant =  { units * rmesa->state.depth.scale };   float_ui32_type factoru = { factor };   RADEON_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 radeonPolygonStipple( GLcontext *ctx, const GLubyte *mask ){   radeonContextPtr rmesa = RADEON_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    */   RADEON_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(drm_radeon_stipple_t) );   UNLOCK_HARDWARE( rmesa );}static void radeonPolygonMode( GLcontext *ctx, GLenum face, GLenum mode ){   radeonContextPtr rmesa = RADEON_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, RADEON_TCL_FALLBACK_UNFILLED, flag);   if (rmesa->TclFallback) {      radeonChooseRenderState( ctx );      radeonChooseVertexState( 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 radeonUpdateSpecular( GLcontext *ctx ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   u_int32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];   GLuint flag = 0;   RADEON_STATECHANGE( rmesa, tcl );   rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR;   rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE;   rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC;   rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_DIFFUSE;   rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE;   p &= ~RADEON_SPECULAR_ENABLE;   rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_DIFFUSE_SPECULAR_COMBINE;   if (ctx->Light.Enabled &&       ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) {      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;      p |=  RADEON_SPECULAR_ENABLE;      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= 	 ~RADEON_DIFFUSE_SPECULAR_COMBINE;   }   else if (ctx->Light.Enabled) {      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;   } else if (ctx->Fog.ColorSumEnabled ) {      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;      p |= RADEON_SPECULAR_ENABLE;   } else {      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;   }   if (ctx->Fog.Enabled) {      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;      if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH) {	 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;      /* Bizzare: have to leave lighting enabled to get fog. */	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;      }      else {      /* cannot do tcl fog factor calculation with fog coord source       * (send precomputed factors). Cannot use precomputed fog       * factors together with tcl spec light (need tcl fallback) */	 flag = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &	    RADEON_TCL_COMPUTE_SPECULAR) != 0;      }   }    TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_FOGCOORDSPEC, flag);   if (NEED_SECONDARY_COLOR(ctx)) {      assert( (p & RADEON_SPECULAR_ENABLE) != 0 );   } else {      assert( (p & RADEON_SPECULAR_ENABLE) == 0 );   }   if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) {      RADEON_STATECHANGE( rmesa, ctx );      rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p;   }   /* Update vertex/render formats    */   if (rmesa->TclFallback) {       radeonChooseRenderState( ctx );      radeonChooseVertexState( ctx );   }}/* ============================================================= * Materials *//* Update on colormaterial, material emmissive/ambient,  * lightmodel.globalambient */static void update_global_ambient( GLcontext *ctx ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   float *fcmd = (float *)RADEON_DB_STATE( glt );   /* Need to do more if both emmissive & ambient are PREMULT:    * Hope this is not needed for MULT    */   if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &       ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |	(3 << RADEON_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 );   }      RADEON_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) {      radeonContextPtr rmesa = RADEON_CONTEXT(ctx);      float *fcmd = (float *)RADEON_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 );            RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );   }}/* Also fallback for asym colormaterial mode in twoside lighting... */static void check_twoside_fallback( GLcontext *ctx ){   GLboolean fallback = GL_FALSE;   GLint i;   if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {      if (ctx->Light.ColorMaterialEnabled &&	  (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) != 	  ((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1))	 fallback = GL_TRUE;      else {	 for (i = MAT_ATTRIB_FRONT_AMBIENT; i < MAT_ATTRIB_FRONT_INDEXES; i+=2)	    if (memcmp( ctx->Light.Material.Attrib[i],			ctx->Light.Material.Attrib[i+1],			sizeof(GLfloat)*4) != 0) {	       fallback = GL_TRUE;  	       break;	    }      }   }   TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback );}static void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode ){      radeonContextPtr rmesa = RADEON_CONTEXT(ctx);      GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];      light_model_ctl1 &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |			   (3 << RADEON_AMBIENT_SOURCE_SHIFT) |			   (3 << RADEON_DIFFUSE_SOURCE_SHIFT) |			   (3 << RADEON_SPECULAR_SOURCE_SHIFT));       if (ctx->Light.ColorMaterialEnabled) {      GLuint mask = ctx->Light.ColorMaterialBitmask;      if (mask & MAT_BIT_FRONT_EMISSION) {	 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<			     RADEON_EMISSIVE_SOURCE_SHIFT);      }      else {	 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<			     RADEON_EMISSIVE_SOURCE_SHIFT);      }      if (mask & MAT_BIT_FRONT_AMBIENT) {	 light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<			     RADEON_AMBIENT_SOURCE_SHIFT);      }      else {	 light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<			     RADEON_AMBIENT_SOURCE_SHIFT);      }	       if (mask & MAT_BIT_FRONT_DIFFUSE) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -