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

📄 r200_texstate.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
   if (use_d3d)      re_cntl |= R200_VTX_STQ0_D3D << (2 * unit);   if ( re_cntl != rmesa->hw.set.cmd[SET_RE_CNTL] ) {      R200_STATECHANGE( rmesa, set );      rmesa->hw.set.cmd[SET_RE_CNTL] = re_cntl;   }}static GLboolean enable_tex_2d( GLcontext *ctx, int unit ){   r200ContextPtr rmesa = R200_CONTEXT(ctx);   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];   struct gl_texture_object *tObj = texUnit->_Current;   r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData;   /* Need to load the 2d images associated with this unit.    */   if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) {      t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2;      t->base.dirty_images[0] = ~0;   }   ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);   if ( t->base.dirty_images[0] ) {      R200_FIREVERTICES( rmesa );      r200SetTexImages( rmesa, tObj );      r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 );      if ( !t->base.memBlock && !t->image_override ) 	 return GL_FALSE;   }   set_re_cntl_d3d( ctx, unit, GL_FALSE );   return GL_TRUE;}#if ENABLE_HW_3D_TEXTUREstatic GLboolean enable_tex_3d( GLcontext *ctx, int unit ){   r200ContextPtr rmesa = R200_CONTEXT(ctx);   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];   struct gl_texture_object *tObj = texUnit->_Current;   r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData;   /* Need to load the 3d images associated with this unit.    */   if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) {      t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2;      t->base.dirty_images[0] = ~0;   }   ASSERT(tObj->Target == GL_TEXTURE_3D);   /* R100 & R200 do not support mipmaps for 3D textures.    */   if ( (tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR) ) {      return GL_FALSE;   }   if ( t->base.dirty_images[0] ) {      R200_FIREVERTICES( rmesa );      r200SetTexImages( rmesa, tObj );      r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 );      if ( !t->base.memBlock ) 	 return GL_FALSE;   }   set_re_cntl_d3d( ctx, unit, GL_TRUE );   return GL_TRUE;}#endifstatic GLboolean enable_tex_cube( GLcontext *ctx, int unit ){   r200ContextPtr rmesa = R200_CONTEXT(ctx);   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];   struct gl_texture_object *tObj = texUnit->_Current;   r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData;   GLuint face;   /* Need to load the 2d images associated with this unit.    */   if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) {      t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2;      for (face = 0; face < 6; face++)         t->base.dirty_images[face] = ~0;   }   ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP);   if ( t->base.dirty_images[0] || t->base.dirty_images[1] ||        t->base.dirty_images[2] || t->base.dirty_images[3] ||        t->base.dirty_images[4] || t->base.dirty_images[5] ) {      /* flush */      R200_FIREVERTICES( rmesa );      /* layout memory space, once for all faces */      r200SetTexImages( rmesa, tObj );   }   /* upload (per face) */   for (face = 0; face < 6; face++) {      if (t->base.dirty_images[face]) {         r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, face );      }   }         if ( !t->base.memBlock ) {      /* texmem alloc failed, use s/w fallback */      return GL_FALSE;   }   set_re_cntl_d3d( ctx, unit, GL_TRUE );   return GL_TRUE;}static GLboolean enable_tex_rect( GLcontext *ctx, int unit ){   r200ContextPtr rmesa = R200_CONTEXT(ctx);   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];   struct gl_texture_object *tObj = texUnit->_Current;   r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData;   if (!(t->pp_txformat & R200_TXFORMAT_NON_POWER2)) {      t->pp_txformat |= R200_TXFORMAT_NON_POWER2;      t->base.dirty_images[0] = ~0;   }   ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);   if ( t->base.dirty_images[0] ) {      R200_FIREVERTICES( rmesa );      r200SetTexImages( rmesa, tObj );      r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 );      if ( !t->base.memBlock &&           !t->image_override &&           !rmesa->prefer_gart_client_texturing ) 	 return GL_FALSE;   }   set_re_cntl_d3d( ctx, unit, GL_FALSE );   return GL_TRUE;}static GLboolean update_tex_common( GLcontext *ctx, int unit ){   r200ContextPtr rmesa = R200_CONTEXT(ctx);   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];   struct gl_texture_object *tObj = texUnit->_Current;   r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData;   /* Fallback if there's a texture border */   if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 )       return GL_FALSE;   /* Update state if this is a different texture object to last    * time.    */   if ( rmesa->state.texture.unit[unit].texobj != t ) {      if ( rmesa->state.texture.unit[unit].texobj != NULL ) {	 /* The old texture is no longer bound to this texture unit.	  * Mark it as such.	  */	 rmesa->state.texture.unit[unit].texobj->base.bound &= 	     ~(1UL << unit);      }      rmesa->state.texture.unit[unit].texobj = t;      t->base.bound |= (1UL << unit);      t->dirty_state |= 1<<unit;      driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */   }   /* Newly enabled?    */   if ( 1|| !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<<unit))) {      R200_STATECHANGE( rmesa, ctx );      rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << unit;      R200_STATECHANGE( rmesa, vtx );      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3);      rmesa->recheck_texgen[unit] = GL_TRUE;   }   if (t->dirty_state & (1<<unit)) {      import_tex_obj_state( rmesa, unit, t );   }   if (rmesa->recheck_texgen[unit]) {      GLboolean fallback = !r200_validate_texgen( ctx, unit );      TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), fallback);      rmesa->recheck_texgen[unit] = 0;      rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;   }   FALLBACK( rmesa, R200_FALLBACK_BORDER_MODE, t->border_fallback );   return !t->border_fallback;}static GLboolean r200UpdateTextureUnit( GLcontext *ctx, int unit ){   r200ContextPtr rmesa = R200_CONTEXT(ctx);   GLuint unitneeded = rmesa->state.texture.unit[unit].unitneeded;   if ( unitneeded & (TEXTURE_RECT_BIT) ) {      return (enable_tex_rect( ctx, unit ) &&	      update_tex_common( ctx, unit ));   }   else if ( unitneeded & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) {      return (enable_tex_2d( ctx, unit ) &&	      update_tex_common( ctx, unit ));   }#if ENABLE_HW_3D_TEXTURE   else if ( unitneeded & (TEXTURE_3D_BIT) ) {      return (enable_tex_3d( ctx, unit ) &&	      update_tex_common( ctx, unit ));   }#endif   else if ( unitneeded & (TEXTURE_CUBE_BIT) ) {      return (enable_tex_cube( ctx, unit ) &&	      update_tex_common( ctx, unit ));   }   else if ( unitneeded ) {      return GL_FALSE;   }   else {      disable_tex( ctx, unit );      return GL_TRUE;   }}void r200UpdateTextureState( GLcontext *ctx ){   r200ContextPtr rmesa = R200_CONTEXT(ctx);   GLboolean ok;   GLuint dbg;   /* NOTE: must not manipulate rmesa->state.texture.unit[].unitneeded or      rmesa->state.envneeded before a R200_STATECHANGE (or R200_NEWPRIM) since      we use these to determine if we want to emit the corresponding state      atoms. */   R200_NEWPRIM( rmesa );   if (ctx->ATIFragmentShader._Enabled) {      GLuint i;      for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) {	 rmesa->state.texture.unit[i].unitneeded = ctx->Texture.Unit[i]._ReallyEnabled;      }      ok = GL_TRUE;   }   else {      ok = r200UpdateAllTexEnv( ctx );   }   if (ok) {      ok = (r200UpdateTextureUnit( ctx, 0 ) &&	 r200UpdateTextureUnit( ctx, 1 ) &&	 r200UpdateTextureUnit( ctx, 2 ) &&	 r200UpdateTextureUnit( ctx, 3 ) &&	 r200UpdateTextureUnit( ctx, 4 ) &&	 r200UpdateTextureUnit( ctx, 5 ));   }   if (ok && ctx->ATIFragmentShader._Enabled) {      r200UpdateFragmentShader(ctx);   }   FALLBACK( rmesa, R200_FALLBACK_TEXTURE, !ok );   if (rmesa->TclFallback)      r200ChooseVertexState( ctx );   if (rmesa->r200Screen->chip_family == CHIP_FAMILY_R200) {      /*       * T0 hang workaround -------------       * not needed for r200 derivatives        */      if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_ENABLE_MASK) == R200_TEX_0_ENABLE &&	 (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) {	 R200_STATECHANGE(rmesa, ctx);	 R200_STATECHANGE(rmesa, tex[1]);	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_1_ENABLE;	 if (!(rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_1_ENABLE))	    rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;	 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] |= R200_TXFORMAT_LOOKUP_DISABLE;      }      else if (!ctx->ATIFragmentShader._Enabled) {	 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE) &&	    (rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] & R200_TXFORMAT_LOOKUP_DISABLE)) {	    R200_STATECHANGE(rmesa, tex[1]);	    rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~R200_TXFORMAT_LOOKUP_DISABLE;         }      }      /* do the same workaround for the first pass of a fragment shader.       * completely unknown if necessary / sufficient.       */      if ((rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_ENABLE_MASK) == R200_PPX_TEX_0_ENABLE &&	 (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) {	 R200_STATECHANGE(rmesa, cst);	 R200_STATECHANGE(rmesa, tex[1]);	 rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_1_ENABLE;	 if (!(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE))	    rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;	 rmesa->hw.tex[1].cmd[TEX_PP_TXMULTI_CTL] |= R200_PASS1_TXFORMAT_LOOKUP_DISABLE;      }      /* maybe needs to be done pairwise due to 2 parallel (physical) tex units ?         looks like that's not the case, if 8500/9100 owners don't complain remove this...      for ( i = 0; i < ctx->Const.MaxTextureUnits; i += 2) {         if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & ((R200_TEX_0_ENABLE |            R200_TEX_1_ENABLE ) << i)) == (R200_TEX_0_ENABLE << i)) &&            ((rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) >            R200_MIN_FILTER_LINEAR)) {            R200_STATECHANGE(rmesa, ctx);            R200_STATECHANGE(rmesa, tex[i+1]);            rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_1_ENABLE << i);            rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;            rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] |= 0x08000000;         }         else {            if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE << i)) &&               (rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) {               R200_STATECHANGE(rmesa, tex[i+1]);               rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000;            }         }      } */      /*       * Texture cache LRU hang workaround -------------       * not needed for r200 derivatives       * hopefully this covers first pass of a shader as well       */      /* While the cases below attempt to only enable the workaround in the       * specific cases necessary, they were insufficient.  See bugzilla #1519,       * #729, #814.  Tests with quake3 showed no impact on performance.       */      dbg = 0x6;      /*      if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE )) &&         ((((rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &         0x04) == 0)) ||         ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_2_ENABLE) &&         ((((rmesa->hw.tex[2].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &         0x04) == 0)) ||         ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_4_ENABLE) &&         ((((rmesa->hw.tex[4].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &         0x04) == 0)))      {         dbg |= 0x02;      }      if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE )) &&         ((((rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &         0x04) == 0)) ||         ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_3_ENABLE) &&         ((((rmesa->hw.tex[3].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &         0x04) == 0)) ||         ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_5_ENABLE) &&         ((((rmesa->hw.tex[5].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &         0x04) == 0)))      {         dbg |= 0x04;      }*/      if (dbg != rmesa->hw.tam.cmd[TAM_DEBUG3]) {         R200_STATECHANGE( rmesa, tam );         rmesa->hw.tam.cmd[TAM_DEBUG3] = dbg;         if (0) printf("TEXCACHE LRU HANG WORKAROUND %x\n", dbg);      }   }}

⌨️ 快捷键说明

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