t_vp_build.c revision 6dd98e9853a6984150aa47467112e016c40a4ab4
1f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* 2f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Mesa 3-D graphics library 36dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul * Version: 7.1 4f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 56dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul * Copyright (C) 2007 Tungsten Graphics All Rights Reserved. 6f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 7f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 8f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * copy of this software and associated documentation files (the "Software"), 9f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * to deal in the Software without restriction, including without limitation 10f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the 12f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Software is furnished to do so, subject to the following conditions: 13f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 14f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * The above copyright notice and this permission notice shall be included 15f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * in all copies or substantial portions of the Software. 16f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 17f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 205f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * TUNGSTEN GRAPHICS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 215f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * WHETHER IN 22f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 25f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 26f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/** 27f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * \file t_vp_build.c 28f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Create a vertex program to execute the current fixed function T&L pipeline. 29f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * \author Keith Whitwell 30f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 31f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 32f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 33f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "glheader.h" 34f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "macros.h" 35f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "enums.h" 36c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian Paul#include "shader/program.h" 37c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian Paul#include "shader/prog_instruction.h" 38c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian Paul#include "shader/prog_parameter.h" 39c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian Paul#include "shader/prog_print.h" 40c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian Paul#include "shader/prog_statevars.h" 410c6723aee564a7b320ca122c3c9b003c863cc714Brian Paul#include "t_context.h" /* NOTE: very light dependency on this */ 42f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#include "t_vp_build.h" 43f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 44f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 45a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstruct state_key { 46a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_global_enabled:1; 47a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_local_viewer:1; 48a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_twoside:1; 49a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_color_material:1; 50a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_color_material_mask:12; 51a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_material_mask:12; 52a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 53a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned normalize:1; 54a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned rescale_normals:1; 55a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned fog_source_is_depth:1; 56a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned tnl_do_vertex_fog:1; 57a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned separate_specular:1; 58a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned fog_mode:2; 59a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned point_attenuated:1; 601c48986e540f573c63b98470f52338dba6353ceaKeith Whitwell unsigned texture_enabled_global:1; 61c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell unsigned fragprog_inputs_read:12; 62a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 63a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct { 64a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_enabled:1; 65a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_eyepos3_is_zero:1; 66a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_spotcutoff_is_180:1; 67a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned light_attenuated:1; 68a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texunit_really_enabled:1; 69a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texmat_enabled:1; 70a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texgen_enabled:4; 71a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texgen_mode0:4; 72a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texgen_mode1:4; 73a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texgen_mode2:4; 74a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell unsigned texgen_mode3:4; 75a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } unit[8]; 76a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell}; 77a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 78a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 79a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 80c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell#define FOG_NONE 0 81c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell#define FOG_LINEAR 1 82c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell#define FOG_EXP 2 83c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell#define FOG_EXP2 3 84a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 85a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic GLuint translate_fog_mode( GLenum mode ) 86a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 87a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell switch (mode) { 88a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_LINEAR: return FOG_LINEAR; 89a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_EXP: return FOG_EXP; 90a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_EXP2: return FOG_EXP2; 91c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell default: return FOG_NONE; 92a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 93a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 94a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 95a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_NONE 0 96a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_OBJ_LINEAR 1 97a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_EYE_LINEAR 2 98a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_SPHERE_MAP 3 99a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_REFLECTION_MAP 4 100a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define TXG_NORMAL_MAP 5 101a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 102a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic GLuint translate_texgen( GLboolean enabled, GLenum mode ) 103a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 104a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (!enabled) 105a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return TXG_NONE; 106a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 107a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell switch (mode) { 108a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_OBJECT_LINEAR: return TXG_OBJ_LINEAR; 109a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_EYE_LINEAR: return TXG_EYE_LINEAR; 110a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_SPHERE_MAP: return TXG_SPHERE_MAP; 111a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_REFLECTION_MAP_NV: return TXG_REFLECTION_MAP; 112a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case GL_NORMAL_MAP_NV: return TXG_NORMAL_MAP; 113a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell default: return TXG_NONE; 114a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 115a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 116a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 117a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic struct state_key *make_state_key( GLcontext *ctx ) 118a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 119a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell TNLcontext *tnl = TNL_CONTEXT(ctx); 120a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct vertex_buffer *VB = &tnl->vb; 121122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; 122a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct state_key *key = CALLOC_STRUCT(state_key); 123a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint i; 124a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 125c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* This now relies on texenvprogram.c being active: 126c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell */ 127c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell assert(fp); 128c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 129de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul key->fragprog_inputs_read = fp->Base.InputsRead; 130c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 131a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->separate_specular = (ctx->Light.Model.ColorControl == 132a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GL_SEPARATE_SPECULAR_COLOR); 133a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 134a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Light.Enabled) { 135a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->light_global_enabled = 1; 136a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 137a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Light.Model.LocalViewer) 138a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->light_local_viewer = 1; 139a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 140a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Light.Model.TwoSide) 141a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->light_twoside = 1; 142a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 143f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell if (ctx->Light.ColorMaterialEnabled) { 144a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->light_color_material = 1; 145f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell key->light_color_material_mask = ctx->Light.ColorMaterialBitmask; 146f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell } 147a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 14894b30dc390f1fdd526c080080830016fad3e2ee2Brian Paul for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) 149a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (VB->AttribPtr[i]->stride) 150f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell key->light_material_mask |= 1<<(i-_TNL_ATTRIB_MAT_FRONT_AMBIENT); 151a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 152a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (i = 0; i < MAX_LIGHTS; i++) { 153a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct gl_light *light = &ctx->Light.Light[i]; 154a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 155a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (light->Enabled) { 156a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].light_enabled = 1; 157a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 158a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (light->EyePosition[3] == 0.0) 159a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].light_eyepos3_is_zero = 1; 160a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 161a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (light->SpotCutoff == 180.0) 162a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].light_spotcutoff_is_180 = 1; 163a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 164a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (light->ConstantAttenuation != 1.0 || 165729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell light->LinearAttenuation != 0.0 || 166729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell light->QuadraticAttenuation != 0.0) 167a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].light_attenuated = 1; 168a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 169a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 170a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 171a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 172a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Transform.Normalize) 173a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->normalize = 1; 174f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 175a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Transform.RescaleNormals) 176a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->rescale_normals = 1; 177a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 178c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell key->fog_mode = translate_fog_mode(fp->FogOption); 179c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 180c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) 181c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell key->fog_source_is_depth = 1; 182c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 183c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (tnl->_DoVertexFog) 184c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell key->tnl_do_vertex_fog = 1; 185a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 186a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Point._Attenuated) 187a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->point_attenuated = 1; 188a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1891c48986e540f573c63b98470f52338dba6353ceaKeith Whitwell if (ctx->Texture._TexGenEnabled || 1901c48986e540f573c63b98470f52338dba6353ceaKeith Whitwell ctx->Texture._TexMatEnabled || 1911c48986e540f573c63b98470f52338dba6353ceaKeith Whitwell ctx->Texture._EnabledUnits) 1921c48986e540f573c63b98470f52338dba6353ceaKeith Whitwell key->texture_enabled_global = 1; 1931c48986e540f573c63b98470f52338dba6353ceaKeith Whitwell 194a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (i = 0; i < MAX_TEXTURE_UNITS; i++) { 195a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; 196a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 197a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (texUnit->_ReallyEnabled) 198a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texunit_really_enabled = 1; 199a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 200a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i)) 201a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texmat_enabled = 1; 202a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 203a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (texUnit->TexGenEnabled) { 204a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texgen_enabled = 1; 205a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 206a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texgen_mode0 = 207a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell translate_texgen( texUnit->TexGenEnabled & (1<<0), 208a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell texUnit->GenModeS ); 209a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texgen_mode1 = 210a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell translate_texgen( texUnit->TexGenEnabled & (1<<1), 211a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell texUnit->GenModeT ); 212a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texgen_mode2 = 213a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell translate_texgen( texUnit->TexGenEnabled & (1<<2), 214a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell texUnit->GenModeR ); 215a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell key->unit[i].texgen_mode3 = 216a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell translate_texgen( texUnit->TexGenEnabled & (1<<3), 217a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell texUnit->GenModeQ ); 218a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 219a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 220a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 221a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return key; 222a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 223a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 224a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 225a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 226f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Very useful debugging tool - produces annotated listing of 227f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * generated program with line/function references for each 228f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * instruction back into this file: 229f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 230729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell#define DISASSEM (MESA_VERBOSE&VERBOSE_DISASSEM) 23110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 23210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell/* Should be tunable by the driver - do we want to do matrix 23310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell * multiplications with DP4's or with MUL/MAD's? SSE works better 23410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell * with the latter, drivers may differ. 23510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell */ 236a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell#define PREFER_DP4 0 237f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 238821b3dd562c0ec4560e50f29084c32653cf18c9dAapo Tahkola#define MAX_INSN 256 2392fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell 240f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Use uregs to represent registers internally, translate to Mesa's 241f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * expected formats on emit. 242f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 243f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * NOTE: These are passed by value extensively in this file rather 244f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * than as usual by pointer reference. If this disturbs you, try 245f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * remembering they are just 32bits in size. 246f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 247f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * GCC is smart enough to deal with these dword-sized structures in 248f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * much the same way as if I had defined them as dwords and was using 249f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * macros to access and set the fields. This is much nicer and easier 250f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * to evolve. 251f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 252f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstruct ureg { 253f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint file:4; 25461e694f270d8a4a03a3245b5e6eea805915ed74bBrian Paul GLint idx:8; /* relative addressing may be negative */ 255f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint negate:1; 256f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint swz:12; 257f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint pad:7; 258f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}; 259f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 260f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 261f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstruct tnl_program { 262a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell const struct state_key *state; 263122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_vertex_program *program; 264f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 2653509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell GLuint temp_in_use; 266f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint temp_reserved; 267f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 268f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_position; 269f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_position_normalized; 270f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_normal; 271f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg identity; 272f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 273f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint materials; 274f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint color_materials; 275f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}; 276f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 277f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 278564b2aa2ef8d5b859bb51d39024373a4865e93e9Brian Paulstatic const struct ureg undef = { 279a89b099c74c0129c975d3f7ba1cdccc6a8d6b6beAlan Hourihane PROGRAM_UNDEFINED, 280f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell ~0, 281f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 0, 282f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 0, 283f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 0 284f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell}; 285f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 286f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Local shorthand: 287f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 288f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define X SWIZZLE_X 289f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define Y SWIZZLE_Y 290f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define Z SWIZZLE_Z 291f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define W SWIZZLE_W 292f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 293f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 294f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Construct a ureg: 295f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 29660a6a0eb51a6cafc9f65bff8028510e0788cf311Brian Paulstatic struct ureg make_ureg(GLuint file, GLint idx) 297f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 298f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg reg; 299f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.file = file; 300f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.idx = idx; 301f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.negate = 0; 302f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.swz = SWIZZLE_NOOP; 303f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.pad = 0; 304f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg; 305f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 306f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 307f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 308f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 309f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg negate( struct ureg reg ) 310f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 311f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.negate ^= 1; 312f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg; 313f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 314f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 315f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 316f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg swizzle( struct ureg reg, int x, int y, int z, int w ) 317f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 318f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell reg.swz = MAKE_SWIZZLE4(GET_SWZ(reg.swz, x), 319f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GET_SWZ(reg.swz, y), 320f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GET_SWZ(reg.swz, z), 321f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GET_SWZ(reg.swz, w)); 322f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 323f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg; 324f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 325f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 326f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg swizzle1( struct ureg reg, int x ) 327f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 328f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return swizzle(reg, x, x, x, x); 329f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 330f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 331f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_temp( struct tnl_program *p ) 332f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 333b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul int bit = _mesa_ffs( ~p->temp_in_use ); 334f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (!bit) { 335b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__); 336b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul _mesa_exit(1); 337f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 338f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 339564b2aa2ef8d5b859bb51d39024373a4865e93e9Brian Paul if ((GLuint) bit > p->program->Base.NumTemporaries) 340c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell p->program->Base.NumTemporaries = bit; 341c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 3423509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p->temp_in_use |= 1<<(bit-1); 343f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_TEMPORARY, bit-1); 344f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 345f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 346f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg reserve_temp( struct tnl_program *p ) 347f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 348f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg temp = get_temp( p ); 349f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->temp_reserved |= 1<<temp.idx; 350f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return temp; 351f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 352f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 353f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void release_temp( struct tnl_program *p, struct ureg reg ) 354f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 355f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (reg.file == PROGRAM_TEMPORARY) { 3563509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p->temp_in_use &= ~(1<<reg.idx); 3573509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p->temp_in_use |= p->temp_reserved; /* can't release reserved temps */ 358f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 359f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 360f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 361f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void release_temps( struct tnl_program *p ) 362f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 3633509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p->temp_in_use = p->temp_reserved; 364f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 365f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 366f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 367f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 368f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_input( struct tnl_program *p, GLuint input ) 369f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 370de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p->program->Base.InputsRead |= (1<<input); 371f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_INPUT, input); 372f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 373f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 374f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_output( struct tnl_program *p, GLuint output ) 375f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 376de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p->program->Base.OutputsWritten |= (1<<output); 377f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_OUTPUT, output); 378f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 379f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 380f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg register_const4f( struct tnl_program *p, 381f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat s0, 382f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat s1, 383f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat s2, 384f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat s3) 385f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 386f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLfloat values[4]; 38760a6a0eb51a6cafc9f65bff8028510e0788cf311Brian Paul GLint idx; 388a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul GLuint swizzle; 389f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell values[0] = s0; 390f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell values[1] = s1; 391f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell values[2] = s2; 392f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell values[3] = s3; 393a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4, 394a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul &swizzle ); 395a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul ASSERT(swizzle == SWIZZLE_NOOP); 396f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_STATE_VAR, idx); 397f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 398f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 399f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_const1f(p, s0) register_const4f(p, s0, 0, 0, 1) 40096582f4f28851f55f6726d1bba8a7f2616c327a4Keith Whitwell#define register_scalar_const(p, s0) register_const4f(p, s0, s0, s0, s0) 401f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_const2f(p, s0, s1) register_const4f(p, s0, s1, 0, 1) 402f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1) 403f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 404f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic GLboolean is_undef( struct ureg reg ) 405f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 406a89b099c74c0129c975d3f7ba1cdccc6a8d6b6beAlan Hourihane return reg.file == PROGRAM_UNDEFINED; 407f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 408f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 409f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_identity_param( struct tnl_program *p ) 410f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 411f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (is_undef(p->identity)) 412f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->identity = register_const4f(p, 0,0,0,1); 413f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 414f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return p->identity; 415f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 416f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 417fce8409cbbe6aa5309163f3d63894233b8833308Brian Paulstatic struct ureg register_param5(struct tnl_program *p, 418f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s0, 419f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s1, 420f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s2, 421f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLint s3, 422fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul GLint s4) 423f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 424fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul gl_state_index tokens[STATE_LENGTH]; 42560a6a0eb51a6cafc9f65bff8028510e0788cf311Brian Paul GLint idx; 426f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[0] = s0; 427f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[1] = s1; 428f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[2] = s2; 429f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[3] = s3; 430f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell tokens[4] = s4; 431de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens ); 432f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return make_ureg(PROGRAM_STATE_VAR, idx); 433f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 434f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 435f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 436fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul#define register_param1(p,s0) register_param5(p,s0,0,0,0,0) 437fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul#define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0) 438fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul#define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0) 439fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul#define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0) 440f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 441f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 442fce8409cbbe6aa5309163f3d63894233b8833308Brian Paulstatic void register_matrix_param5( struct tnl_program *p, 443fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul GLint s0, /* modelview, projection, etc */ 444fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul GLint s1, /* texture matrix number */ 445fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul GLint s2, /* first row */ 446fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul GLint s3, /* last row */ 447fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul GLint s4, /* inverse, transpose, etc */ 448f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg *matrix ) 449f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 450564b2aa2ef8d5b859bb51d39024373a4865e93e9Brian Paul GLint i; 451f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 452f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* This is a bit sad as the support is there to pull the whole 453f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * matrix out in one go: 454f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 455fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul for (i = 0; i <= s3 - s2; i++) 456fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul matrix[i] = register_param5( p, s0, s1, i, i, s4 ); 457f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 458f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 459f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 4606dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul/** 4616dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul * Convert a ureg source register to a prog_src_register. 4626dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul */ 4637e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic void emit_arg( struct prog_src_register *src, 464f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg reg ) 465f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 4666dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul assert(reg.file != PROGRAM_OUTPUT); 467f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->File = reg.file; 468f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->Index = reg.idx; 469f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->Swizzle = reg.swz; 47016d1024f27695bd9ceb86ffcdda960396a23ed2cAapo Tahkola src->NegateBase = reg.negate ? NEGATE_XYZW : 0; 4717e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul src->Abs = 0; 4727e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul src->NegateAbs = 0; 473f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell src->RelAddr = 0; 474f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 475f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 4766dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul/** 4776dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul * Convert a ureg dest register to a prog_dst_register. 4786dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul */ 4797e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic void emit_dst( struct prog_dst_register *dst, 480f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg reg, GLuint mask ) 481f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 4826dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul /* Check for legal output register type. UNDEFINED will occur in 4836dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul * instruction that don't produce a result (like END). 4846dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul */ 4856dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul assert(reg.file == PROGRAM_TEMPORARY || 4866dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul reg.file == PROGRAM_OUTPUT || 4876dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul reg.file == PROGRAM_UNDEFINED); 488f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell dst->File = reg.file; 489f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell dst->Index = reg.idx; 4905f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* allow zero as a shorthand for xyzw */ 4915f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell dst->WriteMask = mask ? mask : WRITEMASK_XYZW; 4927e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul dst->CondMask = COND_TR; 4937e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul dst->CondSwizzle = 0; 4947e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul dst->CondSrc = 0; 495f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell dst->pad = 0; 496f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 497f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 4987e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic void debug_insn( struct prog_instruction *inst, const char *fn, 4995f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint line ) 500f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 501729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell if (DISASSEM) { 502729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell static const char *last_fn; 503f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 504729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell if (fn != last_fn) { 505729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell last_fn = fn; 506729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell _mesa_printf("%s:\n", fn); 507729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell } 508f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 509729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell _mesa_printf("%d:\t", line); 510de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul _mesa_print_instruction(inst); 511729cccba5d20e3b34e7168ffff7515f52c72c26eKeith Whitwell } 512f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 513f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 514f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 515f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_op3fn(struct tnl_program *p, 516f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint op, 517f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dest, 518f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint mask, 519f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src0, 520f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src1, 521f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src2, 522f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell const char *fn, 523f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint line) 524f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 525f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint nr = p->program->Base.NumInstructions++; 526de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul struct prog_instruction *inst = &p->program->Base.Instructions[nr]; 527f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 5282fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell if (p->program->Base.NumInstructions > MAX_INSN) { 529a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell _mesa_problem(0, "Out of instructions in emit_op3fn\n"); 5302fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell return; 5312fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell } 5322fcaf7a529f1e8bbdfbea6c8d9d6703adf5f17baKeith Whitwell 5339580179dfb42d5b81ff6ec9704b82a556c7f1229Brian Paul inst->Opcode = (enum prog_opcode) op; 534dbeea25bb834479a29712100888c862348112018Keith Whitwell inst->StringPos = 0; 535dbeea25bb834479a29712100888c862348112018Keith Whitwell inst->Data = 0; 536f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 537f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_arg( &inst->SrcReg[0], src0 ); 538f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_arg( &inst->SrcReg[1], src1 ); 539f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_arg( &inst->SrcReg[2], src2 ); 540f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 541f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_dst( &inst->DstReg, dest, mask ); 542f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 543f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell debug_insn(inst, fn, line); 544f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 545f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 546f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 5475f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell#define emit_op3(p, op, dst, mask, src0, src1, src2) \ 5485f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op3fn(p, op, dst, mask, src0, src1, src2, __FUNCTION__, __LINE__) 5495f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 5505f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell#define emit_op2(p, op, dst, mask, src0, src1) \ 5515f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op3fn(p, op, dst, mask, src0, src1, undef, __FUNCTION__, __LINE__) 5525f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 5535f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell#define emit_op1(p, op, dst, mask, src0) \ 5545f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell emit_op3fn(p, op, dst, mask, src0, undef, undef, __FUNCTION__, __LINE__) 555f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 556f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 557f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg make_temp( struct tnl_program *p, struct ureg reg ) 558f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 559f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (reg.file == PROGRAM_TEMPORARY && 560f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell !(p->temp_reserved & (1<<reg.idx))) 561f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return reg; 562f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 563f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg temp = get_temp(p); 5647e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, temp, 0, reg); 565f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return temp; 566f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 567f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 568f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 569f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 570f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Currently no tracking performed of input/output/register size or 571f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * active elements. Could be used to reduce these operations, as 572f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * could the matrix type. 573f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 574f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_matrix_transform_vec4( struct tnl_program *p, 575f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dest, 576f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell const struct ureg *mat, 577f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src) 578f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 5797e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP4, dest, WRITEMASK_X, src, mat[0]); 5807e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP4, dest, WRITEMASK_Y, src, mat[1]); 5817e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP4, dest, WRITEMASK_Z, src, mat[2]); 5827e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP4, dest, WRITEMASK_W, src, mat[3]); 5835f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell} 5845f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 58547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell/* This version is much easier to implement if writemasks are not 58647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell * supported natively on the target or (like SSE), the target doesn't 58747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell * have a clean/obvious dotproduct implementation. 58847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell */ 5895f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic void emit_transpose_matrix_transform_vec4( struct tnl_program *p, 5905f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dest, 5915f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell const struct ureg *mat, 5925f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg src) 5935f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{ 5945f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg tmp; 5955f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 5965f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell if (dest.file != PROGRAM_TEMPORARY) 5975f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell tmp = get_temp(p); 5985f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell else 5995f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell tmp = dest; 600f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 6017e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]); 6027e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp); 6037e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp); 6047e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp); 6055f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 6065f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell if (dest.file != PROGRAM_TEMPORARY) 6075f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, tmp); 608f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 609f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 610f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_matrix_transform_vec3( struct tnl_program *p, 611f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dest, 612f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell const struct ureg *mat, 613f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src) 614f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 6157e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, dest, WRITEMASK_X, src, mat[0]); 6167e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, dest, WRITEMASK_Y, src, mat[1]); 6177e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, dest, WRITEMASK_Z, src, mat[2]); 618f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 619f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 620f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 621f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void emit_normalize_vec3( struct tnl_program *p, 622f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dest, 623f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg src ) 624f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 625f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = get_temp(p); 6267e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, tmp, 0, src, src); 6277e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_RSQ, tmp, 0, tmp); 6287e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, dest, 0, src, tmp); 629f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, tmp); 630f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 631f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 63210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwellstatic void emit_passthrough( struct tnl_program *p, 63310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell GLuint input, 63410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell GLuint output ) 63510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell{ 63610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg out = register_output(p, output); 6377e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, out, 0, register_input(p, input)); 63810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell} 63910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 640f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_eye_position( struct tnl_program *p ) 641f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 642f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (is_undef(p->eye_position)) { 643f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg pos = register_input( p, VERT_ATTRIB_POS ); 644f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg modelview[4]; 645f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 646f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->eye_position = reserve_temp(p); 647f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 64810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (PREFER_DP4) { 649fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, 650fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul 0, modelview ); 65110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 65210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_matrix_transform_vec4(p, p->eye_position, modelview, pos); 65310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 65410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell else { 655fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, 65610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell STATE_MATRIX_TRANSPOSE, modelview ); 65710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 65810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_transpose_matrix_transform_vec4(p, p->eye_position, modelview, pos); 65910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 660f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 661f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 662f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return p->eye_position; 663f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 664f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 665f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 666f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_eye_position_normalized( struct tnl_program *p ) 667f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 668f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (is_undef(p->eye_position_normalized)) { 669f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye = get_eye_position(p); 670f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->eye_position_normalized = reserve_temp(p); 671f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_normalize_vec3(p, p->eye_position_normalized, eye); 672f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 673f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 674f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return p->eye_position_normalized; 675f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 676f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 677f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 678f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_eye_normal( struct tnl_program *p ) 679f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 680f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (is_undef(p->eye_normal)) { 681f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL ); 682f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg mvinv[3]; 683f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 684fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 2, 6855f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_MATRIX_INVTRANS, mvinv ); 686f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 687f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->eye_normal = reserve_temp(p); 688f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 689f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Transform to eye space: 690f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 691f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_matrix_transform_vec3( p, p->eye_normal, mvinv, normal ); 692f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 693f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Normalize/Rescale: 694f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 695a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->normalize) { 696f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_normalize_vec3( p, p->eye_normal, p->eye_normal ); 697f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 698a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell else if (p->state->rescale_normals) { 6995f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg rescale = register_param2(p, STATE_INTERNAL, 7005f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_NORMAL_SCALE); 7015f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 7027e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2( p, OPCODE_MUL, p->eye_normal, 0, normal, 7035f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell swizzle1(rescale, X)); 704f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 705f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 706f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 707f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return p->eye_normal; 708f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 709f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 710f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 711f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 712f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_hpos( struct tnl_program *p ) 713f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 714f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg pos = register_input( p, VERT_ATTRIB_POS ); 715f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg hpos = register_output( p, VERT_RESULT_HPOS ); 716f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg mvp[4]; 717f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 71810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (PREFER_DP4) { 719fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, 720fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul 0, mvp ); 72110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_matrix_transform_vec4( p, hpos, mvp, pos ); 72210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 72310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell else { 724fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, 72510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell STATE_MATRIX_TRANSPOSE, mvp ); 72610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_transpose_matrix_transform_vec4( p, hpos, mvp, pos ); 72710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 728f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 729f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 730f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 731f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic GLuint material_attrib( GLuint side, GLuint property ) 732f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 733f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell return ((property - STATE_AMBIENT) * 2 + 7345f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell side); 735f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 736f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 737c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell/* Get a bitmask of which material values vary on a per-vertex basis. 738c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell */ 739f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void set_material_flags( struct tnl_program *p ) 740f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 741f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->color_materials = 0; 742f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->materials = 0; 743f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 744a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->light_color_material) { 745f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p->materials = 746a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p->color_materials = p->state->light_color_material_mask; 747f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 748f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 749a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p->materials |= p->state->light_material_mask; 750f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 751f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 752f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 7535f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic struct ureg get_material( struct tnl_program *p, GLuint side, 7545f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint property ) 755f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 756f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint attrib = material_attrib(side, property); 757f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 758f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (p->color_materials & (1<<attrib)) 759f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_input(p, VERT_ATTRIB_COLOR0); 760f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else if (p->materials & (1<<attrib)) 761f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell return register_input( p, attrib + _TNL_ATTRIB_MAT_FRONT_AMBIENT ); 762f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 763f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_param3( p, STATE_MATERIAL, side, property ); 764f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 765f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 766f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell#define SCENE_COLOR_BITS(side) (( MAT_BIT_FRONT_EMISSION | \ 767f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell MAT_BIT_FRONT_AMBIENT | \ 768f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell MAT_BIT_FRONT_DIFFUSE) << (side)) 769f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 770f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Either return a precalculated constant value or emit code to 771f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * calculate these values dynamically in the case where material calls 772f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * are present between begin/end pairs. 773f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 774f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * Probably want to shift this to the program compilation phase - if 775f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * we always emitted the calculation here, a smart compiler could 776f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * detect that it was constant (given a certain set of inputs), and 777f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * lift it out of the main loop. That way the programs created here 778f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * would be independent of the vertex_buffer details. 779f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 780f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic struct ureg get_scenecolor( struct tnl_program *p, GLuint side ) 781f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 782f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (p->materials & SCENE_COLOR_BITS(side)) { 7835f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg lm_ambient = register_param1(p, STATE_LIGHTMODEL_AMBIENT); 784f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg material_emission = get_material(p, side, STATE_EMISSION); 785f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg material_ambient = get_material(p, side, STATE_AMBIENT); 786f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg material_diffuse = get_material(p, side, STATE_DIFFUSE); 787f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = make_temp(p, material_diffuse); 7887e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, tmp, WRITEMASK_XYZ, lm_ambient, 7895f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell material_ambient, material_emission); 790f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return tmp; 791f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 792f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 793f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_param2( p, STATE_LIGHTMODEL_SCENECOLOR, side ); 794f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 795f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 796f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 7975f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic struct ureg get_lightprod( struct tnl_program *p, GLuint light, 7985f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint side, GLuint property ) 799f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 800f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint attrib = material_attrib(side, property); 801f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (p->materials & (1<<attrib)) { 8025f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg light_value = 8035f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell register_param3(p, STATE_LIGHT, light, property); 804f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg material_value = get_material(p, side, property); 805f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = get_temp(p); 8067e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, tmp, 0, light_value, material_value); 807f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return tmp; 808f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 809f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 810f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell return register_param4(p, STATE_LIGHTPROD, light, side, property); 811f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 812f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 8135f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic struct ureg calculate_light_attenuation( struct tnl_program *p, 8145f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint i, 8155f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg VPpli, 8165f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dist ) 8175f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{ 8185f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg attenuation = register_param3(p, STATE_LIGHT, i, 8195f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_ATTENUATION); 8205f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg att = get_temp(p); 8215f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8225f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* Calculate spot attenuation: 8235f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell */ 824a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (!p->state->unit[i].light_spotcutoff_is_180) { 82554dac2c84310536cce962101de29546d3eb80175Roland Scheidegger struct ureg spot_dir_norm = register_param3(p, STATE_INTERNAL, 82654dac2c84310536cce962101de29546d3eb80175Roland Scheidegger STATE_SPOT_DIR_NORMALIZED, i); 8275f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg spot = get_temp(p); 8285f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg slt = get_temp(p); 82954dac2c84310536cce962101de29546d3eb80175Roland Scheidegger 83054dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op2(p, OPCODE_DP3, spot, 0, negate(VPpli), spot_dir_norm); 83154dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir_norm,W), spot); 8327e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W)); 8337e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, att, 0, slt, spot); 8345f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8355f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, spot); 8365f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, slt); 8375f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell } 8385f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8395f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* Calculate distance attenuation: 8405f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell */ 841a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].light_attenuated) { 8425f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8435f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 1/d,d,d,1/d */ 8447e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_RCP, dist, WRITEMASK_YZ, dist); 8455f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 1,d,d*d,1/d */ 8467e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, dist, WRITEMASK_XZ, dist, swizzle1(dist,Y)); 8475f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 1/dist-atten */ 8487e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, dist, 0, attenuation, dist); 8495f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 850a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (!p->state->unit[i].light_spotcutoff_is_180) { 8515f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* dist-atten */ 8527e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_RCP, dist, 0, dist); 8535f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* spot-atten * dist-atten */ 8547e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, att, 0, dist, att); 8555f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell } else { 8565f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* dist-atten */ 8577e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_RCP, att, 0, dist); 8585f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell } 8595f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell } 8605f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8615f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell return att; 8625f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell} 8635f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 8645f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 865f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 866f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 867f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 868f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell/* Need to add some addtional parameters to allow lighting in object 86923d31efc167f09d47635352f697ffcb087d3ebbdBrian Paul * space - STATE_SPOT_DIRECTION and STATE_HALF_VECTOR implicitly assume eye 870f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * space lighting. 871f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 872f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_lighting( struct tnl_program *p ) 873f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 874a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell const GLboolean twoside = p->state->light_twoside; 875a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell const GLboolean separate = p->state->separate_specular; 876f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint nr_lights = 0, count = 0; 877f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg normal = get_eye_normal(p); 878f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg lit = get_temp(p); 879f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg dots = get_temp(p); 880f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg _col0 = undef, _col1 = undef; 881f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg _bfc0 = undef, _bfc1 = undef; 882f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint i; 883f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 884f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (i = 0; i < MAX_LIGHTS; i++) 885a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].light_enabled) 886f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell nr_lights++; 887f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 888f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell set_material_flags(p); 889f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 890f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell { 891f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg shininess = get_material(p, 0, STATE_SHININESS); 8927e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, dots, WRITEMASK_W, swizzle1(shininess,X)); 893f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, shininess); 894f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 895f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _col0 = make_temp(p, get_scenecolor(p, 0)); 896f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) 897f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _col1 = make_temp(p, get_identity_param(p)); 898f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 899f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _col1 = _col0; 900f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 901f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 902f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 903f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (twoside) { 904f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg shininess = get_material(p, 1, STATE_SHININESS); 9057e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, dots, WRITEMASK_Z, 9065f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell negate(swizzle1(shininess,X))); 907f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, shininess); 908f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 909f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _bfc0 = make_temp(p, get_scenecolor(p, 1)); 910f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) 911f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _bfc1 = make_temp(p, get_identity_param(p)); 912f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 913f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _bfc1 = _bfc0; 914f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 915f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 91610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 91710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell /* If no lights, still need to emit the scenecolor. 91810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell */ 91910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell { 92010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg res0 = register_output( p, VERT_RESULT_COL0 ); 9217e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, res0, 0, _col0); 92210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 92310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 92410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (separate) { 92510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg res1 = register_output( p, VERT_RESULT_COL1 ); 9267e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, res1, 0, _col1); 92710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 92810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 92910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (twoside) { 93010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg res0 = register_output( p, VERT_RESULT_BFC0 ); 9317e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, res0, 0, _bfc0); 93210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 93310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 93410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (twoside && separate) { 93510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg res1 = register_output( p, VERT_RESULT_BFC1 ); 9367e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, res1, 0, _bfc1); 93710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 93810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 939f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell if (nr_lights == 0) { 94010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell release_temps(p); 94110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell return; 94210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 94310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 94410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 945f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (i = 0; i < MAX_LIGHTS; i++) { 946a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].light_enabled) { 947f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg half = undef; 948f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg att = undef, VPpli = undef; 949f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 950f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell count++; 951f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 952a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].light_eyepos3_is_zero) { 95347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell /* Can used precomputed constants in this case. 95447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell * Attenuation never applies to infinite lights. 955f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 9565f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell VPpli = register_param3(p, STATE_LIGHT, i, 9575f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_POSITION_NORMALIZED); 95861ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao if (p->state->light_local_viewer) { 95961ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao struct ureg eye_hat = get_eye_position_normalized(p); 96061ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao half = get_temp(p); 96161ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat); 96261ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao emit_normalize_vec3(p, half, half); 96361ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao } else { 96423d31efc167f09d47635352f697ffcb087d3ebbdBrian Paul half = register_param3(p, STATE_LIGHT, i, STATE_HALF_VECTOR); 96561ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao } 966f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 967f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 9685f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg Ppli = register_param3(p, STATE_LIGHT, i, 9695f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_POSITION); 970f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg V = get_eye_position(p); 9715f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dist = get_temp(p); 9726dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul struct ureg tmpPpli = get_temp(p); 973f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 974f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell VPpli = get_temp(p); 975f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell half = get_temp(p); 976f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 9776dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul /* In homogeneous object coordinates 9786dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul */ 9796dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul emit_op1(p, OPCODE_RCP, dist, 0, swizzle1(Ppli, W)); 9806dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul emit_op2(p, OPCODE_MUL, tmpPpli, 0, Ppli, dist); 981214347fdb4c30dc8bac5d4b9a823458709bc53eaXiang, Haihao 9826dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul /* Calculate VPpli vector 983f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 9846dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul emit_op2(p, OPCODE_SUB, VPpli, 0, tmpPpli, V); 985f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 9865f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* Normalize VPpli. The dist value also used in 987f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * attenuation below. 988f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 9897e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, dist, 0, VPpli, VPpli); 9907e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_RSQ, dist, 0, dist); 9917e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, VPpli, 0, VPpli, dist); 992f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 993f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 994f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calculate attenuation: 995f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 996a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (!p->state->unit[i].light_spotcutoff_is_180 || 997a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p->state->unit[i].light_attenuated) { 998a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell att = calculate_light_attenuation(p, i, VPpli, dist); 999f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1000f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1001f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1002f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calculate viewer direction, or use infinite viewer: 1003f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1004a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->light_local_viewer) { 1005f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_hat = get_eye_position_normalized(p); 10067e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat); 1007f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1008f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 10095f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg z_dir = swizzle(get_identity_param(p),X,Y,W,Z); 10107e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_ADD, half, 0, VPpli, z_dir); 1011f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1012f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1013f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_normalize_vec3(p, half, half); 1014f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 10155f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, dist); 10166dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul release_temp(p, tmpPpli); 1017f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1018f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1019f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calculate dot products: 1020f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 10217e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, dots, WRITEMASK_X, normal, VPpli); 10227e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, dots, WRITEMASK_Y, normal, half); 1023f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1024f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1025f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Front face lighting: 1026f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1027f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell { 1028f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg ambient = get_lightprod(p, i, 0, STATE_AMBIENT); 1029f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg diffuse = get_lightprod(p, i, 0, STATE_DIFFUSE); 1030f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg specular = get_lightprod(p, i, 0, STATE_SPECULAR); 1031f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg res0, res1; 1032f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell GLuint mask0, mask1; 1033f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 10347e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_LIT, lit, 0, dots); 1035f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1036f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (!is_undef(att)) 10377e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, lit, 0, lit, att); 1038f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 103947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 1040f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (count == nr_lights) { 1041f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) { 1042f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = WRITEMASK_XYZ; 1043f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = WRITEMASK_XYZ; 1044f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = register_output( p, VERT_RESULT_COL0 ); 1045f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_COL1 ); 1046f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1047f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 1048f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = 0; 1049f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = WRITEMASK_XYZ; 1050f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _col0; 1051f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_COL0 ); 1052f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1053f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } else { 1054f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = 0; 1055f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = 0; 1056f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _col0; 1057f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = _col1; 1058f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1059f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 10607e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, _col0, 0, swizzle1(lit,X), ambient, _col0); 10617e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _col0); 10627e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _col1); 1063f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1064f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, ambient); 1065f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, diffuse); 1066f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, specular); 1067f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1068f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1069f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Back face lighting: 1070f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1071f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (twoside) { 1072f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg ambient = get_lightprod(p, i, 1, STATE_AMBIENT); 1073f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg diffuse = get_lightprod(p, i, 1, STATE_DIFFUSE); 1074f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg specular = get_lightprod(p, i, 1, STATE_SPECULAR); 1075f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg res0, res1; 1076f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell GLuint mask0, mask1; 1077f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 10787e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_LIT, lit, 0, negate(swizzle(dots,X,Y,W,Z))); 1079f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1080f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (!is_undef(att)) 10817e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, lit, 0, lit, att); 1082f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1083f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (count == nr_lights) { 1084f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) { 1085f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = WRITEMASK_XYZ; 1086f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = WRITEMASK_XYZ; 1087f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = register_output( p, VERT_RESULT_BFC0 ); 1088f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_BFC1 ); 1089f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1090f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 1091f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = 0; 1092f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = WRITEMASK_XYZ; 1093f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _bfc0; 1094f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_BFC0 ); 1095f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1096f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } else { 1097f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _bfc0; 1098f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = _bfc1; 1099f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = 0; 1100f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = 0; 1101f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1102f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 11037e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, _bfc0, 0, swizzle1(lit,X), ambient, _bfc0); 11047e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _bfc0); 11057e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _bfc1); 1106f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1107f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, ambient); 1108f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, diffuse); 1109f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, specular); 1110f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1111f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1112f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, half); 1113f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, VPpli); 1114f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, att); 1115f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1116f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1117f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1118f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temps( p ); 1119f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1120f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1121f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1122f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_fog( struct tnl_program *p ) 1123f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 1124f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg fog = register_output(p, VERT_RESULT_FOGC); 1125f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg input; 112674a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger GLuint useabs = p->state->fog_source_is_depth && p->state->fog_mode && 112774a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger (p->state->fog_mode != FOG_EXP2); 112874a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger 1129a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->fog_source_is_depth) { 1130f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell input = swizzle1(get_eye_position(p), Z); 1131f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1132f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 1133f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X); 1134f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1135f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 113674a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger if (p->state->fog_mode && p->state->tnl_do_vertex_fog) { 113799dfca1e7fb32157135511bded07376ebb25acb3Roland Scheidegger struct ureg params = register_param2(p, STATE_INTERNAL, 113899dfca1e7fb32157135511bded07376ebb25acb3Roland Scheidegger STATE_FOG_PARAMS_OPTIMIZED); 1139f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = get_temp(p); 1140f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 114174a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger if (useabs) { 114274a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger emit_op1(p, OPCODE_ABS, tmp, 0, input); 114374a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger } 114474a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger 1145a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell switch (p->state->fog_mode) { 1146a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case FOG_LINEAR: { 1147f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg id = get_identity_param(p); 114874a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger emit_op3(p, OPCODE_MAD, tmp, 0, useabs ? tmp : input, 114974a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger swizzle1(params,X), swizzle1(params,Y)); 11507e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MAX, tmp, 0, tmp, swizzle1(id,X)); /* saturate */ 11517e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MIN, fog, WRITEMASK_X, tmp, swizzle1(id,W)); 1152f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 1153f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1154a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case FOG_EXP: 115574a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger emit_op2(p, OPCODE_MUL, tmp, 0, useabs ? tmp : input, 115674a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger swizzle1(params,Z)); 115754dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp)); 1158f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 1159a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case FOG_EXP2: 116054dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op2(p, OPCODE_MUL, tmp, 0, input, swizzle1(params,W)); 116174a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); 116254dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp)); 1163f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 1164f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 116574a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger 1166f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, tmp); 1167f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1168f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 1169f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* results = incoming fog coords (compute fog per-fragment later) 1170f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 1171f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * KW: Is it really necessary to do anything in this case? 1172f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 117374a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger emit_op1(p, useabs ? OPCODE_ABS : OPCODE_MOV, fog, WRITEMASK_X, input); 1174f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1175f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 11765f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 11775f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic void build_reflect_texgen( struct tnl_program *p, 11785f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dest, 11795f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint writemask ) 11805f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{ 11815f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg normal = get_eye_normal(p); 11825f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg eye_hat = get_eye_position_normalized(p); 11835f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg tmp = get_temp(p); 1184f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 11855f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* n.u */ 11867e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, tmp, 0, normal, eye_hat); 11875f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 2n.u */ 11887e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_ADD, tmp, 0, tmp, tmp); 11895f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* (-2n.u)n + u */ 11907e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, dest, writemask, negate(tmp), normal, eye_hat); 1191ab377ce414ba5ca286bab0ddc8e80769bcb88656Keith Whitwell 1192ab377ce414ba5ca286bab0ddc8e80769bcb88656Keith Whitwell release_temp(p, tmp); 11935f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell} 11945f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 11955f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic void build_sphere_texgen( struct tnl_program *p, 11965f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dest, 11975f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint writemask ) 11985f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{ 11995f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg normal = get_eye_normal(p); 12005f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg eye_hat = get_eye_position_normalized(p); 12015f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg tmp = get_temp(p); 120296582f4f28851f55f6726d1bba8a7f2616c327a4Keith Whitwell struct ureg half = register_scalar_const(p, .5); 12035f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg r = get_temp(p); 12045f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg inv_m = get_temp(p); 12055f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg id = get_identity_param(p); 12065f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 12075f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* Could share the above calculations, but it would be 12085f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * a fairly odd state for someone to set (both sphere and 12095f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * reflection active for different texture coordinate 12105f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * components. Of course - if two texture units enable 12115f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * reflect and/or sphere, things start to tilt in favour 12125f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * of seperating this out: 12135f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell */ 12145f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 12155f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* n.u */ 12167e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, tmp, 0, normal, eye_hat); 12175f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 2n.u */ 12187e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_ADD, tmp, 0, tmp, tmp); 12195f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* (-2n.u)n + u */ 12207e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, r, 0, negate(tmp), normal, eye_hat); 12215f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* r + 0,0,1 */ 12227e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_ADD, tmp, 0, r, swizzle(id,X,Y,W,Z)); 12235f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* rx^2 + ry^2 + (rz+1)^2 */ 12247e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, tmp, 0, tmp, tmp); 12255f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 2/m */ 12267e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_RSQ, tmp, 0, tmp); 12275f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 1/m */ 12287e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, inv_m, 0, tmp, half); 12295f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* r/m + 1/2 */ 12307e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, dest, writemask, r, inv_m, half); 12315f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 12325f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, tmp); 12335f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, r); 12345f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, inv_m); 12355f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell} 1236f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1237f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1238f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_texture_transform( struct tnl_program *p ) 1239f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 1240f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint i, j; 1241f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1242a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (i = 0; i < MAX_TEXTURE_UNITS; i++) { 1243f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1244e713c21bd09468887faceebcba9a62a406321c07Brian Paul if (!(p->state->fragprog_inputs_read & FRAG_BIT_TEX(i))) 1245c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell continue; 1246c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1247c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->unit[i].texgen_enabled || 1248c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell p->state->unit[i].texmat_enabled) { 1249c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1250c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell GLuint texmat_enabled = p->state->unit[i].texmat_enabled; 125110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg out = register_output(p, VERT_RESULT_TEX0 + i); 1252f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg out_texgen = undef; 1253f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1254a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].texgen_enabled) { 1255f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint copy_mask = 0; 1256f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint sphere_mask = 0; 1257f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint reflect_mask = 0; 1258f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint normal_mask = 0; 1259f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint modes[4]; 1260f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1261f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (texmat_enabled) 1262f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell out_texgen = get_temp(p); 1263f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 1264f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell out_texgen = out; 1265f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1266a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell modes[0] = p->state->unit[i].texgen_mode0; 1267a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell modes[1] = p->state->unit[i].texgen_mode1; 1268a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell modes[2] = p->state->unit[i].texgen_mode2; 1269a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell modes[3] = p->state->unit[i].texgen_mode3; 1270f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1271f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (j = 0; j < 4; j++) { 1272a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell switch (modes[j]) { 1273a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_OBJ_LINEAR: { 1274a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct ureg obj = register_input(p, VERT_ATTRIB_POS); 1275a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct ureg plane = 1276a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell register_param3(p, STATE_TEXGEN, i, 1277a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell STATE_TEXGEN_OBJECT_S + j); 1278a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 12797e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP4, out_texgen, WRITEMASK_X << j, 1280a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell obj, plane ); 1281a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1282f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1283a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_EYE_LINEAR: { 1284a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct ureg eye = get_eye_position(p); 1285a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct ureg plane = 1286a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell register_param3(p, STATE_TEXGEN, i, 1287a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell STATE_TEXGEN_EYE_S + j); 1288a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 12897e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP4, out_texgen, WRITEMASK_X << j, 1290a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell eye, plane ); 1291a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1292a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 1293a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_SPHERE_MAP: 1294a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell sphere_mask |= WRITEMASK_X << j; 1295a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1296a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_REFLECTION_MAP: 1297a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell reflect_mask |= WRITEMASK_X << j; 1298a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1299a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_NORMAL_MAP: 1300a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell normal_mask |= WRITEMASK_X << j; 1301a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1302a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_NONE: 1303f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell copy_mask |= WRITEMASK_X << j; 1304a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 1305a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1306f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1307f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1308f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1309f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (sphere_mask) { 13105f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell build_sphere_texgen(p, out_texgen, sphere_mask); 1311f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1312f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1313f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (reflect_mask) { 13145f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell build_reflect_texgen(p, out_texgen, reflect_mask); 1315f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1316f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1317f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (normal_mask) { 1318f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg normal = get_eye_normal(p); 13197e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, out_texgen, normal_mask, normal ); 1320f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1321f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1322f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (copy_mask) { 1323f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg in = register_input(p, VERT_ATTRIB_TEX0+i); 13247e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, out_texgen, copy_mask, in ); 1325f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1326f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1327f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1328f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (texmat_enabled) { 1329f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg texmat[4]; 13305f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg in = (!is_undef(out_texgen) ? 13315f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell out_texgen : 13325f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell register_input(p, VERT_ATTRIB_TEX0+i)); 133310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (PREFER_DP4) { 1334fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, 1335fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul 0, texmat ); 133610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_matrix_transform_vec4( p, out, texmat, in ); 133710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 133810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell else { 1339fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, 1340fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul STATE_MATRIX_TRANSPOSE, texmat ); 13411c48986e540f573c63b98470f52338dba6353ceaKeith Whitwell emit_transpose_matrix_transform_vec4( p, out, texmat, in ); 134210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 1343f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1344f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1345f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temps(p); 134610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 1347c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell else { 134810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_passthrough(p, VERT_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i); 1349f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1350f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1351f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1352f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1353f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1354f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_pointsize( struct tnl_program *p ) 1355f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 1356f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye = get_eye_position(p); 13575f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg state_size = register_param1(p, STATE_POINT_SIZE); 13585f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg state_attenuation = register_param1(p, STATE_POINT_ATTENUATION); 13595f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg out = register_output(p, VERT_RESULT_PSIZ); 1360f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg ut = get_temp(p); 1361f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1362a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger /* dist = |eyez| */ 1363a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op1(p, OPCODE_ABS, ut, WRITEMASK_Y, swizzle1(eye, Z)); 136454dac2c84310536cce962101de29546d3eb80175Roland Scheidegger /* p1 + dist * (p2 + dist * p3); */ 1365a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op3(p, OPCODE_MAD, ut, WRITEMASK_X, swizzle1(ut, Y), 136654dac2c84310536cce962101de29546d3eb80175Roland Scheidegger swizzle1(state_attenuation, Z), swizzle1(state_attenuation, Y)); 1367a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op3(p, OPCODE_MAD, ut, WRITEMASK_X, swizzle1(ut, Y), 136854dac2c84310536cce962101de29546d3eb80175Roland Scheidegger ut, swizzle1(state_attenuation, X)); 136954dac2c84310536cce962101de29546d3eb80175Roland Scheidegger 137054dac2c84310536cce962101de29546d3eb80175Roland Scheidegger /* 1 / sqrt(factor) */ 1371a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op1(p, OPCODE_RSQ, ut, WRITEMASK_X, ut ); 137254dac2c84310536cce962101de29546d3eb80175Roland Scheidegger 137354dac2c84310536cce962101de29546d3eb80175Roland Scheidegger#if 1 137454dac2c84310536cce962101de29546d3eb80175Roland Scheidegger /* out = pointSize / sqrt(factor) */ 137554dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op2(p, OPCODE_MUL, out, WRITEMASK_X, ut, state_size); 137654dac2c84310536cce962101de29546d3eb80175Roland Scheidegger#else 137754dac2c84310536cce962101de29546d3eb80175Roland Scheidegger /* not sure, might make sense to do clamping here, 137854dac2c84310536cce962101de29546d3eb80175Roland Scheidegger but it's not done in t_vb_points neither */ 1379a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op2(p, OPCODE_MUL, ut, WRITEMASK_X, ut, state_size); 1380a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op2(p, OPCODE_MAX, ut, WRITEMASK_X, ut, swizzle1(state_size, Y)); 138154dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op2(p, OPCODE_MIN, out, WRITEMASK_X, ut, swizzle1(state_size, Z)); 138254dac2c84310536cce962101de29546d3eb80175Roland Scheidegger#endif 1383f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1384f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, ut); 1385f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1386f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1387a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic void build_tnl_program( struct tnl_program *p ) 1388a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ /* Emit the program, starting with modelviewproject: 1389a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1390a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_hpos(p); 1391a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1392a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* Lighting calculations: 1393a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1394c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->fragprog_inputs_read & (FRAG_BIT_COL0|FRAG_BIT_COL1)) { 1395c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->light_global_enabled) 1396c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell build_lighting(p); 1397c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell else { 1398c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->fragprog_inputs_read & FRAG_BIT_COL0) 1399c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell emit_passthrough(p, VERT_ATTRIB_COLOR0, VERT_RESULT_COL0); 1400c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1401c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->fragprog_inputs_read & FRAG_BIT_COL1) 1402f31448f3c86697275bffe5363d473dd128cbd2acAapo Tahkola emit_passthrough(p, VERT_ATTRIB_COLOR1, VERT_RESULT_COL1); 1403c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell } 1404c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell } 1405f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1406c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if ((p->state->fragprog_inputs_read & FRAG_BIT_FOGC) || 1407c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell p->state->fog_mode != FOG_NONE) 1408a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_fog(p); 14095a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1410c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->fragprog_inputs_read & FRAG_BITS_TEX_ANY) 1411a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_texture_transform(p); 14125a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1413a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->point_attenuated) 1414a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_pointsize(p); 14155a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1416a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* Finish up: 1417a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 14187e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_END, undef, 0, undef); 14195a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1420a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* Disassemble: 1421a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1422a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (DISASSEM) { 1423a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell _mesa_printf ("\n"); 1424a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 14255a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell} 14265a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1427f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1428c43f03e38dd4bfbcbc0cc8414e2bacfbffad08a1Brian Paulstatic void 1429c43f03e38dd4bfbcbc0cc8414e2bacfbffad08a1Brian Paulcreate_new_program( const struct state_key *key, 1430122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_vertex_program *program, 1431c43f03e38dd4bfbcbc0cc8414e2bacfbffad08a1Brian Paul GLuint max_temps) 1432f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 1433f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct tnl_program p; 1434f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 143549d8cbe8d110e5c0a23300b5b82d110286bc3609Keith Whitwell _mesa_memset(&p, 0, sizeof(p)); 1436a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p.state = key; 1437a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p.program = program; 1438f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.eye_position = undef; 1439f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.eye_position_normalized = undef; 1440f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.eye_normal = undef; 1441f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.identity = undef; 14423509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p.temp_in_use = 0; 1443a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1444a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (max_temps >= sizeof(int) * 8) 14453509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p.temp_reserved = 0; 14463509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell else 1447a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p.temp_reserved = ~((1<<max_temps)-1); 14483509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell 1449002762b13aa58ca569a564bb64672e343611c9edBrian Paul p.program->Base.Instructions = _mesa_alloc_instructions(MAX_INSN); 1450002762b13aa58ca569a564bb64672e343611c9edBrian Paul p.program->Base.String = NULL; 1451f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumInstructions = 1452f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumTemporaries = 1453f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumParameters = 1454f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0; 1455de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.Parameters = _mesa_new_parameter_list(); 1456de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.InputsRead = 0; 1457de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.OutputsWritten = 0; 1458f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1459a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_tnl_program( &p ); 1460a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1461f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1462a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic void *search_cache( struct tnl_cache *cache, 1463a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint hash, 1464a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell const void *key, 1465a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint keysize) 1466a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 146737f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola struct tnl_cache_item *c; 1468a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 146937f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola for (c = cache->items[hash % cache->size]; c; c = c->next) { 1470aa2069586d434dd0487b0daa2b583efe801a0d51Brian Paul if (c->hash == hash && _mesa_memcmp(c->key, key, keysize) == 0) 1471a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return c->data; 1472a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 1473a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1474a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return NULL; 1475a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1476a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 147737f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkolastatic void rehash( struct tnl_cache *cache ) 147837f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola{ 147937f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola struct tnl_cache_item **items; 148037f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola struct tnl_cache_item *c, *next; 148137f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola GLuint size, i; 148237f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 148337f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola size = cache->size * 3; 14849580179dfb42d5b81ff6ec9704b82a556c7f1229Brian Paul items = (struct tnl_cache_item**) _mesa_malloc(size * sizeof(*items)); 148537f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola _mesa_memset(items, 0, size * sizeof(*items)); 148637f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 148737f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola for (i = 0; i < cache->size; i++) 148837f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola for (c = cache->items[i]; c; c = next) { 148937f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola next = c->next; 149037f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola c->next = items[c->hash % size]; 149137f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola items[c->hash % size] = c; 149237f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola } 149337f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 149437f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(cache->items); 149537f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola cache->items = items; 149637f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola cache->size = size; 149737f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola} 149837f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 149937f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkolastatic void cache_item( struct tnl_cache *cache, 1500a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint hash, 1501a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell void *key, 1502a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell void *data ) 1503a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 15049580179dfb42d5b81ff6ec9704b82a556c7f1229Brian Paul struct tnl_cache_item *c = (struct tnl_cache_item*) _mesa_malloc(sizeof(*c)); 1505a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell c->hash = hash; 1506a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell c->key = key; 1507a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell c->data = data; 150837f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 150937f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola if (++cache->n_items > cache->size * 1.5) 151037f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola rehash(cache); 151137f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 151237f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola c->next = cache->items[hash % cache->size]; 151337f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola cache->items[hash % cache->size] = c; 1514a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1515a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1516a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic GLuint hash_key( struct state_key *key ) 1517a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 1518a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint *ikey = (GLuint *)key; 1519a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint hash = 0, i; 1520a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1521a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* I'm sure this can be improved on, but speed is important: 1522f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1523a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (i = 0; i < sizeof(*key)/sizeof(GLuint); i++) 1524a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell hash ^= ikey[i]; 1525f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1526a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return hash; 1527a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1528f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1529a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellvoid _tnl_UpdateFixedFunctionProgram( GLcontext *ctx ) 1530a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 1531a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell TNLcontext *tnl = TNL_CONTEXT(ctx); 1532a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct state_key *key; 1533a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint hash; 1534122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul const struct gl_vertex_program *prev = ctx->VertexProgram._Current; 1535f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1536dba21ed913da2222e3b55fc8ba724ca93acbabf1Nicolai Hähnle if (!ctx->VertexProgram._Current || 1537dba21ed913da2222e3b55fc8ba724ca93acbabf1Nicolai Hähnle ctx->VertexProgram._Current == ctx->VertexProgram._TnlProgram) { 1538c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* Grab all the relevent state and put it in a single structure: 1539c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell */ 1540c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell key = make_state_key(ctx); 1541c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell hash = hash_key(key); 1542c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1543c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* Look for an already-prepared program for this state: 1544c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell */ 1545a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul ctx->VertexProgram._TnlProgram = (struct gl_vertex_program *) 1546c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell search_cache( tnl->vp_cache, hash, key, sizeof(*key) ); 1547a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1548c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* OK, we'll have to build a new one: 1549c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell */ 1550a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul if (!ctx->VertexProgram._TnlProgram) { 1551c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (0) 1552c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell _mesa_printf("Build new TNL program\n"); 1553c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1554a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul ctx->VertexProgram._TnlProgram = (struct gl_vertex_program *) 1555c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); 1556dbeea25bb834479a29712100888c862348112018Keith Whitwell 1557a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul create_new_program( key, ctx->VertexProgram._TnlProgram, 1558c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell ctx->Const.VertexProgram.MaxTemps ); 1559dbeea25bb834479a29712100888c862348112018Keith Whitwell 1560c9515bf1aec3a3d934535a9d2893e90e8b903043Keith Whitwell if (ctx->Driver.ProgramStringNotify) 1561c9515bf1aec3a3d934535a9d2893e90e8b903043Keith Whitwell ctx->Driver.ProgramStringNotify( ctx, GL_VERTEX_PROGRAM_ARB, 1562a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul &ctx->VertexProgram._TnlProgram->Base ); 1563a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1564a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul cache_item(tnl->vp_cache, hash, key, ctx->VertexProgram._TnlProgram ); 1565c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell } 1566c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell else { 1567c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell FREE(key); 1568c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (0) 1569c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell _mesa_printf("Found existing TNL program for key %x\n", hash); 1570c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell } 1571a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul ctx->VertexProgram._Current = ctx->VertexProgram._TnlProgram; 1572a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 1573a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1574c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* Tell the driver about the change. Could define a new target for 1575c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell * this? 1576a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1577a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul if (ctx->VertexProgram._Current != prev && ctx->Driver.BindProgram) { 1578122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, 1579122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul (struct gl_program *) ctx->VertexProgram._Current); 1580a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul } 1581a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1582a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 15839248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkolavoid _tnl_ProgramCacheInit( GLcontext *ctx ) 15849248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola{ 15859248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola TNLcontext *tnl = TNL_CONTEXT(ctx); 15869248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola 15879248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola tnl->vp_cache = (struct tnl_cache *) MALLOC(sizeof(*tnl->vp_cache)); 15889248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola tnl->vp_cache->size = 17; 15899248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola tnl->vp_cache->n_items = 0; 15909248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola tnl->vp_cache->items = (struct tnl_cache_item**) 15919248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola _mesa_calloc(tnl->vp_cache->size * sizeof(*tnl->vp_cache->items)); 15929248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola} 1593a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1594a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellvoid _tnl_ProgramCacheDestroy( GLcontext *ctx ) 1595a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 1596a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell TNLcontext *tnl = TNL_CONTEXT(ctx); 159737f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola struct tnl_cache_item *c, *next; 159837f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola GLuint i; 1599a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 160037f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola for (i = 0; i < tnl->vp_cache->size; i++) 160137f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola for (c = tnl->vp_cache->items[i]; c; c = next) { 160237f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola next = c->next; 160337f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(c->key); 160437f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(c->data); 160537f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(c); 160637f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola } 160737f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 160837f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(tnl->vp_cache->items); 160937f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(tnl->vp_cache); 1610f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1611