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

📄 r200_fragshader.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
	       dstmod &= ~GL_SATURATE_BIT_ATI;	       SET_INST_2(opnum, optype) |= (dstreg + 1) << R200_TXC_OUTPUT_REG_SHIFT;	       SET_INST_2(opnum, optype) |= dstmask_table[dstmask];		/* fglrx does clamp the last instructions to 0_1 it seems */		/* this won't necessarily catch the last instruction		   which writes to reg0 */	       if (sat || (pc == (shader->numArithInstr[pass] - 1) &&			((pass == 1) || (shader->NumPasses == 1))))		  SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_0_1;	       else		/*should we clamp or not? spec is vague, I would suppose yes but fglrx doesn't */		  SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_8_8;/*		  SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_WRAP;*/	       switch(dstmod) {	       case GL_2X_BIT_ATI:		  SET_INST_2(opnum, optype) |= R200_TXC_SCALE_2X;		  break;	       case GL_4X_BIT_ATI:		  SET_INST_2(opnum, optype) |= R200_TXC_SCALE_4X;		  break;	       case GL_8X_BIT_ATI:		  SET_INST_2(opnum, optype) |= R200_TXC_SCALE_8X;		  break;	       case GL_HALF_BIT_ATI:		  SET_INST_2(opnum, optype) |= R200_TXC_SCALE_INV2;		  break;	       case GL_QUARTER_BIT_ATI:		  SET_INST_2(opnum, optype) |= R200_TXC_SCALE_INV4;		  break;	       case GL_EIGHTH_BIT_ATI:		  SET_INST_2(opnum, optype) |= R200_TXC_SCALE_INV8;		  break;	       default:		  break;	       }	    }	 }/*	 fprintf(stderr, "pass %d nr %d inst 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",		pass, opnum, SET_INST(opnum, 0), SET_INST_2(opnum, 0),		SET_INST(opnum, 1), SET_INST_2(opnum, 1));*/         opnum++;      }      afs_cmd = (GLuint *) rmesa->hw.afs[1].cmd;   }   rmesa->afs_loaded = ctx->ATIFragmentShader.Current;}static void r200UpdateFSRouting( GLcontext *ctx ) {   r200ContextPtr rmesa = R200_CONTEXT(ctx);   const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;   GLuint reg;   R200_STATECHANGE( rmesa, ctx );   R200_STATECHANGE( rmesa, cst );   for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {      if (shader->swizzlerq & (1 << (2 * reg)))	 /* r coord */	 set_re_cntl_d3d( ctx, reg, 1);	 /* q coord */      else set_re_cntl_d3d( ctx, reg, 0);   }   rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_MULTI_PASS_ENABLE |				       R200_TEX_BLEND_ENABLE_MASK |				       R200_TEX_ENABLE_MASK);   rmesa->hw.cst.cmd[CST_PP_CNTL_X] &= ~(R200_PPX_PFS_INST_ENABLE_MASK |					 R200_PPX_TEX_ENABLE_MASK |					 R200_PPX_OUTPUT_REG_MASK);   /* first pass registers use slots 8 - 15      but single pass shaders use slots 0 - 7 */   if (shader->NumPasses < 2) {      rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= shader->numArithInstr[0] == 8 ?	 0xff << (R200_TEX_BLEND_0_ENABLE_SHIFT - 1) :	 (0xff >> (8 - shader->numArithInstr[0])) << R200_TEX_BLEND_0_ENABLE_SHIFT;   } else {      rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_MULTI_PASS_ENABLE;      rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= shader->numArithInstr[1] == 8 ?	 0xff << (R200_TEX_BLEND_0_ENABLE_SHIFT - 1) :	 (0xff >> (8 - shader->numArithInstr[1])) << R200_TEX_BLEND_0_ENABLE_SHIFT;      rmesa->hw.cst.cmd[CST_PP_CNTL_X] |=	 (0xff >> (8 - shader->numArithInstr[0])) << R200_PPX_FPS_INST0_ENABLE_SHIFT;   }   if (shader->NumPasses < 2) {      for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {	 GLbitfield targetbit = ctx->Texture.Unit[reg]._ReallyEnabled;         R200_STATECHANGE( rmesa, tex[reg] );	 rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = 0;	 if (shader->SetupInst[0][reg].Opcode) {	    GLuint txformat = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT]		& ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);	    GLuint txformat_x = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] & ~R200_TEXCOORD_MASK;	    txformat |= (shader->SetupInst[0][reg].src - GL_TEXTURE0_ARB)		<< R200_TXFORMAT_ST_ROUTE_SHIFT;	    /* fix up texcoords for proj/non-proj 2d (3d and cube are not defined when	       using projection so don't have to worry there).	       When passing coords, need R200_TEXCOORD_VOLUME, otherwise loose a coord */	    /* FIXME: someone might rely on default tex coords r/q, which we unfortunately	       don't provide (we have the same problem without shaders) */	    if (shader->SetupInst[0][reg].Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {	       txformat |= R200_TXFORMAT_LOOKUP_DISABLE;	       if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||		  shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {		  txformat_x |= R200_TEXCOORD_VOLUME;	       }	       else {		  txformat_x |= R200_TEXCOORD_PROJ;	       }	       rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;	    }	    else if (targetbit == TEXTURE_3D_BIT) {	       txformat_x |= R200_TEXCOORD_VOLUME;	    }	    else if (targetbit == TEXTURE_CUBE_BIT) {	       txformat_x |= R200_TEXCOORD_CUBIC_ENV;	    }	    else if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||	       shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {	       txformat_x |= R200_TEXCOORD_NONPROJ;	    }	    else {	       txformat_x |= R200_TEXCOORD_PROJ;	    }	    rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT] = txformat;	    rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] = txformat_x;	    /* enabling texturing when unit isn't correctly configured may not be safe */	    if (targetbit)	       rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;	 }      }   } else {      /* setup 1st pass */      for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {	 GLbitfield targetbit = ctx->Texture.Unit[reg]._ReallyEnabled;	 R200_STATECHANGE( rmesa, tex[reg] );	 GLuint txformat_multi = 0;	 if (shader->SetupInst[0][reg].Opcode) {	    txformat_multi |= (shader->SetupInst[0][reg].src - GL_TEXTURE0_ARB)		<< R200_PASS1_ST_ROUTE_SHIFT;	    if (shader->SetupInst[0][reg].Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {	       txformat_multi |= R200_PASS1_TXFORMAT_LOOKUP_DISABLE;	       if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||		  shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {		  txformat_multi |= R200_PASS1_TEXCOORD_VOLUME;	       }	       else {		  txformat_multi |= R200_PASS1_TEXCOORD_PROJ;	       }	       rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_0_ENABLE << reg;	    }	    else if (targetbit == TEXTURE_3D_BIT) {	       txformat_multi |= R200_PASS1_TEXCOORD_VOLUME;	    }	    else if (targetbit == TEXTURE_CUBE_BIT) {	       txformat_multi |= R200_PASS1_TEXCOORD_CUBIC_ENV;	    }	    else if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||		  shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {		  txformat_multi |= R200_PASS1_TEXCOORD_NONPROJ;	    }	    else {	       txformat_multi |= R200_PASS1_TEXCOORD_PROJ;	    }	    if (targetbit)	       rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_0_ENABLE << reg;	 }         rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = txformat_multi;      }      /* setup 2nd pass */      for (reg=0; reg < R200_MAX_TEXTURE_UNITS; reg++) {	 GLbitfield targetbit = ctx->Texture.Unit[reg]._ReallyEnabled;	 if (shader->SetupInst[1][reg].Opcode) {	    GLuint coord = shader->SetupInst[1][reg].src;	    GLuint txformat = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT]		& ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);	    GLuint txformat_x = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] & ~R200_TEXCOORD_MASK;	    R200_STATECHANGE( rmesa, tex[reg] );	    if (shader->SetupInst[1][reg].Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {	       txformat |= R200_TXFORMAT_LOOKUP_DISABLE;	       txformat_x |= R200_TEXCOORD_VOLUME;	       if (shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STR_ATI ||		  shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STQ_ATI) {	          txformat_x |= R200_TEXCOORD_VOLUME;	       }	       else {		  txformat_x |= R200_TEXCOORD_PROJ;	       }	       rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;	    }	    else if (targetbit == TEXTURE_3D_BIT) {	       txformat_x |= R200_TEXCOORD_VOLUME;	    }	    else if (targetbit == TEXTURE_CUBE_BIT) {	       txformat_x |= R200_TEXCOORD_CUBIC_ENV;	    }	    else if (shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STR_ATI ||	       shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STQ_ATI) {	       txformat_x |= R200_TEXCOORD_NONPROJ;	    }	    else {	       txformat_x |= R200_TEXCOORD_PROJ;	    }	    if (coord >= GL_REG_0_ATI) {	       GLuint txformat_multi = rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL];	       txformat_multi |= (coord - GL_REG_0_ATI + 2) << R200_PASS2_COORDS_REG_SHIFT;	       rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = txformat_multi;	       rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= 1 <<		  (R200_PPX_OUTPUT_REG_0_SHIFT + coord - GL_REG_0_ATI);	    } else {	       txformat |= (coord - GL_TEXTURE0_ARB) << R200_TXFORMAT_ST_ROUTE_SHIFT;	    }	    rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] = txformat_x;	    rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT] = txformat;	    if (targetbit)	       rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;	 }      }   }}static void r200UpdateFSConstants( GLcontext *ctx ){   r200ContextPtr rmesa = R200_CONTEXT(ctx);   const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;   GLuint i;   /* update constants */   R200_STATECHANGE(rmesa, atf);   for (i = 0; i < 8; i++)   {      GLubyte con_byte[4];      if ((shader->LocalConstDef >> i) & 1) {	 CLAMPED_FLOAT_TO_UBYTE(con_byte[0], shader->Constants[i][0]);	 CLAMPED_FLOAT_TO_UBYTE(con_byte[1], shader->Constants[i][1]);	 CLAMPED_FLOAT_TO_UBYTE(con_byte[2], shader->Constants[i][2]);	 CLAMPED_FLOAT_TO_UBYTE(con_byte[3], shader->Constants[i][3]);      }      else {	 CLAMPED_FLOAT_TO_UBYTE(con_byte[0], ctx->ATIFragmentShader.GlobalConstants[i][0]);	 CLAMPED_FLOAT_TO_UBYTE(con_byte[1], ctx->ATIFragmentShader.GlobalConstants[i][1]);	 CLAMPED_FLOAT_TO_UBYTE(con_byte[2], ctx->ATIFragmentShader.GlobalConstants[i][2]);	 CLAMPED_FLOAT_TO_UBYTE(con_byte[3], ctx->ATIFragmentShader.GlobalConstants[i][3]);      }      rmesa->hw.atf.cmd[ATF_TFACTOR_0 + i] = r200PackColor (	 4, con_byte[0], con_byte[1], con_byte[2], con_byte[3] );   }}/* update routing, constants and arithmetic * constants need to be updated always (globals can change, no separate notification) * routing needs to be updated always too (non-shader code will overwrite state, plus * some of the routing depends on what sort of texture is bound) * for both of them, we need to update anyway because of disabling/enabling ati_fs which * we'd need to track otherwise * arithmetic is only updated if current shader changes (and probably the data should be * stored in some DriverData object attached to the mesa atifs object, i.e. binding a * shader wouldn't force us to "recompile" the shader). */void r200UpdateFragmentShader( GLcontext *ctx ){   r200ContextPtr rmesa = R200_CONTEXT(ctx);   r200UpdateFSConstants( ctx );   r200UpdateFSRouting( ctx );   if (rmesa->afs_loaded != ctx->ATIFragmentShader.Current)      r200UpdateFSArith( ctx );}

⌨️ 快捷键说明

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