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

📄 brw_vs_tnl.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Mesa 3-D graphics library * Version:  6.3 * * Copyright (C) 2005  Tungsten Graphics   All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL * TUNGSTEN GRAPHICS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *//** * \file t_vp_build.c * Create a vertex program to execute the current fixed function T&L pipeline. * \author Keith Whitwell */#include "glheader.h"#include "macros.h"#include "enums.h"#include "shader/prog_parameter.h"#include "shader/prog_print.h"#include "brw_vs.h"#include "brw_state.h"struct state_key {   unsigned light_global_enabled:1;   unsigned light_local_viewer:1;   unsigned light_twoside:1;   unsigned light_color_material:1;   unsigned light_color_material_mask:12;   unsigned light_material_mask:12;   unsigned normalize:1;   unsigned rescale_normals:1;   unsigned fog_source_is_depth:1;   unsigned tnl_do_vertex_fog:1;   unsigned separate_specular:1;   unsigned fog_option:2;   unsigned point_attenuated:1;   unsigned texture_enabled_global:1;   unsigned fragprog_inputs_read:12;   struct {      unsigned light_enabled:1;      unsigned light_eyepos3_is_zero:1;      unsigned light_spotcutoff_is_180:1;      unsigned light_attenuated:1;            unsigned texunit_really_enabled:1;      unsigned texmat_enabled:1;      unsigned texgen_enabled:4;      unsigned texgen_mode0:4;      unsigned texgen_mode1:4;      unsigned texgen_mode2:4;      unsigned texgen_mode3:4;   } unit[8];};#define FOG_NONE   0#define FOG_LINEAR 1#define FOG_EXP    2#define FOG_EXP2   3static GLuint translate_fog_mode( GLenum mode ){   switch (mode) {   case GL_LINEAR: return FOG_LINEAR;   case GL_EXP: return FOG_EXP;   case GL_EXP2: return FOG_EXP2;   default: return FOG_NONE;   }}#define TXG_NONE           0#define TXG_OBJ_LINEAR     1#define TXG_EYE_LINEAR     2#define TXG_SPHERE_MAP     3#define TXG_REFLECTION_MAP 4#define TXG_NORMAL_MAP     5static GLuint translate_texgen( GLboolean enabled, GLenum mode ){   if (!enabled)      return TXG_NONE;   switch (mode) {   case GL_OBJECT_LINEAR: return TXG_OBJ_LINEAR;   case GL_EYE_LINEAR: return TXG_EYE_LINEAR;   case GL_SPHERE_MAP: return TXG_SPHERE_MAP;   case GL_REFLECTION_MAP_NV: return TXG_REFLECTION_MAP;   case GL_NORMAL_MAP_NV: return TXG_NORMAL_MAP;   default: return TXG_NONE;   }}static void make_state_key( GLcontext *ctx, struct state_key *key ){   struct brw_context *brw = brw_context(ctx);   const struct gl_fragment_program *fp = brw->fragment_program;   GLuint i;   /* This now relies on texenvprogram.c being active:    */   assert(fp);   memset(key, 0, sizeof(*key));   /* BRW_NEW_FRAGMENT_PROGRAM */   key->fragprog_inputs_read = fp->Base.InputsRead;   /* _NEW_LIGHT */   key->separate_specular = (brw->attribs.Light->Model.ColorControl ==			     GL_SEPARATE_SPECULAR_COLOR);   /* _NEW_LIGHT */   if (brw->attribs.Light->Enabled) {      key->light_global_enabled = 1;      if (brw->attribs.Light->Model.LocalViewer)	 key->light_local_viewer = 1;      if (brw->attribs.Light->Model.TwoSide)	 key->light_twoside = 1;      if (brw->attribs.Light->ColorMaterialEnabled) {	 key->light_color_material = 1;	 key->light_color_material_mask = brw->attribs.Light->ColorMaterialBitmask;      }      /* BRW_NEW_INPUT_VARYING */      /* For these programs, material values are stuffed into the       * generic slots:       */      for (i = 0 ; i < MAT_ATTRIB_MAX ; i++) 	 if (brw->vb.info.varying & (1<<(VERT_ATTRIB_GENERIC0 + i))) 	    key->light_material_mask |= 1<<i;      for (i = 0; i < MAX_LIGHTS; i++) {	 struct gl_light *light = &brw->attribs.Light->Light[i];	 if (light->Enabled) {	    key->unit[i].light_enabled = 1;	    if (light->EyePosition[3] == 0.0)	       key->unit[i].light_eyepos3_is_zero = 1;	    	    if (light->SpotCutoff == 180.0)	       key->unit[i].light_spotcutoff_is_180 = 1;	    if (light->ConstantAttenuation != 1.0 ||		light->LinearAttenuation != 0.0 ||		light->QuadraticAttenuation != 0.0)	       key->unit[i].light_attenuated = 1;	 }      }   }   /* _NEW_TRANSFORM */   if (brw->attribs.Transform->Normalize)      key->normalize = 1;   if (brw->attribs.Transform->RescaleNormals)      key->rescale_normals = 1;   /* BRW_NEW_FRAGMENT_PROGRAM */   key->fog_option = translate_fog_mode(fp->FogOption);   if (key->fog_option)      key->fragprog_inputs_read |= FRAG_BIT_FOGC;      /* _NEW_FOG */   if (brw->attribs.Fog->FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT)      key->fog_source_is_depth = 1;      /* _NEW_HINT, ??? */   if (1)      key->tnl_do_vertex_fog = 1;   /* _NEW_POINT */   if (brw->attribs.Point->_Attenuated)      key->point_attenuated = 1;   /* _NEW_TEXTURE */   if (brw->attribs.Texture->_TexGenEnabled ||       brw->attribs.Texture->_TexMatEnabled ||       brw->attribs.Texture->_EnabledUnits)      key->texture_enabled_global = 1;         for (i = 0; i < MAX_TEXTURE_UNITS; i++) {      struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[i];      if (texUnit->_ReallyEnabled) 	 key->unit[i].texunit_really_enabled = 1;      if (brw->attribs.Texture->_TexMatEnabled & ENABLE_TEXMAT(i))      	 key->unit[i].texmat_enabled = 1;            if (texUnit->TexGenEnabled) {	 key->unit[i].texgen_enabled = 1;      	 key->unit[i].texgen_mode0 = 	    translate_texgen( texUnit->TexGenEnabled & (1<<0),			      texUnit->GenModeS );	 key->unit[i].texgen_mode1 = 	    translate_texgen( texUnit->TexGenEnabled & (1<<1),			      texUnit->GenModeT );	 key->unit[i].texgen_mode2 = 	    translate_texgen( texUnit->TexGenEnabled & (1<<2),			      texUnit->GenModeR );	 key->unit[i].texgen_mode3 = 	    translate_texgen( texUnit->TexGenEnabled & (1<<3),			      texUnit->GenModeQ );      }   }}   /* Very useful debugging tool - produces annotated listing of * generated program with line/function references for each * instruction back into this file: */#define DISASSEM 0/* Should be tunable by the driver - do we want to do matrix * multiplications with DP4's or with MUL/MAD's?  SSE works better * with the latter, drivers may differ. */#define PREFER_DP4 1/* Use uregs to represent registers internally, translate to Mesa's * expected formats on emit.   * * NOTE: These are passed by value extensively in this file rather * than as usual by pointer reference.  If this disturbs you, try * remembering they are just 32bits in size. * * GCC is smart enough to deal with these dword-sized structures in * much the same way as if I had defined them as dwords and was using * macros to access and set the fields.  This is much nicer and easier * to evolve. */struct ureg {   GLuint file:4;   GLint idx:8;      /* relative addressing may be negative */   GLuint negate:1;   GLuint swz:12;   GLuint pad:7;};struct tnl_program {   const struct state_key *state;   struct gl_vertex_program *program;      GLuint nr_instructions;   GLuint temp_in_use;   GLuint temp_reserved;      struct ureg eye_position;   struct ureg eye_position_normalized;   struct ureg eye_normal;   struct ureg identity;   GLuint materials;   GLuint color_materials;};const static struct ureg undef = {    PROGRAM_UNDEFINED,   ~0,   0,   0,   0};/* Local shorthand: */#define X    SWIZZLE_X#define Y    SWIZZLE_Y#define Z    SWIZZLE_Z#define W    SWIZZLE_W/* Construct a ureg: */static struct ureg make_ureg(GLuint file, GLint idx){   struct ureg reg;   reg.file = file;   reg.idx = idx;   reg.negate = 0;   reg.swz = SWIZZLE_NOOP;   reg.pad = 0;   return reg;}static struct ureg ureg_negate( struct ureg reg ){   reg.negate ^= 1;   return reg;} static struct ureg swizzle( struct ureg reg, int x, int y, int z, int w ){   reg.swz = MAKE_SWIZZLE4(GET_SWZ(reg.swz, x),			   GET_SWZ(reg.swz, y),			   GET_SWZ(reg.swz, z),			   GET_SWZ(reg.swz, w));   return reg;}static struct ureg swizzle1( struct ureg reg, int x ){   return swizzle(reg, x, x, x, x);}static struct ureg get_temp( struct tnl_program *p ){   int bit = ffs( ~p->temp_in_use );   if (!bit) {      fprintf(stderr, "%s: out of temporaries\n", __FILE__);      assert(0);   }   if (bit > p->program->Base.NumTemporaries)      p->program->Base.NumTemporaries = bit;   p->temp_in_use |= 1<<(bit-1);   return make_ureg(PROGRAM_TEMPORARY, bit-1);}static struct ureg reserve_temp( struct tnl_program *p ){   struct ureg temp = get_temp( p );   p->temp_reserved |= 1<<temp.idx;   return temp;}static void release_temp( struct tnl_program *p, struct ureg reg ){   if (reg.file == PROGRAM_TEMPORARY) {      p->temp_in_use &= ~(1<<reg.idx);      p->temp_in_use |= p->temp_reserved; /* can't release reserved temps */   }}static void release_temps( struct tnl_program *p ){   p->temp_in_use = p->temp_reserved;}static struct ureg register_input( struct tnl_program *p, GLuint input ){   assert(input < 32);   p->program->Base.InputsRead |= (1<<input);   return make_ureg(PROGRAM_INPUT, input);}static struct ureg register_output( struct tnl_program *p, GLuint output ){   p->program->Base.OutputsWritten |= (1<<output);   return make_ureg(PROGRAM_OUTPUT, output);}static struct ureg register_const4f( struct tnl_program *p, 			      GLfloat s0,			      GLfloat s1,			      GLfloat s2,			      GLfloat s3){   GLfloat values[4];   GLint idx;   GLuint swizzle;   values[0] = s0;   values[1] = s1;   values[2] = s2;   values[3] = s3;   idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4,                                     &swizzle);   assert(swizzle == SWIZZLE_NOOP); /* Need to handle swizzle in reg setup */   return make_ureg(PROGRAM_STATE_VAR, idx);}#define register_const1f(p, s0)         register_const4f(p, s0, 0, 0, 1)#define register_scalar_const(p, s0)    register_const4f(p, s0, s0, s0, s0)#define register_const2f(p, s0, s1)     register_const4f(p, s0, s1, 0, 1)#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1)static GLboolean is_undef( struct ureg reg ){   return reg.file == PROGRAM_UNDEFINED;}static struct ureg get_identity_param( struct tnl_program *p ){   if (is_undef(p->identity))       p->identity = register_const4f(p, 0,0,0,1);   return p->identity;}

⌨️ 快捷键说明

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