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

📄 brw_vs_tnl.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 4 页
字号:
static void build_texture_transform( struct tnl_program *p ){   GLuint i, j;   for (i = 0; i < MAX_TEXTURE_UNITS; i++) {      if (!(p->state->fragprog_inputs_read & (FRAG_BIT_TEX0<<i)))	 continue;							           if (p->state->unit[i].texgen_enabled || 	  p->state->unit[i].texmat_enabled) {	 	 GLuint texmat_enabled = p->state->unit[i].texmat_enabled;	 struct ureg out = register_output(p, VERT_RESULT_TEX0 + i);	 struct ureg out_texgen = undef;	 if (p->state->unit[i].texgen_enabled) {	    GLuint copy_mask = 0;	    GLuint sphere_mask = 0;	    GLuint reflect_mask = 0;	    GLuint normal_mask = 0;	    GLuint modes[4];	 	    if (texmat_enabled) 	       out_texgen = get_temp(p);	    else	       out_texgen = out;	    modes[0] = p->state->unit[i].texgen_mode0;	    modes[1] = p->state->unit[i].texgen_mode1;	    modes[2] = p->state->unit[i].texgen_mode2;	    modes[3] = p->state->unit[i].texgen_mode3;	    for (j = 0; j < 4; j++) {	       switch (modes[j]) {	       case TXG_OBJ_LINEAR: {		  struct ureg obj = register_input(p, VERT_ATTRIB_POS);		  struct ureg plane = 		     register_param3(p, STATE_TEXGEN, i,				     STATE_TEXGEN_OBJECT_S + j);		  emit_op2(p, OPCODE_DP4, out_texgen, WRITEMASK_X << j, 			   obj, plane );		  break;	       }	       case TXG_EYE_LINEAR: {		  struct ureg eye = get_eye_position(p);		  struct ureg plane = 		     register_param3(p, STATE_TEXGEN, i, 				     STATE_TEXGEN_EYE_S + j);		  emit_op2(p, OPCODE_DP4, out_texgen, WRITEMASK_X << j, 			   eye, plane );		  break;	       }	       case TXG_SPHERE_MAP: 		  sphere_mask |= WRITEMASK_X << j;		  break;	       case TXG_REFLECTION_MAP:		  reflect_mask |= WRITEMASK_X << j;		  break;	       case TXG_NORMAL_MAP: 		  normal_mask |= WRITEMASK_X << j;		  break;	       case TXG_NONE:		  copy_mask |= WRITEMASK_X << j;	       }	    }	 	    if (sphere_mask) {	       build_sphere_texgen(p, out_texgen, sphere_mask);	    }	    if (reflect_mask) {	       build_reflect_texgen(p, out_texgen, reflect_mask);	    }	    if (normal_mask) {	       struct ureg normal = get_eye_normal(p);	       emit_op1(p, OPCODE_MOV, out_texgen, normal_mask, normal );	    }	    if (copy_mask) {	       struct ureg in = register_input(p, VERT_ATTRIB_TEX0+i);	       emit_op1(p, OPCODE_MOV, out_texgen, copy_mask, in );	    }	 }	 if (texmat_enabled) {	    struct ureg texmat[4];	    struct ureg in = (!is_undef(out_texgen) ? 			      out_texgen : 			      register_input(p, VERT_ATTRIB_TEX0+i));	    if (PREFER_DP4) {	       register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3,				       0, texmat );	       emit_matrix_transform_vec4( p, out, texmat, in );	    }	    else {	       register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3,				       STATE_MATRIX_TRANSPOSE, texmat );	       emit_transpose_matrix_transform_vec4( p, out, texmat, in );	    }	 }	 release_temps(p);      }       else {	 emit_passthrough(p, VERT_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i);      }   }}/* Seems like it could be tighter: */static void build_pointsize( struct tnl_program *p ){   struct ureg eye = get_eye_position(p);   struct ureg state_size = register_param1(p, STATE_POINT_SIZE);   struct ureg state_attenuation = register_param1(p, STATE_POINT_ATTENUATION);   struct ureg out = register_output(p, VERT_RESULT_PSIZ);   struct ureg ut = get_temp(p);   /* 1, Z, Z * Z, 1 */         emit_op1(p, OPCODE_MOV, ut, WRITEMASK_XW, swizzle1(get_identity_param(p), W));   emit_op1(p, OPCODE_ABS, ut, WRITEMASK_YZ, swizzle1(eye, Z));   emit_op2(p, OPCODE_MUL, ut, WRITEMASK_Z, ut, ut);   /* p1 +  p2 * dist + p3 * dist * dist, 0 */   emit_op2(p, OPCODE_DP3, ut, WRITEMASK_X, ut, state_attenuation);   /* 1 / sqrt(factor) */   emit_op1(p, OPCODE_RSQ, ut, WRITEMASK_X, ut );    /* ut = pointSize / factor */   emit_op2(p, OPCODE_MUL, ut, WRITEMASK_X, ut, state_size);    /* Clamp to min/max - state_size.[yz]    */   emit_op2(p, OPCODE_MAX, ut, WRITEMASK_X, ut, swizzle1(state_size, Y));    emit_op2(p, OPCODE_MIN, out, 0, swizzle1(ut, X), swizzle1(state_size, Z));       release_temp(p, ut);}static void build_tnl_program( struct tnl_program *p ){     /* Emit the program, starting with modelviewproject:    */   build_hpos(p);   /* Lighting calculations:    */   if (p->state->fragprog_inputs_read & (FRAG_BIT_COL0|FRAG_BIT_COL1)) {      if (p->state->light_global_enabled)	 build_lighting(p);      else {	 if (p->state->fragprog_inputs_read & FRAG_BIT_COL0)	    emit_passthrough(p, VERT_ATTRIB_COLOR0, VERT_RESULT_COL0);	 if (p->state->fragprog_inputs_read & FRAG_BIT_COL1)	    emit_passthrough(p, VERT_ATTRIB_COLOR1, VERT_RESULT_COL1);      }   }   if ((p->state->fragprog_inputs_read & FRAG_BIT_FOGC) ||       p->state->fog_option != FOG_NONE)      build_fog(p);   if (p->state->fragprog_inputs_read & FRAG_BITS_TEX_ANY)      build_texture_transform(p);   if (p->state->point_attenuated)      build_pointsize(p);   /* Finish up:    */   emit_op1(p, OPCODE_END, undef, 0, undef);   /* Disassemble:    */   if (DISASSEM) {      _mesa_printf ("\n");   }}static void build_new_tnl_program( const struct state_key *key,				   struct gl_vertex_program *program,				   GLuint max_temps){   struct tnl_program p;   _mesa_memset(&p, 0, sizeof(p));   p.state = key;   p.program = program;   p.eye_position = undef;   p.eye_position_normalized = undef;   p.eye_normal = undef;   p.identity = undef;   p.temp_in_use = 0;   p.nr_instructions = 16;      if (max_temps >= sizeof(int) * 8)      p.temp_reserved = 0;   else      p.temp_reserved = ~((1<<max_temps)-1);   p.program->Base.Instructions =       _mesa_malloc(sizeof(struct prog_instruction) * p.nr_instructions);   p.program->Base.String = 0;   p.program->Base.NumInstructions =   p.program->Base.NumTemporaries =   p.program->Base.NumParameters =   p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0;   p.program->Base.Parameters = _mesa_new_parameter_list();   p.program->Base.InputsRead = 0;   p.program->Base.OutputsWritten = 0;   build_tnl_program( &p );}static void *search_cache( struct brw_tnl_cache *cache,			   GLuint hash,			   const void *key,			   GLuint keysize){   struct brw_tnl_cache_item *c;   for (c = cache->items[hash % cache->size]; c; c = c->next) {      if (c->hash == hash && memcmp(c->key, key, keysize) == 0)	 return c->data;   }   return NULL;}static void rehash( struct brw_tnl_cache *cache ){   struct brw_tnl_cache_item **items;   struct brw_tnl_cache_item *c, *next;   GLuint size, i;   size = cache->size * 3;   items = (struct brw_tnl_cache_item**) _mesa_malloc(size * sizeof(*items));   _mesa_memset(items, 0, size * sizeof(*items));   for (i = 0; i < cache->size; i++)      for (c = cache->items[i]; c; c = next) {	 next = c->next;	 c->next = items[c->hash % size];	 items[c->hash % size] = c;      }   FREE(cache->items);   cache->items = items;   cache->size = size;}static void cache_item( struct brw_tnl_cache *cache,			GLuint hash,			const struct state_key *key,			void *data ){   struct brw_tnl_cache_item *c = MALLOC(sizeof(*c));   c->hash = hash;   c->key = malloc(sizeof(*key));   memcpy(c->key, key, sizeof(*key));   c->data = data;   if (++cache->n_items > cache->size * 1.5)      rehash(cache);   c->next = cache->items[hash % cache->size];   cache->items[hash % cache->size] = c;}static GLuint hash_key( struct state_key *key ){   GLuint *ikey = (GLuint *)key;   GLuint hash = 0, i;   /* I'm sure this can be improved on, but speed is important:    */   for (i = 0; i < sizeof(*key)/sizeof(GLuint); i++)      hash += ikey[i];   return hash;}static int prepare_tnl_program( struct brw_context *brw ){   GLcontext *ctx = &brw->intel.ctx;   struct state_key key;   GLuint hash;   struct gl_vertex_program *old = brw->tnl_program;   /* _NEW_PROGRAM */   if (brw->attribs.VertexProgram->_Current)       return 0;         /* Grab all the relevent state and put it in a single structure:    */   make_state_key(ctx, &key);   hash = hash_key(&key);   /* Look for an already-prepared program for this state:    */   brw->tnl_program = (struct gl_vertex_program *)      search_cache( &brw->tnl_program_cache, hash, &key, sizeof(key) );      /* OK, we'll have to build a new one:    */   if (!brw->tnl_program) {      brw->tnl_program = (struct gl_vertex_program *)	 ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);       build_new_tnl_program( &key, brw->tnl_program, /* 			     ctx->Const.MaxVertexProgramTemps  */			     32	 );      if (ctx->Driver.ProgramStringNotify)	 ctx->Driver.ProgramStringNotify( ctx, GL_VERTEX_PROGRAM_ARB, 					  &brw->tnl_program->Base );      cache_item( &brw->tnl_program_cache, 		  hash, &key, brw->tnl_program );   }   if (old != brw->tnl_program)      brw->state.dirty.brw |= BRW_NEW_TNL_PROGRAM;   return 0;}/* Note: See brw_draw.c - the vertex program must not rely on * brw->primitive or brw->reduced_prim. */const struct brw_tracked_state brw_tnl_vertprog = {   .dirty = {      .mesa = (_NEW_PROGRAM | 	       _NEW_LIGHT | 	       _NEW_TRANSFORM | 	       _NEW_FOG | 	       _NEW_HINT | 	       _NEW_POINT | 	       _NEW_TEXTURE |          _NEW_TEXTURE_MATRIX),      .brw = (BRW_NEW_FRAGMENT_PROGRAM | 	      BRW_NEW_INPUT_VARYING),      .cache = 0   },   .prepare = prepare_tnl_program};static int prepare_active_vertprog( struct brw_context *brw ){   const struct gl_vertex_program *prev = brw->vertex_program;   /* NEW_PROGRAM */   if (brw->attribs.VertexProgram->_Current) {      brw->vertex_program = brw->attribs.VertexProgram->_Current;   }   else {      /* BRW_NEW_TNL_PROGRAM */      brw->vertex_program = brw->tnl_program;   }   if (brw->vertex_program != prev)       brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;   return 0;}const struct brw_tracked_state brw_active_vertprog = {   .dirty = {      .mesa = _NEW_PROGRAM,      .brw = BRW_NEW_TNL_PROGRAM,      .cache = 0   },   .prepare = prepare_active_vertprog};void brw_ProgramCacheInit( GLcontext *ctx ){   struct brw_context *brw = brw_context(ctx);   brw->tnl_program_cache.size = 17;   brw->tnl_program_cache.n_items = 0;   brw->tnl_program_cache.items = (struct brw_tnl_cache_item **)      _mesa_calloc(brw->tnl_program_cache.size * 		   sizeof(struct brw_tnl_cache_item));}void brw_ProgramCacheDestroy( GLcontext *ctx ){   struct brw_context *brw = brw_context(ctx);   struct brw_tnl_cache_item *c, *next;   GLuint i;   for (i = 0; i < brw->tnl_program_cache.size; i++)      for (c = brw->tnl_program_cache.items[i]; c; c = next) {	 next = c->next;	 FREE(c->key);	 FREE(c->data);	 FREE(c);      }   FREE(brw->tnl_program_cache.items);}

⌨️ 快捷键说明

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