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

📄 r200_vertprog.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
      VERT_BIT_TEX3 | VERT_BIT_TEX4 | VERT_BIT_TEX5)) != 0) {      if (R200_DEBUG & DEBUG_FALLBACKS) {	 fprintf(stderr, "can't handle vert prog inputs 0x%x\n",	    mesa_vp->Base.InputsRead);      }      return GL_FALSE;   }#endif   if ((mesa_vp->Base.OutputsWritten &      ~((1 << VERT_RESULT_HPOS) | (1 << VERT_RESULT_COL0) | (1 << VERT_RESULT_COL1) |      (1 << VERT_RESULT_FOGC) | (1 << VERT_RESULT_TEX0) | (1 << VERT_RESULT_TEX1) |      (1 << VERT_RESULT_TEX2) | (1 << VERT_RESULT_TEX3) | (1 << VERT_RESULT_TEX4) |      (1 << VERT_RESULT_TEX5) | (1 << VERT_RESULT_PSIZ))) != 0) {      if (R200_DEBUG & DEBUG_FALLBACKS) {	 fprintf(stderr, "can't handle vert prog outputs 0x%x\n",	    mesa_vp->Base.OutputsWritten);      }      return GL_FALSE;   }   if (mesa_vp->IsNVProgram) {   /* subtle differences in spec like guaranteed initialized regs could cause      headaches. Might want to remove the driconf option to enable it completely */      return GL_FALSE;   }   /* Initial value should be last tmp reg that hw supports.      Strangely enough r300 doesnt mind even though these would be out of range.      Smart enough to realize that it doesnt need it? */   int u_temp_i = R200_VSF_MAX_TEMPS - 1;   struct prog_src_register src[3];   struct prog_dst_register dst;/* FIXME: is changing the prog safe to do here? */   if (mesa_vp->IsPositionInvariant &&      /* make sure we only do this once */       !(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) {	 _mesa_insert_mvp_code(ctx, mesa_vp);      }   /* for fogc, can't change mesa_vp, as it would hose swtnl, and exp with      base e isn't directly available neither. */   if ((mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) && !vp->fogpidx) {      struct gl_program_parameter_list *paramList;      gl_state_index tokens[STATE_LENGTH] = { STATE_FOG_PARAMS, 0, 0, 0, 0 };      paramList = mesa_vp->Base.Parameters;      vp->fogpidx = _mesa_add_state_reference(paramList, tokens);   }   vp->pos_end = 0;   mesa_vp->Base.NumNativeInstructions = 0;   if (mesa_vp->Base.Parameters)      mesa_vp->Base.NumNativeParameters = mesa_vp->Base.Parameters->NumParameters;   else      mesa_vp->Base.NumNativeParameters = 0;   for(i = 0; i < VERT_ATTRIB_MAX; i++)      vp->inputs[i] = -1;   for(i = 0; i < 15; i++)      vp->inputmap_rev[i] = 255;   free_inputs = 0x2ffd;/* fglrx uses fixed inputs as follows for conventional attribs.   generic attribs use non-fixed assignment, fglrx will always use the   lowest attrib values available. We'll just do the same.   There are 12 generic attribs possible, corresponding to attrib 0, 2-11   and 13 in a hw vertex prog.   attr 1 and 12 aren't used for generic attribs as those cannot be made vec4   (correspond to vertex normal/weight - maybe weight actually could be made vec4).   Additionally, not more than 12 arrays in total are possible I think.   attr 0 is pos, R200_VTX_XY1|R200_VTX_Z1|R200_VTX_W1 in R200_SE_VTX_FMT_0   attr 2-5 use colors 0-3 (R200_VTX_FP_RGBA << R200_VTX_COLOR_0/1/2/3_SHIFT in R200_SE_VTX_FMT_0)   attr 6-11 use tex 0-5 (4 << R200_VTX_TEX0/1/2/3/4/5_COMP_CNT_SHIFT in R200_SE_VTX_FMT_1)   attr 13 uses vtx1 pos (R200_VTX_XY1|R200_VTX_Z1|R200_VTX_W1 in R200_SE_VTX_FMT_0)*//* attr 4,5 and 13 are only used with generic attribs.   Haven't seen attr 14 used, maybe that's for the hw pointsize vec1 (which is   not possibe to use with vertex progs as it is lacking in vert prog specification) *//* may look different when using idx buf / input_route instead of se_vtx_fmt? */   if (mesa_vp->Base.InputsRead & VERT_BIT_POS) {      vp->inputs[VERT_ATTRIB_POS] = 0;      vp->inputmap_rev[0] = VERT_ATTRIB_POS;      free_inputs &= ~(1 << 0);      array_count++;   }   if (mesa_vp->Base.InputsRead & VERT_BIT_WEIGHT) {      vp->inputs[VERT_ATTRIB_WEIGHT] = 12;      vp->inputmap_rev[1] = VERT_ATTRIB_WEIGHT;      array_count++;   }   if (mesa_vp->Base.InputsRead & VERT_BIT_NORMAL) {      vp->inputs[VERT_ATTRIB_NORMAL] = 1;      vp->inputmap_rev[2] = VERT_ATTRIB_NORMAL;      array_count++;   }   if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR0) {      vp->inputs[VERT_ATTRIB_COLOR0] = 2;      vp->inputmap_rev[4] = VERT_ATTRIB_COLOR0;      free_inputs &= ~(1 << 2);      array_count++;   }   if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR1) {      vp->inputs[VERT_ATTRIB_COLOR1] = 3;      vp->inputmap_rev[5] = VERT_ATTRIB_COLOR1;      free_inputs &= ~(1 << 3);      array_count++;   }   if (mesa_vp->Base.InputsRead & VERT_BIT_FOG) {      vp->inputs[VERT_ATTRIB_FOG] = 15; array_count++;      vp->inputmap_rev[3] = VERT_ATTRIB_FOG;      array_count++;   }   for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX5; i++) {      if (mesa_vp->Base.InputsRead & (1 << i)) {	 vp->inputs[i] = i - VERT_ATTRIB_TEX0 + 6;	 vp->inputmap_rev[8 + i - VERT_ATTRIB_TEX0] = i;	 free_inputs &= ~(1 << (i - VERT_ATTRIB_TEX0 + 6));	 array_count++;      }   }   /* using VERT_ATTRIB_TEX6/7 would be illegal */   /* completely ignore aliasing? */   for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) {      int j;   /* completely ignore aliasing? */      if (mesa_vp->Base.InputsRead & (1 << i)) {	 array_count++;	 if (array_count > 12) {	    if (R200_DEBUG & DEBUG_FALLBACKS) {	       fprintf(stderr, "more than 12 attribs used in vert prog\n");	    }	    return GL_FALSE;	 }	 for (j = 0; j < 14; j++) {	    /* will always find one due to limited array_count */	    if (free_inputs & (1 << j)) {	       free_inputs &= ~(1 << j);	       vp->inputs[i] = j;	       if (j == 0) vp->inputmap_rev[j] = i; /* mapped to pos */	       else if (j < 12) vp->inputmap_rev[j + 2] = i; /* mapped to col/tex */	       else vp->inputmap_rev[j + 1] = i; /* mapped to pos1 */	       break;	    }	 }      }   }   if (!(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) {      if (R200_DEBUG & DEBUG_FALLBACKS) {	 fprintf(stderr, "can't handle vert prog without position output\n");      }      return GL_FALSE;   }   if (free_inputs & 1) {      if (R200_DEBUG & DEBUG_FALLBACKS) {	 fprintf(stderr, "can't handle vert prog without position input\n");      }      return GL_FALSE;   }   o_inst = vp->instr;   for (vpi = mesa_vp->Base.Instructions; vpi->Opcode != OPCODE_END; vpi++, o_inst++){      operands = op_operands(vpi->Opcode);      are_srcs_scalar = operands & SCALAR_FLAG;      operands &= OP_MASK;      for(i = 0; i < operands; i++) {	 src[i] = vpi->SrcReg[i];	 /* hack up default attrib values as per spec as swizzling.	    normal, fog, secondary color. Crazy?	    May need more if we don't submit vec4 elements? */	 if (src[i].File == PROGRAM_INPUT) {	    if (src[i].Index == VERT_ATTRIB_NORMAL) {	       int j;	       for (j = 0; j < 4; j++) {		  if (GET_SWZ(src[i].Swizzle, j) == SWIZZLE_W) {		     src[i].Swizzle &= ~(SWIZZLE_W << (j*3));		     src[i].Swizzle |= SWIZZLE_ONE << (j*3);		  }	       }	    }	    else if (src[i].Index == VERT_ATTRIB_COLOR1) {	       int j;	       for (j = 0; j < 4; j++) {		  if (GET_SWZ(src[i].Swizzle, j) == SWIZZLE_W) {		     src[i].Swizzle &= ~(SWIZZLE_W << (j*3));		     src[i].Swizzle |= SWIZZLE_ZERO << (j*3);		  }	       }	    }	    else if (src[i].Index == VERT_ATTRIB_FOG) {	       int j;	       for (j = 0; j < 4; j++) {		  if (GET_SWZ(src[i].Swizzle, j) == SWIZZLE_W) {		     src[i].Swizzle &= ~(SWIZZLE_W << (j*3));		     src[i].Swizzle |= SWIZZLE_ONE << (j*3);		  }		  else if ((GET_SWZ(src[i].Swizzle, j) == SWIZZLE_Y) ||			    GET_SWZ(src[i].Swizzle, j) == SWIZZLE_Z) {		     src[i].Swizzle &= ~(SWIZZLE_W << (j*3));		     src[i].Swizzle |= SWIZZLE_ZERO << (j*3);		  }	       }	    }	 }      }      if(operands == 3){	 if( CMP_SRCS(src[1], src[2]) || CMP_SRCS(src[0], src[2]) ){	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD,		(u_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,		VSF_FLAG_ALL);	    o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[2]),		  SWIZZLE_X, SWIZZLE_Y,		  SWIZZLE_Z, SWIZZLE_W,		  t_src_class(src[2].File), VSF_FLAG_NONE) | (src[2].RelAddr << 4);	    o_inst->src1 = ZERO_SRC_0;	    o_inst->src2 = UNUSED_SRC_1;	    o_inst++;	    src[2].File = PROGRAM_TEMPORARY;	    src[2].Index = u_temp_i;	    src[2].RelAddr = 0;	    u_temp_i--;	 }      }      if(operands >= 2){	 if( CMP_SRCS(src[1], src[0]) ){	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD,		(u_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,		VSF_FLAG_ALL);	    o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),		  SWIZZLE_X, SWIZZLE_Y,		  SWIZZLE_Z, SWIZZLE_W,		  t_src_class(src[0].File), VSF_FLAG_NONE) | (src[0].RelAddr << 4);	    o_inst->src1 = ZERO_SRC_0;	    o_inst->src2 = UNUSED_SRC_1;	    o_inst++;	    src[0].File = PROGRAM_TEMPORARY;	    src[0].Index = u_temp_i;	    src[0].RelAddr = 0;	    u_temp_i--;	 }      }      dst = vpi->DstReg;      if (dst.File == PROGRAM_OUTPUT &&	  dst.Index == VERT_RESULT_FOGC &&	  dst.WriteMask & WRITEMASK_X) {	  fog_temp_i = u_temp_i;	  dst.File = PROGRAM_TEMPORARY;	  dst.Index = fog_temp_i;	  dofogfix = 1;	  u_temp_i--;      }      /* These ops need special handling. */      switch(vpi->Opcode){      case OPCODE_POW:/* pow takes only one argument, first scalar is in slot x, 2nd in slot z (other slots don't matter).   So may need to insert additional instruction */	 if ((src[0].File == src[1].File) &&	     (src[0].Index == src[1].Index)) {	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_POW, t_dst(&dst),		   t_dst_mask(dst.WriteMask));	    o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),		   t_swizzle(GET_SWZ(src[0].Swizzle, 0)),		   SWIZZLE_ZERO,		   t_swizzle(GET_SWZ(src[1].Swizzle, 0)),		   SWIZZLE_ZERO,		   t_src_class(src[0].File),		   src[0].NegateBase) | (src[0].RelAddr << 4);	    o_inst->src1 = UNUSED_SRC_0;	    o_inst->src2 = UNUSED_SRC_0;	 }	 else {	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD,		   (u_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,		   VSF_FLAG_ALL);	    o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),		   t_swizzle(GET_SWZ(src[0].Swizzle, 0)),		   SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO,		   t_src_class(src[0].File),		   src[0].NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4);	    o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),		   SWIZZLE_ZERO, SWIZZLE_ZERO,		   t_swizzle(GET_SWZ(src[1].Swizzle, 0)), SWIZZLE_ZERO,		   t_src_class(src[1].File),		   src[1].NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4);	    o_inst->src2 = UNUSED_SRC_1;	    o_inst++;	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_POW, t_dst(&dst),		   t_dst_mask(dst.WriteMask));	    o_inst->src0 = MAKE_VSF_SOURCE(u_temp_i,		   VSF_IN_COMPONENT_X,		   VSF_IN_COMPONENT_Y,		   VSF_IN_COMPONENT_Z,		   VSF_IN_COMPONENT_W,		   VSF_IN_CLASS_TMP,		   VSF_FLAG_NONE);	    o_inst->src1 = UNUSED_SRC_0;	    o_inst->src2 = UNUSED_SRC_0;	    u_temp_i--;	 }	 goto next;      case OPCODE_MOV://ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO}       case OPCODE_SWZ:	 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, t_dst(&dst),		t_dst_mask(dst.WriteMask));	 o_inst->src0 = t_src(vp, &src[0]);	 o_inst->src1 = ZERO_SRC_0;	 o_inst->src2 = UNUSED_SRC_1;	 goto next;      case OPCODE_MAD:	 /* only 2 read ports into temp memory thus may need the macro op MAD_2	    instead (requiring 2 clocks) if all inputs are in temp memory	    (and, only if they actually reference 3 distinct temps) */	 hw_op=(src[0].File == PROGRAM_TEMPORARY &&	    src[1].File == PROGRAM_TEMPORARY &&	    src[2].File == PROGRAM_TEMPORARY &&	    (((src[0].RelAddr << 8) | src[0].Index) != ((src[1].RelAddr << 8) | src[1].Index)) &&	    (((src[0].RelAddr << 8) | src[0].Index) != ((src[2].RelAddr << 8) | src[2].Index)) &&	    (((src[1].RelAddr << 8) | src[1].Index) != ((src[2].RelAddr << 8) | src[2].Index))) ?	    R200_VPI_OUT_OP_MAD_2 : R200_VPI_OUT_OP_MAD;	 o_inst->op = MAKE_VSF_OP(hw_op, t_dst(&dst),	    t_dst_mask(dst.WriteMask));	 o_inst->src0 = t_src(vp, &src[0]);#if 0if ((o_inst - vp->instr) == 31) {/* fix up the broken vertex program of quake4 demo... */o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),			SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X,			t_src_class(src[1].File),			src[1].NegateBase) | (src[1].RelAddr << 4);o_inst->src2 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),			SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y,			t_src_class(src[1].File),			src[1].NegateBase) | (src[1].RelAddr << 4);}else {	 o_inst->src1 = t_src(vp, &src[1]);	 o_inst->src2 = t_src(vp, &src[2]);}#else	 o_inst->src1 = t_src(vp, &src[1]);	 o_inst->src2 = t_src(vp, &src[2]);#endif	 goto next;      case OPCODE_DP3://DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ZERO} PARAM 0{} {X Y Z ZERO} 	 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_DOT, t_dst(&dst),		t_dst_mask(dst.WriteMask));	 o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),		t_swizzle(GET_SWZ(src[0].Swizzle, 0)),		t_swizzle(GET_SWZ(src[0].Swizzle, 1)),		t_swizzle(GET_SWZ(src[0].Swizzle, 2)),		SWIZZLE_ZERO,		t_src_class(src[0].File),		src[0].NegateBase) | (src[0].RelAddr << 4);	 o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),		t_swizzle(GET_SWZ(src[1].Swizzle, 0)),		t_swizzle(GET_SWZ(src[1].Swizzle, 1)),		t_swizzle(GET_SWZ(src[1].Swizzle, 2)),		SWIZZLE_ZERO,		t_src_class(src[1].File),		src[1].NegateBase) | (src[1].RelAddr << 4);	 o_inst->src2 = UNUSED_SRC_1;	 goto next;      case OPCODE_DPH://DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ONE} PARAM 0{} {X Y Z W} 	 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_DOT, t_dst(&dst),		t_dst_mask(dst.WriteMask));	 o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),		t_swizzle(GET_SWZ(src[0].Swizzle, 0)),		t_swizzle(GET_SWZ(src[0].Swizzle, 1)),		t_swizzle(GET_SWZ(src[0].Swizzle, 2)),		VSF_IN_COMPONENT_ONE,		t_src_class(src[0].File),		src[0].NegateBase) | (src[0].RelAddr << 4);	 o_inst->src1 = t_src(vp, &src[1]);	 o_inst->src2 = UNUSED_SRC_1;	 goto next;      case OPCODE_SUB://ADD RESULT 1.X Y Z W TMP 0{} {X Y Z W} PARAM 1{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W	 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, t_dst(&dst),		t_dst_mask(dst.WriteMask));	 o_inst->src0 = t_src(vp, &src[0]);	 o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),		t_swizzle(GET_SWZ(src[1].Swizzle, 0)),		t_swizzle(GET_SWZ(src[1].Swizzle, 1)),		t_swizzle(GET_SWZ(src[1].Swizzle, 2)),		t_swizzle(GET_SWZ(src[1].Swizzle, 3)),		t_src_class(src[1].File),		(!src[1].NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4);	 o_inst->src2 = UNUSED_SRC_1;	 goto next;      case OPCODE_ABS://MAX RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W	 o_inst->op=MAKE_VSF_OP(R200_VPI_OUT_OP_MAX, t_dst(&dst),		t_dst_mask(dst.WriteMask));	 o_inst->src0=t_src(vp, &src[0]);	 o_inst->src1=MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),		t_swizzle(GET_SWZ(src[0].Swizzle, 0)),		t_swizzle(GET_SWZ(src[0].Swizzle, 1)),		t_swizzle(GET_SWZ(src[0].Swizzle, 2)),		t_swizzle(GET_SWZ(src[0].Swizzle, 3)),		t_src_class(src[0].File),

⌨️ 快捷键说明

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