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

📄 radeon_texstate.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
   if (texobj->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {      GLuint *txr_cmd = RADEON_DB_STATE( txr[unit] );      txr_cmd[TXR_PP_TEX_SIZE] = texobj->pp_txsize; /* NPOT only! */      txr_cmd[TXR_PP_TEX_PITCH] = texobj->pp_txpitch; /* NPOT only! */      RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.txr[unit] );      se_coord_fmt |= RADEON_VTX_ST0_NONPARAMETRIC << unit;   }   else {      se_coord_fmt &= ~(RADEON_VTX_ST0_NONPARAMETRIC << unit);      if (texobj->base.tObj->Target == GL_TEXTURE_CUBE_MAP) {	 int *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];	 GLuint bytesPerFace = texobj->base.totalSize / 6;	 ASSERT(texobj->base.totalSize % 6 == 0);	 RADEON_STATECHANGE( rmesa, cube[unit] );	 cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;	 /* dont know if this setup conforms to OpenGL.. 	  * at least it matches the behavior of mesa software renderer	  */	 cube_cmd[CUBE_PP_CUBIC_OFFSET_0] = texobj->pp_txoffset; /* right */	 cube_cmd[CUBE_PP_CUBIC_OFFSET_1] = texobj->pp_txoffset + 1 * bytesPerFace; /* left */	 cube_cmd[CUBE_PP_CUBIC_OFFSET_2] = texobj->pp_txoffset + 2 * bytesPerFace; /* top */	 cube_cmd[CUBE_PP_CUBIC_OFFSET_3] = texobj->pp_txoffset + 3 * bytesPerFace; /* bottom */	 cube_cmd[CUBE_PP_CUBIC_OFFSET_4] = texobj->pp_txoffset + 4 * bytesPerFace; /* front */	 cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset + 5 * bytesPerFace; /* back */      }   }   if (se_coord_fmt != rmesa->hw.set.cmd[SET_SE_COORDFMT]) {      RADEON_STATECHANGE( rmesa, set );      rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt;   }   texobj->dirty_state &= ~(1<<unit);}static void set_texgen_matrix( radeonContextPtr rmesa, 			       GLuint unit,			       const GLfloat *s_plane,			       const GLfloat *t_plane,			       const GLfloat *r_plane,			       const GLfloat *q_plane ){   rmesa->TexGenMatrix[unit].m[0]  = s_plane[0];   rmesa->TexGenMatrix[unit].m[4]  = s_plane[1];   rmesa->TexGenMatrix[unit].m[8]  = s_plane[2];   rmesa->TexGenMatrix[unit].m[12] = s_plane[3];   rmesa->TexGenMatrix[unit].m[1]  = t_plane[0];   rmesa->TexGenMatrix[unit].m[5]  = t_plane[1];   rmesa->TexGenMatrix[unit].m[9]  = t_plane[2];   rmesa->TexGenMatrix[unit].m[13] = t_plane[3];   rmesa->TexGenMatrix[unit].m[2]  = r_plane[0];   rmesa->TexGenMatrix[unit].m[6]  = r_plane[1];   rmesa->TexGenMatrix[unit].m[10] = r_plane[2];   rmesa->TexGenMatrix[unit].m[14] = r_plane[3];   rmesa->TexGenMatrix[unit].m[3]  = q_plane[0];   rmesa->TexGenMatrix[unit].m[7]  = q_plane[1];   rmesa->TexGenMatrix[unit].m[11] = q_plane[2];   rmesa->TexGenMatrix[unit].m[15] = q_plane[3];   rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE << unit;   rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;}/* Returns GL_FALSE if fallback required. */static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];   GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;   GLuint tmp = rmesa->TexGenEnabled;   static const GLfloat reflect[16] = {      -1,  0,  0,  0,       0, -1,  0,  0,       0,  0,  -1, 0,       0,  0,  0,  1 };   rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE << unit);   rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE << unit);   rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK << inputshift);   rmesa->TexGenNeedNormals[unit] = 0;   if ((texUnit->TexGenEnabled & (S_BIT|T_BIT|R_BIT|Q_BIT)) == 0) {      /* Disabled, no fallback:       */      rmesa->TexGenEnabled |=	 (RADEON_TEXGEN_INPUT_TEXCOORD_0 + unit) << inputshift;      return GL_TRUE;   }   /* the r100 cannot do texgen for some coords and not for others    * we do not detect such cases (certainly can't do it here) and just    * ASSUME that when S and T are texgen enabled we do not need other    * non-texgen enabled coords, no matter if the R and Q bits are texgen    * enabled. Still check for mixed mode texgen for all coords.    */   else if ( (texUnit->TexGenEnabled & S_BIT) &&	     (texUnit->TexGenEnabled & T_BIT) &&	     (texUnit->GenModeS == texUnit->GenModeT) ) {      if ( ((texUnit->TexGenEnabled & R_BIT) &&	    (texUnit->GenModeS != texUnit->GenModeR)) ||	   ((texUnit->TexGenEnabled & Q_BIT) &&	    (texUnit->GenModeS != texUnit->GenModeQ)) ) {	 /* Mixed modes, fallback:	  */	 if (RADEON_DEBUG & DEBUG_FALLBACKS)	    fprintf(stderr, "fallback mixed texgen\n");	 return GL_FALSE;      }      rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit;   }   else {   /* some texgen mode not including both S and T bits */      if (RADEON_DEBUG & DEBUG_FALLBACKS)	 fprintf(stderr, "fallback mixed texgen/nontexgen\n");      return GL_FALSE;   }   if ((texUnit->TexGenEnabled & (R_BIT | Q_BIT)) != 0) {      /* need this here for vtxfmt presumably. Argh we need to set         this from way too many places, would be much easier if we could leave         tcl q coord always enabled as on r200) */      RADEON_STATECHANGE( rmesa, tcl );      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_Q_BIT(unit);   }   switch (texUnit->GenModeS) {   case GL_OBJECT_LINEAR:      rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_OBJ << inputshift;      set_texgen_matrix( rmesa, unit,			 texUnit->ObjectPlaneS,			 texUnit->ObjectPlaneT,			 texUnit->ObjectPlaneR,			 texUnit->ObjectPlaneQ);      break;   case GL_EYE_LINEAR:      rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE << inputshift;      set_texgen_matrix( rmesa, unit,			 texUnit->EyePlaneS,			 texUnit->EyePlaneT,			 texUnit->EyePlaneR,			 texUnit->EyePlaneQ);      break;   case GL_REFLECTION_MAP_NV:      rmesa->TexGenNeedNormals[unit] = GL_TRUE;      rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT << inputshift;      /* TODO: unknown if this is needed/correct */      set_texgen_matrix( rmesa, unit, reflect, reflect + 4,			reflect + 8, reflect + 12 );      break;   case GL_NORMAL_MAP_NV:      rmesa->TexGenNeedNormals[unit] = GL_TRUE;      rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL << inputshift;      break;   case GL_SPHERE_MAP:      /* the mode which everyone uses :-( */   default:      /* Unsupported mode, fallback:       */      if (RADEON_DEBUG & DEBUG_FALLBACKS) 	 fprintf(stderr, "fallback GL_SPHERE_MAP\n");      return GL_FALSE;   }   if (tmp != rmesa->TexGenEnabled) {      rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;   }   return GL_TRUE;}static void disable_tex( GLcontext *ctx, int unit ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit)) {      /* Texture unit disabled */      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 = NULL;      }      RADEON_STATECHANGE( rmesa, ctx );      rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= 	  ~((RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit);      RADEON_STATECHANGE( rmesa, tcl );      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_ST_BIT(unit) |						RADEON_Q_BIT(unit));      if (rmesa->TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<<unit)) {	 TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);	 rmesa->recheck_texgen[unit] = GL_TRUE;      }      if (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) {      /* this seems to be a genuine (r100 only?) hw bug. Need to remove the         cubic_map bit on unit 2 when the unit is disabled, otherwise every	 2nd (2d) mipmap on unit 0 will be broken (may not be needed for other	 units, better be safe than sorry though).*/	 RADEON_STATECHANGE( rmesa, tex[unit] );	 rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &= ~RADEON_TXFORMAT_CUBIC_MAP_ENABLE;      }      {	 GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;	 GLuint tmp = rmesa->TexGenEnabled;	 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);	 rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);	 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);	 rmesa->TexGenNeedNormals[unit] = 0;	 rmesa->TexGenEnabled |= 	     (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;	 if (tmp != rmesa->TexGenEnabled) {	    rmesa->recheck_texgen[unit] = GL_TRUE;	    rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;	 }      }   }}static GLboolean enable_tex_2d( GLcontext *ctx, int unit ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];   struct gl_texture_object *tObj = texUnit->_Current;   radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;   /* Need to load the 2d images associated with this unit.    */   if (t->pp_txformat & RADEON_TXFORMAT_NON_POWER2) {      t->pp_txformat &= ~RADEON_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] ) {      RADEON_FIREVERTICES( rmesa );      radeonSetTexImages( rmesa, tObj );      radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 );      if ( !t->base.memBlock && !t->image_override ) 	return GL_FALSE;   }   return GL_TRUE;}static GLboolean enable_tex_cube( GLcontext *ctx, int unit ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];   struct gl_texture_object *tObj = texUnit->_Current;   radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;   GLuint face;   /* Need to load the 2d images associated with this unit.    */   if (t->pp_txformat & RADEON_TXFORMAT_NON_POWER2) {      t->pp_txformat &= ~RADEON_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 */      RADEON_FIREVERTICES( rmesa );      /* layout memory space, once for all faces */      radeonSetTexImages( rmesa, tObj );   }   /* upload (per face) */   for (face = 0; face < 6; face++) {      if (t->base.dirty_images[face]) {         radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, face );      }   }         if ( !t->base.memBlock ) {      /* texmem alloc failed, use s/w fallback */      return GL_FALSE;   }   return GL_TRUE;}static GLboolean enable_tex_rect( GLcontext *ctx, int unit ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];   struct gl_texture_object *tObj = texUnit->_Current;   radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;   if (!(t->pp_txformat & RADEON_TXFORMAT_NON_POWER2)) {      t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;      t->base.dirty_images[0] = ~0;   }   ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);   if ( t->base.dirty_images[0] ) {      RADEON_FIREVERTICES( rmesa );      radeonSetTexImages( rmesa, tObj );      radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 );      if ( !t->base.memBlock &&           !t->image_override /* && !rmesa->prefer_gart_client_texturing  FIXME */ ) {	 fprintf(stderr, "%s: upload failed\n", __FUNCTION__);	 return GL_FALSE;      }   }   return GL_TRUE;}static GLboolean update_tex_common( GLcontext *ctx, int unit ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];   struct gl_texture_object *tObj = texUnit->_Current;   radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;   GLenum format;   /* Fallback if there's a texture border */   if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) {      fprintf(stderr, "%s: border\n", __FUNCTION__);      return GL_FALSE;   }   /* yuv conversion only works in first unit */   if (unit != 0 && (t->pp_txfilter & RADEON_YUV_TO_RGB))      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 ( !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit))) {      RADEON_STATECHANGE( rmesa, ctx );      rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= 	  (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit;      RADEON_STATECHANGE( rmesa, tcl );      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_ST_BIT(unit);      rmesa->recheck_texgen[unit] = GL_TRUE;   }   if (t->dirty_state & (1<<unit)) {      import_tex_obj_state( rmesa, unit, t );      /* may need to update texture matrix (for texrect adjustments) */      rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;   }   if (rmesa->recheck_texgen[unit]) {      GLboolean fallback = !radeon_validate_texgen( ctx, unit );      TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), fallback);      rmesa->recheck_texgen[unit] = 0;      rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;   }   format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;   if ( rmesa->state.texture.unit[unit].format != format ||	rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) {      rmesa->state.texture.unit[unit].format = format;      rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode;      if ( ! radeonUpdateTextureEnv( ctx, unit ) ) {	 return GL_FALSE;      }   }   FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );   return !t->border_fallback;}static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit ){   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];   if ( texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT) ) {      return (enable_tex_rect( ctx, unit ) &&	      update_tex_common( ctx, unit ));   }   else if ( texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) {      return (enable_tex_2d( ctx, unit ) &&	      update_tex_common( ctx, unit ));   }   else if ( texUnit->_ReallyEnabled & (TEXTURE_CUBE_BIT) ) {      return (enable_tex_cube( ctx, unit ) &&	      update_tex_common( ctx, unit ));   }   else if ( texUnit->_ReallyEnabled ) {      return GL_FALSE;   }   else {      disable_tex( ctx, unit );      return GL_TRUE;   }}void radeonUpdateTextureState( GLcontext *ctx ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   GLboolean ok;   ok = (radeonUpdateTextureUnit( ctx, 0 ) &&	 radeonUpdateTextureUnit( ctx, 1 ) &&	 radeonUpdateTextureUnit( ctx, 2 ));   FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, !ok );   if (rmesa->TclFallback)      radeonChooseVertexState( ctx );}

⌨️ 快捷键说明

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