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

📄 t_vp_build.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
   debug_insn(inst, fn, line);}#define emit_op3(p, op, dst, mask, src0, src1, src2) \   emit_op3fn(p, op, dst, mask, src0, src1, src2, __FUNCTION__, __LINE__)#define emit_op2(p, op, dst, mask, src0, src1) \    emit_op3fn(p, op, dst, mask, src0, src1, undef, __FUNCTION__, __LINE__)#define emit_op1(p, op, dst, mask, src0) \    emit_op3fn(p, op, dst, mask, src0, undef, undef, __FUNCTION__, __LINE__)static struct ureg make_temp( struct tnl_program *p, struct ureg reg ){   if (reg.file == PROGRAM_TEMPORARY &&        !(p->temp_reserved & (1<<reg.idx)))      return reg;   else {      struct ureg temp = get_temp(p);      emit_op1(p, OPCODE_MOV, temp, 0, reg);      return temp;   }}/* Currently no tracking performed of input/output/register size or * active elements.  Could be used to reduce these operations, as * could the matrix type. */static void emit_matrix_transform_vec4( struct tnl_program *p,					struct ureg dest,					const struct ureg *mat,					struct ureg src){   emit_op2(p, OPCODE_DP4, dest, WRITEMASK_X, src, mat[0]);   emit_op2(p, OPCODE_DP4, dest, WRITEMASK_Y, src, mat[1]);   emit_op2(p, OPCODE_DP4, dest, WRITEMASK_Z, src, mat[2]);   emit_op2(p, OPCODE_DP4, dest, WRITEMASK_W, src, mat[3]);}/* This version is much easier to implement if writemasks are not * supported natively on the target or (like SSE), the target doesn't * have a clean/obvious dotproduct implementation. */static void emit_transpose_matrix_transform_vec4( struct tnl_program *p,						  struct ureg dest,						  const struct ureg *mat,						  struct ureg src){   struct ureg tmp;   if (dest.file != PROGRAM_TEMPORARY)      tmp = get_temp(p);   else      tmp = dest;   emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]);   emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp);   emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp);   emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp);   if (dest.file != PROGRAM_TEMPORARY)      release_temp(p, tmp);}static void emit_matrix_transform_vec3( struct tnl_program *p,					struct ureg dest,					const struct ureg *mat,					struct ureg src){   emit_op2(p, OPCODE_DP3, dest, WRITEMASK_X, src, mat[0]);   emit_op2(p, OPCODE_DP3, dest, WRITEMASK_Y, src, mat[1]);   emit_op2(p, OPCODE_DP3, dest, WRITEMASK_Z, src, mat[2]);}static void emit_normalize_vec3( struct tnl_program *p,				 struct ureg dest,				 struct ureg src ){   struct ureg tmp = get_temp(p);   emit_op2(p, OPCODE_DP3, tmp, 0, src, src);   emit_op1(p, OPCODE_RSQ, tmp, 0, tmp);   emit_op2(p, OPCODE_MUL, dest, 0, src, tmp);   release_temp(p, tmp);}static void emit_passthrough( struct tnl_program *p, 			      GLuint input,			      GLuint output ){   struct ureg out = register_output(p, output);   emit_op1(p, OPCODE_MOV, out, 0, register_input(p, input)); }static struct ureg get_eye_position( struct tnl_program *p ){   if (is_undef(p->eye_position)) {      struct ureg pos = register_input( p, VERT_ATTRIB_POS );       struct ureg modelview[4];      p->eye_position = reserve_temp(p);      if (PREFER_DP4) {	 register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3,                                 0, modelview );	 emit_matrix_transform_vec4(p, p->eye_position, modelview, pos);      }      else {	 register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3,				 STATE_MATRIX_TRANSPOSE, modelview );	 emit_transpose_matrix_transform_vec4(p, p->eye_position, modelview, pos);      }   }      return p->eye_position;}static struct ureg get_eye_position_normalized( struct tnl_program *p ){   if (is_undef(p->eye_position_normalized)) {      struct ureg eye = get_eye_position(p);      p->eye_position_normalized = reserve_temp(p);      emit_normalize_vec3(p, p->eye_position_normalized, eye);   }      return p->eye_position_normalized;}static struct ureg get_eye_normal( struct tnl_program *p ){   if (is_undef(p->eye_normal)) {      struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL );      struct ureg mvinv[3];      register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 2,			      STATE_MATRIX_INVTRANS, mvinv );      p->eye_normal = reserve_temp(p);      /* Transform to eye space:       */      emit_matrix_transform_vec3( p, p->eye_normal, mvinv, normal );      /* Normalize/Rescale:       */      if (p->state->normalize) {	 emit_normalize_vec3( p, p->eye_normal, p->eye_normal );      }      else if (p->state->rescale_normals) {	 struct ureg rescale = register_param2(p, STATE_INTERNAL,					       STATE_NORMAL_SCALE);	 emit_op2( p, OPCODE_MUL, p->eye_normal, 0, p->eye_normal,		   swizzle1(rescale, X));      }   }   return p->eye_normal;}static void build_hpos( struct tnl_program *p ){   struct ureg pos = register_input( p, VERT_ATTRIB_POS );    struct ureg hpos = register_output( p, VERT_RESULT_HPOS );   struct ureg mvp[4];   if (PREFER_DP4) {      register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, 			      0, mvp );      emit_matrix_transform_vec4( p, hpos, mvp, pos );   }   else {      register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, 			      STATE_MATRIX_TRANSPOSE, mvp );      emit_transpose_matrix_transform_vec4( p, hpos, mvp, pos );   }}static GLuint material_attrib( GLuint side, GLuint property ){   return ((property - STATE_AMBIENT) * 2 + 	   side);}/* Get a bitmask of which material values vary on a per-vertex basis. */static void set_material_flags( struct tnl_program *p ){   p->color_materials = 0;   p->materials = 0;   if (p->state->light_color_material) {      p->materials = 	 p->color_materials = p->state->light_color_material_mask;   }   p->materials |= p->state->light_material_mask;}static struct ureg get_material( struct tnl_program *p, GLuint side, 				 GLuint property ){   GLuint attrib = material_attrib(side, property);   if (p->color_materials & (1<<attrib))      return register_input(p, VERT_ATTRIB_COLOR0);   else if (p->materials & (1<<attrib))       return register_input( p, attrib + _TNL_ATTRIB_MAT_FRONT_AMBIENT );   else      return register_param3( p, STATE_MATERIAL, side, property );}#define SCENE_COLOR_BITS(side) (( MAT_BIT_FRONT_EMISSION | \				   MAT_BIT_FRONT_AMBIENT | \				   MAT_BIT_FRONT_DIFFUSE) << (side))/* Either return a precalculated constant value or emit code to * calculate these values dynamically in the case where material calls * are present between begin/end pairs. * * Probably want to shift this to the program compilation phase - if * we always emitted the calculation here, a smart compiler could * detect that it was constant (given a certain set of inputs), and * lift it out of the main loop.  That way the programs created here * would be independent of the vertex_buffer details. */static struct ureg get_scenecolor( struct tnl_program *p, GLuint side ){   if (p->materials & SCENE_COLOR_BITS(side)) {      struct ureg lm_ambient = register_param1(p, STATE_LIGHTMODEL_AMBIENT);      struct ureg material_emission = get_material(p, side, STATE_EMISSION);      struct ureg material_ambient = get_material(p, side, STATE_AMBIENT);      struct ureg material_diffuse = get_material(p, side, STATE_DIFFUSE);      struct ureg tmp = make_temp(p, material_diffuse);      emit_op3(p, OPCODE_MAD, tmp,  WRITEMASK_XYZ, lm_ambient, 	       material_ambient, material_emission);      return tmp;   }   else      return register_param2( p, STATE_LIGHTMODEL_SCENECOLOR, side );}static struct ureg get_lightprod( struct tnl_program *p, GLuint light, 				  GLuint side, GLuint property ){   GLuint attrib = material_attrib(side, property);   if (p->materials & (1<<attrib)) {      struct ureg light_value = 	 register_param3(p, STATE_LIGHT, light, property);      struct ureg material_value = get_material(p, side, property);      struct ureg tmp = get_temp(p);      emit_op2(p, OPCODE_MUL, tmp,  0, light_value, material_value);      return tmp;   }   else      return register_param4(p, STATE_LIGHTPROD, light, side, property);}static struct ureg calculate_light_attenuation( struct tnl_program *p,						GLuint i, 						struct ureg VPpli,						struct ureg dist ){   struct ureg attenuation = register_param3(p, STATE_LIGHT, i,					     STATE_ATTENUATION);   struct ureg att = get_temp(p);   /* Calculate spot attenuation:    */   if (!p->state->unit[i].light_spotcutoff_is_180) {      struct ureg spot_dir_norm = register_param3(p, STATE_INTERNAL,						  STATE_SPOT_DIR_NORMALIZED, i);      struct ureg spot = get_temp(p);      struct ureg slt = get_temp(p);      emit_op2(p, OPCODE_DP3, spot, 0, negate(VPpli), spot_dir_norm);      emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir_norm,W), spot);      emit_op2(p, OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W));      emit_op2(p, OPCODE_MUL, att, 0, slt, spot);      release_temp(p, spot);      release_temp(p, slt);   }   /* Calculate distance attenuation:    */   if (p->state->unit[i].light_attenuated) {      /* 1/d,d,d,1/d */      emit_op1(p, OPCODE_RCP, dist, WRITEMASK_YZ, dist);       /* 1,d,d*d,1/d */      emit_op2(p, OPCODE_MUL, dist, WRITEMASK_XZ, dist, swizzle1(dist,Y));       /* 1/dist-atten */      emit_op2(p, OPCODE_DP3, dist, 0, attenuation, dist);       if (!p->state->unit[i].light_spotcutoff_is_180) {	 /* dist-atten */	 emit_op1(p, OPCODE_RCP, dist, 0, dist); 	 /* spot-atten * dist-atten */	 emit_op2(p, OPCODE_MUL, att, 0, dist, att);	      } else {	 /* dist-atten */	 emit_op1(p, OPCODE_RCP, att, 0, dist);       }   }   return att;}						/* Need to add some addtional parameters to allow lighting in object * space - STATE_SPOT_DIRECTION and STATE_HALF_VECTOR implicitly assume eye * space lighting. */static void build_lighting( struct tnl_program *p ){   const GLboolean twoside = p->state->light_twoside;   const GLboolean separate = p->state->separate_specular;   GLuint nr_lights = 0, count = 0;   struct ureg normal = get_eye_normal(p);   struct ureg lit = get_temp(p);   struct ureg dots = get_temp(p);   struct ureg _col0 = undef, _col1 = undef;   struct ureg _bfc0 = undef, _bfc1 = undef;   GLuint i;   for (i = 0; i < MAX_LIGHTS; i++)       if (p->state->unit[i].light_enabled)	 nr_lights++;      set_material_flags(p);   {      struct ureg shininess = get_material(p, 0, STATE_SHININESS);      emit_op1(p, OPCODE_MOV, dots,  WRITEMASK_W, swizzle1(shininess,X));      _col0 = make_temp(p, get_scenecolor(p, 0));      if (separate)	 _col1 = make_temp(p, get_identity_param(p));      else	 _col1 = _col0;   }   if (twoside) {      struct ureg shininess = get_material(p, 1, STATE_SHININESS);      emit_op1(p, OPCODE_MOV, dots, WRITEMASK_Z, 	       negate(swizzle1(shininess,X)));      _bfc0 = make_temp(p, get_scenecolor(p, 1));      if (separate)	 _bfc1 = make_temp(p, get_identity_param(p));      else	 _bfc1 = _bfc0;   }   /* If no lights, still need to emit the scenecolor.    */      {	 struct ureg res0 = register_output( p, VERT_RESULT_COL0 );	 emit_op1(p, OPCODE_MOV, res0, 0, _col0);      }      if (separate) {	 struct ureg res1 = register_output( p, VERT_RESULT_COL1 );	 emit_op1(p, OPCODE_MOV, res1, 0, _col1);      }      if (twoside) {	 struct ureg res0 = register_output( p, VERT_RESULT_BFC0 );	 emit_op1(p, OPCODE_MOV, res0, 0, _bfc0);      }            if (twoside && separate) {	 struct ureg res1 = register_output( p, VERT_RESULT_BFC1 );	 emit_op1(p, OPCODE_MOV, res1, 0, _bfc1);      }         if (nr_lights == 0) {      release_temps(p);      return;   }   for (i = 0; i < MAX_LIGHTS; i++) {      if (p->state->unit[i].light_enabled) {	 struct ureg half = undef;	 struct ureg att = undef, VPpli = undef;	  	 count++;	 if (p->state->unit[i].light_eyepos3_is_zero) {	    /* Can used precomputed constants in this case.	     * Attenuation never applies to infinite lights.	     */	    VPpli = register_param3(p, STATE_LIGHT, i, 				    STATE_POSITION_NORMALIZED);             if (p->state->light_local_viewer) {                struct ureg eye_hat = get_eye_position_normalized(p);                half = get_temp(p);                emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat);                emit_normalize_vec3(p, half, half);            } else {                half = register_param3(p, STATE_LIGHT, i, STATE_HALF_VECTOR);            }	 } 	 else {	    struct ureg Ppli = register_param3(p, STATE_LIGHT, i, 					       STATE_POSITION); 	    struct ureg V = get_eye_position(p);	    struct ureg dist = get_temp(p);	    struct ureg tmpPpli = get_temp(p);	    VPpli = get_temp(p);              /* In homogeneous object coordinates             */            emit_op1(p, OPCODE_RCP, dist, 0, swizzle1(Ppli, W));            emit_op2(p, OPCODE_MUL, tmpPpli, 0, Ppli, dist);	    /* Calculate VPpli vector	     */	    emit_op2(p, OPCODE_SUB, VPpli, 0, tmpPpli, V);             /* we're done with tmpPpli now */	    release_temp(p, tmpPpli);	    /* Normalize VPpli.  The dist value also used in	     * attenuation below.	     */	    emit_op2(p, OPCODE_DP3, dist, 0, VPpli, VPpli);	    emit_op1(p, OPCODE_RSQ, dist, 0, dist);	    emit_op2(p, OPCODE_MUL, VPpli, 0, VPpli, dist);	    /* Calculate  attenuation:	     */ 	    if (!p->state->unit[i].light_spotcutoff_is_180 ||		p->state->unit[i].light_attenuated) {	       att = calculate_light_attenuation(p, i, VPpli, dist);	    }	    	    /* We're done with dist now */	    release_temp(p, dist);	       	    /* Calculate viewer direction, or use infinite viewer:	     */	    half = get_temp(p);	    if (p->state->light_local_viewer) {	       struct ureg eye_hat = get_eye_position_normalized(p);	       emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat);	    }	    else {	       struct ureg z_dir = swizzle(get_identity_param(p),X,Y,W,Z); 	       emit_op2(p, OPCODE_ADD, half, 0, VPpli, z_dir);	    }	    emit_normalize_vec3(p, half, half);	 }	 /* Calculate dot products:	  */	 emit_op2(p, OPCODE_DP3, dots, WRITEMASK_X, normal, VPpli);	 emit_op2(p, OPCODE_DP3, dots, WRITEMASK_Y, normal, half);	 /* we're done with VPpli and half now, so free them as to not drive up	    our temp usage unnecessary */	 release_temp(p, VPpli);	 release_temp(p, half);		 /* Front face lighting:	  */	 {	    struct ureg ambient = get_lightprod(p, i, 0, STATE_AMBIENT);	    struct ureg diffuse = get_lightprod(p, i, 0, STATE_DIFFUSE);	    struct ureg specular = get_lightprod(p, i, 0, STATE_SPECULAR);	    struct ureg res0, res1;	    GLuint mask0, mask1;	    emit_op1(p, OPCODE_LIT, lit, 0, dots);   	    if (!is_undef(att)) 	       emit_op2(p, OPCODE_MUL, lit, 0, lit, att);   	    	    if (count == nr_lights) {	       if (separate) {		  mask0 = WRITEMASK_XYZ;		  mask1 = WRITEMASK_XYZ;		  res0 = register_output( p, VERT_RESULT_COL0 );		  res1 = register_output( p, VERT_RESULT_COL1 );	       }	       else {		  mask0 = 0;		  mask1 = WRITEMASK_XYZ;		  res0 = _col0;		  res1 = register_output( p, VERT_RESULT_COL0 );	       }	    } else {	       mask0 = 0;	       mask1 = 0;	       res0 = _col0;	       res1 = _col1;	    }	    emit_op3(p, OPCODE_MAD, _col0, 0, swizzle1(lit,X), ambient, _col0);	    emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _col0);	    emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _col1);      	    release_temp(p, ambient);	    release_temp(p, diffuse);	    release_temp(p, specular);	 }	 /* Back face lighting:	  */	 if (twoside) {	    struct ureg ambient = get_lightprod(p, i, 1, STATE_AMBIENT);	    struct ureg diffuse = get_lightprod(p, i, 1, STATE_DIFFUSE);	    struct ureg specular = get_lightprod(p, i, 1, STATE_SPECULAR);	    struct ureg res0, res1;	    GLuint mask0, mask1;	       

⌨️ 快捷键说明

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