t_vp_build.c revision bbd287103dad776d8a45c87c4e51fbc26d9b80d5
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 33bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h" 34bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h" 35bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/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 2386138ee9de0330b9a2bf300bc0d52b471191dd1edBrian Paul#define MAX_INSN 350 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; 492c9d495c6f064aacd1e072033b9c17a83b8c37fa1Brian Paul dst->CondMask = COND_TR; /* always pass cond test */ 493c9d495c6f064aacd1e072033b9c17a83b8c37fa1Brian Paul dst->CondSwizzle = SWIZZLE_NOOP; 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, 516c9d495c6f064aacd1e072033b9c17a83b8c37fa1Brian Paul enum prog_opcode 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 702cab0dce6766c9ac728bc9f88dc94b8651fc257fbBrian Paul emit_op2( p, OPCODE_MUL, p->eye_normal, 0, p->eye_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 894f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _col0 = make_temp(p, get_scenecolor(p, 0)); 895f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) 896f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _col1 = make_temp(p, get_identity_param(p)); 897f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 898f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _col1 = _col0; 899f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 900f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 901f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 902f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (twoside) { 903f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg shininess = get_material(p, 1, STATE_SHININESS); 9047e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, dots, WRITEMASK_Z, 9055f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell negate(swizzle1(shininess,X))); 906f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 907f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _bfc0 = make_temp(p, get_scenecolor(p, 1)); 908f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) 909f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _bfc1 = make_temp(p, get_identity_param(p)); 910f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 911f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell _bfc1 = _bfc0; 912f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 913f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 91410432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 91510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell /* If no lights, still need to emit the scenecolor. 91610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell */ 91710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell { 91810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg res0 = register_output( p, VERT_RESULT_COL0 ); 9197e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, res0, 0, _col0); 92010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 92110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 92210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (separate) { 92310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg res1 = register_output( p, VERT_RESULT_COL1 ); 9247e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, res1, 0, _col1); 92510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 92610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 92710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (twoside) { 92810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg res0 = register_output( p, VERT_RESULT_BFC0 ); 9297e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, res0, 0, _bfc0); 93010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 93110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 93210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (twoside && separate) { 93310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg res1 = register_output( p, VERT_RESULT_BFC1 ); 9347e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, res1, 0, _bfc1); 93510432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 93610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 937f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell if (nr_lights == 0) { 93810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell release_temps(p); 93910432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell return; 94010432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 94110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 94210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell 943f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (i = 0; i < MAX_LIGHTS; i++) { 944a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].light_enabled) { 945f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg half = undef; 946f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg att = undef, VPpli = undef; 947f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 948f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell count++; 949f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 950a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].light_eyepos3_is_zero) { 95147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell /* Can used precomputed constants in this case. 95247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell * Attenuation never applies to infinite lights. 953f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 9545f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell VPpli = register_param3(p, STATE_LIGHT, i, 9555f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_POSITION_NORMALIZED); 95661ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao if (p->state->light_local_viewer) { 95761ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao struct ureg eye_hat = get_eye_position_normalized(p); 95861ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao half = get_temp(p); 95961ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat); 96061ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao emit_normalize_vec3(p, half, half); 96161ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao } else { 96223d31efc167f09d47635352f697ffcb087d3ebbdBrian Paul half = register_param3(p, STATE_LIGHT, i, STATE_HALF_VECTOR); 96361ec23cc63a040a2edf1bc466917e85362514c89Xiang, Haihao } 964f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 965f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 9665f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg Ppli = register_param3(p, STATE_LIGHT, i, 9675f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell STATE_POSITION); 968f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg V = get_eye_position(p); 9695f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dist = get_temp(p); 9706dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul struct ureg tmpPpli = get_temp(p); 971f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 972f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell VPpli = get_temp(p); 973f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 9746dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul /* In homogeneous object coordinates 9756dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul */ 9766dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul emit_op1(p, OPCODE_RCP, dist, 0, swizzle1(Ppli, W)); 9776dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul emit_op2(p, OPCODE_MUL, tmpPpli, 0, Ppli, dist); 978214347fdb4c30dc8bac5d4b9a823458709bc53eaXiang, Haihao 9796dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul /* Calculate VPpli vector 980f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 9816dd98e9853a6984150aa47467112e016c40a4ab4Brian Paul emit_op2(p, OPCODE_SUB, VPpli, 0, tmpPpli, V); 982f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 983d3033cad7c8a077b093fc5b0c423950473aed9e7Hans de Goede /* we're done with tmpPpli now */ 984d3033cad7c8a077b093fc5b0c423950473aed9e7Hans de Goede release_temp(p, tmpPpli); 985d3033cad7c8a077b093fc5b0c423950473aed9e7Hans de Goede 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 } 1000d3033cad7c8a077b093fc5b0c423950473aed9e7Hans de Goede 1001d3033cad7c8a077b093fc5b0c423950473aed9e7Hans de Goede /* We're done with dist now */ 1002d3033cad7c8a077b093fc5b0c423950473aed9e7Hans de Goede release_temp(p, dist); 1003f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1004f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1005f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calculate viewer direction, or use infinite viewer: 1006f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1007d3033cad7c8a077b093fc5b0c423950473aed9e7Hans de Goede half = get_temp(p); 1008a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->light_local_viewer) { 1009f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye_hat = get_eye_position_normalized(p); 10107e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat); 1011f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1012f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 10135f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg z_dir = swizzle(get_identity_param(p),X,Y,W,Z); 10147e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_ADD, half, 0, VPpli, z_dir); 1015f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1016f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1017f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell emit_normalize_vec3(p, half, half); 1018f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1019f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1020f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Calculate dot products: 1021f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 10227e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, dots, WRITEMASK_X, normal, VPpli); 10237e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, dots, WRITEMASK_Y, normal, half); 1024f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1025d3033cad7c8a077b093fc5b0c423950473aed9e7Hans de Goede /* we're done with VPpli and half now, so free them as to not drive up 1026d3033cad7c8a077b093fc5b0c423950473aed9e7Hans de Goede our temp usage unnecessary */ 1027d3033cad7c8a077b093fc5b0c423950473aed9e7Hans de Goede release_temp(p, VPpli); 1028d3033cad7c8a077b093fc5b0c423950473aed9e7Hans de Goede release_temp(p, half); 1029f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1030f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Front face lighting: 1031f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1032f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell { 1033f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg ambient = get_lightprod(p, i, 0, STATE_AMBIENT); 1034f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg diffuse = get_lightprod(p, i, 0, STATE_DIFFUSE); 1035f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg specular = get_lightprod(p, i, 0, STATE_SPECULAR); 1036f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg res0, res1; 1037f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell GLuint mask0, mask1; 1038f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 10397e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_LIT, lit, 0, dots); 1040f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1041f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (!is_undef(att)) 10427e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, lit, 0, lit, att); 1043f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 104447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 1045f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (count == nr_lights) { 1046f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) { 1047f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = WRITEMASK_XYZ; 1048f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = WRITEMASK_XYZ; 1049f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = register_output( p, VERT_RESULT_COL0 ); 1050f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_COL1 ); 1051f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1052f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 1053f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = 0; 1054f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = WRITEMASK_XYZ; 1055f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _col0; 1056f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_COL0 ); 1057f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1058f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } else { 1059f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = 0; 1060f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = 0; 1061f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _col0; 1062f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = _col1; 1063f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1064f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 10657e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, _col0, 0, swizzle1(lit,X), ambient, _col0); 10667e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _col0); 10677e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _col1); 1068f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1069f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, ambient); 1070f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, diffuse); 1071f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, specular); 1072f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1073f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1074f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* Back face lighting: 1075f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1076f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (twoside) { 1077f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg ambient = get_lightprod(p, i, 1, STATE_AMBIENT); 1078f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg diffuse = get_lightprod(p, i, 1, STATE_DIFFUSE); 1079f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg specular = get_lightprod(p, i, 1, STATE_SPECULAR); 1080f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg res0, res1; 1081f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell GLuint mask0, mask1; 1082f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 10837e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_LIT, lit, 0, negate(swizzle(dots,X,Y,W,Z))); 1084f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1085f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (!is_undef(att)) 10867e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, lit, 0, lit, att); 1087f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1088f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (count == nr_lights) { 1089f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (separate) { 1090f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = WRITEMASK_XYZ; 1091f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = WRITEMASK_XYZ; 1092f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = register_output( p, VERT_RESULT_BFC0 ); 1093f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_BFC1 ); 1094f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1095f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 1096f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = 0; 1097f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = WRITEMASK_XYZ; 1098f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _bfc0; 1099f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = register_output( p, VERT_RESULT_BFC0 ); 1100f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1101f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } else { 1102f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res0 = _bfc0; 1103f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell res1 = _bfc1; 1104f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask0 = 0; 1105f6e7cfb60d3c4ceb2242cbc57c7e87c3c8e362feKeith Whitwell mask1 = 0; 1106f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1107f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 11087e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, _bfc0, 0, swizzle1(lit,X), ambient, _bfc0); 11097e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _bfc0); 11107e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _bfc1); 1111f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1112f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, ambient); 1113f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, diffuse); 1114f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, specular); 1115f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1116f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1117f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, att); 1118f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1119f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1120f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1121f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temps( p ); 1122f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1123f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1124f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1125f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_fog( struct tnl_program *p ) 1126f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 1127f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg fog = register_output(p, VERT_RESULT_FOGC); 1128f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg input; 112974a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger 1130a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->fog_source_is_depth) { 1131f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell input = swizzle1(get_eye_position(p), Z); 1132f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1133f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 1134f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X); 1135f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1136f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 113774a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger if (p->state->fog_mode && p->state->tnl_do_vertex_fog) { 113899dfca1e7fb32157135511bded07376ebb25acb3Roland Scheidegger struct ureg params = register_param2(p, STATE_INTERNAL, 113999dfca1e7fb32157135511bded07376ebb25acb3Roland Scheidegger STATE_FOG_PARAMS_OPTIMIZED); 1140f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg tmp = get_temp(p); 1141cab0dce6766c9ac728bc9f88dc94b8651fc257fbBrian Paul GLboolean useabs = (p->state->fog_mode != FOG_EXP2); 1142f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 114374a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger if (useabs) { 114474a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger emit_op1(p, OPCODE_ABS, tmp, 0, input); 114574a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger } 114674a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger 1147a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell switch (p->state->fog_mode) { 1148a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case FOG_LINEAR: { 1149f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg id = get_identity_param(p); 115074a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger emit_op3(p, OPCODE_MAD, tmp, 0, useabs ? tmp : input, 115174a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger swizzle1(params,X), swizzle1(params,Y)); 11527e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MAX, tmp, 0, tmp, swizzle1(id,X)); /* saturate */ 11537e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MIN, fog, WRITEMASK_X, tmp, swizzle1(id,W)); 1154f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 1155f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1156a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case FOG_EXP: 115774a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger emit_op2(p, OPCODE_MUL, tmp, 0, useabs ? tmp : input, 115874a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger swizzle1(params,Z)); 115954dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp)); 1160f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 1161a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case FOG_EXP2: 116254dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op2(p, OPCODE_MUL, tmp, 0, input, swizzle1(params,W)); 116374a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); 116454dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp)); 1165f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell break; 1166f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 116774a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger 1168f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, tmp); 1169f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1170f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else { 1171f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell /* results = incoming fog coords (compute fog per-fragment later) 1172f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * 1173f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell * KW: Is it really necessary to do anything in this case? 1174cab0dce6766c9ac728bc9f88dc94b8651fc257fbBrian Paul * BP: Yes, we always need to compute the absolute value, unless 1175cab0dce6766c9ac728bc9f88dc94b8651fc257fbBrian Paul * we want to push that down into the fragment program... 1176f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1177cab0dce6766c9ac728bc9f88dc94b8651fc257fbBrian Paul GLboolean useabs = GL_TRUE; 117874a30c351fe98f41150dfe81a6aba05087997206Roland Scheidegger emit_op1(p, useabs ? OPCODE_ABS : OPCODE_MOV, fog, WRITEMASK_X, input); 1179f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1180f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 11815f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 11825f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic void build_reflect_texgen( struct tnl_program *p, 11835f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dest, 11845f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint writemask ) 11855f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{ 11865f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg normal = get_eye_normal(p); 11875f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg eye_hat = get_eye_position_normalized(p); 11885f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg tmp = get_temp(p); 1189f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 11905f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* n.u */ 11917e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, tmp, 0, normal, eye_hat); 11925f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 2n.u */ 11937e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_ADD, tmp, 0, tmp, tmp); 11945f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* (-2n.u)n + u */ 11957e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, dest, writemask, negate(tmp), normal, eye_hat); 1196ab377ce414ba5ca286bab0ddc8e80769bcb88656Keith Whitwell 1197ab377ce414ba5ca286bab0ddc8e80769bcb88656Keith Whitwell release_temp(p, tmp); 11985f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell} 11995f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 12005f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwellstatic void build_sphere_texgen( struct tnl_program *p, 12015f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg dest, 12025f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell GLuint writemask ) 12035f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell{ 12045f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg normal = get_eye_normal(p); 12055f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg eye_hat = get_eye_position_normalized(p); 12065f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg tmp = get_temp(p); 120796582f4f28851f55f6726d1bba8a7f2616c327a4Keith Whitwell struct ureg half = register_scalar_const(p, .5); 12085f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg r = get_temp(p); 12095f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg inv_m = get_temp(p); 12105f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg id = get_identity_param(p); 12115f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 12125f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* Could share the above calculations, but it would be 12135f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * a fairly odd state for someone to set (both sphere and 12145f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * reflection active for different texture coordinate 12155f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * components. Of course - if two texture units enable 12165f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * reflect and/or sphere, things start to tilt in favour 12175f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell * of seperating this out: 12185f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell */ 12195f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 12205f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* n.u */ 12217e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, tmp, 0, normal, eye_hat); 12225f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 2n.u */ 12237e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_ADD, tmp, 0, tmp, tmp); 12245f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* (-2n.u)n + u */ 12257e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, r, 0, negate(tmp), normal, eye_hat); 12265f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* r + 0,0,1 */ 12277e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_ADD, tmp, 0, r, swizzle(id,X,Y,W,Z)); 12285f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* rx^2 + ry^2 + (rz+1)^2 */ 12297e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP3, tmp, 0, tmp, tmp); 12305f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 2/m */ 12317e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_RSQ, tmp, 0, tmp); 12325f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* 1/m */ 12337e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_MUL, inv_m, 0, tmp, half); 12345f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell /* r/m + 1/2 */ 12357e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op3(p, OPCODE_MAD, dest, writemask, r, inv_m, half); 12365f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell 12375f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, tmp); 12385f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, r); 12395f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell release_temp(p, inv_m); 12405f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell} 1241f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1242f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1243f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_texture_transform( struct tnl_program *p ) 1244f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 1245f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint i, j; 1246f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1247a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (i = 0; i < MAX_TEXTURE_UNITS; i++) { 1248f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1249e713c21bd09468887faceebcba9a62a406321c07Brian Paul if (!(p->state->fragprog_inputs_read & FRAG_BIT_TEX(i))) 1250c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell continue; 1251c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1252c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->unit[i].texgen_enabled || 1253c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell p->state->unit[i].texmat_enabled) { 1254c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1255c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell GLuint texmat_enabled = p->state->unit[i].texmat_enabled; 125610432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell struct ureg out = register_output(p, VERT_RESULT_TEX0 + i); 1257f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg out_texgen = undef; 1258f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1259a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->unit[i].texgen_enabled) { 1260f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint copy_mask = 0; 1261f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint sphere_mask = 0; 1262f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint reflect_mask = 0; 1263f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint normal_mask = 0; 1264f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell GLuint modes[4]; 1265f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1266f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (texmat_enabled) 1267f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell out_texgen = get_temp(p); 1268f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell else 1269f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell out_texgen = out; 1270f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1271a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell modes[0] = p->state->unit[i].texgen_mode0; 1272a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell modes[1] = p->state->unit[i].texgen_mode1; 1273a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell modes[2] = p->state->unit[i].texgen_mode2; 1274a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell modes[3] = p->state->unit[i].texgen_mode3; 1275f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1276f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell for (j = 0; j < 4; j++) { 1277a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell switch (modes[j]) { 1278a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_OBJ_LINEAR: { 1279a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct ureg obj = register_input(p, VERT_ATTRIB_POS); 1280a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct ureg plane = 1281a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell register_param3(p, STATE_TEXGEN, i, 1282a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell STATE_TEXGEN_OBJECT_S + j); 1283a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 12847e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP4, out_texgen, WRITEMASK_X << j, 1285a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell obj, plane ); 1286a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1287f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1288a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_EYE_LINEAR: { 1289a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct ureg eye = get_eye_position(p); 1290a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct ureg plane = 1291a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell register_param3(p, STATE_TEXGEN, i, 1292a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell STATE_TEXGEN_EYE_S + j); 1293a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 12947e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op2(p, OPCODE_DP4, out_texgen, WRITEMASK_X << j, 1295a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell eye, plane ); 1296a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1297a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 1298a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_SPHERE_MAP: 1299a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell sphere_mask |= WRITEMASK_X << j; 1300a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1301a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_REFLECTION_MAP: 1302a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell reflect_mask |= WRITEMASK_X << j; 1303a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1304a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_NORMAL_MAP: 1305a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell normal_mask |= WRITEMASK_X << j; 1306a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell break; 1307a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell case TXG_NONE: 1308f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell copy_mask |= WRITEMASK_X << j; 1309a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 1310a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1311f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1312f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1313f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1314f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (sphere_mask) { 13155f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell build_sphere_texgen(p, out_texgen, sphere_mask); 1316f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1317f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1318f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (reflect_mask) { 13195f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell build_reflect_texgen(p, out_texgen, reflect_mask); 1320f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1321f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1322f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (normal_mask) { 1323f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg normal = get_eye_normal(p); 13247e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, out_texgen, normal_mask, normal ); 1325f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1326f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1327f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (copy_mask) { 1328f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg in = register_input(p, VERT_ATTRIB_TEX0+i); 13297e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_MOV, out_texgen, copy_mask, in ); 1330f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1331f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1332f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1333f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell if (texmat_enabled) { 1334f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg texmat[4]; 13355f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg in = (!is_undef(out_texgen) ? 13365f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell out_texgen : 13375f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell register_input(p, VERT_ATTRIB_TEX0+i)); 133810432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell if (PREFER_DP4) { 1339fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, 1340fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul 0, texmat ); 134110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_matrix_transform_vec4( p, out, texmat, in ); 134210432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 134310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell else { 1344fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, 1345fce8409cbbe6aa5309163f3d63894233b8833308Brian Paul STATE_MATRIX_TRANSPOSE, texmat ); 13461c48986e540f573c63b98470f52338dba6353ceaKeith Whitwell emit_transpose_matrix_transform_vec4( p, out, texmat, in ); 134710432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 1348f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1349f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1350f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temps(p); 135110432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell } 1352c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell else { 135310432bcc0a2c89916bc98921bcf01e0fbb422dc5Keith Whitwell emit_passthrough(p, VERT_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i); 1354f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1355f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell } 1356f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1357f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1358f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1359f069e5e412eebabe64286d35598173caac5c132eKeith Whitwellstatic void build_pointsize( struct tnl_program *p ) 1360f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 1361f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg eye = get_eye_position(p); 13625f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg state_size = register_param1(p, STATE_POINT_SIZE); 13635f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg state_attenuation = register_param1(p, STATE_POINT_ATTENUATION); 13645f534aa1e2c53360bb1ae42fb196e41aa29d0d3dKeith Whitwell struct ureg out = register_output(p, VERT_RESULT_PSIZ); 1365f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct ureg ut = get_temp(p); 1366f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1367a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger /* dist = |eyez| */ 1368a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op1(p, OPCODE_ABS, ut, WRITEMASK_Y, swizzle1(eye, Z)); 136954dac2c84310536cce962101de29546d3eb80175Roland Scheidegger /* p1 + dist * (p2 + dist * p3); */ 1370a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op3(p, OPCODE_MAD, ut, WRITEMASK_X, swizzle1(ut, Y), 137154dac2c84310536cce962101de29546d3eb80175Roland Scheidegger swizzle1(state_attenuation, Z), swizzle1(state_attenuation, Y)); 1372a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op3(p, OPCODE_MAD, ut, WRITEMASK_X, swizzle1(ut, Y), 137354dac2c84310536cce962101de29546d3eb80175Roland Scheidegger ut, swizzle1(state_attenuation, X)); 137454dac2c84310536cce962101de29546d3eb80175Roland Scheidegger 137554dac2c84310536cce962101de29546d3eb80175Roland Scheidegger /* 1 / sqrt(factor) */ 1376a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op1(p, OPCODE_RSQ, ut, WRITEMASK_X, ut ); 137754dac2c84310536cce962101de29546d3eb80175Roland Scheidegger 137854dac2c84310536cce962101de29546d3eb80175Roland Scheidegger#if 1 137954dac2c84310536cce962101de29546d3eb80175Roland Scheidegger /* out = pointSize / sqrt(factor) */ 138054dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op2(p, OPCODE_MUL, out, WRITEMASK_X, ut, state_size); 138154dac2c84310536cce962101de29546d3eb80175Roland Scheidegger#else 138254dac2c84310536cce962101de29546d3eb80175Roland Scheidegger /* not sure, might make sense to do clamping here, 138354dac2c84310536cce962101de29546d3eb80175Roland Scheidegger but it's not done in t_vb_points neither */ 1384a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op2(p, OPCODE_MUL, ut, WRITEMASK_X, ut, state_size); 1385a6cc9ab493a2efa9a0ea91cddba0e85c8c8c83f1Roland Scheidegger emit_op2(p, OPCODE_MAX, ut, WRITEMASK_X, ut, swizzle1(state_size, Y)); 138654dac2c84310536cce962101de29546d3eb80175Roland Scheidegger emit_op2(p, OPCODE_MIN, out, WRITEMASK_X, ut, swizzle1(state_size, Z)); 138754dac2c84310536cce962101de29546d3eb80175Roland Scheidegger#endif 1388f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1389f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell release_temp(p, ut); 1390f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1391f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1392a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic void build_tnl_program( struct tnl_program *p ) 1393a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ /* Emit the program, starting with modelviewproject: 1394a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1395a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_hpos(p); 1396a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1397a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* Lighting calculations: 1398a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1399c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->fragprog_inputs_read & (FRAG_BIT_COL0|FRAG_BIT_COL1)) { 1400c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->light_global_enabled) 1401c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell build_lighting(p); 1402c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell else { 1403c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->fragprog_inputs_read & FRAG_BIT_COL0) 1404c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell emit_passthrough(p, VERT_ATTRIB_COLOR0, VERT_RESULT_COL0); 1405c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1406c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->fragprog_inputs_read & FRAG_BIT_COL1) 1407f31448f3c86697275bffe5363d473dd128cbd2acAapo Tahkola emit_passthrough(p, VERT_ATTRIB_COLOR1, VERT_RESULT_COL1); 1408c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell } 1409c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell } 1410f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1411c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if ((p->state->fragprog_inputs_read & FRAG_BIT_FOGC) || 1412c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell p->state->fog_mode != FOG_NONE) 1413a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_fog(p); 14145a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1415c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (p->state->fragprog_inputs_read & FRAG_BITS_TEX_ANY) 1416a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_texture_transform(p); 14175a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1418a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (p->state->point_attenuated) 1419a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_pointsize(p); 14205a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1421a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* Finish up: 1422a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 14237e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_op1(p, OPCODE_END, undef, 0, undef); 14245a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1425a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* Disassemble: 1426a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1427a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (DISASSEM) { 1428a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell _mesa_printf ("\n"); 1429a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 14305a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell} 14315a5b4436cb71575884f76bc079156f77e30d72a7Keith Whitwell 1432f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1433c43f03e38dd4bfbcbc0cc8414e2bacfbffad08a1Brian Paulstatic void 1434c43f03e38dd4bfbcbc0cc8414e2bacfbffad08a1Brian Paulcreate_new_program( const struct state_key *key, 1435122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_vertex_program *program, 1436c43f03e38dd4bfbcbc0cc8414e2bacfbffad08a1Brian Paul GLuint max_temps) 1437f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell{ 1438f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell struct tnl_program p; 1439f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 144049d8cbe8d110e5c0a23300b5b82d110286bc3609Keith Whitwell _mesa_memset(&p, 0, sizeof(p)); 1441a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p.state = key; 1442a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p.program = program; 1443f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.eye_position = undef; 1444f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.eye_position_normalized = undef; 1445f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.eye_normal = undef; 1446f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.identity = undef; 14473509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p.temp_in_use = 0; 1448a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1449a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell if (max_temps >= sizeof(int) * 8) 14503509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell p.temp_reserved = 0; 14513509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell else 1452a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell p.temp_reserved = ~((1<<max_temps)-1); 14533509fd8c1b38d955a066a2bad429dbfba162fa30Keith Whitwell 1454002762b13aa58ca569a564bb64672e343611c9edBrian Paul p.program->Base.Instructions = _mesa_alloc_instructions(MAX_INSN); 1455002762b13aa58ca569a564bb64672e343611c9edBrian Paul p.program->Base.String = NULL; 1456f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumInstructions = 1457f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumTemporaries = 1458f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumParameters = 1459f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0; 1460de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.Parameters = _mesa_new_parameter_list(); 1461de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.InputsRead = 0; 1462de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.OutputsWritten = 0; 1463f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1464a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell build_tnl_program( &p ); 1465a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1466f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 14675b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 14685b5c9315275752add1215dba0f86d5f5068d856bBrian Paulstatic struct gl_vertex_program * 14695b5c9315275752add1215dba0f86d5f5068d856bBrian Paulsearch_cache(struct tnl_cache *cache, GLuint hash, 14705b5c9315275752add1215dba0f86d5f5068d856bBrian Paul const void *key, GLuint keysize) 1471a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 147237f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola struct tnl_cache_item *c; 1473a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 147437f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola for (c = cache->items[hash % cache->size]; c; c = c->next) { 1475aa2069586d434dd0487b0daa2b583efe801a0d51Brian Paul if (c->hash == hash && _mesa_memcmp(c->key, key, keysize) == 0) 14765b5c9315275752add1215dba0f86d5f5068d856bBrian Paul return c->prog; 1477a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 1478a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1479a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return NULL; 1480a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1481a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 14825b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 148337f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkolastatic void rehash( struct tnl_cache *cache ) 148437f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola{ 148537f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola struct tnl_cache_item **items; 148637f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola struct tnl_cache_item *c, *next; 148737f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola GLuint size, i; 148837f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 148937f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola size = cache->size * 3; 14909580179dfb42d5b81ff6ec9704b82a556c7f1229Brian Paul items = (struct tnl_cache_item**) _mesa_malloc(size * sizeof(*items)); 149137f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola _mesa_memset(items, 0, size * sizeof(*items)); 149237f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 149337f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola for (i = 0; i < cache->size; i++) 149437f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola for (c = cache->items[i]; c; c = next) { 149537f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola next = c->next; 149637f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola c->next = items[c->hash % size]; 149737f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola items[c->hash % size] = c; 149837f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola } 149937f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 150037f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(cache->items); 150137f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola cache->items = items; 150237f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola cache->size = size; 150337f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola} 150437f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 15055b5c9315275752add1215dba0f86d5f5068d856bBrian Paulstatic void cache_item( GLcontext *ctx, 15065b5c9315275752add1215dba0f86d5f5068d856bBrian Paul struct tnl_cache *cache, 1507a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint hash, 1508a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell void *key, 15095b5c9315275752add1215dba0f86d5f5068d856bBrian Paul struct gl_vertex_program *prog ) 1510a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 15115b5c9315275752add1215dba0f86d5f5068d856bBrian Paul struct tnl_cache_item *c = CALLOC_STRUCT(tnl_cache_item); 1512a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell c->hash = hash; 1513a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell c->key = key; 151496adcc2e214e2fdc2ad15ecac20b1066c6cdd1caNicolai Hähnle 151596adcc2e214e2fdc2ad15ecac20b1066c6cdd1caNicolai Hähnle c->prog = prog; 151637f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 151737f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola if (++cache->n_items > cache->size * 1.5) 151837f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola rehash(cache); 151937f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 152037f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola c->next = cache->items[hash % cache->size]; 152137f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola cache->items[hash % cache->size] = c; 1522a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1523a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1524a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellstatic GLuint hash_key( struct state_key *key ) 1525a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 1526a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint *ikey = (GLuint *)key; 1527a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint hash = 0, i; 1528a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1529a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell /* I'm sure this can be improved on, but speed is important: 1530f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell */ 1531a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell for (i = 0; i < sizeof(*key)/sizeof(GLuint); i++) 1532a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell hash ^= ikey[i]; 1533f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1534a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell return hash; 1535a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1536f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1537a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellvoid _tnl_UpdateFixedFunctionProgram( GLcontext *ctx ) 1538a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 1539a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell TNLcontext *tnl = TNL_CONTEXT(ctx); 1540a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell struct state_key *key; 1541a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell GLuint hash; 1542122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul const struct gl_vertex_program *prev = ctx->VertexProgram._Current; 1543f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell 1544dba21ed913da2222e3b55fc8ba724ca93acbabf1Nicolai Hähnle if (!ctx->VertexProgram._Current || 1545dba21ed913da2222e3b55fc8ba724ca93acbabf1Nicolai Hähnle ctx->VertexProgram._Current == ctx->VertexProgram._TnlProgram) { 15465b5c9315275752add1215dba0f86d5f5068d856bBrian Paul struct gl_vertex_program *newProg; 15475b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 1548c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* Grab all the relevent state and put it in a single structure: 1549c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell */ 1550c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell key = make_state_key(ctx); 1551c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell hash = hash_key(key); 1552c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1553c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* Look for an already-prepared program for this state: 1554c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell */ 15555b5c9315275752add1215dba0f86d5f5068d856bBrian Paul newProg = search_cache( tnl->vp_cache, hash, key, sizeof(*key)); 1556a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1557c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* OK, we'll have to build a new one: 1558c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell */ 15595b5c9315275752add1215dba0f86d5f5068d856bBrian Paul if (!newProg) { 15605b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 1561c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell if (0) 1562c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell _mesa_printf("Build new TNL program\n"); 1563c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 15645b5c9315275752add1215dba0f86d5f5068d856bBrian Paul newProg = (struct gl_vertex_program *) 1565c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); 1566dbeea25bb834479a29712100888c862348112018Keith Whitwell 15675b5c9315275752add1215dba0f86d5f5068d856bBrian Paul create_new_program( key, newProg, ctx->Const.VertexProgram.MaxTemps ); 1568dbeea25bb834479a29712100888c862348112018Keith Whitwell 1569c9515bf1aec3a3d934535a9d2893e90e8b903043Keith Whitwell if (ctx->Driver.ProgramStringNotify) 1570c9515bf1aec3a3d934535a9d2893e90e8b903043Keith Whitwell ctx->Driver.ProgramStringNotify( ctx, GL_VERTEX_PROGRAM_ARB, 15715b5c9315275752add1215dba0f86d5f5068d856bBrian Paul &newProg->Base ); 1572a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 157396adcc2e214e2fdc2ad15ecac20b1066c6cdd1caNicolai Hähnle /* Our ownership of newProg is transferred to the cache */ 15745b5c9315275752add1215dba0f86d5f5068d856bBrian Paul cache_item(ctx, tnl->vp_cache, hash, key, newProg); 1575c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell } 1576e291cf6f8d3423c2f1e123ec2a42f0568019da80Shunichi Fuji else { 1577f27c6f313955b737888ce80752ee9cd895562d40Brian Paul FREE(key); 1578e291cf6f8d3423c2f1e123ec2a42f0568019da80Shunichi Fuji } 15795b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 15805b5c9315275752add1215dba0f86d5f5068d856bBrian Paul _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, newProg); 15815b5c9315275752add1215dba0f86d5f5068d856bBrian Paul _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, newProg); 1582a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell } 1583a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1584c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* Tell the driver about the change. Could define a new target for 1585c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell * this? 1586a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell */ 1587a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul if (ctx->VertexProgram._Current != prev && ctx->Driver.BindProgram) { 1588122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, 1589122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul (struct gl_program *) ctx->VertexProgram._Current); 1590a328e469d328f8b6fd5afdfc21d576fa1a2c43fcBrian Paul } 1591a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell} 1592a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 15939248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkolavoid _tnl_ProgramCacheInit( GLcontext *ctx ) 15949248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola{ 15959248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola TNLcontext *tnl = TNL_CONTEXT(ctx); 15969248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola 15979248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola tnl->vp_cache = (struct tnl_cache *) MALLOC(sizeof(*tnl->vp_cache)); 15989248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola tnl->vp_cache->size = 17; 15999248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola tnl->vp_cache->n_items = 0; 16009248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola tnl->vp_cache->items = (struct tnl_cache_item**) 16019248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola _mesa_calloc(tnl->vp_cache->size * sizeof(*tnl->vp_cache->items)); 16029248882ca27b289180a76262aa3d9b26c0cb0e8bAapo Tahkola} 1603a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 1604a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwellvoid _tnl_ProgramCacheDestroy( GLcontext *ctx ) 1605a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell{ 1606a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell TNLcontext *tnl = TNL_CONTEXT(ctx); 160737f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola struct tnl_cache_item *c, *next; 160837f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola GLuint i; 1609a8534885efb13ec7f071192c1504513cd90d07deKeith Whitwell 161037f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola for (i = 0; i < tnl->vp_cache->size; i++) 161137f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola for (c = tnl->vp_cache->items[i]; c; c = next) { 161237f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola next = c->next; 161337f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(c->key); 16145b5c9315275752add1215dba0f86d5f5068d856bBrian Paul _mesa_reference_vertprog(ctx, &c->prog, NULL); 161537f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(c); 161637f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola } 161737f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola 161837f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(tnl->vp_cache->items); 161937f2eaa316d507b729ca392b651ae18ef92efcacAapo Tahkola FREE(tnl->vp_cache); 1620f069e5e412eebabe64286d35598173caac5c132eKeith Whitwell} 1621